Prevent showing windows while animating to avoid color mode switch
If we switch the color mode during a transition, it's pretty much
guaranteed that SF is going to jank. To work around that, we
disallow showing the real content while an activity with a
non-standard-color mode is animating.
Test: Reopen photos, observe no jank
Bug: 79878256
Change-Id: Id27db483844d9424ccfb9afdebd31325eae0cdd8
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 08d0ae9..fa6079c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -19,6 +19,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.pm.ActivityInfo.COLOR_MODE_DEFAULT;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
@@ -1377,7 +1378,7 @@
setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM, "checkAppWindowsReadyToShow");
// We can now show all of the drawn windows!
- if (!mService.mOpeningApps.contains(this)) {
+ if (!mService.mOpeningApps.contains(this) && canShowWindows()) {
showAllWindowsLocked();
}
}
@@ -2270,4 +2271,21 @@
boolean isClosingOrEnteringPip() {
return (isAnimating() && hiddenRequested) || mWillCloseOrEnterPip;
}
+
+ /**
+ * @return Whether we are allowed to show non-starting windows at the moment. We disallow
+ * showing windows during transitions in case we have windows that have wide-color-gamut
+ * color mode set to avoid jank in the middle of the transition.
+ */
+ boolean canShowWindows() {
+ return allDrawn && !(isReallyAnimating() && hasNonDefaultColorWindow());
+ }
+
+ /**
+ * @return true if we have a window that has a non-default color mode set; false otherwise.
+ */
+ private boolean hasNonDefaultColorWindow() {
+ return forAllWindows(ws -> ws.mAttrs.getColorMode() != COLOR_MODE_DEFAULT,
+ true /* topToBottom */);
+ }
}