summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Tiger Huang <tigerhuang@google.com> 2022-12-06 05:46:04 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-12-06 05:46:04 +0000
commit80c145dca032eb727292abfe3b02e3b0df3777ff (patch)
tree4e36d7895644ab24b616a5b4e3e56b222c7ad295
parent73420439bcfdbca4672a2bc9f55e9144bfe22664 (diff)
parentadfbe26af2d63684b73af8973de78a00d663dcb2 (diff)
Merge "Reduce unnecessary measure" into tm-qpr-dev
-rw-r--r--core/java/android/view/ViewRootImpl.java71
1 files changed, 63 insertions, 8 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b4698dee6019..d21ba014e166 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -77,6 +77,7 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
@@ -502,6 +503,13 @@ public final class ViewRootImpl implements ViewParent,
Region mTouchableRegion;
Region mPreviousTouchableRegion;
+ private int mMeasuredWidth;
+ private int mMeasuredHeight;
+
+ // This indicates that we've already known the window size but without measuring the views.
+ // If this is true, we must measure the views before laying out them.
+ private boolean mViewMeasureDeferred;
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
int mWidth;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -2566,7 +2574,8 @@ public final class ViewRootImpl implements ViewParent,
}
private boolean measureHierarchy(final View host, final WindowManager.LayoutParams lp,
- final Resources res, final int desiredWindowWidth, final int desiredWindowHeight) {
+ final Resources res, final int desiredWindowWidth, final int desiredWindowHeight,
+ boolean forRootSizeOnly) {
int childWidthMeasureSpec;
int childHeightMeasureSpec;
boolean windowSizeMayChange = false;
@@ -2622,7 +2631,15 @@ public final class ViewRootImpl implements ViewParent,
lp.privateFlags);
childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height,
lp.privateFlags);
- performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
+ if (!forRootSizeOnly || !setMeasuredRootSizeFromSpec(
+ childWidthMeasureSpec, childHeightMeasureSpec)) {
+ performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
+ } else {
+ // We already know how big the window should be before measuring the views.
+ // We can measure the views before laying out them. This is to avoid unnecessary
+ // measure.
+ mViewMeasureDeferred = true;
+ }
if (mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight()) {
windowSizeMayChange = true;
}
@@ -2638,6 +2655,25 @@ public final class ViewRootImpl implements ViewParent,
}
/**
+ * Sets the measured root size for requesting the window frame.
+ *
+ * @param widthMeasureSpec contains the size and the mode of the width.
+ * @param heightMeasureSpec contains the size and the mode of the height.
+ * @return {@code true} if we actually set the measured size; {@code false} otherwise.
+ */
+ private boolean setMeasuredRootSizeFromSpec(int widthMeasureSpec, int heightMeasureSpec) {
+ final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ if (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY) {
+ // We don't know the exact size. We need to measure the hierarchy to know that.
+ return false;
+ }
+ mMeasuredWidth = MeasureSpec.getSize(widthMeasureSpec);
+ mMeasuredHeight = MeasureSpec.getSize(heightMeasureSpec);
+ return true;
+ }
+
+ /**
* Modifies the input matrix such that it maps view-local coordinates to
* on-screen coordinates.
*
@@ -2724,6 +2760,14 @@ public final class ViewRootImpl implements ViewParent,
|| lp.type == TYPE_VOLUME_OVERLAY;
}
+ /**
+ * @return {@code true} if we should reduce unnecessary measure for the window.
+ * TODO(b/260382739): Apply this to all windows.
+ */
+ private static boolean shouldOptimizeMeasure(final WindowManager.LayoutParams lp) {
+ return lp.type == TYPE_NOTIFICATION_SHADE;
+ }
+
private Rect getWindowBoundsInsetSystemBars() {
final Rect bounds = new Rect(
mContext.getResources().getConfiguration().windowConfiguration.getBounds());
@@ -2774,6 +2818,7 @@ public final class ViewRootImpl implements ViewParent,
mAppVisibilityChanged = false;
final boolean viewUserVisibilityChanged = !mFirst &&
((mViewVisibility == View.VISIBLE) != (viewVisibility == View.VISIBLE));
+ final boolean shouldOptimizeMeasure = shouldOptimizeMeasure(lp);
WindowManager.LayoutParams params = null;
CompatibilityInfo compatibilityInfo =
@@ -2895,7 +2940,7 @@ public final class ViewRootImpl implements ViewParent,
// Ask host how big it wants to be
windowSizeMayChange |= measureHierarchy(host, lp, mView.getContext().getResources(),
- desiredWindowWidth, desiredWindowHeight);
+ desiredWindowWidth, desiredWindowHeight, shouldOptimizeMeasure);
}
if (collectViewAttributes()) {
@@ -2935,8 +2980,8 @@ public final class ViewRootImpl implements ViewParent,
// we don't need to go through two layout passes when things
// change due to fitting system windows, which can happen a lot.
windowSizeMayChange |= measureHierarchy(host, lp,
- mView.getContext().getResources(),
- desiredWindowWidth, desiredWindowHeight);
+ mView.getContext().getResources(), desiredWindowWidth, desiredWindowHeight,
+ shouldOptimizeMeasure);
}
}
@@ -3351,6 +3396,13 @@ public final class ViewRootImpl implements ViewParent,
maybeHandleWindowMove(frame);
}
+ if (mViewMeasureDeferred) {
+ // It's time to measure the views since we are going to layout them.
+ performMeasure(
+ MeasureSpec.makeMeasureSpec(frame.width(), MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(frame.height(), MeasureSpec.EXACTLY));
+ }
+
if (!mRelayoutRequested && mCheckIfCanDraw) {
// We had a sync previously, but we didn't call IWindowSession#relayout in this
// traversal. So we don't know if the sync is complete that we can continue to draw.
@@ -3940,6 +3992,9 @@ public final class ViewRootImpl implements ViewParent,
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
+ mMeasuredWidth = mView.getMeasuredWidth();
+ mMeasuredHeight = mView.getMeasuredHeight();
+ mViewMeasureDeferred = false;
}
/**
@@ -4035,7 +4090,7 @@ public final class ViewRootImpl implements ViewParent,
view.requestLayout();
}
measureHierarchy(host, lp, mView.getContext().getResources(),
- desiredWindowWidth, desiredWindowHeight);
+ desiredWindowWidth, desiredWindowHeight, false /* forRootSizeOnly */);
mInLayout = true;
host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
@@ -8101,8 +8156,8 @@ public final class ViewRootImpl implements ViewParent,
final WindowConfiguration winConfigFromWm =
mLastReportedMergedConfiguration.getGlobalConfiguration().windowConfiguration;
final WindowConfiguration winConfig = getCompatWindowConfiguration();
- final int measuredWidth = mView.getMeasuredWidth();
- final int measuredHeight = mView.getMeasuredHeight();
+ final int measuredWidth = mMeasuredWidth;
+ final int measuredHeight = mMeasuredHeight;
final boolean relayoutAsync;
if (LOCAL_LAYOUT
&& (mViewFrameInfo.flags & FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED) == 0