Merge "Refine zoom in and zoom out transition of iamge wallpaper." into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
9bd11895d8
@@ -83,7 +83,7 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(SurfaceHolder surfaceHolder) {
|
public void onCreate(SurfaceHolder surfaceHolder) {
|
||||||
setFixedSizeAllowed(true);
|
setFixedSizeAllowed(true);
|
||||||
setOffsetNotificationsEnabled(false);
|
setOffsetNotificationsEnabled(true);
|
||||||
updateSurfaceSize();
|
updateSurfaceSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +95,12 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
holder.setFixedSize(width, height);
|
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
|
@Override
|
||||||
public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
|
public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
|
||||||
mRenderer.updateAmbientMode(inAmbientMode,
|
mRenderer.updateAmbientMode(inAmbientMode,
|
||||||
|
|||||||
@@ -51,6 +51,13 @@ public interface GLWallpaperRenderer {
|
|||||||
*/
|
*/
|
||||||
void updateAmbientMode(boolean inAmbientMode, long duration);
|
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.
|
* Ask renderer to report the surface size it needs.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -33,9 +33,12 @@ import static android.opengl.GLES20.glUniform1i;
|
|||||||
import static android.opengl.GLES20.glVertexAttribPointer;
|
import static android.opengl.GLES20.glVertexAttribPointer;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.opengl.GLUtils;
|
import android.opengl.GLUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.FileDescriptor;
|
||||||
|
import java.io.PrintWriter;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
@@ -91,6 +94,8 @@ class ImageGLWallpaper {
|
|||||||
private int mUniTexture;
|
private int mUniTexture;
|
||||||
private int mTextureId;
|
private int mTextureId;
|
||||||
|
|
||||||
|
private float[] mCurrentTexCoordinate;
|
||||||
|
|
||||||
ImageGLWallpaper(ImageGLProgram program) {
|
ImageGLWallpaper(ImageGLProgram program) {
|
||||||
mProgram = program;
|
mProgram = program;
|
||||||
|
|
||||||
@@ -195,4 +200,106 @@ class ImageGLWallpaper {
|
|||||||
glUniform1i(mUniTexture, 0);
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ import android.graphics.Rect;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.MathUtils;
|
import android.util.MathUtils;
|
||||||
import android.util.Size;
|
import android.util.Size;
|
||||||
|
import android.view.DisplayInfo;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
|
||||||
@@ -41,8 +43,8 @@ import java.io.PrintWriter;
|
|||||||
public class ImageWallpaperRenderer implements GLWallpaperRenderer,
|
public class ImageWallpaperRenderer implements GLWallpaperRenderer,
|
||||||
ImageRevealHelper.RevealStateListener {
|
ImageRevealHelper.RevealStateListener {
|
||||||
private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
|
private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
|
||||||
private static final float SCALE_VIEWPORT_MIN = 0.98f;
|
private static final float SCALE_VIEWPORT_MIN = 1f;
|
||||||
private static final float SCALE_VIEWPORT_MAX = 1f;
|
private static final float SCALE_VIEWPORT_MAX = 1.1f;
|
||||||
|
|
||||||
private final WallpaperManager mWallpaperManager;
|
private final WallpaperManager mWallpaperManager;
|
||||||
private final ImageGLProgram mProgram;
|
private final ImageGLProgram mProgram;
|
||||||
@@ -51,8 +53,13 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
|
|||||||
private final ImageRevealHelper mImageRevealHelper;
|
private final ImageRevealHelper mImageRevealHelper;
|
||||||
|
|
||||||
private SurfaceProxy mProxy;
|
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 Bitmap mBitmap;
|
||||||
|
private boolean mScissorMode;
|
||||||
|
private float mXOffset;
|
||||||
|
private float mYOffset;
|
||||||
|
|
||||||
public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) {
|
public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) {
|
||||||
mWallpaperManager = context.getSystemService(WallpaperManager.class);
|
mWallpaperManager = context.getSystemService(WallpaperManager.class);
|
||||||
@@ -60,6 +67,11 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
|
|||||||
Log.w(TAG, "WallpaperManager not available");
|
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;
|
mProxy = proxy;
|
||||||
mProgram = new ImageGLProgram(context);
|
mProgram = new ImageGLProgram(context);
|
||||||
mWallpaper = new ImageGLWallpaper(mProgram);
|
mWallpaper = new ImageGLWallpaper(mProgram);
|
||||||
@@ -91,7 +103,7 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
|
|||||||
mBitmap = mWallpaperManager.getBitmap();
|
mBitmap = mWallpaperManager.getBitmap();
|
||||||
mWallpaperManager.forgetLoadedWallpaper();
|
mWallpaperManager.forgetLoadedWallpaper();
|
||||||
if (mBitmap != null) {
|
if (mBitmap != null) {
|
||||||
mSurfaceSize = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
|
mSurfaceSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mBitmap != null;
|
return mBitmap != null;
|
||||||
@@ -107,13 +119,17 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
|
|||||||
float threshold = mImageProcessHelper.getThreshold();
|
float threshold = mImageProcessHelper.getThreshold();
|
||||||
float reveal = mImageRevealHelper.getReveal();
|
float reveal = mImageRevealHelper.getReveal();
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_AOD2OPACITY), 1);
|
glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_AOD2OPACITY), 1);
|
||||||
glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_PER85), threshold);
|
glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_PER85), threshold);
|
||||||
glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_REVEAL), reveal);
|
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.useTexture();
|
||||||
mWallpaper.draw();
|
mWallpaper.draw();
|
||||||
}
|
}
|
||||||
@@ -123,6 +139,15 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
|
|||||||
mImageRevealHelper.updateAwake(!inAmbientMode, duration);
|
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
|
@Override
|
||||||
public Size reportSurfaceSize() {
|
public Size reportSurfaceSize() {
|
||||||
return new Size(mSurfaceSize.width(), mSurfaceSize.height());
|
return new Size(mSurfaceSize.width(), mSurfaceSize.height());
|
||||||
@@ -134,15 +159,18 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void scaleViewport(float reveal) {
|
private void scaleViewport(float reveal) {
|
||||||
int width = mSurfaceSize.width();
|
int left = mScissor.left;
|
||||||
int height = mSurfaceSize.height();
|
int top = mScissor.top;
|
||||||
|
int width = mScissor.width();
|
||||||
|
int height = mScissor.height();
|
||||||
// Interpolation between SCALE_VIEWPORT_MAX and SCALE_VIEWPORT_MIN by reveal.
|
// 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.
|
// 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.
|
// 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));
|
(int) (width * vpScaled), (int) (height * vpScaled));
|
||||||
|
glViewport(mViewport.left, mViewport.top, mViewport.right, mViewport.bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -152,11 +180,19 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRevealStart() {
|
public void onRevealStart() {
|
||||||
|
mScissorMode = true;
|
||||||
|
// Use current display area of texture.
|
||||||
|
mWallpaper.adjustTextureCoordinates(mSurfaceSize, mScissor, mXOffset, mYOffset);
|
||||||
mProxy.preRender();
|
mProxy.preRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRevealEnd() {
|
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();
|
mProxy.postRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,6 +200,12 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
|
|||||||
public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
|
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("mProxy="); out.print(mProxy);
|
||||||
out.print(prefix); out.print("mSurfaceSize="); out.print(mSurfaceSize);
|
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());
|
out.print(prefix); out.print("threshold="); out.print(mImageProcessHelper.getThreshold());
|
||||||
|
mWallpaper.dump(prefix, fd, out, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user