diff options
4 files changed, 63 insertions, 7 deletions
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index b4131b44263a..415e70ca03fd 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -51,6 +51,7 @@ public class SurfaceControl { private static native void nativeSetLayer(long nativeObject, int zorder); private static native void nativeSetPosition(long nativeObject, float x, float y); + private static native void nativeSetPositionAppliesWithResize(long nativeObject); private static native void nativeSetSize(long nativeObject, int w, int h); private static native void nativeSetTransparentRegionHint(long nativeObject, Region region); private static native void nativeSetAlpha(long nativeObject, float alpha); @@ -407,6 +408,16 @@ public class SurfaceControl { nativeSetPosition(mNativeObject, x, y); } + /** + * If the size changes in this transaction, position updates specified + * in this transaction will not complete until a buffer of the new size + * arrives. + */ + public void setPositionAppliesWithResize() { + checkNotReleased(); + nativeSetPositionAppliesWithResize(mNativeObject); + } + public void setSize(int w, int h) { checkNotReleased(); nativeSetSize(mNativeObject, w, h); diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index a9ed9dce590e..ff75677536c4 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -248,6 +248,15 @@ static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong nativeObject, jfl } } +static void nativeSetPositionAppliesWithResize(JNIEnv* env, jclass clazz, + jlong nativeObject) { + SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); + status_t err = ctrl->setPositionAppliesWithResize(); + if (err < 0 && err != NO_INIT) { + doThrowIAE(env); + } +} + static void nativeSetSize(JNIEnv* env, jclass clazz, jlong nativeObject, jint w, jint h) { SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); status_t err = ctrl->setSize(w, h); @@ -658,6 +667,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetLayer }, {"nativeSetPosition", "(JFF)V", (void*)nativeSetPosition }, + {"nativeSetPositionAppliesWithResize", "(J)V", + (void*)nativeSetPositionAppliesWithResize }, {"nativeSetSize", "(JII)V", (void*)nativeSetSize }, {"nativeSetTransparentRegionHint", "(JLandroid/graphics/Region;)V", diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index e46ed8d2ac1f..881fc10c88de 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1314,7 +1314,6 @@ class WindowStateAnimator { } private int resolveStackClip() { - // App animation overrides window animation stack clip mode. if (mAppAnimator != null && mAppAnimator.animation != null) { return mAppAnimator.getStackClip(); @@ -1420,6 +1419,9 @@ class WindowStateAnimator { // aren't observing known issues here outside of PiP resizing. (Typically // the other windows that use -1 are PopupWindows which aren't likely // to be rendering while we resize). + + boolean wasForceScaled = mForceScaleUntilResize; + if (!w.inPinnedWorkspace() || (!w.mRelayoutCalled || w.mInRelayout)) { mSurfaceResized = mSurfaceController.setSizeInTransaction( mTmpSize.width(), mTmpSize.height(), recoveringMemory); @@ -1428,13 +1430,17 @@ class WindowStateAnimator { } mForceScaleUntilResize = mForceScaleUntilResize && !mSurfaceResized; - calculateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect); + + float surfaceWidth = mSurfaceController.getWidth(); + float surfaceHeight = mSurfaceController.getHeight(); + if ((task != null && task.mStack.getForceScaleToCrop()) || mForceScaleUntilResize) { int hInsets = w.getAttrs().surfaceInsets.left + w.getAttrs().surfaceInsets.right; int vInsets = w.getAttrs().surfaceInsets.top + w.getAttrs().surfaceInsets.bottom; - float surfaceWidth = mSurfaceController.getWidth(); - float surfaceHeight = mSurfaceController.getHeight(); + if (!mForceScaleUntilResize) { + mSurfaceController.forceScaleableInTransaction(true); + } // We want to calculate the scaling based on the content area, not based on // the entire surface, so that we scale in sync with windows that don't have insets. mExtraHScale = (mTmpClipRect.width() - hInsets) / (float)(surfaceWidth - hInsets); @@ -1455,7 +1461,8 @@ class WindowStateAnimator { posX += w.getAttrs().surfaceInsets.left * (1 - mExtraHScale); posY += w.getAttrs().surfaceInsets.top * (1 - mExtraVScale); - mSurfaceController.setPositionInTransaction(posX, posY, recoveringMemory); + mSurfaceController.setPositionInTransaction((float)Math.floor(posX), + (float)Math.floor(posY), recoveringMemory); // Since we are scaled to fit in our previously desired crop, we can now // expose the whole window in buffer space, and not risk extending @@ -1467,7 +1474,7 @@ class WindowStateAnimator { // We need to ensure for each surface, that we disable transformation matrix // scaling in the same transaction which we resize the surface in. // As we are in SCALING_MODE_SCALE_TO_WINDOW, SurfaceFlinger will - // then take over the scaling until the new buffer arrives, and things + // then take over the scaling until the new buffer arrives, and things // will be seamless. mForceScaleUntilResize = true; } else { @@ -1475,6 +1482,22 @@ class WindowStateAnimator { recoveringMemory); } + // If we are ending the scaling mode. We switch to SCALING_MODE_FREEZE + // to prevent further updates until buffer latch. Normally position + // would continue to apply immediately. But we need a different position + // before and after resize (since we have scaled the shadows, as discussed + // above). + if (wasForceScaled && !mForceScaleUntilResize) { + mSurfaceController.setPositionAppliesWithResizeInTransaction(true); + mSurfaceController.forceScaleableInTransaction(false); + } + if (w.inPinnedWorkspace()) { + mTmpClipRect.set(0, 0, -1, -1); + task.mStack.getDimBounds(mTmpFinalClipRect); + mTmpFinalClipRect.inset(-w.mAttrs.surfaceInsets.left, -w.mAttrs.surfaceInsets.top, + -w.mAttrs.surfaceInsets.right, -w.mAttrs.surfaceInsets.bottom); + } + updateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect, recoveringMemory); mSurfaceController.setMatrixInTransaction(mDsDx * w.mHScale * mExtraHScale, diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index 9646a49b8a88..c30da141d985 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -176,7 +176,7 @@ class WindowSurfaceController { if (SHOW_TRANSACTIONS) logSurface( "CROP " + clipRect.toShortString(), null); try { - if (clipRect.width() > 0 && clipRect.height() > 0) { + if (clipRect.width() != 0 && clipRect.height() != 0) { mSurfaceControl.setWindowCrop(clipRect); mHiddenForCrop = false; updateVisibility(); @@ -236,6 +236,10 @@ class WindowSurfaceController { } } + void setPositionAppliesWithResizeInTransaction(boolean recoveringMemory) { + mSurfaceControl.setPositionAppliesWithResize(); + } + void setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy, boolean recoveringMemory) { try { @@ -554,6 +558,13 @@ class WindowSurfaceController { } @Override + public void setPositionAppliesWithResize() { + if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPositionAppliesWithResize(): OLD: " + + this + ". Called by" + Debug.getCallers(9)); + super.setPositionAppliesWithResize(); + } + + @Override public void setSize(int w, int h) { if (w != mSize.x || h != mSize.y) { if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:" |