From 698b684fdd467c3e8d251cef9d4f9da0daa8195b Mon Sep 17 00:00:00 2001 From: Rob Carr Date: Fri, 6 Mar 2020 15:33:31 -0800 Subject: [PATCH] WindowManager: Avoid reparenting BLAST Surface in reparentChildren In cases where we are replacing the client surface transparently (e.g. preserved surfaces), we call reparentChildren to move client added Surfaces of the preserved Surface to the new Layer. However we are calling this on the WSA layer, and so we end up reparenting the BLAST Surface to the new layer. But since we always construct a new BLAST surface on the WM side, we end up with 2! Rather than try and juggle about when we need to or need not to construct a BLAST surface and reparenting them across preservedSurfaces, it seemed either to just use the BLAST surface as the root of the reparentChildren operation. Bug: 150013915 Test: Enable BLAST, use split-screen Change-Id: I1357200b41d183c2331b684ff636dd40a3b98168 --- core/java/android/view/ViewRootImpl.java | 2 +- .../server/wm/InsetsSourceProvider.java | 2 +- .../android/server/wm/SeamlessRotator.java | 4 +-- .../com/android/server/wm/WindowState.java | 4 +-- .../server/wm/WindowStateAnimator.java | 26 ++++++++++--------- .../server/wm/WindowSurfaceController.java | 10 ++++++- 6 files changed, 29 insertions(+), 19 deletions(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 8d3cffc512c3c..9228fbdf82c82 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1735,7 +1735,7 @@ public final class ViewRootImpl implements ViewParent, mBoundsLayer = new SurfaceControl.Builder(mSurfaceSession) .setContainerLayer() .setName("Bounds for - " + getTitle().toString()) - .setParent(mSurfaceControl) + .setParent(getRenderSurfaceControl()) .build(); setBoundsLayerCrop(); mTransaction.show(mBoundsLayer).apply(); diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 58aefdc0e5477..ada6d47109675 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -274,7 +274,7 @@ class InsetsSourceProvider { // window crop of the surface controls (including the leash) until the client finishes // drawing the new frame of the new orientation. Although we cannot defer the reparent // operation, it is fine, because reparent won't cause any visual effect. - final SurfaceControl barrier = mWin.getDeferTransactionBarrier(); + final SurfaceControl barrier = mWin.getClientViewRootSurface(); t.deferTransactionUntil(mWin.getSurfaceControl(), barrier, frameNumber); t.deferTransactionUntil(leash, barrier, frameNumber); } diff --git a/services/core/java/com/android/server/wm/SeamlessRotator.java b/services/core/java/com/android/server/wm/SeamlessRotator.java index 024da888248df..8e1c6329f39d9 100644 --- a/services/core/java/com/android/server/wm/SeamlessRotator.java +++ b/services/core/java/com/android/server/wm/SeamlessRotator.java @@ -118,9 +118,9 @@ public class SeamlessRotator { finish(t, win); if (win.mWinAnimator.mSurfaceController != null && !timeout) { t.deferTransactionUntil(win.mSurfaceControl, - win.getDeferTransactionBarrier(), win.getFrameNumber()); + win.getClientViewRootSurface(), win.getFrameNumber()); t.deferTransactionUntil(win.mWinAnimator.mSurfaceController.mSurfaceControl, - win.getDeferTransactionBarrier(), win.getFrameNumber()); + win.getClientViewRootSurface(), win.getFrameNumber()); } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 27f1ca025a933..386755de9b873 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -5660,8 +5660,8 @@ class WindowState extends WindowContainer implements WindowManagerP return mSession.mPid == pid && isNonToastOrStarting() && isVisibleNow(); } - SurfaceControl getDeferTransactionBarrier() { - return mWinAnimator.getDeferTransactionBarrier(); + SurfaceControl getClientViewRootSurface() { + return mWinAnimator.getClientViewRootSurface(); } @Override diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 81d0e3e88c1a8..79dc5366445e3 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -383,8 +383,9 @@ class WindowStateAnimator { // Make sure to reparent any children of the new surface back to the preserved // surface before destroying it. if (mSurfaceController != null && mPendingDestroySurface != null) { - mPostDrawTransaction.reparentChildren(mSurfaceController.mSurfaceControl, - mPendingDestroySurface.mSurfaceControl).apply(); + mPostDrawTransaction.reparentChildren( + mSurfaceController.getClientViewRootSurface(), + mPendingDestroySurface.mSurfaceControl).apply(); } destroySurfaceLocked(); mSurfaceDestroyDeferred = true; @@ -413,9 +414,9 @@ class WindowStateAnimator { // child layers need to be reparented to the new surface to make this // transparent to the app. if (mWin.mActivityRecord == null || mWin.mActivityRecord.isRelaunching() == false) { - mPostDrawTransaction.reparentChildren(mPendingDestroySurface.mSurfaceControl, - mSurfaceController.mSurfaceControl) - .apply(); + mPostDrawTransaction.reparentChildren( + mPendingDestroySurface.getClientViewRootSurface(), + mSurfaceController.mSurfaceControl).apply(); } } } @@ -875,7 +876,7 @@ class WindowStateAnimator { if (mSurfaceResized && (mAttrType == TYPE_BASE_APPLICATION) && (task != null) && (task.getMainWindowSizeChangeTransaction() != null)) { - mSurfaceController.deferTransactionUntil(mWin.getDeferTransactionBarrier(), + mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(), mWin.getFrameNumber()); SurfaceControl.mergeToGlobalTransaction(task.getMainWindowSizeChangeTransaction()); task.setMainWindowSizeChangeTransaction(null); @@ -1012,7 +1013,7 @@ class WindowStateAnimator { // the WS position is reset (so the stack position is shown) at the same // time that the buffer size changes. setOffsetPositionForStackResize(false); - mSurfaceController.deferTransactionUntil(mWin.getDeferTransactionBarrier(), + mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(), mWin.getFrameNumber()); } else { final ActivityStack stack = mWin.getRootTask(); @@ -1043,7 +1044,7 @@ class WindowStateAnimator { // comes in at the new size (normally position and crop are unfrozen). // deferTransactionUntil accomplishes this for us. if (wasForceScaled && !mForceScaleUntilResize) { - mSurfaceController.deferTransactionUntil(mWin.getDeferTransactionBarrier(), + mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(), mWin.getFrameNumber()); mSurfaceController.forceScaleableInTransaction(false); } @@ -1288,8 +1289,9 @@ class WindowStateAnimator { if (mPendingDestroySurface != null && mDestroyPreservedSurfaceUponRedraw) { final SurfaceControl pendingSurfaceControl = mPendingDestroySurface.mSurfaceControl; mPostDrawTransaction.reparent(pendingSurfaceControl, null); - mPostDrawTransaction.reparentChildren(pendingSurfaceControl, - mSurfaceController.mSurfaceControl); + mPostDrawTransaction.reparentChildren( + mPendingDestroySurface.getClientViewRootSurface(), + mSurfaceController.mSurfaceControl); } SurfaceControl.mergeToGlobalTransaction(mPostDrawTransaction); @@ -1521,10 +1523,10 @@ class WindowStateAnimator { mOffsetPositionForStackResize = offsetPositionForStackResize; } - SurfaceControl getDeferTransactionBarrier() { + SurfaceControl getClientViewRootSurface() { if (!hasSurface()) { return null; } - return mSurfaceController.getDeferTransactionBarrier(); + return mSurfaceController.getClientViewRootSurface(); } } diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index 383c0d9ab3d42..d7c97b922d2d2 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -533,7 +533,15 @@ class WindowSurfaceController { return mSurfaceH; } - SurfaceControl getDeferTransactionBarrier() { + /** + * Returns the Surface which the client-framework ViewRootImpl will be using. + * This is either the WSA SurfaceControl or it's BLAST child surface. + * This has too main uses: + * 1. This is the Surface the client will add children to, we use this to make + * sure we don't reparent the BLAST surface itself when calling reparentChildren + * 2. We use this as the barrier Surface for some deferTransaction operations. + */ + SurfaceControl getClientViewRootSurface() { if (mBLASTSurfaceControl != null) { return mBLASTSurfaceControl; }