diff options
| author | Chet Haase <chet@google.com> | 2012-03-16 09:21:14 -0700 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-03-16 09:21:14 -0700 |
| commit | 4bf8b209955e8a35ec2e4101ed3612e03ecc5dbb (patch) | |
| tree | 247ee3a66ce5bc03974bbb42cea668169bc9085c /core/java | |
| parent | ddc421d19c797096de77c24f68a37ad23216e2a7 (diff) | |
| parent | 9d1992deaeb3d60d5928f05b649a2cc654ba98a3 (diff) | |
| download | frameworks_base-4bf8b209955e8a35ec2e4101ed3612e03ecc5dbb.zip frameworks_base-4bf8b209955e8a35ec2e4101ed3612e03ecc5dbb.tar.gz frameworks_base-4bf8b209955e8a35ec2e4101ed3612e03ecc5dbb.tar.bz2 | |
Merge "Optimizing DisplayList properties"
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/view/HardwareRenderer.java | 5 | ||||
| -rw-r--r-- | core/java/android/view/View.java | 222 | ||||
| -rw-r--r-- | core/java/android/view/ViewGroup.java | 67 | ||||
| -rw-r--r-- | core/java/android/view/ViewPropertyAnimator.java | 19 |
4 files changed, 217 insertions, 96 deletions
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index bf91700..d08a61f 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -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) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index cb73856..6d1f207 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -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,39 +8234,43 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal final boolean matrixIsIdentity = mTransformationInfo == null || mTransformationInfo.mMatrixIsIdentity; if (matrixIsIdentity) { - final ViewParent p = mParent; - if (p != null && mAttachInfo != null) { - final Rect r = mAttachInfo.mTmpInvalRect; - int minTop; - int maxBottom; - int yLoc; - if (offset < 0) { - minTop = mTop + offset; - maxBottom = mBottom; - yLoc = offset; - } else { - minTop = mTop; - maxBottom = mBottom + offset; - yLoc = 0; + 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; + int minTop; + int maxBottom; + int yLoc; + if (offset < 0) { + minTop = mTop + offset; + maxBottom = mBottom; + yLoc = offset; + } else { + minTop = mTop; + maxBottom = mBottom + offset; + yLoc = 0; + } + r.set(0, yLoc, mRight - mLeft, maxBottom - minTop); + p.invalidateChild(this, r); } - 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) { + invalidateViewProperty(false, true); + } + invalidateParentIfNeeded(); } - - if (!matrixIsIdentity) { - mPrivateFlags |= DRAWN; // force another invalidation with the new orientation - invalidate(false); - } - invalidateParentIfNeeded(); } } @@ -8307,36 +8285,40 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal final boolean matrixIsIdentity = mTransformationInfo == null || mTransformationInfo.mMatrixIsIdentity; if (matrixIsIdentity) { - final ViewParent p = mParent; - if (p != null && mAttachInfo != null) { - final Rect r = mAttachInfo.mTmpInvalRect; - int minLeft; - int maxRight; - if (offset < 0) { - minLeft = mLeft + offset; - maxRight = mRight; - } else { - minLeft = mLeft; - maxRight = mRight + offset; + 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; + int minLeft; + int maxRight; + if (offset < 0) { + minLeft = mLeft + offset; + maxRight = mRight; + } else { + minLeft = mLeft; + maxRight = mRight + offset; + } + r.set(0, 0, maxRight - minLeft, mBottom - mTop); + p.invalidateChild(this, r); } - 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) { + invalidateViewProperty(false, true); + } + invalidateParentIfNeeded(); } - - if (!matrixIsIdentity) { - mPrivateFlags |= DRAWN; // force another invalidation with the new orientation - invalidate(false); - } - invalidateParentIfNeeded(); } } @@ -8741,6 +8723,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), * which is necessary when various parent-managed properties of the view change, such as diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 1993ce6..42426b9 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3896,6 +3896,72 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } /** + * 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. * @param descendant A descendant of this view @@ -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); } } } diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index fe0e659..623b567 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -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; - mView.invalidateParentCaches(); + 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; - mView.mPrivateFlags |= View.DRAWN; // force another invalidation + 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); + } } } } |
