diff options
| author | 2022-07-21 12:55:30 +0800 | |
|---|---|---|
| committer | 2022-07-21 18:01:50 +0800 | |
| commit | 7d03d85d8e5998824ea83e54fbe9e7bf71a36d0f (patch) | |
| tree | 7ab0db83935e4b15303e1cdfe9c50a9f2c86574f | |
| parent | 14768734236315b93d4d808035884d242b99433a (diff) | |
Support display resize animation for shell transition
Apply scale to screenshot layer according to the display size.
Use sync transaction for display traversal, so when the logical
display is changed, the screenshot can cover the change at the
same time. The windows (e.g. display cutout) above the screenshot
layer are also requested to use sync transaction, so before the
sync start transaction is applied, the intermediate buffer won't
show on screen.
Bug: 223397416
Test: adb shell setprop persist.wm.debug.shell_transit 1; reboot
Enter Settings -> Display -> Screen resolution
Observe no flickering when switching resolution.
Change-Id: I30b147a220fa2e0b18f0948baa4e65436d995623
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java | 77 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/RootWindowContainer.java | 20 |
2 files changed, 42 insertions, 55 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java index 46f73fda37a1..1005ef1705f0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java @@ -34,7 +34,6 @@ import android.annotation.NonNull; import android.content.Context; import android.graphics.Color; import android.graphics.ColorSpace; -import android.graphics.GraphicBuffer; import android.graphics.Matrix; import android.graphics.Rect; import android.hardware.HardwareBuffer; @@ -85,8 +84,6 @@ class ScreenRotationAnimation { private final Context mContext; private final TransactionPool mTransactionPool; private final float[] mTmpFloats = new float[9]; - // Complete transformations being applied. - private final Matrix mSnapshotInitialMatrix = new Matrix(); /** The leash of display. */ private final SurfaceControl mSurfaceControl; private final Rect mStartBounds = new Rect(); @@ -169,16 +166,15 @@ class ScreenRotationAnimation { .setName("RotationLayer") .build(); - GraphicBuffer buffer = GraphicBuffer.createFromHardwareBuffer( - screenshotBuffer.getHardwareBuffer()); - t.setLayer(mAnimLeash, SCREEN_FREEZE_LAYER_BASE); t.setPosition(mAnimLeash, 0, 0); t.setAlpha(mAnimLeash, 1); t.show(mAnimLeash); - t.setBuffer(mScreenshotLayer, buffer); - t.setColorSpace(mScreenshotLayer, screenshotBuffer.getColorSpace()); + final ColorSpace colorSpace = screenshotBuffer.getColorSpace(); + final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer(); + t.setDataSpace(mScreenshotLayer, colorSpace.getDataSpace()); + t.setBuffer(mScreenshotLayer, hardwareBuffer); t.show(mScreenshotLayer); if (!isCustomRotate()) { @@ -189,8 +185,7 @@ class ScreenRotationAnimation { .setName("BackColorSurface") .build(); - HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer(); - mStartLuma = getMedianBorderLuma(hardwareBuffer, screenshotBuffer.getColorSpace()); + mStartLuma = getMedianBorderLuma(hardwareBuffer, colorSpace); t.setLayer(mBackColorSurface, -1); t.setColor(mBackColorSurface, new float[]{mStartLuma, mStartLuma, mStartLuma}); @@ -202,7 +197,7 @@ class ScreenRotationAnimation { Slog.w(TAG, "Unable to allocate freeze surface", e); } - setRotation(t); + setScreenshotTransform(t); t.apply(); } @@ -210,19 +205,36 @@ class ScreenRotationAnimation { return mAnimHint == ROTATION_ANIMATION_CROSSFADE || mAnimHint == ROTATION_ANIMATION_JUMPCUT; } - private void setRotation(SurfaceControl.Transaction t) { - // Compute the transformation matrix that must be applied - // to the snapshot to make it stay in the same original position - // with the current screen rotation. - int delta = deltaRotation(mEndRotation, mStartRotation); - createRotationMatrix(delta, mStartWidth, mStartHeight, mSnapshotInitialMatrix); - setRotationTransform(t, mSnapshotInitialMatrix); - } - - private void setRotationTransform(SurfaceControl.Transaction t, Matrix matrix) { + private void setScreenshotTransform(SurfaceControl.Transaction t) { if (mScreenshotLayer == null) { return; } + final Matrix matrix = new Matrix(); + final int delta = deltaRotation(mEndRotation, mStartRotation); + if (delta != 0) { + // Compute the transformation matrix that must be applied to the snapshot to make it + // stay in the same original position with the current screen rotation. + switch (delta) { + case Surface.ROTATION_90: + matrix.setRotate(90, 0, 0); + matrix.postTranslate(mStartHeight, 0); + break; + case Surface.ROTATION_180: + matrix.setRotate(180, 0, 0); + matrix.postTranslate(mStartWidth, mStartHeight); + break; + case Surface.ROTATION_270: + matrix.setRotate(270, 0, 0); + matrix.postTranslate(0, mStartWidth); + break; + } + } else if ((mEndWidth > mStartWidth) == (mEndHeight > mStartHeight) + && (mEndWidth != mStartWidth || mEndHeight != mStartHeight)) { + // Display resizes without rotation change. + final float scale = Math.max((float) mEndWidth / mStartHeight, + (float) mEndHeight / mStartHeight); + matrix.setScale(scale, scale); + } matrix.getValues(mTmpFloats); float x = mTmpFloats[Matrix.MTRANS_X]; float y = mTmpFloats[Matrix.MTRANS_Y]; @@ -230,9 +242,7 @@ class ScreenRotationAnimation { t.setMatrix(mScreenshotLayer, mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y], mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]); - t.setAlpha(mScreenshotLayer, (float) 1.0); - t.show(mScreenshotLayer); } /** @@ -486,27 +496,6 @@ class ScreenRotationAnimation { return getMedianBorderLuma(buffer.getHardwareBuffer(), buffer.getColorSpace()); } - private static void createRotationMatrix(int rotation, int width, int height, - Matrix outMatrix) { - switch (rotation) { - case Surface.ROTATION_0: - outMatrix.reset(); - break; - case Surface.ROTATION_90: - outMatrix.setRotate(90, 0, 0); - outMatrix.postTranslate(height, 0); - break; - case Surface.ROTATION_180: - outMatrix.setRotate(180, 0, 0); - outMatrix.postTranslate(width, height); - break; - case Surface.ROTATION_270: - outMatrix.setRotate(270, 0, 0); - outMatrix.postTranslate(0, width); - break; - } - } - private static void applyColor(int startColor, int endColor, float[] rgbFloat, float fraction, SurfaceControl surface, SurfaceControl.Transaction t) { final int color = (Integer) ArgbEvaluator.getInstance().evaluate(fraction, startColor, diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index dfce40b874c0..9474f185fa42 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -212,10 +212,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // Map from the PID to the top most app which has a focused window of the process. final ArrayMap<Integer, ActivityRecord> mTopFocusedAppByProcess = new ArrayMap<>(); - // Only a separate transaction until we separate the apply surface changes - // transaction from the global transaction. - private final SurfaceControl.Transaction mDisplayTransaction; - // The tag for the token to put root tasks on the displays to sleep. private static final String DISPLAY_OFF_SLEEP_TOKEN_TAG = "Display-off"; @@ -460,7 +456,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> RootWindowContainer(WindowManagerService service) { super(service); - mDisplayTransaction = service.mTransactionFactory.get(); mHandler = new MyHandler(service.mH.getLooper()); mService = service.mAtmService; mTaskSupervisor = mService.mTaskSupervisor; @@ -1001,19 +996,20 @@ class RootWindowContainer extends WindowContainer<DisplayContent> mObscuringWindow = null; // TODO(multi-display): Support these features on secondary screens. - final DisplayContent defaultDc = mWmService.getDefaultDisplayContentLocked(); + final DisplayContent defaultDc = mDefaultDisplay; final DisplayInfo defaultInfo = defaultDc.getDisplayInfo(); final int defaultDw = defaultInfo.logicalWidth; final int defaultDh = defaultInfo.logicalHeight; + final SurfaceControl.Transaction t = defaultDc.getSyncTransaction(); if (mWmService.mWatermark != null) { - mWmService.mWatermark.positionSurface(defaultDw, defaultDh, mDisplayTransaction); + mWmService.mWatermark.positionSurface(defaultDw, defaultDh, t); } if (mWmService.mStrictModeFlash != null) { - mWmService.mStrictModeFlash.positionSurface(defaultDw, defaultDh, mDisplayTransaction); + mWmService.mStrictModeFlash.positionSurface(defaultDw, defaultDh, t); } if (mWmService.mEmulatorDisplayOverlay != null) { mWmService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh, - mWmService.getDefaultDisplayRotation(), mDisplayTransaction); + defaultDc.getRotation(), t); } final int count = mChildren.size(); @@ -1024,8 +1020,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // Give the display manager a chance to adjust properties like display rotation if it needs // to. - mWmService.mDisplayManagerInternal.performTraversal(mDisplayTransaction); - SurfaceControl.mergeToGlobalTransaction(mDisplayTransaction); + mWmService.mDisplayManagerInternal.performTraversal(t); + if (t != defaultDc.mSyncTransaction) { + SurfaceControl.mergeToGlobalTransaction(t); + } } /** |