Merge "Reduce unnecessary measure" into tm-qpr-dev
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -2637,6 +2654,25 @@ public final class ViewRootImpl implements ViewParent,
|
||||
return windowSizeMayChange;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
Reference in New Issue
Block a user