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

Commit e16e1fa9 authored by Ahan Wu's avatar Ahan Wu Committed by Wu Ahan
Browse files

Refine zoom in and zoom out transition of iamge wallpaper.

We do zoom in from lockscreen to aod1 and zoom out in reverse
transition.

Bug: 124822340
Bug: 133785684
Test: manually set image wallpaper.
Test: Press power key back and forth and observe.
Change-Id: I842f929c730d1234717faa77e32f733f131c6ca0
parent f3825f11
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ public class ImageWallpaper extends WallpaperService {
        @Override
        public void onCreate(SurfaceHolder surfaceHolder) {
            setFixedSizeAllowed(true);
            setOffsetNotificationsEnabled(false);
            setOffsetNotificationsEnabled(true);
            updateSurfaceSize();
        }

@@ -95,6 +95,12 @@ public class ImageWallpaper extends WallpaperService {
            holder.setFixedSize(width, height);
        }

        @Override
        public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep,
                float yOffsetStep, int xPixelOffset, int yPixelOffset) {
            mRenderer.updateOffsets(xOffset, yOffset);
        }

        @Override
        public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
            mRenderer.updateAmbientMode(inAmbientMode,
+7 −0
Original line number Diff line number Diff line
@@ -51,6 +51,13 @@ public interface GLWallpaperRenderer {
     */
    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.
     */
+107 −0
Original line number Diff line number Diff line
@@ -33,9 +33,12 @@ 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;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
@@ -91,6 +94,8 @@ class ImageGLWallpaper {
    private int mUniTexture;
    private int mTextureId;

    private float[] mCurrentTexCoordinate;

    ImageGLWallpaper(ImageGLProgram program) {
        mProgram = program;

@@ -195,4 +200,106 @@ 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.
     * @param fd fd.
     * @param out out.
     * @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());
    }
}
+54 −12
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import android.graphics.Rect;
import android.util.Log;
import android.util.MathUtils;
import android.util.Size;
import android.view.DisplayInfo;
import android.view.WindowManager;

import com.android.systemui.R;

@@ -41,8 +43,8 @@ import java.io.PrintWriter;
public class ImageWallpaperRenderer implements GLWallpaperRenderer,
        ImageRevealHelper.RevealStateListener {
    private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
    private static final float SCALE_VIEWPORT_MIN = 0.98f;
    private static final float SCALE_VIEWPORT_MAX = 1f;
    private static final float SCALE_VIEWPORT_MIN = 1f;
    private static final float SCALE_VIEWPORT_MAX = 1.1f;

    private final WallpaperManager mWallpaperManager;
    private final ImageGLProgram mProgram;
@@ -51,8 +53,13 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
    private final ImageRevealHelper mImageRevealHelper;

    private SurfaceProxy mProxy;
    private Rect mSurfaceSize;
    private final Rect mScissor;
    private final Rect mSurfaceSize = new Rect();
    private final Rect mViewport = new Rect();
    private Bitmap mBitmap;
    private boolean mScissorMode;
    private float mXOffset;
    private float mYOffset;

    public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) {
        mWallpaperManager = context.getSystemService(WallpaperManager.class);
@@ -60,6 +67,11 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
            Log.w(TAG, "WallpaperManager not available");
        }

        DisplayInfo displayInfo = new DisplayInfo();
        WindowManager wm = context.getSystemService(WindowManager.class);
        wm.getDefaultDisplay().getDisplayInfo(displayInfo);
        mScissor = new Rect(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);

        mProxy = proxy;
        mProgram = new ImageGLProgram(context);
        mWallpaper = new ImageGLWallpaper(mProgram);
@@ -91,7 +103,7 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
            mBitmap = mWallpaperManager.getBitmap();
            mWallpaperManager.forgetLoadedWallpaper();
            if (mBitmap != null) {
                mSurfaceSize = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
                mSurfaceSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
            }
        }
        return mBitmap != null;
