diff options
4 files changed, 36 insertions, 8 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 e632b56d5e54..d25318df6b6a 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 @@ -228,7 +228,7 @@ class ScreenRotationAnimation { } else if ((mEndWidth > mStartWidth) == (mEndHeight > mStartHeight) && (mEndWidth != mStartWidth || mEndHeight != mStartHeight)) { // Display resizes without rotation change. - final float scale = Math.max((float) mEndWidth / mStartHeight, + final float scale = Math.max((float) mEndWidth / mStartWidth, (float) mEndHeight / mStartHeight); matrix.setScale(scale, scale); } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 37ee2e2a1187..1604c2a0343b 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1567,7 +1567,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (configChanged) { mWaitingForConfig = true; if (mTransitionController.isShellTransitionsEnabled()) { - requestChangeTransitionIfNeeded(changes, null /* displayChange */); + final TransitionRequestInfo.DisplayChange change = + mTransitionController.isCollecting() + ? null : new TransitionRequestInfo.DisplayChange(mDisplayId); + if (change != null) { + change.setStartAbsBounds(currentDisplayConfig.windowConfiguration.getBounds()); + change.setEndAbsBounds(mTmpConfiguration.windowConfiguration.getBounds()); + } + requestChangeTransitionIfNeeded(changes, change); } else if (mLastHasContent) { mWmService.startFreezingDisplay(0 /* exitAnim */, 0 /* enterAnim */, this); } diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index f314b21a0d72..7e267e47ede3 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -30,6 +30,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.IApplicationThread; import android.app.WindowConfiguration; +import android.graphics.Rect; import android.os.Handler; import android.os.IBinder; import android.os.IRemoteCallback; @@ -465,6 +466,28 @@ class TransitionController { return type == TRANSIT_OPEN || type == TRANSIT_CLOSE; } + /** Whether the display change should run with blast sync. */ + private static boolean shouldSync(@NonNull TransitionRequestInfo.DisplayChange displayChange) { + if ((displayChange.getStartRotation() + displayChange.getEndRotation()) % 2 == 0) { + // 180 degrees rotation change may not change screen size. So the clients may draw + // some frames before and after the display projection transaction is applied by the + // remote player. That may cause some buffers to show in different rotation. So use + // sync method to pause clients drawing until the projection transaction is applied. + return true; + } + final Rect startBounds = displayChange.getStartAbsBounds(); + final Rect endBounds = displayChange.getEndAbsBounds(); + if (startBounds == null || endBounds == null) return false; + final int startWidth = startBounds.width(); + final int startHeight = startBounds.height(); + final int endWidth = endBounds.width(); + final int endHeight = endBounds.height(); + // This is changing screen resolution. Because the screen decor layers are excluded from + // screenshot, their draw transactions need to run with the start transaction. + return (endWidth > startWidth) == (endHeight > startHeight) + && (endWidth != startWidth || endHeight != startHeight); + } + /** * If a transition isn't requested yet, creates one and asks the TransitionPlayer (Shell) to * start it. Collection can start immediately. @@ -494,12 +517,7 @@ class TransitionController { } else { newTransition = requestStartTransition(createTransition(type, flags), trigger != null ? trigger.asTask() : null, remoteTransition, displayChange); - if (newTransition != null && displayChange != null && (displayChange.getStartRotation() - + displayChange.getEndRotation()) % 2 == 0) { - // 180 degrees rotation change may not change screen size. So the clients may draw - // some frames before and after the display projection transaction is applied by the - // remote player. That may cause some buffers to show in different rotation. So use - // sync method to pause clients drawing until the projection transaction is applied. + if (newTransition != null && displayChange != null && shouldSync(displayChange)) { mAtm.mWindowManager.mSyncEngine.setSyncMethod(newTransition.getSyncId(), BLASTSyncEngine.METHOD_BLAST); } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index d1bd06f7fa99..232b817b8314 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2343,6 +2343,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // to be removed before the parent (so that the sync-engine tracking works). Since // WindowStateAnimator is a "virtual" child, we have to do it manually here. mWinAnimator.destroySurfaceLocked(getSyncTransaction()); + if (!mDrawHandlers.isEmpty()) { + mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this); + } super.removeImmediately(); final DisplayContent dc = getDisplayContent(); |