Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31b94bfc authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Remove unnecessary transition logic from ImageWallpaper" into rvc-dev

parents cd63ddf9 4a297798
Loading
Loading
Loading
Loading
+1 −66
Original line number Diff line number Diff line
@@ -3,74 +3,9 @@ precision mediump float;
// The actual wallpaper texture.
uniform sampler2D uTexture;

// The 85th percenile for the luminance histogram of the image (a value between 0 and 1).
// This value represents the point in histogram that includes 85% of the pixels of the image.
uniform float uPer85;

// Reveal is the animation value that goes from 1 (the image is hidden) to 0 (the image is visible).
uniform float uReveal;

// The opacity of locked screen (constant value).
uniform float uAod2Opacity;
varying vec2 vTextureCoordinates;

/*
 * Calculates the relative luminance of the pixel.
 */
vec3 luminosity(vec3 color) {
    float lum = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
    return vec3(lum);
}

vec4 transform(vec3 diffuse) {
    // Getting the luminance for this pixel
    vec3 lum = luminosity(diffuse);

    /*
     * while the reveal > per85, it shows the luminance image (B&W image)
     * then when moving passed that value, the image gets colored.
     */
    float trans = smoothstep(0., uPer85, uReveal);
    diffuse = mix(diffuse, lum, trans);

    // 'lower' value represents the capped 'reveal' value to the range [0, per85]
    float selector = step(uPer85, uReveal);
    float lower = mix(uReveal, uPer85, selector);

    /*
     * Remaps image:
     * - from reveal=1 to reveal=per85 => lower=per85, diffuse=luminance
     *   That means that remaps black and white image pixel
     *   from a possible values of [0,1] to [per85, 1] (if the pixel is darker than per85,
     *   it's gonna be black, if it's between per85 and 1, it's gonna be gray
     *   and if it's 1 it's gonna be white).
     * - from reveal=per85 to reveal=0 => lower=reveal, 'diffuse' changes from luminance to color
     *   That means that remaps each image pixel color (rgb)
     *   from a possible values of [0,1] to [lower, 1] (if the pixel color is darker than 'lower',
     *   it's gonna be 0, if it's between 'lower' and 1, it's gonna be remap to a value
     *   between 0 and 1 and if it's 1 it's gonna be 1).
     * - if reveal=0 => lower=0, diffuse=color image
     *   The image is shown as it is, colored.
     */
    vec3 remaps = smoothstep(lower, 1., diffuse);

    // Interpolate between diffuse and remaps using reveal to avoid over saturation.
    diffuse = mix(diffuse, remaps, uReveal);

    /*
     * Fades in the pixel value:
     * - if reveal=1 => fadeInOpacity=0
     * - from reveal=1 to reveal=per85 => 0<=fadeInOpacity<=1
     * - if reveal>per85 => fadeInOpacity=1
     */
    float fadeInOpacity = 1. - smoothstep(uPer85, 1., uReveal);
    diffuse *= uAod2Opacity * fadeInOpacity;

    return vec4(diffuse.r, diffuse.g, diffuse.b, 1.);
}

void main() {
    // gets the pixel value of the wallpaper for this uv coordinates on screen.
    vec4 fragColor = texture2D(uTexture, vTextureCoordinates);
    gl_FragColor = transform(fragColor.rgb);
    gl_FragColor = texture2D(uTexture, vTextureCoordinates);
}
 No newline at end of file
+11 −176
Original line number Diff line number Diff line
@@ -16,9 +16,6 @@

package com.android.systemui;

