Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9cefbda1 authored by Adam Powell's avatar Adam Powell
Browse files

View measurement optimization

If a view hasn't explicitly requested layout and it's asked to measure
with MeasureSpec.EXACTLY in both dimensions and sizes that match its
current measured size, the measure operation is a no-op.

This helps out a number of ViewGroups that perform initial speculative
measurements with AT_MOST or UNSPECIFIED followed by looping over
child views and measuring EXACTLY to lock in the final measurement
with perhaps some extra leftover space distributed. In practice this
happens a fair bit, especially for views high up in the view
hierarchy. This optimization allows ViewGroup measurement code to be a
little cleaner in not having to keep track of this on its own.

Change-Id: I88ff46a7d37aeda7a4cd16204b68cab0d051b341
parent 074c5b5b
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -17418,17 +17418,22 @@ 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;
        final boolean isExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY &&
                MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY;
        final boolean matchingSize = isExactly &&
                getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec) &&
                getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec);
        if (forceLayout || !matchingSize &&
                (widthMeasureSpec != mOldWidthMeasureSpec ||
                        heightMeasureSpec != mOldHeightMeasureSpec)) {
            // 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);