From d98c3d0c76b7c560e3db78b05a25d69450663538 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Wed, 16 Feb 2022 16:38:58 +0800 Subject: [PATCH] Tweak screenshot animation for display resolution changed The screenshot is taken in old resolution, so if the logical display changed size, the screenshot should resize with it to fill current screen size. Also remove logic added in commit 338374 because now there is letterbox configuration to show app in its requested orientation on a non-rotatable device, which won't use this animation. Bug: 217279239 Test: Loop commands: adb shell wm size 800x1600 adb shell wm size reset There should be no obvious flickering. Change-Id: Ifb4ee93aa0d101f68159a9d03806589cfea79080 --- .../server/wm/ScreenRotationAnimation.java | 56 +++++++------------ 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index d1460f41cad68..6bb63d933353a 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -108,15 +108,12 @@ class ScreenRotationAnimation { */ private SurfaceControl mBackColorSurface; private BlackFrame mEnteringBlackFrame; - private int mWidth, mHeight; private final int mOriginalRotation; private final int mOriginalWidth; private final int mOriginalHeight; private int mCurRotation; - private Rect mOriginalDisplayRect = new Rect(); - private Rect mCurrentDisplayRect = new Rect(); // The current active animation to move from the old to the new rotated // state. Which animation is run here will depend on the old and new // rotations. @@ -127,7 +124,6 @@ class ScreenRotationAnimation { private boolean mAnimRunning; private boolean mFinishAnimReady; private long mFinishAnimStartTime; - private boolean mForceDefaultOrientation; private SurfaceRotationAnimationController mSurfaceRotationAnimationController; /** Intensity of light/whiteness of the layout before rotation occurs. */ private float mStartLuma; @@ -138,25 +134,13 @@ class ScreenRotationAnimation { mService = displayContent.mWmService; mContext = mService.mContext; mDisplayContent = displayContent; - displayContent.getBounds(mOriginalDisplayRect); + final Rect currentBounds = displayContent.getBounds(); + final int width = currentBounds.width(); + final int height = currentBounds.height(); // Screenshot does NOT include rotation! final DisplayInfo displayInfo = displayContent.getDisplayInfo(); final int realOriginalRotation = displayInfo.rotation; - final int originalWidth; - final int originalHeight; - if (displayContent.getDisplayRotation().isFixedToUserRotation()) { - // Emulated orientation. - mForceDefaultOrientation = true; - originalWidth = displayContent.mBaseDisplayWidth; - originalHeight = displayContent.mBaseDisplayHeight; - } else { - // Normal situation - originalWidth = displayInfo.logicalWidth; - originalHeight = displayInfo.logicalHeight; - } - mWidth = originalWidth; - mHeight = originalHeight; mOriginalRotation = originalRotation; // If the delta is not zero, the rotation of display may not change, but we still want to @@ -165,8 +149,8 @@ class ScreenRotationAnimation { // when restoring the rotated app to the same rotation as current display. final int delta = deltaRotation(originalRotation, realOriginalRotation); final boolean flipped = delta == Surface.ROTATION_90 || delta == Surface.ROTATION_270; - mOriginalWidth = flipped ? originalHeight : originalWidth; - mOriginalHeight = flipped ? originalWidth : originalHeight; + mOriginalWidth = flipped ? height : width; + mOriginalHeight = flipped ? width : height; mSurfaceRotationAnimationController = new SurfaceRotationAnimationController(); // Check whether the current screen contains any secure content. @@ -179,7 +163,7 @@ class ScreenRotationAnimation { new SurfaceControl.LayerCaptureArgs.Builder(displayContent.getSurfaceControl()) .setCaptureSecureLayers(true) .setAllowProtected(true) - .setSourceCrop(new Rect(0, 0, mWidth, mHeight)) + .setSourceCrop(new Rect(0, 0, width, height)) .build(); SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = SurfaceControl.captureLayers(args); @@ -244,6 +228,19 @@ class ScreenRotationAnimation { Slog.w(TAG, "Unable to allocate freeze surface", e); } + // If display size is changed with the same orientation, map the bounds of screenshot to + // the new logical display size. Currently pending transaction and RWC#mDisplayTransaction + // are merged to global transaction, so it can be synced with display change when calling + // DisplayManagerInternal#performTraversal(transaction). + final int logicalWidth = displayInfo.logicalWidth; + final int logicalHeight = displayInfo.logicalHeight; + if (logicalWidth > mOriginalWidth == logicalHeight > mOriginalHeight + && (logicalWidth != mOriginalWidth || logicalHeight != mOriginalHeight)) { + displayContent.getPendingTransaction().setGeometry(mScreenshotLayer, + new Rect(0, 0, mOriginalWidth, mOriginalHeight), + new Rect(0, 0, logicalWidth, logicalHeight), Surface.ROTATION_0); + } + ProtoLog.i(WM_SHOW_SURFACE_ALLOC, " FREEZE %s: CREATE", mScreenshotLayer); if (originalRotation == realOriginalRotation) { @@ -277,11 +274,6 @@ class ScreenRotationAnimation { matrix.getValues(mTmpFloats); float x = mTmpFloats[Matrix.MTRANS_X]; float y = mTmpFloats[Matrix.MTRANS_Y]; - if (mForceDefaultOrientation) { - mDisplayContent.getBounds(mCurrentDisplayRect); - x -= mCurrentDisplayRect.left; - y -= mCurrentDisplayRect.top; - } t.setPosition(mScreenshotLayer, x, y); t.setMatrix(mScreenshotLayer, mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y], @@ -293,8 +285,6 @@ class ScreenRotationAnimation { public void printTo(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("mSurface="); pw.print(mScreenshotLayer); - pw.print(" mWidth="); pw.print(mWidth); - pw.print(" mHeight="); pw.println(mHeight); pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame); @@ -315,11 +305,6 @@ class ScreenRotationAnimation { pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println(); pw.print(prefix); pw.print("mSnapshotInitialMatrix="); mSnapshotInitialMatrix.dump(pw); pw.println(); - pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation); - if (mForceDefaultOrientation) { - pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString()); - pw.print(" mCurrentDisplayRect="); pw.println(mCurrentDisplayRect.toShortString()); - } } public void setRotation(SurfaceControl.Transaction t, int rotation) { @@ -329,7 +314,8 @@ class ScreenRotationAnimation { // to the snapshot to make it stay in the same original position // with the current screen rotation. int delta = deltaRotation(rotation, mOriginalRotation); - RotationAnimationUtils.createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix); + RotationAnimationUtils.createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, + mSnapshotInitialMatrix); setRotationTransform(t, mSnapshotInitialMatrix); }