import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Handler;
import android.os.HandlerThread;
@@ -27,17 +24,12 @@ import android.os.Trace;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.util.Size;
import android.view.DisplayInfo;
import android.view.SurfaceHolder;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.glwallpaper.EglHelper;
import com.android.systemui.glwallpaper.GLWallpaperRenderer;
import com.android.systemui.glwallpaper.ImageWallpaperRenderer;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.DozeParameters;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -53,16 +45,12 @@ public class ImageWallpaper extends WallpaperService {
    // We delayed destroy render context that subsequent render requests have chance to cancel it.
    // This is to avoid destroying then recreating render context in a very short time.
    private static final int DELAY_FINISH_RENDERING = 1000;
    private static final int INTERVAL_WAIT_FOR_RENDERING = 100;
    private static final int PATIENCE_WAIT_FOR_RENDERING = 10;
    private static final boolean DEBUG = true;
    private final DozeParameters mDozeParameters;
    private static final boolean DEBUG = false;
    private HandlerThread mWorker;

    @Inject
    public ImageWallpaper(DozeParameters dozeParameters) {
    public ImageWallpaper() {
        super();
        mDozeParameters = dozeParameters;
    }

    @Override
@@ -74,7 +62,7 @@ public class ImageWallpaper extends WallpaperService {

    @Override
    public Engine onCreateEngine() {
        return new GLEngine(this, mDozeParameters);
        return new GLEngine();
    }

    @Override
@@ -84,7 +72,7 @@ public class ImageWallpaper extends WallpaperService {
        mWorker = null;
    }

    class GLEngine extends Engine implements GLWallpaperRenderer.SurfaceProxy, StateListener {
    class GLEngine extends Engine {
        // Surface is rejected if size below a threshold on some devices (ie. 8px on elfin)
        // set min to 64 px (CTS covers this), please refer to ag/4867989 for detail.
        @VisibleForTesting
@@ -94,40 +82,15 @@ public class ImageWallpaper extends WallpaperService {

        private GLWallpaperRenderer mRenderer;
        private EglHelper mEglHelper;
        private StatusBarStateController mController;
        private final Runnable mFinishRenderingTask = this::finishRendering;
        private boolean mShouldStopTransition;
        private final DisplayInfo mDisplayInfo = new DisplayInfo();
        private final Object mMonitor = new Object();
        @VisibleForTesting
        boolean mIsHighEndGfx;
        private boolean mDisplayNeedsBlanking;
        private boolean mNeedTransition;
        private boolean mNeedRedraw;
        // This variable can only be accessed in synchronized block.
        private boolean mWaitingForRendering;

        GLEngine(Context context, DozeParameters dozeParameters) {
            init(dozeParameters);
        GLEngine() {
        }

        @VisibleForTesting
        GLEngine(DozeParameters dozeParameters, Handler handler) {
        GLEngine(Handler handler) {
            super(SystemClock::elapsedRealtime, handler);
            init(dozeParameters);
        }

        private void init(DozeParameters dozeParameters) {
            mIsHighEndGfx = ActivityManager.isHighEndGfx();
            mDisplayNeedsBlanking = dozeParameters.getDisplayNeedsBlanking();
            mNeedTransition = false;

            // We will preserve EGL context when we are in lock screen or aod
            // to avoid janking in following transition, we need to release when back to home.
            mController = Dependency.get(StatusBarStateController.class);
            if (mController != null) {
                mController.addCallback(this /* StateListener */);
            }
        }

        @Override
@@ -135,9 +98,8 @@ public class ImageWallpaper extends WallpaperService {
            mEglHelper = getEglHelperInstance();
            // Deferred init renderer because we need to get wallpaper by display context.
            mRenderer = getRendererInstance();
            getDisplayContext().getDisplay().getDisplayInfo(mDisplayInfo);
            setFixedSizeAllowed(true);
            setOffsetNotificationsEnabled(mNeedTransition);
            setOffsetNotificationsEnabled(false);
            updateSurfaceSize();
        }

@@ -146,7 +108,7 @@ public class ImageWallpaper extends WallpaperService {
        }

        ImageWallpaperRenderer getRendererInstance() {
            return new ImageWallpaperRenderer(getDisplayContext(), this /* SurfaceProxy */);
            return new ImageWallpaperRenderer(getDisplayContext());
        }

        private void updateSurfaceSize() {
@@ -157,79 +119,13 @@ public class ImageWallpaper extends WallpaperService {
            holder.setFixedSize(width, height);
        }

        /**
         * Check if necessary to stop transition with current wallpaper on this device. <br/>
         * This should only be invoked after {@link #onSurfaceCreated(SurfaceHolder)}}
         * is invoked since it needs display context and surface frame size.
         * @return true if need to stop transition.
         */
        @VisibleForTesting
        boolean checkIfShouldStopTransition() {
            int orientation = getDisplayContext().getResources().getConfiguration().orientation;
            Rect frame = getSurfaceHolder().getSurfaceFrame();
            Rect display = new Rect();
            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
                display.set(0, 0, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
            } else {
                display.set(0, 0, mDisplayInfo.logicalHeight, mDisplayInfo.logicalWidth);
            }
            return mNeedTransition
                    && (frame.width() < display.width() || frame.height() < display.height());
        }

        @Override
        public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep,
                float yOffsetStep, int xPixelOffset, int yPixelOffset) {
            if (mWorker == null) return;
            mWorker.getThreadHandler().post(() -> mRenderer.updateOffsets(xOffset, yOffset));
        }

        @Override
        public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
            if (mWorker == null || !mNeedTransition) return;
            final long duration = mShouldStopTransition ? 0 : animationDuration;
            if (DEBUG) {
                Log.d(TAG, "onAmbientModeChanged: inAmbient=" + inAmbientMode
                        + ", duration=" + duration
                        + ", mShouldStopTransition=" + mShouldStopTransition);
            }
            mWorker.getThreadHandler().post(
                    () -> mRenderer.updateAmbientMode(inAmbientMode, duration));
            if (inAmbientMode && animationDuration == 0) {
                // This means that we are transiting from home to aod, to avoid
                // race condition between window visibility and transition,
                // we don't return until the transition is finished. See b/136643341.
                waitForBackgroundRendering();
            }
        }

        @Override
        public boolean shouldZoomOutWallpaper() {
            return true;
        }

        private void waitForBackgroundRendering() {
            synchronized (mMonitor) {
                try {
                    mWaitingForRendering = true;
                    for (int patience = 1; mWaitingForRendering; patience++) {
                        mMonitor.wait(INTERVAL_WAIT_FOR_RENDERING);
                        mWaitingForRendering &= patience < PATIENCE_WAIT_FOR_RENDERING;
                    }
                } catch (InterruptedException ex) {
                } finally {
                    mWaitingForRendering = false;
                }
            }
        }

        @Override
        public void onDestroy() {
            if (mController != null) {
                mController.removeCallback(this /* StateListener */);
            }
            mController = null;

            mWorker.getThreadHandler().post(() -> {
                mRenderer.finish();
                mRenderer = null;
@@ -240,7 +136,6 @@ public class ImageWallpaper extends WallpaperService {

        @Override
        public void onSurfaceCreated(SurfaceHolder holder) {
            mShouldStopTransition = checkIfShouldStopTransition();
            if (mWorker == null) return;
            mWorker.getThreadHandler().post(() -> {
                mEglHelper.init(holder, needSupportWideColorGamut());
@@ -251,32 +146,13 @@ public class ImageWallpaper extends WallpaperService {
        @Override
        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            if (mWorker == null) return;
            mWorker.getThreadHandler().post(() -> {
                mRenderer.onSurfaceChanged(width, height);
                mNeedRedraw = true;
            });
            mWorker.getThreadHandler().post(() -> mRenderer.onSurfaceChanged(width, height));
        }

        @Override
        public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
            if (mWorker == null) return;
            if (DEBUG) {
                Log.d(TAG, "onSurfaceRedrawNeeded: mNeedRedraw=" + mNeedRedraw);
            }

            mWorker.getThreadHandler().post(() -> {
                if (mNeedRedraw) {
                    drawFrame();
                    mNeedRedraw = false;
                }
            });
        }

        @Override
        public void onVisibilityChanged(boolean visible) {
            if (DEBUG) {
                Log.d(TAG, "wallpaper visibility changes: " + visible);
            }
            mWorker.getThreadHandler().post(this::drawFrame);
        }

        private void drawFrame() {
@@ -285,15 +161,6 @@ public class ImageWallpaper extends WallpaperService {
            postRender();
        }

        @Override
        public void onStatePostChange() {
            // When back to home, we try to release EGL, which is preserved in lock screen or aod.
            if (mWorker != null && mController.getState() == StatusBarState.SHADE) {
                mWorker.getThreadHandler().post(this::scheduleFinishRendering);
            }
        }

        @Override
        public void preRender() {
            // This method should only be invoked from worker thread.
            Trace.beginSection("ImageWallpaper#preRender");
@@ -330,7 +197,6 @@ public class ImageWallpaper extends WallpaperService {
            }
        }

        @Override
        public void requestRender() {
            // This method should only be invoked from worker thread.
            Trace.beginSection("ImageWallpaper#requestRender");
@@ -355,27 +221,13 @@ public class ImageWallpaper extends WallpaperService {
            }
        }

        @Override
        public void postRender() {
            // This method should only be invoked from worker thread.
            Trace.beginSection("ImageWallpaper#postRender");
            notifyWaitingThread();
            scheduleFinishRendering();
            Trace.endSection();
        }

        private void notifyWaitingThread() {
            synchronized (mMonitor) {
                if (mWaitingForRendering) {
                    try {
                        mWaitingForRendering = false;
                        mMonitor.notify();
                    } catch (IllegalMonitorStateException ex) {
                    }
                }
            }
        }

        private void cancelFinishRenderingTask() {
            if (mWorker == null) return;
            mWorker.getThreadHandler().removeCallbacks(mFinishRenderingTask);
@@ -391,18 +243,11 @@ public class ImageWallpaper extends WallpaperService {
            Trace.beginSection("ImageWallpaper#finishRendering");
            if (mEglHelper != null) {
                mEglHelper.destroyEglSurface();
                if (!needPreserveEglContext()) {
                mEglHelper.destroyEglContext();
            }
            }
            Trace.endSection();
        }

        private boolean needPreserveEglContext() {
            return mNeedTransition && mController != null
                    && mController.getState() == StatusBarState.KEYGUARD;
        }

        private boolean needSupportWideColorGamut() {
            return mRenderer.isWcgContent();
        }
@@ -411,16 +256,6 @@ public class ImageWallpaper extends WallpaperService {
        protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
            super.dump(prefix, fd, out, args);
            out.print(prefix); out.print("Engine="); out.println(this);
            out.print(prefix); out.print("isHighEndGfx="); out.println(mIsHighEndGfx);
            out.print(prefix); out.print("displayNeedsBlanking=");
            out.println(mDisplayNeedsBlanking);
            out.print(prefix); out.print("displayInfo="); out.print(mDisplayInfo);
            out.print(prefix); out.print("mNeedTransition="); out.println(mNeedTransition);
            out.print(prefix); out.print("mShouldStopTransition=");
            out.println(mShouldStopTransition);
            out.print(prefix); out.print("StatusBarState=");
            out.println(mController != null ? mController.getState() : "null");

            out.print(prefix); out.print("valid surface=");
            out.println(getSurfaceHolder() != null && getSurfaceHolder().getSurface() != null
                    ? getSurfaceHolder().getSurface().isValid()
+0 −34
Original line number Diff line number Diff line
@@ -48,20 +48,6 @@ public interface GLWallpaperRenderer {
     */
    void onDrawFrame();

    /**
     * Notify ambient mode is changed.
     * @param inAmbientMode true if in ambient mode.
     * @param duration duration of transition.
     */
    void updateAmbientMode(boolean inAmbientMode, long duration);

    /**
     * Notify the wallpaper offsets changed.
     * @param xOffset offset along x axis.
     * @param yOffset offset along y axis.
     */
    void updateOffsets(float xOffset, float yOffset);

    /**
     * Ask renderer to report the surface size it needs.
     */
@@ -81,24 +67,4 @@ public interface GLWallpaperRenderer {
     */
    void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args);

    /**
     * A proxy which owns surface holder.
     */
    interface SurfaceProxy {

        /**
         * Ask proxy to start rendering frame to surface.
         */
        void requestRender();

        /**
         * Ask proxy to prepare render context.
         */
        void preRender();

        /**
         * Ask proxy to destroy render context.
         */
        void postRender();
    }
}
+3 −129
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import static android.opengl.GLES20.glUniform1i;
import static android.opengl.GLES20.glVertexAttribPointer;

import android.graphics.Bitmap;
import android.graphics.Rect;
import android.opengl.GLUtils;
import android.util.Log;

@@ -50,14 +49,9 @@ import java.nio.FloatBuffer;
class ImageGLWallpaper {
    private static final String TAG = ImageGLWallpaper.class.getSimpleName();

    static final String A_POSITION = "aPosition";
    static final String A_TEXTURE_COORDINATES = "aTextureCoordinates";
    static final String U_PER85 = "uPer85";
    static final String U_REVEAL = "uReveal";
    static final String U_AOD2OPACITY = "uAod2Opacity";
    static final String U_TEXTURE = "uTexture";

    private static final int HANDLE_UNDEFINED = -1;
    private static final String A_POSITION = "aPosition";
    private static final String A_TEXTURE_COORDINATES = "aTextureCoordinates";
    private static final String U_TEXTURE = "uTexture";
    private static final int POSITION_COMPONENT_COUNT = 2;
    private static final int TEXTURE_COMPONENT_COUNT = 2;
    private static final int BYTES_PER_FLOAT = 4;
@@ -88,14 +82,9 @@ class ImageGLWallpaper {

    private int mAttrPosition;
    private int mAttrTextureCoordinates;
    private int mUniAod2Opacity;
    private int mUniPer85;
    private int mUniReveal;
    private int mUniTexture;
    private int mTextureId;

    private float[] mCurrentTexCoordinate;

    ImageGLWallpaper(ImageGLProgram program) {
        mProgram = program;

@@ -135,31 +124,9 @@ class ImageGLWallpaper {
    }

    private void setupUniforms() {
        mUniAod2Opacity = mProgram.getUniformHandle(U_AOD2OPACITY);
        mUniPer85 = mProgram.getUniformHandle(U_PER85);
        mUniReveal = mProgram.getUniformHandle(U_REVEAL);
        mUniTexture = mProgram.getUniformHandle(U_TEXTURE);
    }

    int getHandle(String name) {
        switch (name) {
            case A_POSITION:
                return mAttrPosition;
            case A_TEXTURE_COORDINATES:
                return mAttrTextureCoordinates;
            case U_AOD2OPACITY:
                return mUniAod2Opacity;
            case U_PER85:
                return mUniPer85;
            case U_REVEAL:
                return mUniReveal;
            case U_TEXTURE:
                return mUniTexture;
            default:
                return HANDLE_UNDEFINED;
        }
    }

    void draw() {
        glDrawArrays(GL_TRIANGLES, 0, VERTICES.length / 2);
    }
@@ -200,87 +167,6 @@ class ImageGLWallpaper {
        glUniform1i(mUniTexture, 0);
    }

    /**
     * This method adjust s(x-axis), t(y-axis) texture coordinates to get current display area
     * of texture and will be used during transition.
     * The adjustment happens if either the width or height of the surface is larger than
     * corresponding size of the display area.
     * If both width and height are larger than corresponding size of the display area,
     * the adjustment will happen at both s, t side.
     *
     * @param surface The size of the surface.
     * @param scissor The display area.
     * @param xOffset The offset amount along s axis.
     * @param yOffset The offset amount along t axis.
     */
    void adjustTextureCoordinates(Rect surface, Rect scissor, float xOffset, float yOffset) {
        mCurrentTexCoordinate = TEXTURES.clone();

        if (surface == null || scissor == null) {
            mTextureBuffer.put(mCurrentTexCoordinate);
            mTextureBuffer.position(0);
            return;
        }

        int surfaceWidth = surface.width();
        int surfaceHeight = surface.height();
        int scissorWidth = scissor.width();
        int scissorHeight = scissor.height();

        if (surfaceWidth > scissorWidth) {
            // Calculate the new s pos in pixels.
            float pixelS = (float) Math.round((surfaceWidth - scissorWidth) * xOffset);
            // Calculate the s pos in texture coordinate.
            float coordinateS = pixelS / surfaceWidth;
            // Calculate the percentage occupied by the scissor width in surface width.
            float surfacePercentageW = (float) scissorWidth / surfaceWidth;
            // Need also consider the case if surface height is smaller than scissor height.
            if (surfaceHeight < scissorHeight) {
                // We will narrow the surface percentage to keep aspect ratio.
                surfacePercentageW *= (float) surfaceHeight / scissorHeight;
            }
            // Determine the final s pos, also limit the legal s pos to prevent from out of range.
            float s = coordinateS + surfacePercentageW > 1f ? 1f - surfacePercentageW : coordinateS;
            // Traverse the s pos in texture coordinates array and adjust the s pos accordingly.
            for (int i = 0; i < mCurrentTexCoordinate.length; i += 2) {
                // indices 2, 4 and 6 are the end of s coordinates.
                if (i == 2 || i == 4 || i == 6) {
                    mCurrentTexCoordinate[i] = Math.min(1f, s + surfacePercentageW);
                } else {
                    mCurrentTexCoordinate[i] = s;
                }
            }
        }

        if (surfaceHeight > scissorHeight) {
            // Calculate the new t pos in pixels.
            float pixelT = (float) Math.round((surfaceHeight - scissorHeight) * yOffset);
            // Calculate the t pos in texture coordinate.
            float coordinateT = pixelT / surfaceHeight;
            // Calculate the percentage occupied by the scissor height in surface height.
            float surfacePercentageH = (float) scissorHeight / surfaceHeight;
            // Need also consider the case if surface width is smaller than scissor width.
            if (surfaceWidth < scissorWidth) {
                // We will narrow the surface percentage to keep aspect ratio.
                surfacePercentageH *= (float) surfaceWidth / scissorWidth;
            }
            // Determine the final t pos, also limit the legal t pos to prevent from out of range.
            float t = coordinateT + surfacePercentageH > 1f ? 1f - surfacePercentageH : coordinateT;
            // Traverse the t pos in texture coordinates array and adjust the t pos accordingly.
            for (int i = 1; i < mCurrentTexCoordinate.length; i += 2) {
                // indices 1, 3 and 11 are the end of t coordinates.
                if (i == 1 || i == 3 || i == 11) {
                    mCurrentTexCoordinate[i] = Math.min(1f, t + surfacePercentageH);
                } else {
                    mCurrentTexCoordinate[i] = t;
                }
            }
        }

        mTextureBuffer.put(mCurrentTexCoordinate);
        mTextureBuffer.position(0);
    }

    /**
     * Called to dump current state.
     * @param prefix prefix.
@@ -289,17 +175,5 @@ class ImageGLWallpaper {
     * @param args args.
     */
    public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
        StringBuilder sb = new StringBuilder();
        sb.append('{');
        if (mCurrentTexCoordinate != null) {
            for (int i = 0; i < mCurrentTexCoordinate.length; i++) {
                sb.append(mCurrentTexCoordinate[i]).append(',');
                if (i == mCurrentTexCoordinate.length - 1) {
                    sb.deleteCharAt(sb.length() - 1);
                }
            }
        }
        sb.append('}');
        out.print(prefix); out.print("mTexCoordinates="); out.println(sb.toString());
    }
}
+0 −246

File deleted.

Preview size limit exceeded, changes collapsed.

Loading