From af1c7cfd1e290f2181a46435bcd7d9735c6a89fd Mon Sep 17 00:00:00 2001 From: Tiger Date: Tue, 1 Aug 2023 19:15:11 +0800 Subject: [PATCH] Refine the performance of updating the insets hint Previously, the insets hint was checked and updated every time in InsetsSourceProvider#onPostLayout via setServerVisible. Most of them were just checking but not updating. That still caused the regression of performance. This CL flags the insets hint as stale when the source frame or the window container bounds is changed, and only updates the insets hints when someone calls getInsetsHint(). Fix: 292177371 Test: atest InsetsSourceProviderTest Test: Switch to 3-button navigation bar and reboot the device. Make sure the back button is not shown on the lockscreen. Change-Id: I59e21581d7ca136d4e4eb8c1a442fc74a92914b7 --- .../server/wm/InsetsSourceProvider.java | 43 +++++++++++-------- .../android/server/wm/WindowContainer.java | 6 +++ 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 5f3d517b2cdfa..02f5c217e5d8e 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -81,8 +81,8 @@ class InsetsSourceProvider { private boolean mIsLeashReadyForDispatching; private final Rect mSourceFrame = new Rect(); private final Rect mLastSourceFrame = new Rect(); - private final Rect mLastContainerBounds = new Rect(); private @NonNull Insets mInsetsHint = Insets.NONE; + private boolean mInsetsHintStale = true; private @Flags int mFlagsFromFrameProvider; private @Flags int mFlagsFromServer; @@ -238,6 +238,10 @@ class InsetsSourceProvider { mSource.setFlags(mFlagsFromFrameProvider | mFlagsFromServer); } updateSourceFrameForServerVisibility(); + if (!mLastSourceFrame.equals(mSourceFrame)) { + mLastSourceFrame.set(mSourceFrame); + mInsetsHintStale = true; + } if (mOverrideFrameProviders != null) { // Not necessary to clear the mOverrideFrames here. It will be cleared every time the @@ -279,28 +283,29 @@ class InsetsSourceProvider { // visible. (i.e. No surface, pending insets that were given during layout, etc..) if (mServerVisible) { mSource.setFrame(mSourceFrame); - updateInsetsHint(); } else { mSource.setFrame(0, 0, 0, 0); } } - // To be called when mSourceFrame or the window container bounds is changed. - private void updateInsetsHint() { - if (!mControllable || !mServerVisible) { - return; - } - final Rect bounds = mWindowContainer.getBounds(); - if (mSourceFrame.equals(mLastSourceFrame) && bounds.equals(mLastContainerBounds)) { - return; - } - mLastSourceFrame.set(mSourceFrame); - mLastContainerBounds.set(bounds); - mInsetsHint = mSource.calculateInsets(bounds, true /* ignoreVisibility */); + void onWindowContainerBoundsChanged() { + mInsetsHintStale = true; } @VisibleForTesting Insets getInsetsHint() { + if (!mServerVisible) { + return mInsetsHint; + } + final WindowState win = mWindowContainer.asWindowState(); + if (win != null && win.mGivenInsetsPending) { + return mInsetsHint; + } + if (mInsetsHintStale) { + final Rect bounds = mWindowContainer.getBounds(); + mInsetsHint = mSource.calculateInsets(bounds, true /* ignoreVisibility */); + mInsetsHintStale = false; + } return mInsetsHint; } @@ -359,8 +364,9 @@ class InsetsSourceProvider { mSetLeashPositionConsumer.accept(t); } } - if (!mControl.getInsetsHint().equals(mInsetsHint)) { - mControl.setInsetsHint(mInsetsHint); + final Insets insetsHint = getInsetsHint(); + if (!mControl.getInsetsHint().equals(insetsHint)) { + mControl.setInsetsHint(insetsHint); changed = true; } if (changed) { @@ -494,7 +500,7 @@ class InsetsSourceProvider { mControlTarget = target; updateVisibility(); mControl = new InsetsSourceControl(mSource.getId(), mSource.getType(), leash, - mClientVisible, surfacePosition, mInsetsHint); + mClientVisible, surfacePosition, getInsetsHint()); ProtoLog.d(WM_DEBUG_WINDOW_INSETS, "InsetsSource Control %s for target %s", mControl, mControlTarget); @@ -605,6 +611,9 @@ class InsetsSourceProvider { if (mControllable) { pw.print(prefix + "mInsetsHint="); pw.print(mInsetsHint); + if (mInsetsHintStale) { + pw.print(" stale"); + } pw.println(); } pw.print(prefix); diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 457a555416c10..dae61da26b687 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -1143,6 +1143,9 @@ class WindowContainer extends ConfigurationContainer< } void onResize() { + if (mControllableInsetProvider != null) { + mControllableInsetProvider.onWindowContainerBoundsChanged(); + } for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowContainer wc = mChildren.get(i); wc.onParentResize(); @@ -1162,6 +1165,9 @@ class WindowContainer extends ConfigurationContainer< } void onMovedByResize() { + if (mControllableInsetProvider != null) { + mControllableInsetProvider.onWindowContainerBoundsChanged(); + } for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowContainer wc = mChildren.get(i); wc.onMovedByResize();