@@ -107,13 +119,17 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
        float threshold = mImageProcessHelper.getThreshold();
        float reveal = mImageRevealHelper.getReveal();

        glClear(GL_COLOR_BUFFER_BIT);

        glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_AOD2OPACITY), 1);
        glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_PER85), threshold);
        glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_REVEAL), reveal);

        glClear(GL_COLOR_BUFFER_BIT);
        // We only need to scale viewport while doing transition.
        if (mScissorMode) {
            scaleViewport(reveal);
        } else {
            glViewport(0, 0, mSurfaceSize.width(), mSurfaceSize.height());
        }
        mWallpaper.useTexture();
        mWallpaper.draw();
    }
@@ -123,6 +139,15 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
        mImageRevealHelper.updateAwake(!inAmbientMode, duration);
    }

    @Override
    public void updateOffsets(float xOffset, float yOffset) {
        mXOffset = xOffset;
        mYOffset = yOffset;
        int left = (int) ((mSurfaceSize.width() - mScissor.width()) * xOffset);
        int right = left + mScissor.width();
        mScissor.set(left, mScissor.top, right, mScissor.bottom);
    }

    @Override
    public Size reportSurfaceSize() {
        return new Size(mSurfaceSize.width(), mSurfaceSize.height());
@@ -134,15 +159,18 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
    }

    private void scaleViewport(float reveal) {
        int width = mSurfaceSize.width();
        int height = mSurfaceSize.height();
        int left = mScissor.left;
        int top = mScissor.top;
        int width = mScissor.width();
        int height = mScissor.height();
        // Interpolation between SCALE_VIEWPORT_MAX and SCALE_VIEWPORT_MIN by reveal.
        float vpScaled = MathUtils.lerp(SCALE_VIEWPORT_MAX, SCALE_VIEWPORT_MIN, reveal);
        float vpScaled = MathUtils.lerp(SCALE_VIEWPORT_MIN, SCALE_VIEWPORT_MAX, reveal);
        // Calculate the offset amount from the lower left corner.
        float offset = (SCALE_VIEWPORT_MAX - vpScaled) / 2;
        float offset = (SCALE_VIEWPORT_MIN - vpScaled) / 2;
        // Change the viewport.
        glViewport((int) (width * offset), (int) (height * offset),
        mViewport.set((int) (left + width * offset), (int) (top + height * offset),
                (int) (width * vpScaled), (int) (height * vpScaled));
        glViewport(mViewport.left, mViewport.top, mViewport.right, mViewport.bottom);
    }

    @Override
@@ -152,11 +180,19 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,

    @Override
    public void onRevealStart() {
        mScissorMode = true;
        // Use current display area of texture.
        mWallpaper.adjustTextureCoordinates(mSurfaceSize, mScissor, mXOffset, mYOffset);
        mProxy.preRender();
    }

    @Override
    public void onRevealEnd() {
        mScissorMode = false;
        // reset texture coordinates to use full texture.
        mWallpaper.adjustTextureCoordinates(null, null, 0, 0);
        // We need draw full texture back before finishing render.
        mProxy.requestRender();
        mProxy.postRender();
    }

@@ -164,6 +200,12 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
    public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
        out.print(prefix); out.print("mProxy="); out.print(mProxy);
        out.print(prefix); out.print("mSurfaceSize="); out.print(mSurfaceSize);
        out.print(prefix); out.print("mScissor="); out.print(mScissor);
        out.print(prefix); out.print("mViewport="); out.print(mViewport);
        out.print(prefix); out.print("mScissorMode="); out.print(mScissorMode);
        out.print(prefix); out.print("mXOffset="); out.print(mXOffset);
        out.print(prefix); out.print("mYOffset="); out.print(mYOffset);
        out.print(prefix); out.print("threshold="); out.print(mImageProcessHelper.getThreshold());
        mWallpaper.dump(prefix, fd, out, args);
    }
}