diff options
author | Robert Carr <racarr@google.com> | 2020-01-22 13:32:38 -0800 |
---|---|---|
committer | Robert Carr <racarr@google.com> | 2020-01-27 16:47:33 -0800 |
commit | 2e20bcd65ecdb06eeaac2dc8356dec90c756d271 (patch) | |
tree | 707c73d18147e571adcf388036a0c0510770d99c | |
parent | 6871767aaa276165c41db4c330e9ebe07cd7501c (diff) |
WM: Defer transactions for BLAST Surfaces too.
For switching on BLAST we are implementing deferred transactions for
compatibility. Presently the BLAST Surface is constructed by the ViewRootImpl
and so the WM has no reference to pass when using it as a barrier layer for
deferTransactionUntil. To resolve this we construct and hold a reference to
the BLAST Surface on the server side, and pass it down to the client in relayoutWindow.
We don't use the WindowStateAnimator surface directly as both the BLAST Adapter and
the WindowStateAnimator would then be setting crops on it.
Bug: 146598493
Test: Builds, existing tests pass.
Change-Id: I6513e0442f5c75f01eb8dde5f1924dd7b636163c
14 files changed, 84 insertions, 32 deletions
diff --git a/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java b/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java index c62aad622f25..b6e39e14602a 100644 --- a/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java +++ b/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java @@ -150,7 +150,7 @@ public class RelayoutPerfTest extends WindowManagerPerfTestBase { mViewVisibility.getAsInt(), mFlags, mFrameNumber, mOutFrame, mOutContentInsets, mOutVisibleInsets, mOutStableInsets, mOutBackDropFrame, mOutDisplayCutout, mOutMergedConfiguration, - mOutSurfaceControl, mOutInsetsState, new Point()); + mOutSurfaceControl, mOutInsetsState, new Point(), new SurfaceControl()); } } } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index dd78c78654c3..e9285cc7931d 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -223,6 +223,9 @@ public abstract class WallpaperService extends Service { SurfaceControl mSurfaceControl = new SurfaceControl(); + // Unused relayout out-param + SurfaceControl mTmpSurfaceControl = new SurfaceControl(); + final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() { { mRequestedFormat = PixelFormat.RGBX_8888; @@ -902,7 +905,7 @@ public abstract class WallpaperService extends Service { View.VISIBLE, 0, -1, mWinFrame, mContentInsets, mVisibleInsets, mStableInsets, mBackdropFrame, mDisplayCutout, mMergedConfiguration, mSurfaceControl, - mInsetsState, mSurfaceSize); + mInsetsState, mSurfaceSize, mTmpSurfaceControl); if (mSurfaceControl.isValid()) { mSurfaceHolder.mSurface.copyFrom(mSurfaceControl); mSurfaceControl.release(); diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index e3446e1f7b57..1677357dedbe 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -92,6 +92,9 @@ interface IWindowSession { * @param outSurface Object in which is placed the new display surface. * @param insetsState The current insets state in the system. * @param outSurfaceSize The width and height of the surface control + * @param outBlastSurfaceControl A BLAST SurfaceControl allocated by the WindowManager + * the SurfaceControl willl be managed by the client side, but the WindowManager + * may use it as a deferTransaction barrier. * * @return int Result flags: {@link WindowManagerGlobal#RELAYOUT_SHOW_FOCUS}, * {@link WindowManagerGlobal#RELAYOUT_FIRST_TIME}. @@ -103,7 +106,8 @@ interface IWindowSession { out Rect outBackdropFrame, out DisplayCutout.ParcelableWrapper displayCutout, out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl, - out InsetsState insetsState, out Point outSurfaceSize); + out InsetsState insetsState, out Point outSurfaceSize, + out SurfaceControl outBlastSurfaceControl); /* * Notify the window manager that an application is relaunching and diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 7a93dcc9e4ec..fbcc261a956e 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -507,7 +507,7 @@ public final class ViewRootImpl implements ViewParent, @UnsupportedAppUsage public final Surface mSurface = new Surface(); private final SurfaceControl mSurfaceControl = new SurfaceControl(); - private SurfaceControl mBlastSurfaceControl; + private SurfaceControl mBlastSurfaceControl = new SurfaceControl(); private BLASTBufferQueue mBlastBufferQueue; @@ -1690,23 +1690,17 @@ public final class ViewRootImpl implements ViewParent, .build(); setBoundsLayerCrop(); mTransaction.show(mBoundsLayer).apply(); - } - return mBoundsLayer; + } + return mBoundsLayer; } Surface getOrCreateBLASTSurface(int width, int height) { if (mSurfaceControl == null || !mSurfaceControl.isValid()) { return null; } - if (mBlastSurfaceControl == null) { - mBlastSurfaceControl = new SurfaceControl.Builder(mSurfaceSession) - .setParent(mSurfaceControl) - .setName("BLAST") - .setBLASTLayer() - .build(); + if ((mBlastBufferQueue != null) && mBlastSurfaceControl.isValid()) { mBlastBufferQueue = new BLASTBufferQueue( mBlastSurfaceControl, width, height); - } mBlastBufferQueue.update(mBlastSurfaceControl, width, height); @@ -7344,7 +7338,8 @@ public final class ViewRootImpl implements ViewParent, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber, mTmpFrame, mPendingContentInsets, mPendingVisibleInsets, mPendingStableInsets, mPendingBackDropFrame, mPendingDisplayCutout, - mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mSurfaceSize); + mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mSurfaceSize, + mBlastSurfaceControl); if (mSurfaceControl.isValid()) { if (!WindowManagerGlobal.USE_BLAST_ADAPTER) { mSurface.copyFrom(mSurfaceControl); diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index 9f2784889cab..91778aaf51fd 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -161,7 +161,7 @@ public class WindowlessWindowManager implements IWindowSession { Rect outStableInsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, - Point outSurfaceSize) { + Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { State state = null; synchronized (this) { state = mStateForWindow.get(window.asBinder()); diff --git a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java index 5aba013a7fb8..adce1248b04b 100644 --- a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java +++ b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java @@ -239,12 +239,12 @@ public class SystemWindows { Rect outVisibleInsets, Rect outStableInsets, DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, - Point outSurfaceSize) { + Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { int res = super.relayout(window, seq, attrs, requestedWidth, requestedHeight, viewVisibility, flags, frameNumber, outFrame, outOverscanInsets, outContentInsets, outVisibleInsets, outStableInsets, cutout, mergedConfiguration, outSurfaceControl, outInsetsState, - outSurfaceSize); + outSurfaceSize, outBLASTSurfaceControl); if (res != 0) { return res; } diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 5a591ecd4746..2bb58ddc5b38 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -233,7 +233,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.mWinAnimator.mSurfaceController.mSurfaceControl; + final SurfaceControl barrier = mWin.getDeferTransactionBarrier(); 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 ba31818d6331..c621c48b0028 100644 --- a/services/core/java/com/android/server/wm/SeamlessRotator.java +++ b/services/core/java/com/android/server/wm/SeamlessRotator.java @@ -101,9 +101,9 @@ public class SeamlessRotator { t.setPosition(win.mSurfaceControl, win.mLastSurfacePosition.x, win.mLastSurfacePosition.y); if (win.mWinAnimator.mSurfaceController != null && !timeout) { t.deferTransactionUntil(win.mSurfaceControl, - win.mWinAnimator.mSurfaceController.mSurfaceControl, win.getFrameNumber()); + win.getDeferTransactionBarrier(), win.getFrameNumber()); t.deferTransactionUntil(win.mWinAnimator.mSurfaceController.mSurfaceControl, - win.mWinAnimator.mSurfaceController.mSurfaceControl, win.getFrameNumber()); + win.getDeferTransactionBarrier(), win.getFrameNumber()); } } diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 5babdafc856d..de7f9e41cac0 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -191,7 +191,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { Rect outStableInsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, - Point outSurfaceSize) { + Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from " + Binder.getCallingPid()); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag); @@ -199,7 +199,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { requestedWidth, requestedHeight, viewFlags, flags, frameNumber, outFrame, outContentInsets, outVisibleInsets, outStableInsets, outBackdropFrame, cutout, - mergedConfiguration, outSurfaceControl, outInsetsState, outSurfaceSize); + mergedConfiguration, outSurfaceControl, outInsetsState, outSurfaceSize, + outBLASTSurfaceControl); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to " + Binder.getCallingPid()); diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index 57de7536409f..e47eaee5bce4 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -116,7 +116,11 @@ class TaskSnapshotSurface implements StartingSurface { private static final String TAG = TAG_WITH_CLASS_NAME ? "SnapshotStartingWindow" : TAG_WM; private static final int MSG_REPORT_DRAW = 0; private static final String TITLE_FORMAT = "SnapshotStartingWindow for taskId=%s"; - private static final Point sSurfaceSize = new Point(); //tmp var for unused relayout param + + //tmp vars for unused relayout params + private static final Point sTmpSurfaceSize = new Point(); + private static final SurfaceControl sTmpSurfaceControl = new SurfaceControl(); + private final Window mWindow; private final Surface mSurface; private SurfaceControl mSurfaceControl; @@ -230,7 +234,7 @@ class TaskSnapshotSurface implements StartingSurface { session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, -1, tmpFrame, tmpContentInsets, tmpRect, tmpStableInsets, tmpRect, tmpCutout, tmpMergedConfiguration, surfaceControl, mTmpInsetsState, - sSurfaceSize); + sTmpSurfaceSize, sTmpSurfaceControl); } catch (RemoteException e) { // Local call. } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index e13083007237..2c6c756dda3b 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2071,7 +2071,7 @@ public class WindowManagerService extends IWindowManager.Stub Rect outVisibleInsets, Rect outStableInsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, - Point outSurfaceSize) { + Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { int result = 0; boolean configChanged; final int pid = Binder.getCallingPid(); @@ -2238,7 +2238,8 @@ public class WindowManagerService extends IWindowManager.Stub result = win.relayoutVisibleWindow(result, attrChanges); try { - result = createSurfaceControl(outSurfaceControl, result, win, winAnimator); + result = createSurfaceControl(outSurfaceControl, outBLASTSurfaceControl, + result, win, winAnimator); } catch (Exception e) { displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/); @@ -2270,6 +2271,7 @@ public class WindowManagerService extends IWindowManager.Stub // surface, let the client use that, but don't create new surface at this point. Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: getSurface"); winAnimator.mSurfaceController.getSurfaceControl(outSurfaceControl); + winAnimator.mSurfaceController.getBLASTSurfaceControl(outBLASTSurfaceControl); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } else { if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win); @@ -2451,7 +2453,8 @@ public class WindowManagerService extends IWindowManager.Stub } private int createSurfaceControl(SurfaceControl outSurfaceControl, - int result, WindowState win, WindowStateAnimator winAnimator) { + SurfaceControl outBLASTSurfaceControl, int result, + WindowState win, WindowStateAnimator winAnimator) { if (!win.mHasSurface) { result |= RELAYOUT_RES_SURFACE_CHANGED; } @@ -2465,6 +2468,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (surfaceController != null) { surfaceController.getSurfaceControl(outSurfaceControl); + surfaceController.getBLASTSurfaceControl(outBLASTSurfaceControl); ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl); } else { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 73984fd49f73..b9694c3b9bd3 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -5616,4 +5616,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP boolean isNonToastWindowVisibleForPid(int pid) { return mSession.mPid == pid && isNonToastOrStarting() && isVisibleNow(); } + + SurfaceControl getDeferTransactionBarrier() { + return mWinAnimator.getDeferTransactionBarrier(); + } } diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 069ee4fea8ec..9552df7b5899 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1010,7 +1010,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(mSurfaceController.mSurfaceControl, + mSurfaceController.deferTransactionUntil(mWin.getDeferTransactionBarrier(), mWin.getFrameNumber()); } else { final ActivityStack stack = mWin.getRootTask(); @@ -1041,7 +1041,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(mSurfaceController.mSurfaceControl, + mSurfaceController.deferTransactionUntil(mWin.getDeferTransactionBarrier(), mWin.getFrameNumber()); mSurfaceController.forceScaleableInTransaction(false); } @@ -1518,4 +1518,11 @@ class WindowStateAnimator { void setOffsetPositionForStackResize(boolean offsetPositionForStackResize) { mOffsetPositionForStackResize = offsetPositionForStackResize; } + + SurfaceControl getDeferTransactionBarrier() { + if (!hasSurface()) { + return null; + } + return mSurfaceController.getDeferTransactionBarrier(); + } } diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index 5b8015be1a7a..383c0d9ab3d4 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -51,6 +51,11 @@ class WindowSurfaceController { SurfaceControl mSurfaceControl; + /** + * WM only uses for deferred transactions. + */ + SurfaceControl mBLASTSurfaceControl; + // Should only be set from within setShown(). private boolean mSurfaceShown = false; private float mSurfaceX = 0; @@ -110,13 +115,22 @@ class WindowSurfaceController { .setMetadata(METADATA_WINDOW_TYPE, windowType) .setMetadata(METADATA_OWNER_UID, ownerUid); - if ((win.getAttrs().privateFlags & - WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0) { + final boolean useBLAST = (win.getAttrs().privateFlags & + WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0; + if (useBLAST) { b.setContainerLayer(); } - mSurfaceControl = b.build(); + + if (useBLAST) { + mBLASTSurfaceControl = win.makeSurface() + .setParent(mSurfaceControl) + .setName("BLAST Adapter Layer") + .setBLASTLayer() + .build(); + } + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } @@ -168,6 +182,9 @@ class WindowSurfaceController { } finally { setShown(false); mSurfaceControl = null; + if (mBLASTSurfaceControl != null) { + mBLASTSurfaceControl.release(); + } } } @@ -474,6 +491,12 @@ class WindowSurfaceController { outSurfaceControl.copyFrom(mSurfaceControl); } + void getBLASTSurfaceControl(SurfaceControl outSurfaceControl) { + if (mBLASTSurfaceControl != null) { + outSurfaceControl.copyFrom(mBLASTSurfaceControl); + } + } + int getLayer() { return mSurfaceLayer; } @@ -510,6 +533,13 @@ class WindowSurfaceController { return mSurfaceH; } + SurfaceControl getDeferTransactionBarrier() { + if (mBLASTSurfaceControl != null) { + return mBLASTSurfaceControl; + } + return mSurfaceControl; + } + void dumpDebug(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); proto.write(SHOWN, mSurfaceShown); |