diff options
author | Craig Mautner <cmautner@google.com> | 2012-09-03 23:23:58 -0700 |
---|---|---|
committer | Craig Mautner <cmautner@google.com> | 2012-09-04 08:59:39 -0700 |
commit | 76a7165719dc3ccce902953f6244e2c2668aa753 (patch) | |
tree | 15774855504edc0b7985da491abce291520a10be | |
parent | e94831e5ed4aa3b1ebc5444cc1b16cdab8cb92f8 (diff) | |
download | frameworks_base-76a7165719dc3ccce902953f6244e2c2668aa753.zip frameworks_base-76a7165719dc3ccce902953f6244e2c2668aa753.tar.gz frameworks_base-76a7165719dc3ccce902953f6244e2c2668aa753.tar.bz2 |
Change layout inner loop order for multi display.
The inner loop that ran over each display had a few problems:
- The Surface transaction was starting and stopping between each
display.
- The layout change bits were being applied globally so all
displays were layed out when only individual displays needed to be.
- Wallpaper and input actions were being applied each time through
the display loop rather than once only for the default display.
Change-Id: I924252bab28c426222a4bb73693accc4b21cecbe
5 files changed, 318 insertions, 242 deletions
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java index c25f010..c6b7e0d 100644 --- a/services/java/com/android/server/wm/AppWindowAnimator.java +++ b/services/java/com/android/server/wm/AppWindowAnimator.java @@ -234,10 +234,8 @@ public class AppWindowAnimator { return false; } - mAnimator.mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; - if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { - mService.debugLayoutRepeats("AppWindowToken", mAnimator.mPendingLayoutChanges); - } + mAnimator.setAppLayoutChanges(this, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM, + "AppWindowToken"); clearAnimation(); animating = false; diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java index 1e1b097..f4964cf 100644 --- a/services/java/com/android/server/wm/DisplayContent.java +++ b/services/java/com/android/server/wm/DisplayContent.java @@ -64,6 +64,7 @@ class DisplayContent { // Accessed directly by all users. boolean layoutNeeded; + int pendingLayoutChanges; DisplayContent(Display display) { mDisplay = display; @@ -84,6 +85,7 @@ class DisplayContent { } DisplayInfo getDisplayInfo() { + mDisplay.getDisplayInfo(mDisplayInfo); return mDisplayInfo; } diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java index 232f2ed..9eab92c 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/java/com/android/server/wm/WindowAnimator.java @@ -16,12 +16,12 @@ import android.content.Context; import android.os.SystemClock; import android.util.Log; import android.util.Slog; +import android.util.SparseIntArray; import android.view.Display; import android.view.Surface; import android.view.WindowManagerPolicy; import android.view.animation.Animation; -import com.android.internal.policy.impl.PhoneWindowManager; import com.android.server.wm.WindowManagerService.AppWindowAnimParams; import com.android.server.wm.WindowManagerService.LayoutToAnimatorParams; @@ -47,7 +47,8 @@ public class WindowAnimator { int mAdjResult; - int mPendingLayoutChanges; + // Layout changes for individual Displays. Indexed by displayId. + SparseIntArray mPendingLayoutChanges = new SparseIntArray(); /** Overall window dimensions */ int mDw, mDh; @@ -97,7 +98,7 @@ public class WindowAnimator { static class AnimatorToLayoutParams { boolean mUpdateQueued; int mBulkUpdateParams; - int mPendingLayoutChanges; + SparseIntArray mPendingLayoutChanges; WindowState mWindowDetachedWallpaper; } /** Do not modify unless holding mService.mWindowMap or this and mAnimToLayout in that order */ @@ -137,7 +138,7 @@ public class WindowAnimator { final AnimatorToLayoutParams animToLayout = mAnimToLayout; synchronized (animToLayout) { animToLayout.mBulkUpdateParams = mBulkUpdateParams; - animToLayout.mPendingLayoutChanges = mPendingLayoutChanges; + animToLayout.mPendingLayoutChanges = mPendingLayoutChanges.clone(); animToLayout.mWindowDetachedWallpaper = mWindowDetachedWallpaper; if (!animToLayout.mUpdateQueued) { @@ -214,7 +215,8 @@ public class WindowAnimator { if (!winAnimator.mLastHidden) { winAnimator.hide(); mService.dispatchWallpaperVisibility(wallpaper, false); - mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; + setPendingLayoutChanges(Display.DEFAULT_DISPLAY, + WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); } } token.hidden = true; @@ -233,11 +235,8 @@ public class WindowAnimator { mAnimating = true; } else if (wasAnimating) { // stopped animating, do one more pass through the layout - mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; - if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { - mService.debugLayoutRepeats("appToken " + appAnimator.mAppToken + " done", - mPendingLayoutChanges); - } + setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, + "appToken " + appAnimator.mAppToken + " done"); if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, "updateWindowsApps...: done animating " + appAnimator.mAppToken); } @@ -252,11 +251,8 @@ public class WindowAnimator { mAnimating = true; } else if (wasAnimating) { // stopped animating, do one more pass through the layout - mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; - if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { - mService.debugLayoutRepeats("exiting appToken " + appAnimator.mAppToken - + " done", mPendingLayoutChanges); - } + setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, + "exiting appToken " + appAnimator.mAppToken + " done"); if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken); } @@ -302,10 +298,11 @@ public class WindowAnimator { if (wasAnimating && !winAnimator.mAnimating && mWallpaperTarget == win) { mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; - mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; + setPendingLayoutChanges(Display.DEFAULT_DISPLAY, + WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 2", - mPendingLayoutChanges); + mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY)); } } @@ -315,10 +312,12 @@ public class WindowAnimator { WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Animation started that could impact force hide: " + win); mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED; - mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; + final int displayId = win.mDisplayContent.getDisplayId(); + setPendingLayoutChanges(displayId, + WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 3", - mPendingLayoutChanges); + mPendingLayoutChanges.get(displayId)); } mService.mFocusMayChange = true; } @@ -377,10 +376,11 @@ public class WindowAnimator { } if (changed && (flags & FLAG_SHOW_WALLPAPER) != 0) { mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; - mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; + setPendingLayoutChanges(Display.DEFAULT_DISPLAY, + WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 4", - mPendingLayoutChanges); + mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY)); } } } @@ -390,10 +390,12 @@ public class WindowAnimator { if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) { if (atoken == null || atoken.allDrawn) { if (winAnimator.performShowLocked()) { - mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; + final int displayId = win.mDisplayContent.getDisplayId(); + mPendingLayoutChanges.put(displayId, + WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5", - mPendingLayoutChanges); + mPendingLayoutChanges.get(displayId)); } } } @@ -536,14 +538,14 @@ public class WindowAnimator { + wtoken + " numInteresting=" + wtoken.numInterestingWindows + " numDrawn=" + wtoken.numDrawnWindows); // This will set mOrientationChangeComplete and cause a pass through layout. - mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; + setAppLayoutChanges(appAnimator, + WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, + "testTokenMayBeDrawnLocked: freezingScreen"); } else { - mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM; - if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { - mService.debugLayoutRepeats("testTokenMayBeDrawnLocked", - mPendingLayoutChanges); - } - + setAppLayoutChanges(appAnimator, + WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM, + "testTokenMayBeDrawnLocked"); + // We can now show all of the drawn windows! if (!mService.mOpeningApps.contains(wtoken)) { mAnimating |= appAnimator.showAllWindowsLocked(); @@ -558,8 +560,11 @@ public class WindowAnimator { updateWindowsLocked(winAnimatorList); updateWallpaperLocked(winAnimatorList); - if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { - mPendingActions |= WALLPAPER_ACTION_PENDING; + for (int i = mPendingLayoutChanges.size() - 1; i >= 0; i--) { + if ((mPendingLayoutChanges.valueAt(i) + & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { + mPendingActions |= WALLPAPER_ACTION_PENDING; + } } testTokenMayBeDrawnLocked(); @@ -577,7 +582,7 @@ public class WindowAnimator { } private void animateLocked(final WinAnimatorList winAnimatorList) { - mPendingLayoutChanges = 0; + mPendingLayoutChanges.clear(); mCurrentTime = SystemClock.uptimeMillis(); mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE; boolean wasAnimating = mAnimating; @@ -631,7 +636,7 @@ public class WindowAnimator { Surface.closeTransaction(); } - if (mBulkUpdateParams != 0 || mPendingLayoutChanges != 0) { + if (mBulkUpdateParams != 0 || mPendingLayoutChanges.size() > 0) { updateAnimToLayoutLocked(); } @@ -645,7 +650,8 @@ public class WindowAnimator { if (WindowManagerService.DEBUG_WINDOW_TRACE) { Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams) - + " mPendingLayoutChanges=" + Integer.toHexString(mPendingLayoutChanges)); + + " mPendingLayoutChanges(DEFAULT_DISPLAY)=" + + Integer.toHexString(mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY))); } } @@ -705,7 +711,30 @@ public class WindowAnimator { } } - synchronized void clearPendingActions() { - mPendingActions = 0; + void clearPendingActions() { + synchronized (this) { + mPendingActions = 0; + } + } + + void setPendingLayoutChanges(final int displayId, final int changes) { + mPendingLayoutChanges.put(displayId, mPendingLayoutChanges.get(displayId) | changes); + } + + void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) { + // Used to track which displays layout changes have been done. + SparseIntArray displays = new SparseIntArray(); + for (int i = appAnimator.mAllAppWinAnimators.size() - 1; i >= 0; i--) { + WindowStateAnimator winAnimator = appAnimator.mAllAppWinAnimators.get(i); + final int displayId = winAnimator.mWin.mDisplayContent.getDisplayId(); + if (displays.indexOfKey(displayId) < 0) { + setPendingLayoutChanges(displayId, changes); + if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { + mService.debugLayoutRepeats(s, mPendingLayoutChanges.get(displayId)); + } + // Keep from processing this display again. + displays.put(displayId, changes); + } + } } } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index b7eeb69..0d6de38 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -454,7 +454,6 @@ public class WindowManagerService extends IWindowManager.Stub int mSystemDecorLayer = 0; final Rect mScreenRect = new Rect(); - int mPendingLayoutChanges = 0; boolean mLayoutNeeded = true; boolean mTraversalScheduled = false; boolean mDisplayFrozen = false; @@ -3807,6 +3806,7 @@ public class WindowManagerService extends IWindowManager.Stub } } + @Override public int getAppOrientation(IApplicationToken token) { synchronized(mWindowMap) { AppWindowToken wtoken = findAppWindowToken(token.asBinder()); @@ -3818,6 +3818,7 @@ public class WindowManagerService extends IWindowManager.Stub } } + @Override public void setFocusedApp(IBinder token, boolean moveFocusNow) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "setFocusedApp()")) { @@ -3855,6 +3856,7 @@ public class WindowManagerService extends IWindowManager.Stub } } + @Override public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "prepareAppTransition()")) { @@ -7831,27 +7833,7 @@ public class WindowManagerService extends IWindowManager.Stub } try { - DisplayContentsIterator iterator = new DisplayContentsIterator(); - while (iterator.hasNext()) { - final DisplayContent displayContent = iterator.next(); - performLayoutAndPlaceSurfacesLockedInner(displayContent, recoveringMemory); - - final int N = mPendingRemove.size(); - if (N > 0) { - if (mPendingRemoveTmp.length < N) { - mPendingRemoveTmp = new WindowState[N+10]; - } - mPendingRemove.toArray(mPendingRemoveTmp); - mPendingRemove.clear(); - for (int i=0; i<N; i++) { - WindowState w = mPendingRemoveTmp[i]; - removeWindowInnerLocked(w.mSession, w); - } - - assignLayersLocked(displayContent.getWindowList()); - mLayoutNeeded = true; - } - } + performLayoutAndPlaceSurfacesLockedInner(recoveringMemory); mInLayout = false; @@ -8525,8 +8507,7 @@ public class WindowManagerService extends IWindowManager.Stub } // "Something has changed! Let's make it correct now." - private final void performLayoutAndPlaceSurfacesLockedInner( - final DisplayContent displayContent, boolean recoveringMemory) { + private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) { if (DEBUG_WINDOW_TRACE) { Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by " + Debug.getCallers(3)); @@ -8536,13 +8517,7 @@ public class WindowManagerService extends IWindowManager.Stub return; } - final WindowList windows = displayContent.getWindowList(); final long currentTime = SystemClock.uptimeMillis(); - final DisplayInfo displayInfo = displayContent.getDisplayInfo(); - final int dw = displayInfo.logicalWidth; - final int dh = displayInfo.logicalHeight; - final int innerDw = displayInfo.appWidth; - final int innerDh = displayInfo.appHeight; int i; @@ -8567,201 +8542,237 @@ public class WindowManagerService extends IWindowManager.Stub mInnerFields.mButtonBrightness = -1; mTransactionSequence++; + final DisplayContent defaultDisplay = getDefaultDisplayContent(); + final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo(); + final int defaultDw = defaultInfo.logicalWidth; + final int defaultDh = defaultInfo.logicalHeight; + final int defaultInnerDw = defaultInfo.appWidth; + final int defaultInnerDh = defaultInfo.appHeight; + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); - Surface.openTransaction(); try { + if (mWatermark != null) { - mWatermark.positionSurface(dw, dh); + mWatermark.positionSurface(defaultDw, defaultDh); } if (mStrictModeFlash != null) { - mStrictModeFlash.positionSurface(dw, dh); + mStrictModeFlash.positionSurface(defaultDw, defaultDh); } // Give the display manager a chance to adjust properties // like display rotation if it needs to. mDisplayManagerService.performTraversalInTransactionFromWindowManager(); - int repeats = 0; + boolean focusDisplayed = false; + boolean updateAllDrawn = false; - do { - repeats++; - if (repeats > 6) { - Slog.w(TAG, "Animation repeat aborted after too many iterations"); - mLayoutNeeded = false; - break; - } + DisplayContentsIterator iterator = new DisplayContentsIterator(); + while (iterator.hasNext()) { + final DisplayContent displayContent = iterator.next(); + WindowList windows = displayContent.getWindowList(); + DisplayInfo displayInfo = displayContent.getDisplayInfo(); + final int dw = displayInfo.logicalWidth; + final int dh = displayInfo.logicalHeight; + final int innerDw = displayInfo.appWidth; + final int innerDh = displayInfo.appHeight; + final boolean isDefaultDisplay = + displayContent.getDisplayId() == Display.DEFAULT_DISPLAY; + + int repeats = 0; + do { + repeats++; + if (repeats > 6) { + Slog.w(TAG, "Animation repeat aborted after too many iterations"); + mLayoutNeeded = false; + displayContent.layoutNeeded = false; + break; + } - if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner", - mPendingLayoutChanges); + if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner", + displayContent.pendingLayoutChanges); - if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { - if ((adjustWallpaperWindowsLocked() & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) { + if (isDefaultDisplay && ((displayContent.pendingLayoutChanges + & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) + && ((adjustWallpaperWindowsLocked() + & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0)) { assignLayersLocked(windows); mLayoutNeeded = true; + displayContent.layoutNeeded = true; + } + + if (isDefaultDisplay && (displayContent.pendingLayoutChanges + & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) { + if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout"); + if (updateOrientationFromAppTokensLocked(true)) { + mLayoutNeeded = true; + displayContent.layoutNeeded = true; + mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); + } } - } - if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) { - if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout"); - if (updateOrientationFromAppTokensLocked(true)) { + if ((displayContent.pendingLayoutChanges + & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) { mLayoutNeeded = true; - mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); + displayContent.layoutNeeded = true; } - } - if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) { - mLayoutNeeded = true; - } + // FIRST LOOP: Perform a layout, if needed. + if (repeats < 4) { + performLayoutLockedInner(displayContent, repeats == 1, + false /*updateInputWindows*/); + } else { + Slog.w(TAG, "Layout repeat skipped after too many iterations"); + } - // FIRST LOOP: Perform a layout, if needed. - if (repeats < 4) { - performLayoutLockedInner(displayContent, repeats == 1, false /*updateInputWindows*/); - } else { - Slog.w(TAG, "Layout repeat skipped after too many iterations"); - } + // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think + // it is animating. + displayContent.pendingLayoutChanges = 0; - // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think - // it is animating. - mPendingLayoutChanges = 0; - if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number " + mLayoutRepeatCount, - mPendingLayoutChanges); - mPolicy.beginPostLayoutPolicyLw(dw, dh); - for (i = windows.size() - 1; i >= 0; i--) { - WindowState w = windows.get(i); - if (w.mHasSurface) { - mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs); - } - } - mPendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw(); - if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw", - mPendingLayoutChanges); - } while (mPendingLayoutChanges != 0); + if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number " + + mLayoutRepeatCount, displayContent.pendingLayoutChanges); - final boolean someoneLosingFocus = !mLosingFocus.isEmpty(); + mPolicy.beginPostLayoutPolicyLw(dw, dh); + for (i = windows.size() - 1; i >= 0; i--) { + WindowState w = windows.get(i); + if (w.mHasSurface) { + mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs); + } + } + displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw(); + if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw", + displayContent.pendingLayoutChanges); + } while (displayContent.pendingLayoutChanges != 0); - mInnerFields.mObscured = false; - mInnerFields.mDimming = false; - mInnerFields.mSyswin = false; + mInnerFields.mObscured = false; + mInnerFields.mDimming = false; + mInnerFields.mSyswin = false; - boolean focusDisplayed = false; - boolean updateAllDrawn = false; - final int N = windows.size(); - for (i=N-1; i>=0; i--) { - WindowState w = windows.get(i); + // Only used if default window + final boolean someoneLosingFocus = !mLosingFocus.isEmpty(); - final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured; + final int N = windows.size(); + for (i=N-1; i>=0; i--) { + WindowState w = windows.get(i); - // Update effect. - w.mObscured = mInnerFields.mObscured; - if (!mInnerFields.mObscured) { - handleNotObscuredLocked(w, currentTime, innerDw, innerDh); - } + final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured; - if (obscuredChanged && (mWallpaperTarget == w) && w.isVisibleLw()) { - // This is the wallpaper target and its obscured state - // changed... make sure the current wallaper's visibility - // has been updated accordingly. - updateWallpaperVisibilityLocked(); - } + // Update effect. + w.mObscured = mInnerFields.mObscured; + if (!mInnerFields.mObscured) { + handleNotObscuredLocked(w, currentTime, innerDw, innerDh); + } - final WindowStateAnimator winAnimator = w.mWinAnimator; + if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w) + && w.isVisibleLw()) { + // This is the wallpaper target and its obscured state + // changed... make sure the current wallaper's visibility + // has been updated accordingly. + updateWallpaperVisibilityLocked(); + } - // If the window has moved due to its containing - // content frame changing, then we'd like to animate - // it. - if (w.mHasSurface && w.shouldAnimateMove()) { - // Frame has moved, containing content frame - // has also moved, and we're not currently animating... - // let's do something. - Animation a = AnimationUtils.loadAnimation(mContext, - com.android.internal.R.anim.window_move_from_decor); - winAnimator.setAnimation(a); - winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left; - winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top; - try { - w.mClient.moved(w.mFrame.left, w.mFrame.top); - } catch (RemoteException e) { + final WindowStateAnimator winAnimator = w.mWinAnimator; + + // If the window has moved due to its containing + // content frame changing, then we'd like to animate + // it. + if (w.mHasSurface && w.shouldAnimateMove()) { + // Frame has moved, containing content frame + // has also moved, and we're not currently animating... + // let's do something. + Animation a = AnimationUtils.loadAnimation(mContext, + com.android.internal.R.anim.window_move_from_decor); + winAnimator.setAnimation(a); + winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left; + winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top; + try { + w.mClient.moved(w.mFrame.left, w.mFrame.top); + } catch (RemoteException e) { + } } - } - //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing"); - w.mContentChanged = false; + //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing"); + w.mContentChanged = false; - // Moved from updateWindowsAndWallpaperLocked(). - if (w.mHasSurface) { - // Take care of the window being ready to display. - if (winAnimator.commitFinishDrawingLocked(currentTime)) { - if ((w.mAttrs.flags - & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) { - if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG, - "First draw done in potential wallpaper target " + w); - mInnerFields.mWallpaperMayChange = true; - mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; - if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { - debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true", - mPendingLayoutChanges); + // Moved from updateWindowsAndWallpaperLocked(). + if (w.mHasSurface) { + // Take care of the window being ready to display. + if (isDefaultDisplay + && winAnimator.commitFinishDrawingLocked(currentTime)) { + if ((w.mAttrs.flags + & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) { + if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG, + "First draw done in potential wallpaper target " + w); + mInnerFields.mWallpaperMayChange = true; + displayContent.pendingLayoutChanges |= + WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; + if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { + debugLayoutRepeats( + "wallpaper and commitFinishDrawingLocked true", + displayContent.pendingLayoutChanges); + } } } - } - winAnimator.setSurfaceBoundaries(recoveringMemory); + winAnimator.setSurfaceBoundaries(recoveringMemory); - final AppWindowToken atoken = w.mAppToken; - if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) { - Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" - + w.isOnScreen() + " allDrawn=" + atoken.allDrawn - + " freezingScreen=" + atoken.mAppAnimator.freezingScreen); - } - if (atoken != null - && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) { - if (atoken.lastTransactionSequence != mTransactionSequence) { - atoken.lastTransactionSequence = mTransactionSequence; - atoken.numInterestingWindows = atoken.numDrawnWindows = 0; - atoken.startingDisplayed = false; + final AppWindowToken atoken = w.mAppToken; + if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) { + Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + + w.isOnScreen() + " allDrawn=" + atoken.allDrawn + + " freezingScreen=" + atoken.mAppAnimator.freezingScreen); } - if ((w.isOnScreen() || winAnimator.mAttrType - == WindowManager.LayoutParams.TYPE_BASE_APPLICATION) - && !w.mExiting && !w.mDestroying) { - if (WindowManagerService.DEBUG_VISIBILITY || - WindowManagerService.DEBUG_ORIENTATION) { - Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw() - + ", isAnimating=" + winAnimator.isAnimating()); - if (!w.isDrawnLw()) { - Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurface - + " pv=" + w.mPolicyVisibility - + " mDrawState=" + winAnimator.mDrawState - + " ah=" + w.mAttachedHidden - + " th=" + atoken.hiddenRequested - + " a=" + winAnimator.mAnimating); - } + if (atoken != null + && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) { + if (atoken.lastTransactionSequence != mTransactionSequence) { + atoken.lastTransactionSequence = mTransactionSequence; + atoken.numInterestingWindows = atoken.numDrawnWindows = 0; + atoken.startingDisplayed = false; } - if (w != atoken.startingWindow) { - if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) { - atoken.numInterestingWindows++; - if (w.isDrawnLw()) { - atoken.numDrawnWindows++; - if (WindowManagerService.DEBUG_VISIBILITY || - WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG, - "tokenMayBeDrawn: " + atoken - + " freezingScreen=" + atoken.mAppAnimator.freezingScreen - + " mAppFreezing=" + w.mAppFreezing); - updateAllDrawn = true; + if ((w.isOnScreen() || winAnimator.mAttrType + == WindowManager.LayoutParams.TYPE_BASE_APPLICATION) + && !w.mExiting && !w.mDestroying) { + if (WindowManagerService.DEBUG_VISIBILITY || + WindowManagerService.DEBUG_ORIENTATION) { + Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw() + + ", isAnimating=" + winAnimator.isAnimating()); + if (!w.isDrawnLw()) { + Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurface + + " pv=" + w.mPolicyVisibility + + " mDrawState=" + winAnimator.mDrawState + + " ah=" + w.mAttachedHidden + + " th=" + atoken.hiddenRequested + + " a=" + winAnimator.mAnimating); + } + } + if (w != atoken.startingWindow) { + if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) { + atoken.numInterestingWindows++; + if (w.isDrawnLw()) { + atoken.numDrawnWindows++; + if (WindowManagerService.DEBUG_VISIBILITY || + WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG, + "tokenMayBeDrawn: " + atoken + + " freezingScreen=" + atoken.mAppAnimator.freezingScreen + + " mAppFreezing=" + w.mAppFreezing); + updateAllDrawn = true; + } } + } else if (w.isDrawnLw()) { + atoken.startingDisplayed = true; } - } else if (w.isDrawnLw()) { - atoken.startingDisplayed = true; } } } - } - if (someoneLosingFocus && w == mCurrentFocus && w.isDisplayedLw()) { - focusDisplayed = true; - } + if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus) + && w.isDisplayedLw()) { + focusDisplayed = true; + } - updateResizingWindows(w); + updateResizingWindows(w); + } } if (updateAllDrawn) { @@ -8781,13 +8792,15 @@ public class WindowManagerService extends IWindowManager.Stub Surface.closeTransaction(); } + final WindowList defaultWindows = defaultDisplay.getWindowList(); + // If we are ready to perform an app transition, check through // all of the app tokens to be shown and see if they are ready // to go. if (mAppTransitionReady) { - mPendingLayoutChanges |= handleAppTransitionReadyLocked(windows); + defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows); if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked", - mPendingLayoutChanges); + defaultDisplay.pendingLayoutChanges); } mInnerFields.mAdjResult = 0; @@ -8799,22 +8812,22 @@ public class WindowManagerService extends IWindowManager.Stub // reflects the correct Z-order, but the window list may now // be out of sync with it. So here we will just rebuild the // entire app window list. Fun! - mPendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked(); + defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked(); if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock", - mPendingLayoutChanges); + defaultDisplay.pendingLayoutChanges); } - if (mInnerFields.mWallpaperForceHidingChanged && mPendingLayoutChanges == 0 && - !mAppTransitionReady) { + if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0 + && !mAppTransitionReady) { // At this point, there was a window with a wallpaper that // was force hiding other windows behind it, but now it // is going away. This may be simple -- just animate // away the wallpaper and its window -- or it may be // hard -- the wallpaper now needs to be shown behind // something that was hidden. - mPendingLayoutChanges |= animateAwayWallpaperLocked(); + defaultDisplay.pendingLayoutChanges |= animateAwayWallpaperLocked(); if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked", - mPendingLayoutChanges); + defaultDisplay.pendingLayoutChanges); } mInnerFields.mWallpaperForceHidingChanged = false; @@ -8827,26 +8840,27 @@ public class WindowManagerService extends IWindowManager.Stub if ((mInnerFields.mAdjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) { if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper layer changed: assigning layers + relayout"); - mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT; - assignLayersLocked(windows); + defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; + assignLayersLocked(defaultWindows); } else if ((mInnerFields.mAdjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) { if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility changed: relayout"); - mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT; + defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; } if (mFocusMayChange) { mFocusMayChange = false; if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, false /*updateInputWindows*/)) { - mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM; + defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; mInnerFields.mAdjResult = 0; } } if (mLayoutNeeded) { - mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT; - if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded", mPendingLayoutChanges); + defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; + if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded", + defaultDisplay.pendingLayoutChanges); } if (!mResizingWindows.isEmpty()) { @@ -8957,8 +8971,13 @@ public class WindowManagerService extends IWindowManager.Stub if (wallpaperDestroyed) { mLayoutNeeded |= adjustWallpaperWindowsLocked() != 0; } - if (mPendingLayoutChanges != 0) { - mLayoutNeeded = true; + + DisplayContentsIterator iterator = new DisplayContentsIterator(); + while (iterator.hasNext()) { + DisplayContent displayContent = iterator.next(); + if (displayContent.pendingLayoutChanges != 0) { + mLayoutNeeded = true; + } } // Finally update all input windows now that the window changes have stabilized. @@ -9000,6 +9019,28 @@ public class WindowManagerService extends IWindowManager.Stub checkDrawnWindowsLocked(); } + final int N = mPendingRemove.size(); + if (N > 0) { + if (mPendingRemoveTmp.length < N) { + mPendingRemoveTmp = new WindowState[N+10]; + } + mPendingRemove.toArray(mPendingRemoveTmp); + mPendingRemove.clear(); + DisplayContentList displayList = new DisplayContentList(); + for (i = 0; i < N; i++) { + WindowState w = mPendingRemoveTmp[i]; + removeWindowInnerLocked(w.mSession, w); + if (!displayList.contains(w.mDisplayContent)) { + displayList.add(w.mDisplayContent); + } + } + + for (DisplayContent displayContent : displayList) { + assignLayersLocked(displayContent.getWindowList()); + } + mLayoutNeeded = true; + } + // Check to see if we are now in a state where the screen should // be enabled, because the window obscured flags have changed. enableScreenIfNeededLocked(); @@ -9007,9 +9048,8 @@ public class WindowManagerService extends IWindowManager.Stub updateLayoutToAnimationLocked(); if (DEBUG_WINDOW_TRACE) { - Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: mPendingLayoutChanges=" - + Integer.toHexString(mPendingLayoutChanges) + " mLayoutNeeded=" + mLayoutNeeded - + " animating=" + mAnimator.mAnimating); + Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: mLayoutNeeded=" + + mLayoutNeeded + " animating=" + mAnimator.mAnimating); } } @@ -9197,10 +9237,15 @@ public class WindowManagerService extends IWindowManager.Stub mTurnOnScreen = true; } - mPendingLayoutChanges |= animToLayout.mPendingLayoutChanges; - if (mPendingLayoutChanges != 0) { + SparseIntArray pendingLayouts = animToLayout.mPendingLayoutChanges; + final int count = pendingLayouts.size(); + if (count > 0) { doRequest = true; } + for (int i = 0; i < count; ++i) { + final DisplayContent displayContent = getDisplayContent(pendingLayouts.keyAt(i)); + displayContent.pendingLayoutChanges = pendingLayouts.valueAt(i); + } mWindowDetachedWallpaper = animToLayout.mWindowDetachedWallpaper; } diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index 1bda22a..a7b116a 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -359,9 +359,10 @@ class WindowStateAnimator { } finishExit(); - mAnimator.mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; + final int displayId = mWin.mDisplayContent.getDisplayId(); + mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats( - "WindowStateAnimator", mAnimator.mPendingLayoutChanges); + "WindowStateAnimator", mAnimator.mPendingLayoutChanges.get(displayId)); if (mWin.mAppToken != null) { mWin.mAppToken.updateReportedVisibilityLocked(); @@ -1106,8 +1107,9 @@ class WindowStateAnimator { "SIZE " + width + "x" + height, null); mSurfaceResized = true; mSurface.setSize(width, height); - mAnimator.mPendingLayoutChanges |= - WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; + final int displayId = w.mDisplayContent.getDisplayId(); + mAnimator.setPendingLayoutChanges(displayId, + WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) { final DisplayInfo displayInfo = mWin.mDisplayContent.getDisplayInfo(); mService.startDimming(this, w.mExiting ? 0 : w.mAttrs.dimAmount, |