summaryrefslogtreecommitdiffstats
path: root/core/java/android/view/View.java
diff options
context:
space:
mode:
authorChet Haase <chet@google.com>2012-03-13 11:03:25 -0700
committerChet Haase <chet@google.com>2012-03-16 09:14:52 -0700
commit9d1992deaeb3d60d5928f05b649a2cc654ba98a3 (patch)
treef6f5b527f3c4e2e43546ad65b24397734ac83e86 /core/java/android/view/View.java
parentf63c52ac87c07ca37b9681a949b1bb5febce3e43 (diff)
downloadframeworks_base-9d1992deaeb3d60d5928f05b649a2cc654ba98a3.zip
frameworks_base-9d1992deaeb3d60d5928f05b649a2cc654ba98a3.tar.gz
frameworks_base-9d1992deaeb3d60d5928f05b649a2cc654ba98a3.tar.bz2
Optimizing DisplayList properties
DisplayList properties are still disabled default (flags in View.java and DisplayListRenderer.h). When they are enabled, and when a View has a DisplayList, invalidations due to property changes are now optimized to avoid causing DisplayList recreation. This eliminates the drawing step of invalidation (due to changes in these properties), only requiring issuing the previously-created DisplayList to the GL renderer. Invalidation is slightly faster (less overhead as we walk up the hierarchy), getDisplayList() is potentially much faster (going down to ~0ms), depending on the complexity of the View being redrawn and the size of the invalidated hierarchy. Change-Id: I57587d5b810c3595bdd72a6c52349c2a3d1bdf25
Diffstat (limited to 'core/java/android/view/View.java')
-rw-r--r--core/java/android/view/View.java222
1 files changed, 130 insertions, 92 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1ef46a9..9863309 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