From 7636dfbc3331dec0cea374a9540a1f31fb7dbf77 Mon Sep 17 00:00:00 2001 From: Craig Mautner Date: Fri, 16 Nov 2012 15:24:11 -0800 Subject: [PATCH] Do not clear AppWindowToken.allDrawn while animating. Creating new surfaces for applications clears the allDrawn flag in the AppWindowToken. If the app windows were animating when this happened the animation would complete immediately resulting in jank. This fix defers clearing allDrawn until the animation completes. Bug 7326635 fixed. Change-Id: I5abe3b9ecfbefb476de6a6c8acc394373cc11751 --- .../java/com/android/server/wm/AppWindowAnimator.java | 4 ++++ services/java/com/android/server/wm/AppWindowToken.java | 3 +++ .../java/com/android/server/wm/WindowManagerService.java | 4 ++++ .../java/com/android/server/wm/WindowStateAnimator.java | 9 ++++++++- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java index ca94d04436170..e044c6d43c702 100644 --- a/services/java/com/android/server/wm/AppWindowAnimator.java +++ b/services/java/com/android/server/wm/AppWindowAnimator.java @@ -100,6 +100,10 @@ public class AppWindowAnimator { animInitialized = false; } clearThumbnail(); + if (mAppToken.deferClearAllDrawn) { + mAppToken.allDrawn = false; + mAppToken.deferClearAllDrawn = false; + } } public void clearThumbnail() { diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java index 7efffe503ee4a..3ec6d26e98f0b 100644 --- a/services/java/com/android/server/wm/AppWindowToken.java +++ b/services/java/com/android/server/wm/AppWindowToken.java @@ -64,6 +64,9 @@ class AppWindowToken extends WindowToken { int numDrawnWindows; boolean inPendingTransaction; boolean allDrawn; + // Set to true when this app creates a surface while in the middle of an animation. In that + // case do not clear allDrawn until the animation completes. + boolean deferClearAllDrawn; // Is this token going to be hidden in a little while? If so, it // won't be taken into account for setting the screen orientation. diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 5adc082ac0091..921147d3f5343 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -4295,6 +4295,7 @@ public class WindowManagerService extends IWindowManager.Stub // the new one. if (ttoken.allDrawn) { wtoken.allDrawn = true; + wtoken.deferClearAllDrawn = ttoken.deferClearAllDrawn; } if (ttoken.firstWindowDrawn) { wtoken.firstWindowDrawn = true; @@ -4602,6 +4603,7 @@ public class WindowManagerService extends IWindowManager.Stub // its windows to be ready. if (wtoken.hidden) { wtoken.allDrawn = false; + wtoken.deferClearAllDrawn = false; wtoken.waitingToShow = true; if (wtoken.clientHidden) { @@ -8708,6 +8710,7 @@ public class WindowManagerService extends IWindowManager.Stub // this guy's animations regardless of whether it's // gotten drawn. wtoken.allDrawn = true; + wtoken.deferClearAllDrawn = false; } if (mNextAppTransitionThumbnail != null && topOpeningApp != null @@ -8878,6 +8881,7 @@ public class WindowManagerService extends IWindowManager.Stub winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING; if (w.mAppToken != null) { w.mAppToken.allDrawn = false; + w.mAppToken.deferClearAllDrawn = false; } } if (!mResizingWindows.contains(w)) { diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index 7b30c898c78a0..4ecc19128562a 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -626,7 +626,14 @@ class WindowStateAnimator { "createSurface " + this + ": mDrawState=DRAW_PENDING"); mDrawState = DRAW_PENDING; if (mWin.mAppToken != null) { - mWin.mAppToken.allDrawn = false; + if (mWin.mAppToken.mAppAnimator.animation == null) { + mWin.mAppToken.allDrawn = false; + mWin.mAppToken.deferClearAllDrawn = false; + } else { + // Currently animating, persist current state of allDrawn until animation + // is complete. + mWin.mAppToken.deferClearAllDrawn = true; + } } mService.makeWindowFreezingScreenIfNeededLocked(mWin);