From 1ccd42510fe40f5ece98c54cc6fcd2b2724440ac Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Mon, 15 Aug 2016 12:05:21 -0700 Subject: [PATCH 1/2] Allow seamless rotation before mTopIsFullscreen is set. The difference between mTopFullscreenOpaqueWindowState != null and mTopIsFullscreen relates to whether the status bar is animating. However the flag won't be cleared until the next layout pass following the animation. As long as the window isn't animating we are fine to rotate seamlessly. This check was copied from selectRotationAnimationLw. A little code archaeology implies it was perhaps historical and introduced before the flag had this meaning. Bug: 30171992 Change-Id: I326bf7766f8ebe307b833d1ca0c0cdfe80b1eb6c --- .../core/java/com/android/server/policy/PhoneWindowManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 0b07902eb440b..6295630a7a8eb 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -7758,7 +7758,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // it and is in the fullscreen opaque state. Seamless rotation // requires freezing various Surface states and won't work well // with animations, so we disable it in the animation case for now. - if (w != null && mTopIsFullscreen && !w.isAnimatingLw() && + if (w != null && !w.isAnimatingLw() && ((w.getAttrs().rotationAnimation == ROTATION_ANIMATION_JUMPCUT) || (w.getAttrs().rotationAnimation == ROTATION_ANIMATION_SEAMLESS))) { return true; From aab09158e91d6e80e36ef06429d6227413a499b0 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Mon, 15 Aug 2016 12:19:00 -0700 Subject: [PATCH 2/2] Limit seamless rotation to TRANSFORM_INVERSE_DISPLAY children. In what can only be called an unfortunate workaround we require seamlessly rotated child windows to have the TRANSFORM_TO_DISPLAY_INVERSE flag. Due to limitations in the client API, there is no way for the client to set this flag in a race free fashion. If we seamlessly rotate a window which does not have this flag, but then it gains it, we will have an incorrect visual result (rotated buffer contents). This means if we want to support seamlessly rotating windows which could gain this flag, we can't seamlessly rotate windows which don't have it. This unfortunately limits seamless rotation in N to Camera framework users, native code, and applications without child windows. This is unfortunate but having the camera work was always our primary use case, and it's not as if we are offering an API for it, it's a behind the scenes enhancement of ROTATION_ANIMATION_JUMPCUT. Bug: 30171992 Change-Id: I082e323ee569cfc1ff2559657cc22194c251c7ec --- .../android/server/wm/WindowManagerService.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 6fdfaa25e14e1..c0b2d336b33c7 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -6772,6 +6772,20 @@ public class WindowManagerService extends IWindowManager.Stub rotateSeamlessly = false; break; } + // In what can only be called an unfortunate workaround we require + // seamlessly rotated child windows to have the TRANSFORM_TO_DISPLAY_INVERSE + // flag. Due to limitations in the client API, there is no way for + // the client to set this flag in a race free fashion. If we seamlessly rotate + // a window which does not have this flag, but then gains it, we will get + // an incorrect visual result (rotated viewfinder). This means if we want to + // support seamlessly rotating windows which could gain this flag, we can't + // rotate windows without it. This limits seamless rotation in N to camera framework + // users, windows without children, and native code. This is unfortunate but + // having the camera work is our primary goal. + if (w.isChildWindow() & w.isVisibleNow() && + !w.mWinAnimator.mSurfaceController.getTransformToDisplayInverse()) { + rotateSeamlessly = false; + } } }