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

Commit 4bf8b209 authored by Chet Haase's avatar Chet Haase Committed by Android (Google) Code Review
Browse files

Merge "Optimizing DisplayList properties"

parents ddc421d1 9d1992de
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -960,6 +960,11 @@ public abstract class HardwareRenderer {
                                Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- getDisplayList() took " +
                                        total + "ms");
                            }
                            if (View.USE_DISPLAY_LIST_PROPERTIES) {
                                Log.d("DLProperties", "getDisplayList():\t" +
                                        mProfileData[mProfileCurrentFrame]);
                            }

                        }

                        if (displayList != null) {
+130 −92
Original line number Diff line number Diff line
@@ -1503,7 +1503,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
     * apps.
     * @hide
     */
    protected static final boolean USE_DISPLAY_LIST_PROPERTIES = false;
    public static final boolean USE_DISPLAY_LIST_PROPERTIES = false;
    /**
     * Map used to store views' tags.
@@ -7349,8 +7349,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
     * @see #setRotationY(float) 
     */
    public void setCameraDistance(float distance) {
        invalidateParentCaches();
        invalidate(false);
        invalidateViewProperty(true, false);
        ensureTransformationInfo();
        final float dpi = mResources.getDisplayMetrics().densityDpi;
@@ -7363,7 +7362,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        info.mCamera.setLocation(0.0f, 0.0f, -Math.abs(distance) / dpi);
        info.mMatrixDirty = true;
        invalidate(false);
        invalidateViewProperty(false, false);
        if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
            mDisplayList.setCameraDistance(distance);
        }
@@ -7401,13 +7400,11 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        ensureTransformationInfo();
        final TransformationInfo info = mTransformationInfo;
        if (info.mRotation != rotation) {
            invalidateParentCaches();
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate(false);
            invalidateViewProperty(true, false);
            info.mRotation = rotation;
            info.mMatrixDirty = true;
            mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
            invalidate(false);
            invalidateViewProperty(false, true);
            if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                mDisplayList.setRotation(rotation);
            }
@@ -7451,13 +7448,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        ensureTransformationInfo();
        final TransformationInfo info = mTransformationInfo;
        if (info.mRotationY != rotationY) {
            invalidateParentCaches();
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate(false);
            invalidateViewProperty(true, false);
            info.mRotationY = rotationY;
            info.mMatrixDirty = true;
            mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
            invalidate(false);
            invalidateViewProperty(false, true);
            if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                mDisplayList.setRotationY(rotationY);
            }
@@ -7501,13 +7495,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        ensureTransformationInfo();
        final TransformationInfo info = mTransformationInfo;
        if (info.mRotationX != rotationX) {
            invalidateParentCaches();
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate(false);
            invalidateViewProperty(true, false);
            info.mRotationX = rotationX;
            info.mMatrixDirty = true;
            mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
            invalidate(false);
            invalidateViewProperty(false, true);
            if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                mDisplayList.setRotationX(rotationX);
            }
@@ -7543,13 +7534,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        ensureTransformationInfo();
        final TransformationInfo info = mTransformationInfo;
        if (info.mScaleX != scaleX) {
            invalidateParentCaches();
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate(false);
            invalidateViewProperty(true, false);
            info.mScaleX = scaleX;
            info.mMatrixDirty = true;
            mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
            invalidate(false);
            invalidateViewProperty(false, true);
            if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                mDisplayList.setScaleX(scaleX);
            }
@@ -7585,13 +7573,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        ensureTransformationInfo();
        final TransformationInfo info = mTransformationInfo;
        if (info.mScaleY != scaleY) {
            invalidateParentCaches();
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate(false);
            invalidateViewProperty(true, false);
            info.mScaleY = scaleY;
            info.mMatrixDirty = true;
            mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
            invalidate(false);
            invalidateViewProperty(false, true);
            if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                mDisplayList.setScaleY(scaleY);
            }
@@ -7633,13 +7618,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        mPrivateFlags |= PIVOT_EXPLICITLY_SET;
        final TransformationInfo info = mTransformationInfo;
        if (info.mPivotX != pivotX) {
            invalidateParentCaches();
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate(false);
            invalidateViewProperty(true, false);
            info.mPivotX = pivotX;
            info.mMatrixDirty = true;
            mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
            invalidate(false);
            invalidateViewProperty(false, true);
            if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                mDisplayList.setPivotX(pivotX);
            }
@@ -7680,13 +7662,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        mPrivateFlags |= PIVOT_EXPLICITLY_SET;
        final TransformationInfo info = mTransformationInfo;
        if (info.mPivotY != pivotY) {
            invalidateParentCaches();
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate(false);
            invalidateViewProperty(true, false);
            info.mPivotY = pivotY;
            info.mMatrixDirty = true;
            mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
            invalidate(false);
            invalidateViewProperty(false, true);
            if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                mDisplayList.setPivotY(pivotY);
            }
@@ -7728,14 +7707,14 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        ensureTransformationInfo();
        if (mTransformationInfo.mAlpha != alpha) {
            mTransformationInfo.mAlpha = alpha;
            invalidateParentCaches();
            if (onSetAlpha((int) (alpha * 255))) {
                mPrivateFlags |= ALPHA_SET;
                // subclass is handling alpha - don't optimize rendering cache invalidation
                invalidateParentCaches();
                invalidate(true);
            } else {
                mPrivateFlags &= ~ALPHA_SET;
                invalidate(false);
                invalidateViewProperty(true, false);
                if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                    mDisplayList.setAlpha(alpha);
                }
@@ -8102,13 +8081,11 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        ensureTransformationInfo();
        final TransformationInfo info = mTransformationInfo;
        if (info.mTranslationX != translationX) {
            invalidateParentCaches();
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate(false);
            invalidateViewProperty(true, false);
            info.mTranslationX = translationX;
            info.mMatrixDirty = true;
            mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
            invalidate(false);
            invalidateViewProperty(false, true);
            if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                mDisplayList.setTranslationX(translationX);
            }
@@ -8142,13 +8119,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        ensureTransformationInfo();
        final TransformationInfo info = mTransformationInfo;
        if (info.mTranslationY != translationY) {
            invalidateParentCaches();
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate(false);
            invalidateViewProperty(true, false);
            info.mTranslationY = translationY;
            info.mMatrixDirty = true;
            mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
            invalidate(false);
            invalidateViewProperty(false, true);
            if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                mDisplayList.setTranslationY(translationY);
            }
@@ -8260,6 +8234,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
            final boolean matrixIsIdentity = mTransformationInfo == null
                    || mTransformationInfo.mMatrixIsIdentity;
            if (matrixIsIdentity) {
                if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                    invalidateViewProperty(false, false);
                } else {
                    final ViewParent p = mParent;
                    if (p != null && mAttachInfo != null) {
                        final Rect r = mAttachInfo.mTmpInvalRect;
@@ -8278,23 +8255,24 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
                        r.set(0, yLoc, mRight - mLeft, maxBottom - minTop);
                        p.invalidateChild(this, r);
                    }
                }
            } else {
                invalidate(false);
                invalidateViewProperty(false, false);
            }
            mTop += offset;
            mBottom += offset;
            if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                mDisplayList.offsetTopBottom(offset);
            }
                invalidateViewProperty(false, false);
            } else {
                if (!matrixIsIdentity) {
                mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
                invalidate(false);
                    invalidateViewProperty(false, true);
                }
                invalidateParentIfNeeded();
            }
        }
    }
    /**
     * Offset this view's horizontal location by the specified amount of pixels.
@@ -8307,6 +8285,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
            final boolean matrixIsIdentity = mTransformationInfo == null
                    || mTransformationInfo.mMatrixIsIdentity;
            if (matrixIsIdentity) {
                if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                    invalidateViewProperty(false, false);
                } else {
                    final ViewParent p = mParent;
                    if (p != null && mAttachInfo != null) {
                        final Rect r = mAttachInfo.mTmpInvalRect;
@@ -8322,23 +8303,24 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
                        r.set(0, 0, maxRight - minLeft, mBottom - mTop);
                        p.invalidateChild(this, r);
                    }
                }
            } else {
                invalidate(false);
                invalidateViewProperty(false, false);
            }
            mLeft += offset;
            mRight += offset;
            if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) {
                mDisplayList.offsetLeftRight(offset);
            }
                invalidateViewProperty(false, false);
            } else {
                if (!matrixIsIdentity) {
                mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
                invalidate(false);
                    invalidateViewProperty(false, true);
                }
                invalidateParentIfNeeded();
            }
        }
    }
    /**
     * Get the LayoutParams associated with this view. All views should have
@@ -8740,6 +8722,62 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        }
    }
    /**
     * Quick invalidation for View property changes (alpha, translationXY, etc.). We don't want to
     * set any flags or handle all of the cases handled by the default invalidation methods.
     * Instead, we just want to schedule a traversal in ViewRootImpl with the appropriate
     * dirty rect. This method calls into fast invalidation methods in ViewGroup that
     * walk up the hierarchy, transforming the dirty rect as necessary.
     *
     * The method also handles normal invalidation logic if display list properties are not
     * being used in this view. The invalidateParent and forceRedraw flags are used by that
     * backup approach, to handle these cases used in the various property-setting methods.
     *
     * @param invalidateParent Force a call to invalidateParentCaches() if display list properties
     * are not being used in this view
     * @param forceRedraw Mark the view as DRAWN to force the invalidation to propagate, if display
     * list properties are not being used in this view
     */
    void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) {
        if (!USE_DISPLAY_LIST_PROPERTIES || mDisplayList == null ||
                (mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION) {
            if (invalidateParent) {
                invalidateParentCaches();
            }
            if (forceRedraw) {
                mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
            }
            invalidate(false);
        } else {
            final AttachInfo ai = mAttachInfo;
            final ViewParent p = mParent;
            if (p != null && ai != null) {
                final Rect r = ai.mTmpInvalRect;
                r.set(0, 0, mRight - mLeft, mBottom - mTop);
                if (mParent instanceof ViewGroup) {
                    ((ViewGroup) mParent).invalidateChildFast(this, r);
                } else {
                    mParent.invalidateChild(this, r);
                }
            }
        }
    }
    /**
     * Utility method to transform a given Rect by the current matrix of this view.
     */
    void transformRect(final Rect rect) {
        if (!getMatrix().isIdentity()) {
            RectF boundingRect = mAttachInfo.mTmpTransformRect;
            boundingRect.set(rect);
            getMatrix().mapRect(boundingRect);
            rect.set((int) (boundingRect.left - 0.5f),
                    (int) (boundingRect.top - 0.5f),
                    (int) (boundingRect.right + 0.5f),
                    (int) (boundingRect.bottom + 0.5f));
        }
    }
    /**
     * Used to indicate that the parent of this view should clear its caches. This functionality
     * is used to force the parent to rebuild its display list (when hardware-accelerated),
+67 −0
Original line number Diff line number Diff line
@@ -3895,6 +3895,72 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        return null;
    }

    /**
     * Quick invalidation method called by View.invalidateViewProperty. This doesn't set the
     * DRAWN flags and doesn't handle the Animation logic that the default invalidation methods
     * do; all we want to do here is schedule a traversal with the appropriate dirty rect.
     *
     * @hide
     */
    public void invalidateChildFast(View child, final Rect dirty) {
        ViewParent parent = this;

        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            if (child.mLayerType != LAYER_TYPE_NONE) {
                child.mLocalDirtyRect.union(dirty);
            }

            int left = child.mLeft;
            int top = child.mTop;
            if (!child.getMatrix().isIdentity()) {
                child.transformRect(dirty);
            }

            do {
                if (parent instanceof ViewGroup) {
                    ViewGroup parentVG = (ViewGroup) parent;
                    parent = parentVG.invalidateChildInParentFast(left, top, dirty);
                    left = parentVG.mLeft;
                    top = parentVG.mTop;
                } else {
                    // Reached the top; this calls into the usual invalidate method in
                    // ViewRootImpl, which schedules a traversal
                    final int[] location = attachInfo.mInvalidateChildLocation;
                    location[0] = left;
                    location[1] = top;
                    parent = parent.invalidateChildInParent(location, dirty);
                }
            } while (parent != null);
        }
    }

    /**
     * Quick invalidation method that simply transforms the dirty rect into the parent's
     * coordinate system, pruning the invalidation if the parent has already been invalidated.
     */
    private ViewParent invalidateChildInParentFast(int left, int top, final Rect dirty) {
        if ((mPrivateFlags & DRAWN) == DRAWN ||
                (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) {
            dirty.offset(left - mScrollX, top - mScrollY);

            if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0 ||
                    dirty.intersect(0, 0, mRight - mLeft, mBottom - mTop)) {

                if (mLayerType != LAYER_TYPE_NONE) {
                    mLocalDirtyRect.union(dirty);
                }
                if (!getMatrix().isIdentity()) {
                    transformRect(dirty);
                }

                return mParent;
            }
        }

        return null;
    }

    /**
     * Offset a rectangle that is in a descendant's coordinate
     * space into our coordinate space.
@@ -3986,6 +4052,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            v.mBottom += offset;
            if (USE_DISPLAY_LIST_PROPERTIES && v.mDisplayList != null) {
                v.mDisplayList.offsetTopBottom(offset);
                invalidateViewProperty(false, false);
            }
        }
    }
+15 −4
Original line number Diff line number Diff line
@@ -986,17 +986,22 @@ public class ViewPropertyAnimator {
                // Shouldn't happen, but just to play it safe
                return;
            }
            boolean useDisplayListProperties = View.USE_DISPLAY_LIST_PROPERTIES &&
                    mView.mDisplayList != null;

            // alpha requires slightly different treatment than the other (transform) properties.
            // The logic in setAlpha() is not simply setting mAlpha, plus the invalidation
            // logic is dependent on how the view handles an internal call to onSetAlpha().
            // We track what kinds of properties are set, and how alpha is handled when it is
            // set, and perform the invalidation steps appropriately.
            boolean alphaHandled = false;
            if (!useDisplayListProperties) {
                mView.invalidateParentCaches();
            }
            float fraction = animation.getAnimatedFraction();
            int propertyMask = propertyBundle.mPropertyMask;
            if ((propertyMask & TRANSFORM_MASK) != 0) {
                mView.invalidate(false);
                mView.invalidateViewProperty(false, false);
            }
            ArrayList<NameValuesHolder> valueList = propertyBundle.mNameValuesHolder;
            if (valueList != null) {
@@ -1013,11 +1018,17 @@ public class ViewPropertyAnimator {
            }
            if ((propertyMask & TRANSFORM_MASK) != 0) {
                mView.mTransformationInfo.mMatrixDirty = true;
                if (!useDisplayListProperties) {
                    mView.mPrivateFlags |= View.DRAWN; // force another invalidation
                }
            }
            // invalidate(false) in all cases except if alphaHandled gets set to true
            // via the call to setAlphaNoInvalidation(), above
            mView.invalidate(alphaHandled);
            if (alphaHandled) {
                mView.invalidate(true);
            } else {
                mView.invalidateViewProperty(false, false);
            }
        }
    }
}
+26 −26
Original line number Diff line number Diff line
@@ -671,18 +671,6 @@ void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
        if (mLeft != 0 || mTop != 0) {
            ALOGD("%s%s %d, %d", indent, "Translate", mLeft, mTop);
        }
        if (mAlpha < 1) {
            // TODO: should be able to store the size of a DL at record time and not
            // have to pass it into this call. In fact, this information might be in the
            // location/size info that we store with the new native transform data.
            int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
            if (mClipChildren) {
                flags |= SkCanvas::kClipToLayer_SaveFlag;
            }
            ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
                    (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
                    mMultipliedAlpha, flags);
        }
        if (mMatrixFlags != 0) {
            if (mMatrixFlags == TRANSLATION) {
                ALOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
@@ -696,6 +684,18 @@ void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
                        mTransformMatrix->get(8));
            }
        }
        if (mAlpha < 1) {
            // TODO: should be able to store the size of a DL at record time and not
            // have to pass it into this call. In fact, this information might be in the
            // location/size info that we store with the new native transform data.
            int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
            if (mClipChildren) {
                flags |= SkCanvas::kClipToLayer_SaveFlag;
            }
            ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
                    (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
                    mMultipliedAlpha, flags);
        }
        if (mClipChildren) {
            ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
                    (float) mRight - mLeft, (float) mBottom - mTop);
@@ -724,20 +724,6 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t width, ui
                    mApplicationScale, mApplicationScale);
            renderer.scale(mApplicationScale, mApplicationScale);
        }
        if (mAlpha < 1 && !mCaching) {
            // TODO: should be able to store the size of a DL at record time and not
            // have to pass it into this call. In fact, this information might be in the
            // location/size info that we store with the new native transform data.
            int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
            if (mClipChildren) {
                flags |= SkCanvas::kClipToLayer_SaveFlag;
            }
            DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
                    (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
                    mMultipliedAlpha, flags);
            renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
                    mMultipliedAlpha, flags);
        }
        if (mMatrixFlags != 0) {
            if (mMatrixFlags == TRANSLATION) {
                DISPLAY_LIST_LOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
@@ -754,6 +740,20 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t width, ui
                renderer.concatMatrix(mTransformMatrix);
            }
        }
        if (mAlpha < 1 && !mCaching) {
            // TODO: should be able to store the size of a DL at record time and not
            // have to pass it into this call. In fact, this information might be in the
            // location/size info that we store with the new native transform data.
            int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
            if (mClipChildren) {
                flags |= SkCanvas::kClipToLayer_SaveFlag;
            }
            DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
                    (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
                    mMultipliedAlpha, flags);
            renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
                    mMultipliedAlpha, flags);
        }
        if (mClipChildren) {
            DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
                    (float) mRight - mLeft, (float) mBottom - mTop);