diff options
4 files changed, 175 insertions, 13 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java index 84842563cbdc..e9eda4f5577b 100644 --- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java @@ -83,7 +83,7 @@ public class ImageWallpaper extends WallpaperService {          @Override          public void onCreate(SurfaceHolder surfaceHolder) {              setFixedSizeAllowed(true); -            setOffsetNotificationsEnabled(false); +            setOffsetNotificationsEnabled(true);              updateSurfaceSize();          } @@ -96,6 +96,12 @@ public class ImageWallpaper extends WallpaperService {          }          @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,                      (mNeedTransition || animationDuration != 0) ? animationDuration : 0); diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java index 5d85cbf88f4e..b615a5f32835 100644 --- a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java +++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java @@ -52,6 +52,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.       */      Size reportSurfaceSize(); diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java index 4be7623f90f2..626d0cfed997 100644 --- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java @@ -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()); +    }  } diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java index 21711fb1890c..93d8dd6146a6 100644 --- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java +++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java @@ -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); -        scaleViewport(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();      } @@ -124,6 +140,15 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,      }      @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);      }  }  |