diff options
| author | Jorim Jaggi <jjaggi@google.com> | 2020-03-19 01:12:44 +0100 |
|---|---|---|
| committer | Jorim Jaggi <jjaggi@google.com> | 2020-03-23 22:31:52 +0100 |
| commit | 22488d31bbff0f5ad29d820f001ae827332354be (patch) | |
| tree | be30fca2d1ca9b47e01d28e8bf66a9a58a8167bb /core/java/android/view/ViewRootImpl.java | |
| parent | 5bd455ac5f0f09280ae59e3eeb74ea7e3b7e4823 (diff) | |
Performance optimizations for new insets
- Prevent unnecesary dispatchApplyInsets caused by legacy system
also requesting inset changes
- Make insetsModified oneway. It's safe to do so because we
absolutely don't care about interleaving with other WindowSession
methods.
- Do not trigger layout if nothing relevant has changed
- Only trigger requestFitSystemWindows if state actually changed
Test: Systrace. Automated perf test will be added
Bug: 151865131
Change-Id: I24944875e739e4a74606e3a02bbf14585c1c13db
Diffstat (limited to 'core/java/android/view/ViewRootImpl.java')
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 152 |
1 files changed, 29 insertions, 123 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index dd34bcb018b9..993edcdd1ed3 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -548,13 +548,11 @@ public final class ViewRootImpl implements ViewParent, boolean mAddedTouchMode; final Rect mTmpFrame = new Rect(); + final Rect mTmpRect = new Rect(); // These are accessed by multiple threads. final Rect mWinFrame; // frame given by window manager. - final Rect mPendingVisibleInsets = new Rect(); - final Rect mPendingStableInsets = new Rect(); - final Rect mPendingContentInsets = new Rect(); final Rect mPendingBackDropFrame = new Rect(); final DisplayCutout.ParcelableWrapper mPendingDisplayCutout = new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT); @@ -563,10 +561,6 @@ public final class ViewRootImpl implements ViewParent, final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets = new ViewTreeObserver.InternalInsetsInfo(); - final Rect mDispatchContentInsets = new Rect(); - final Rect mDispatchStableInsets = new Rect(); - DisplayCutout mDispatchDisplayCutout = DisplayCutout.NO_CUTOUT; - private WindowInsets mLastWindowInsets; // Insets types hidden by legacy window flags or system UI flags. @@ -1020,10 +1014,7 @@ public final class ViewRootImpl implements ViewParent, if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets); } - mPendingContentInsets.set(mAttachInfo.mContentInsets); - mPendingStableInsets.set(mAttachInfo.mStableInsets); mPendingDisplayCutout.set(mAttachInfo.mDisplayCutout); - mPendingVisibleInsets.set(0, 0, 0, 0); mAttachInfo.mAlwaysConsumeSystemBars = (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS) != 0; mPendingAlwaysConsumeSystemBars = mAttachInfo.mAlwaysConsumeSystemBars; @@ -2204,45 +2195,20 @@ public final class ViewRootImpl implements ViewParent, /* package */ WindowInsets getWindowInsets(boolean forceConstruct) { if (mLastWindowInsets == null || forceConstruct) { - mDispatchContentInsets.set(mAttachInfo.mContentInsets); - mDispatchStableInsets.set(mAttachInfo.mStableInsets); - mDispatchDisplayCutout = mAttachInfo.mDisplayCutout.get(); - - Rect contentInsets = mDispatchContentInsets; - Rect stableInsets = mDispatchStableInsets; - DisplayCutout displayCutout = mDispatchDisplayCutout; - // For dispatch we preserve old logic, but for direct requests from Views we allow to - // immediately use pending insets. This is such that getRootWindowInsets returns the - // result from the layout hint before we ran a traversal shortly after adding a window. - if (!forceConstruct - && (!mPendingContentInsets.equals(contentInsets) || - !mPendingStableInsets.equals(stableInsets) || - !mPendingDisplayCutout.get().equals(displayCutout))) { - contentInsets = mPendingContentInsets; - stableInsets = mPendingStableInsets; - displayCutout = mPendingDisplayCutout.get(); - } - contentInsets = ensureInsetsNonNegative(contentInsets, "content"); - stableInsets = ensureInsetsNonNegative(stableInsets, "stable"); mLastWindowInsets = mInsetsController.calculateInsets( mContext.getResources().getConfiguration().isScreenRound(), - mAttachInfo.mAlwaysConsumeSystemBars, displayCutout, - contentInsets, stableInsets, mWindowAttributes.softInputMode, - (mWindowAttributes.systemUiVisibility + mAttachInfo.mAlwaysConsumeSystemBars, mPendingDisplayCutout.get(), + mWindowAttributes.softInputMode, (mWindowAttributes.systemUiVisibility | mWindowAttributes.subtreeSystemUiVisibility)); - } - return mLastWindowInsets; - } - private Rect ensureInsetsNonNegative(Rect insets, String kind) { - if (insets.left < 0 || insets.top < 0 || insets.right < 0 || insets.bottom < 0) { - Log.wtf(mTag, "Negative " + kind + "Insets: " + insets + ", mFirst=" + mFirst); - return new Rect(Math.max(0, insets.left), - Math.max(0, insets.top), - Math.max(0, insets.right), - Math.max(0, insets.bottom)); + Rect visibleInsets = mInsetsController.calculateVisibleInsets( + mWindowAttributes.softInputMode); + + mAttachInfo.mVisibleInsets.set(visibleInsets); + mAttachInfo.mContentInsets.set(mLastWindowInsets.getSystemWindowInsets().toRect()); + mAttachInfo.mStableInsets.set(mLastWindowInsets.getStableInsets().toRect()); } - return insets; + return mLastWindowInsets; } public void dispatchApplyInsets(View host) { @@ -2266,12 +2232,6 @@ public final class ViewRootImpl implements ViewParent, == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; } - private void updateVisibleInsets() { - Rect visibleInsets = mInsetsController.calculateVisibleInsets(mPendingVisibleInsets, - mWindowAttributes.softInputMode); - mAttachInfo.mVisibleInsets.set(visibleInsets); - } - @VisibleForTesting public InsetsController getInsetsController() { return mInsetsController; @@ -2398,7 +2358,7 @@ public final class ViewRootImpl implements ViewParent, // Execute enqueued actions on every traversal in case a detached view enqueued an action getRunQueue().executeActions(mAttachInfo.mHandler); - boolean insetsChanged = false; + boolean cutoutChanged = false; boolean layoutRequested = mLayoutRequested && (!mStopped || mReportNextDraw); if (layoutRequested) { @@ -2411,22 +2371,8 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mInTouchMode = !mAddedTouchMode; ensureTouchModeLocally(mAddedTouchMode); } else { - if (!mPendingContentInsets.equals(mAttachInfo.mContentInsets)) { - insetsChanged = true; - } - if (!mPendingStableInsets.equals(mAttachInfo.mStableInsets)) { - insetsChanged = true; - } if (!mPendingDisplayCutout.equals(mAttachInfo.mDisplayCutout)) { - insetsChanged = true; - } - if (!mPendingVisibleInsets.equals(mAttachInfo.mVisibleInsets)) { - updateVisibleInsets(); - if (DEBUG_LAYOUT) Log.v(mTag, "Visible insets changing to: " - + mAttachInfo.mVisibleInsets); - } - if (mPendingAlwaysConsumeSystemBars != mAttachInfo.mAlwaysConsumeSystemBars) { - insetsChanged = true; + cutoutChanged = true; } if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) { @@ -2489,7 +2435,6 @@ public final class ViewRootImpl implements ViewParent, } if (mApplyInsetsRequested) { - updateVisibleInsets(); dispatchApplyInsets(host); if (mLayoutRequested) { // Short-circuit catching a new layout request here, so @@ -2557,8 +2502,8 @@ public final class ViewRootImpl implements ViewParent, controlInsetsForCompatibility(params); } - if (mFirst || windowShouldResize || insetsChanged || - viewVisibilityChanged || params != null || mForceNextWindowRelayout) { + if (mFirst || windowShouldResize || viewVisibilityChanged || cutoutChanged || params != null + || mForceNextWindowRelayout) { mForceNextWindowRelayout = false; if (isViewVisible) { @@ -2580,7 +2525,7 @@ public final class ViewRootImpl implements ViewParent, } boolean hwInitialized = false; - boolean contentInsetsChanged = false; + boolean dispatchApplyInsets = false; boolean hadSurface = mSurface.isValid(); try { @@ -2603,9 +2548,6 @@ public final class ViewRootImpl implements ViewParent, relayoutResult = relayoutWindow(params, viewVisibility, insetsPending); if (DEBUG_LAYOUT) Log.v(mTag, "relayout: frame=" + frame.toShortString() - + " content=" + mPendingContentInsets.toShortString() - + " visible=" + mPendingVisibleInsets.toShortString() - + " stable=" + mPendingStableInsets.toShortString() + " cutout=" + mPendingDisplayCutout.get().toString() + " surface=" + mSurface); @@ -2622,14 +2564,7 @@ public final class ViewRootImpl implements ViewParent, updatedConfiguration = true; } - contentInsetsChanged = !mPendingContentInsets.equals( - mAttachInfo.mContentInsets); - final boolean visibleInsetsChanged = !mPendingVisibleInsets.equals( - mAttachInfo.mVisibleInsets); - final boolean stableInsetsChanged = !mPendingStableInsets.equals( - mAttachInfo.mStableInsets); - final boolean cutoutChanged = !mPendingDisplayCutout.equals( - mAttachInfo.mDisplayCutout); + cutoutChanged = !mPendingDisplayCutout.equals(mAttachInfo.mDisplayCutout); surfaceSizeChanged = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0; final boolean alwaysConsumeSystemBarsChanged = @@ -2640,42 +2575,25 @@ public final class ViewRootImpl implements ViewParent, surfaceReplaced = (surfaceGenerationId != mSurface.getGenerationId()) && mSurface.isValid(); - if (contentInsetsChanged) { - mAttachInfo.mContentInsets.set(mPendingContentInsets); - if (DEBUG_LAYOUT) Log.v(mTag, "Content insets changing to: " - + mAttachInfo.mContentInsets); - } - if (stableInsetsChanged) { - mAttachInfo.mStableInsets.set(mPendingStableInsets); - if (DEBUG_LAYOUT) Log.v(mTag, "Decor insets changing to: " - + mAttachInfo.mStableInsets); - // Need to relayout with content insets. - contentInsetsChanged = true; - } if (cutoutChanged) { mAttachInfo.mDisplayCutout.set(mPendingDisplayCutout); if (DEBUG_LAYOUT) { Log.v(mTag, "DisplayCutout changing to: " + mAttachInfo.mDisplayCutout); } // Need to relayout with content insets. - contentInsetsChanged = true; + dispatchApplyInsets = true; } if (alwaysConsumeSystemBarsChanged) { mAttachInfo.mAlwaysConsumeSystemBars = mPendingAlwaysConsumeSystemBars; - contentInsetsChanged = true; + dispatchApplyInsets = true; } - if (contentInsetsChanged || mLastSystemUiVisibility != + if (dispatchApplyInsets || mLastSystemUiVisibility != mAttachInfo.mSystemUiVisibility || mApplyInsetsRequested) { mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility; dispatchApplyInsets(host); // We applied insets so force contentInsetsChanged to ensure the // hierarchy is measured below. - contentInsetsChanged = true; - } - if (visibleInsetsChanged) { - updateVisibleInsets(); - if (DEBUG_LAYOUT) Log.v(mTag, "Visible insets changing to: " - + mAttachInfo.mVisibleInsets); + dispatchApplyInsets = true; } if (colorModeChanged && mAttachInfo.mThreadedRenderer != null) { mAttachInfo.mThreadedRenderer.setWideGamut( @@ -2766,7 +2684,8 @@ public final class ViewRootImpl implements ViewParent, && mWinFrame.height() == mPendingBackDropFrame.height(); // TODO: Need cutout? startDragResizing(mPendingBackDropFrame, !backdropSizeMatchesFrame, - mPendingVisibleInsets, mPendingStableInsets, mResizeMode); + mLastWindowInsets.getSystemWindowInsets().toRect(), + mLastWindowInsets.getStableInsets().toRect(), mResizeMode); } else { // We shouldn't come here, but if we come we should end the resize. endDragResizing(); @@ -2857,7 +2776,7 @@ public final class ViewRootImpl implements ViewParent, boolean focusChangedDueToTouchMode = ensureTouchModeLocally( (relayoutResult&WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE) != 0); if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth() - || mHeight != host.getMeasuredHeight() || contentInsetsChanged || + || mHeight != host.getMeasuredHeight() || dispatchApplyInsets || updatedConfiguration) { int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width); int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height); @@ -2866,7 +2785,7 @@ public final class ViewRootImpl implements ViewParent, + mWidth + " measuredWidth=" + host.getMeasuredWidth() + " mHeight=" + mHeight + " measuredHeight=" + host.getMeasuredHeight() - + " coveredInsetsChanged=" + contentInsetsChanged); + + " dispatchApplyInsets=" + dispatchApplyInsets); // Ask host how big it wants to be performMeasure(childWidthMeasureSpec, childHeightMeasureSpec); @@ -4912,12 +4831,9 @@ public final class ViewRootImpl implements ViewParent, // Recycled in the fall through... SomeArgs args = (SomeArgs) msg.obj; if (mWinFrame.equals(args.arg1) - && mPendingContentInsets.equals(args.arg2) - && mPendingStableInsets.equals(args.arg6) && mPendingDisplayCutout.get().equals(args.arg9) - && mPendingVisibleInsets.equals(args.arg3) && mPendingBackDropFrame.equals(args.arg8) - && args.arg4 == null + && mLastReportedMergedConfiguration.equals(args.arg4) && args.argi1 == 0 && mDisplay.getDisplayId() == args.argi3) { break; @@ -4945,16 +4861,10 @@ public final class ViewRootImpl implements ViewParent, } final boolean framesChanged = !mWinFrame.equals(args.arg1) - || !mPendingContentInsets.equals(args.arg2) - || !mPendingStableInsets.equals(args.arg6) - || !mPendingDisplayCutout.get().equals(args.arg9) - || !mPendingVisibleInsets.equals(args.arg3); + || !mPendingDisplayCutout.get().equals(args.arg9); setFrame((Rect) args.arg1); - mPendingContentInsets.set((Rect) args.arg2); - mPendingStableInsets.set((Rect) args.arg6); mPendingDisplayCutout.set((DisplayCutout) args.arg9); - mPendingVisibleInsets.set((Rect) args.arg3); mPendingBackDropFrame.set((Rect) args.arg8); mForceNextWindowRelayout = args.argi1 != 0; mPendingAlwaysConsumeSystemBars = args.argi2 != 0; @@ -7408,10 +7318,9 @@ public final class ViewRootImpl implements ViewParent, (int) (mView.getMeasuredWidth() * appScale + 0.5f), (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber, - mTmpFrame, mPendingContentInsets, mPendingVisibleInsets, - mPendingStableInsets, mPendingBackDropFrame, mPendingDisplayCutout, - mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mSurfaceSize, - mBlastSurfaceControl); + mTmpFrame, mTmpRect, mTmpRect, mTmpRect, mPendingBackDropFrame, + mPendingDisplayCutout, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, + mSurfaceSize, mBlastSurfaceControl); if (mSurfaceControl.isValid()) { if (!mUseBLASTAdapter) { mSurface.copyFrom(mSurfaceControl); @@ -7432,9 +7341,6 @@ public final class ViewRootImpl implements ViewParent, if (mTranslator != null) { mTranslator.translateRectInScreenToAppWinFrame(mTmpFrame); - mTranslator.translateRectInScreenToAppWindow(mPendingContentInsets); - mTranslator.translateRectInScreenToAppWindow(mPendingVisibleInsets); - mTranslator.translateRectInScreenToAppWindow(mPendingStableInsets); } setFrame(mTmpFrame); mInsetsController.onStateChanged(mTempInsets); |
