Merge "Revert "Revert "View measurement optimization"""

This commit is contained in:
Alan Viverette
2015-08-26 16:53:19 +00:00
committed by Android (Google) Code Review

View File

@@ -800,6 +800,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
private static boolean sIgnoreMeasureCache = false;
/**
* Ignore an optimization that skips unnecessary EXACTLY layout passes.
*/
private static boolean sAlwaysRemeasureExactly = false;
/**
* This view does not want keystrokes. Use with TAKES_FOCUS_MASK when
* calling setFlags.
@@ -3865,6 +3870,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// specifically apps that use some popular open source libraries.
sUseZeroUnspecifiedMeasureSpec = targetSdkVersion < M;
// Old versions of the platform would give different results from
// LinearLayout measurement passes using EXACTLY and non-EXACTLY
// modes, so we always need to run an additional EXACTLY pass.
sAlwaysRemeasureExactly = targetSdkVersion <= M;
sCompatibilityDone = true;
}
}
@@ -18820,17 +18830,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ||
widthMeasureSpec != mOldWidthMeasureSpec ||
heightMeasureSpec != mOldHeightMeasureSpec) {
final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
// Optimize layout by avoiding an extra EXACTLY pass when the view is
// already measured as the correct size. In API 23 and below, this
// extra pass is required to make LinearLayout re-distribute weight.
final boolean specChanged = widthMeasureSpec != mOldWidthMeasureSpec
|| heightMeasureSpec != mOldHeightMeasureSpec;
final boolean isSpecExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY
&& MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY;
final boolean matchesSpecSize = getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec)
&& getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec);
final boolean needsLayout = specChanged
&& (sAlwaysRemeasureExactly || !isSpecExactly || !matchesSpecSize);
if (forceLayout || needsLayout) {
// first clears the measured dimension flag
mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
resolveRtlPropertiesIfNeeded();
int cacheIndex = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ? -1 :
mMeasureCache.indexOfKey(key);
int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
if (cacheIndex < 0 || sIgnoreMeasureCache) {
// measure ourselves, this should set the measured dimension flag back
onMeasure(widthMeasureSpec, heightMeasureSpec);