diff options
author | Chris Craik <ccraik@google.com> | 2014-04-03 17:14:53 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-04-03 17:14:53 +0000 |
commit | ef4c0c9fd5db395b2eea0a246b93bce9cc9e859a (patch) | |
tree | f469797c7f5bbb4ae24d49ca730a30f9e279b8f8 | |
parent | 537be409f281d4a872cbcebb6ac3a4d767ded4da (diff) | |
parent | 49e6c73913e9bee58ea5e3984be151ee8e033163 (diff) | |
download | frameworks_base-ef4c0c9fd5db395b2eea0a246b93bce9cc9e859a.zip frameworks_base-ef4c0c9fd5db395b2eea0a246b93bce9cc9e859a.tar.gz frameworks_base-ef4c0c9fd5db395b2eea0a246b93bce9cc9e859a.tar.bz2 |
Merge "Move most TransformationInfo properties to RenderNode"
-rw-r--r-- | core/java/android/view/RenderNode.java | 80 | ||||
-rw-r--r-- | core/java/android/view/View.java | 626 | ||||
-rw-r--r-- | core/java/android/view/ViewGroup.java | 10 | ||||
-rw-r--r-- | core/java/android/view/ViewOverlay.java | 10 | ||||
-rw-r--r-- | core/java/android/view/ViewPropertyAnimator.java | 57 | ||||
-rw-r--r-- | core/jni/android_view_RenderNode.cpp | 88 | ||||
-rw-r--r-- | libs/hwui/RenderNode.cpp | 8 | ||||
-rw-r--r-- | libs/hwui/RenderProperties.cpp | 59 | ||||
-rw-r--r-- | libs/hwui/RenderProperties.h | 29 |
9 files changed, 327 insertions, 640 deletions
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java index a27c313..26eaef8 100644 --- a/core/java/android/view/RenderNode.java +++ b/core/java/android/view/RenderNode.java @@ -16,6 +16,7 @@ package android.view; +import android.annotation.NonNull; import android.graphics.Matrix; import android.graphics.Outline; @@ -196,18 +197,20 @@ public class RenderNode { } /** - * Starts recording the display list. All operations performed on the - * returned canvas are recorded and stored in this display list. + * Starts recording a display list for the render node. All + * operations performed on the returned canvas are recorded and + * stored in this display list. * - * Calling this method will mark the display list invalid until - * {@link #end()} is called. Only valid display lists can be replayed. + * Calling this method will mark the render node invalid until + * {@link #end(HardwareRenderer, HardwareCanvas)} is called. + * Only valid render nodes can be replayed. * - * @param width The width of the display list's viewport - * @param height The height of the display list's viewport + * @param width The width of the recording viewport + * @param height The height of the recording viewport * * @return A canvas to record drawing operations. * - * @see #end() + * @see #end(HardwareRenderer, HardwareCanvas) * @see #isValid() */ public HardwareCanvas start(int width, int height) { @@ -284,7 +287,23 @@ public class RenderNode { } /////////////////////////////////////////////////////////////////////////// - // DisplayList Property Setters + // Matrix manipulation + /////////////////////////////////////////////////////////////////////////// + + public boolean hasIdentityMatrix() { + return nHasIdentityMatrix(mNativeDisplayList); + } + + public void getMatrix(@NonNull Matrix outMatrix) { + nGetTransformMatrix(mNativeDisplayList, outMatrix.native_instance); + } + + public void getInverseMatrix(@NonNull Matrix outMatrix) { + nGetInverseTransformMatrix(mNativeDisplayList, outMatrix.native_instance); + } + + /////////////////////////////////////////////////////////////////////////// + // RenderProperty Setters /////////////////////////////////////////////////////////////////////////// /** @@ -301,7 +320,7 @@ public class RenderNode { } /** - * Set whether the display list should clip itself to its bounds. This property is controlled by + * Set whether the Render node should clip itself to its bounds. This property is controlled by * the view's parent. * * @param clipToBounds true if the display list should clip to its bounds @@ -312,9 +331,7 @@ public class RenderNode { /** * Sets whether the display list should be drawn immediately after the - * closest ancestor display list where isolateZVolume is true. If the - * display list itself satisfies this constraint, changing this attribute - * has no effect on drawing order. + * closest ancestor display list containing a projection receiver. * * @param shouldProject true if the display list should be projected onto a * containing volume. @@ -373,9 +390,6 @@ public class RenderNode { * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.) * * @param matrix A transform matrix to apply to this display list - * - * @see #getMatrix(android.graphics.Matrix) - * @see #getMatrix() */ public void setStaticMatrix(Matrix matrix) { nSetStaticMatrix(mNativeDisplayList, matrix.native_instance); @@ -613,28 +627,6 @@ public class RenderNode { } /** - * Sets all of the transform-related values of the display list - * - * @param alpha The alpha value of the display list - * @param translationX The translationX value of the display list - * @param translationY The translationY value of the display list - * @param rotation The rotation value of the display list - * @param rotationX The rotationX value of the display list - * @param rotationY The rotationY value of the display list - * @param scaleX The scaleX value of the display list - * @param scaleY The scaleY value of the display list - * - * @hide - */ - public void setTransformationInfo(float alpha, - float translationX, float translationY, float translationZ, - float rotation, float rotationX, float rotationY, float scaleX, float scaleY) { - nSetTransformationInfo(mNativeDisplayList, alpha, - translationX, translationY, translationZ, - rotation, rotationX, rotationY, scaleX, scaleY); - } - - /** * Sets the pivot value for the display list on the X axis * * @param pivotX The pivot value of the display list on the X axis, in pixels @@ -676,6 +668,10 @@ public class RenderNode { return nGetPivotY(mNativeDisplayList); } + public boolean isPivotExplicitlySet() { + return nIsPivotExplicitlySet(mNativeDisplayList); + } + /** * Sets the camera distance for the display list. Refer to * {@link View#setCameraDistance(float)} for more information on how to @@ -842,6 +838,12 @@ public class RenderNode { private static native void nDestroyDisplayList(long displayList); private static native void nSetDisplayListName(long displayList, String name); + // Matrix + + private static native void nGetTransformMatrix(long displayList, long nativeMatrix); + private static native void nGetInverseTransformMatrix(long displayList, long nativeMatrix); + private static native boolean nHasIdentityMatrix(long displayList); + // Properties private static native void nOffsetTopAndBottom(long displayList, float offset); @@ -877,9 +879,6 @@ public class RenderNode { private static native void nSetRotationY(long displayList, float rotationY); private static native void nSetScaleX(long displayList, float scaleX); private static native void nSetScaleY(long displayList, float scaleY); - private static native void nSetTransformationInfo(long displayList, float alpha, - float translationX, float translationY, float translationZ, - float rotation, float rotationX, float rotationY, float scaleX, float scaleY); private static native void nSetStaticMatrix(long displayList, long nativeMatrix); private static native void nSetAnimationMatrix(long displayList, long animationMatrix); @@ -898,6 +897,7 @@ public class RenderNode { private static native float nGetRotation(long displayList); private static native float nGetRotationX(long displayList); private static native float nGetRotationY(long displayList); + private static native boolean nIsPivotExplicitlySet(long displayList); private static native float nGetPivotX(long displayList); private static native float nGetPivotY(long displayList); private static native void nOutput(long displayList); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index badd2c8..6c414f6 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -1792,12 +1792,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private static final int PFLAG_HOVERED = 0x10000000; /** - * Indicates that pivotX or pivotY were explicitly set and we should not assume the center - * for transform operations - * - * @hide + * no longer needed, should be reused */ - private static final int PFLAG_PIVOT_EXPLICITLY_SET = 0x20000000; + private static final int PFLAG_DOES_NOTHING_REUSE_PLEASE = 0x20000000; /** {@hide} */ static final int PFLAG_ACTIVATED = 0x40000000; @@ -2930,123 +2927,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback, static class TransformationInfo { /** * The transform matrix for the View. This transform is calculated internally - * based on the rotation, scaleX, and scaleY properties. The identity matrix - * is used by default. Do *not* use this variable directly; instead call - * getMatrix(), which will automatically recalculate the matrix if necessary - * to get the correct matrix based on the latest rotation and scale properties. + * based on the translation, rotation, and scale properties. + * + * Do *not* use this variable directly; instead call getMatrix(), which will + * load the value from the View's RenderNode. */ private final Matrix mMatrix = new Matrix(); /** - * The transform matrix for the View. This transform is calculated internally - * based on the rotation, scaleX, and scaleY properties. The identity matrix - * is used by default. Do *not* use this variable directly; instead call - * getInverseMatrix(), which will automatically recalculate the matrix if necessary - * to get the correct matrix based on the latest rotation and scale properties. + * The inverse transform matrix for the View. This transform is calculated + * internally based on the translation, rotation, and scale properties. + * + * Do *not* use this variable directly; instead call getInverseMatrix(), + * which will load the value from the View's RenderNode. */ private Matrix mInverseMatrix; /** - * An internal variable that tracks whether we need to recalculate the - * transform matrix, based on whether the rotation or scaleX/Y properties - * have changed since the matrix was last calculated. - */ - boolean mMatrixDirty = false; - - /** - * An internal variable that tracks whether we need to recalculate the - * transform matrix, based on whether the rotation or scaleX/Y properties - * have changed since the matrix was last calculated. - */ - private boolean mInverseMatrixDirty = true; - - /** - * A variable that tracks whether we need to recalculate the - * transform matrix, based on whether the rotation or scaleX/Y properties - * have changed since the matrix was last calculated. This variable - * is only valid after a call to updateMatrix() or to a function that - * calls it such as getMatrix(), hasIdentityMatrix() and getInverseMatrix(). - */ - private boolean mMatrixIsIdentity = true; - - /** - * The Camera object is used to compute a 3D matrix when rotationX or rotationY are set. - */ - private Camera mCamera = null; - - /** - * This matrix is used when computing the matrix for 3D rotations. - */ - private Matrix matrix3D = null; - - /** - * These prev values are used to recalculate a centered pivot point when necessary. The - * pivot point is only used in matrix operations (when rotation, scale, or translation are - * set), so thes values are only used then as well. - */ - private int mPrevWidth = -1; - private int mPrevHeight = -1; - - /** - * The degrees rotation around the vertical axis through the pivot point. - */ - @ViewDebug.ExportedProperty - float mRotationY = 0f; - - /** - * The degrees rotation around the horizontal axis through the pivot point. - */ - @ViewDebug.ExportedProperty - float mRotationX = 0f; - - /** - * The degrees rotation around the pivot point. - */ - @ViewDebug.ExportedProperty - float mRotation = 0f; - - /** - * The amount of translation of the object away from its left property (post-layout). - */ - @ViewDebug.ExportedProperty - float mTranslationX = 0f; - - /** - * The amount of translation of the object away from its top property (post-layout). - */ - @ViewDebug.ExportedProperty - float mTranslationY = 0f; - - @ViewDebug.ExportedProperty - float mTranslationZ = 0f; - - /** - * The amount of scale in the x direction around the pivot point. A - * value of 1 means no scaling is applied. - */ - @ViewDebug.ExportedProperty - float mScaleX = 1f; - - /** - * The amount of scale in the y direction around the pivot point. A - * value of 1 means no scaling is applied. - */ - @ViewDebug.ExportedProperty - float mScaleY = 1f; - - /** - * The x location of the point around which the view is rotated and scaled. - */ - @ViewDebug.ExportedProperty - float mPivotX = 0f; - - /** - * The y location of the point around which the view is rotated and scaled. - */ - @ViewDebug.ExportedProperty - float mPivotY = 0f; - - /** * The opacity of the View. This is a value from 0 to 1, where 0 means * completely transparent and 1 means completely opaque. */ @@ -3557,7 +3454,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * of the View content. Its DisplayList content is cleared on temporary detach and reset on * cleanup. */ - RenderNode mRenderNode; + final RenderNode mRenderNode; /** * Set to true when the view is sending hover accessibility events because it @@ -3608,6 +3505,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS); mUserPaddingStart = UNDEFINED_PADDING; mUserPaddingEnd = UNDEFINED_PADDING; + mRenderNode = RenderNode.create(getClass().getName()); if (!sCompatibilityDone && context != null) { final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion; @@ -4172,6 +4070,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ View() { mResources = null; + mRenderNode = RenderNode.create(getClass().getName()); } public String toString() { @@ -9685,21 +9584,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return The current transform matrix for the view */ public Matrix getMatrix() { - if (mTransformationInfo != null) { - updateMatrix(); - return mTransformationInfo.mMatrix; - } - return Matrix.IDENTITY_MATRIX; - } - - /** - * Utility function to determine if the value is far enough away from zero to be - * considered non-zero. - * @param value A floating point value to check for zero-ness - * @return whether the passed-in value is far enough away from zero to be considered non-zero - */ - private static boolean nonzero(float value) { - return (value < -NONZERO_EPSILON || value > NONZERO_EPSILON); + ensureTransformationInfo(); + final Matrix matrix = mTransformationInfo.mMatrix; + mRenderNode.getMatrix(matrix); + return matrix; } /** @@ -9709,11 +9597,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return True if the transform matrix is the identity matrix, false otherwise. */ final boolean hasIdentityMatrix() { - if (mTransformationInfo != null) { - updateMatrix(); - return mTransformationInfo.mMatrixIsIdentity; - } - return true; + return mRenderNode.hasIdentityMatrix(); } void ensureTransformationInfo() { @@ -9722,59 +9606,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - void ensureRenderNode() { - if (mRenderNode == null) { - mRenderNode = RenderNode.create(getClass().getName()); - } - } - - /** - * Recomputes the transform matrix if necessary. - */ - private void updateMatrix() { - final TransformationInfo info = mTransformationInfo; - if (info == null) { - return; - } - if (info.mMatrixDirty) { - // transform-related properties have changed since the last time someone - // asked for the matrix; recalculate it with the current values - - // Figure out if we need to update the pivot point - if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { - if ((mRight - mLeft) != info.mPrevWidth || (mBottom - mTop) != info.mPrevHeight) { - info.mPrevWidth = mRight - mLeft; - info.mPrevHeight = mBottom - mTop; - info.mPivotX = info.mPrevWidth / 2f; - info.mPivotY = info.mPrevHeight / 2f; - } - } - info.mMatrix.reset(); - if (!nonzero(info.mRotationX) && !nonzero(info.mRotationY)) { - info.mMatrix.setTranslate(info.mTranslationX, info.mTranslationY); - info.mMatrix.preRotate(info.mRotation, info.mPivotX, info.mPivotY); - info.mMatrix.preScale(info.mScaleX, info.mScaleY, info.mPivotX, info.mPivotY); - } else { - if (info.mCamera == null) { - info.mCamera = new Camera(); - info.matrix3D = new Matrix(); - } - info.mCamera.save(); - info.mMatrix.preScale(info.mScaleX, info.mScaleY, info.mPivotX, info.mPivotY); - info.mCamera.rotate(info.mRotationX, info.mRotationY, -info.mRotation); - info.mCamera.getMatrix(info.matrix3D); - info.matrix3D.preTranslate(-info.mPivotX, -info.mPivotY); - info.matrix3D.postTranslate(info.mPivotX + info.mTranslationX, - info.mPivotY + info.mTranslationY); - info.mMatrix.postConcat(info.matrix3D); - info.mCamera.restore(); - } - info.mMatrixDirty = false; - info.mMatrixIsIdentity = info.mMatrix.isIdentity(); - info.mInverseMatrixDirty = true; - } - } - /** * Utility method to retrieve the inverse of the current mMatrix property. * We cache the matrix to avoid recalculating it when transform properties @@ -9783,19 +9614,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return The inverse of the current matrix of this view. */ final Matrix getInverseMatrix() { - final TransformationInfo info = mTransformationInfo; - if (info != null) { - updateMatrix(); - if (info.mInverseMatrixDirty) { - if (info.mInverseMatrix == null) { - info.mInverseMatrix = new Matrix(); - } - info.mMatrix.invert(info.mInverseMatrix); - info.mInverseMatrixDirty = false; - } - return info.mInverseMatrix; + ensureTransformationInfo(); + if (mTransformationInfo.mInverseMatrix == null) { + mTransformationInfo.mInverseMatrix = new Matrix(); } - return Matrix.IDENTITY_MATRIX; + final Matrix matrix = mTransformationInfo.mInverseMatrix; + mRenderNode.getInverseMatrix(matrix); + return matrix; } /** @@ -9806,14 +9631,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return The distance along the Z axis. */ public float getCameraDistance() { - ensureTransformationInfo(); final float dpi = mResources.getDisplayMetrics().densityDpi; - final TransformationInfo info = mTransformationInfo; - if (info.mCamera == null) { - info.mCamera = new Camera(); - info.matrix3D = new Matrix(); - } - return -(info.mCamera.getLocationZ() * dpi); + return -(mRenderNode.getCameraDistance() * dpi); } /** @@ -9856,27 +9675,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #setRotationY(float) */ public void setCameraDistance(float distance) { - invalidateViewProperty(true, false); - - ensureTransformationInfo(); final float dpi = mResources.getDisplayMetrics().densityDpi; - final TransformationInfo info = mTransformationInfo; - if (info.mCamera == null) { - info.mCamera = new Camera(); - info.matrix3D = new Matrix(); - } - - info.mCamera.setLocation(0.0f, 0.0f, -Math.abs(distance) / dpi); - info.mMatrixDirty = true; + invalidateViewProperty(true, false); + mRenderNode.setCameraDistance(-Math.abs(distance) / dpi); invalidateViewProperty(false, false); - if (mRenderNode != null) { - mRenderNode.setCameraDistance(-Math.abs(distance) / dpi); - } - if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { - // View was rejected last time it was drawn by its parent; this may have changed - invalidateParentIfNeeded(); - } + + invalidateParentIfNeededAndWasQuickRejected(); } /** @@ -9890,7 +9695,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public float getRotation() { - return mTransformationInfo != null ? mTransformationInfo.mRotation : 0; + return mRenderNode.getRotation(); } /** @@ -9908,21 +9713,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @attr ref android.R.styleable#View_rotation */ public void setRotation(float rotation) { - ensureTransformationInfo(); - final TransformationInfo info = mTransformationInfo; - if (info.mRotation != rotation) { + if (rotation != getRotation()) { // Double-invalidation is necessary to capture view's old and new areas invalidateViewProperty(true, false); - info.mRotation = rotation; - info.mMatrixDirty = true; + mRenderNode.setRotation(rotation); invalidateViewProperty(false, true); - if (mRenderNode != null) { - mRenderNode.setRotation(rotation); - } - if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { - // View was rejected last time it was drawn by its parent; this may have changed - invalidateParentIfNeeded(); - } + + invalidateParentIfNeededAndWasQuickRejected(); } } @@ -9937,7 +9734,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public float getRotationY() { - return mTransformationInfo != null ? mTransformationInfo.mRotationY : 0; + return mRenderNode.getRotationY(); } /** @@ -9960,20 +9757,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @attr ref android.R.styleable#View_rotationY */ public void setRotationY(float rotationY) { - ensureTransformationInfo(); - final TransformationInfo info = mTransformationInfo; - if (info.mRotationY != rotationY) { + if (rotationY != getRotationY()) { invalidateViewProperty(true, false); - info.mRotationY = rotationY; - info.mMatrixDirty = true; + mRenderNode.setRotationY(rotationY); invalidateViewProperty(false, true); - if (mRenderNode != null) { - mRenderNode.setRotationY(rotationY); - } - if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { - // View was rejected last time it was drawn by its parent; this may have changed - invalidateParentIfNeeded(); - } + + invalidateParentIfNeededAndWasQuickRejected(); } } @@ -9988,7 +9777,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public float getRotationX() { - return mTransformationInfo != null ? mTransformationInfo.mRotationX : 0; + return mRenderNode.getRotationX(); } /** @@ -10011,20 +9800,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @attr ref android.R.styleable#View_rotationX */ public void setRotationX(float rotationX) { - ensureTransformationInfo(); - final TransformationInfo info = mTransformationInfo; - if (info.mRotationX != rotationX) { + if (rotationX != getRotationX()) { invalidateViewProperty(true, false); - info.mRotationX = rotationX; - info.mMatrixDirty = true; + mRenderNode.setRotationX(rotationX); invalidateViewProperty(false, true); - if (mRenderNode != null) { - mRenderNode.setRotationX(rotationX); - } - if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { - // View was rejected last time it was drawn by its parent; this may have changed - invalidateParentIfNeeded(); - } + + invalidateParentIfNeededAndWasQuickRejected(); } } @@ -10040,7 +9821,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public float getScaleX() { - return mTransformationInfo != null ? mTransformationInfo.mScaleX : 1; + return mRenderNode.getScaleX(); } /** @@ -10054,20 +9835,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @attr ref android.R.styleable#View_scaleX */ public void setScaleX(float scaleX) { - ensureTransformationInfo(); - final TransformationInfo info = mTransformationInfo; - if (info.mScaleX != scaleX) { + if (scaleX != getScaleX()) { invalidateViewProperty(true, false); - info.mScaleX = scaleX; - info.mMatrixDirty = true; + mRenderNode.setScaleX(scaleX); invalidateViewProperty(false, true); - if (mRenderNode != null) { - mRenderNode.setScaleX(scaleX); - } - if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { - // View was rejected last time it was drawn by its parent; this may have changed - invalidateParentIfNeeded(); - } + + invalidateParentIfNeededAndWasQuickRejected(); } } @@ -10083,7 +9856,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public float getScaleY() { - return mTransformationInfo != null ? mTransformationInfo.mScaleY : 1; + return mRenderNode.getScaleY(); } /** @@ -10097,20 +9870,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @attr ref android.R.styleable#View_scaleY */ public void setScaleY(float scaleY) { - ensureTransformationInfo(); - final TransformationInfo info = mTransformationInfo; - if (info.mScaleY != scaleY) { + if (scaleY != getScaleY()) { invalidateViewProperty(true, false); - info.mScaleY = scaleY; - info.mMatrixDirty = true; + mRenderNode.setScaleY(scaleY); invalidateViewProperty(false, true); - if (mRenderNode != null) { - mRenderNode.setScaleY(scaleY); - } - if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { - // View was rejected last time it was drawn by its parent; this may have changed - invalidateParentIfNeeded(); - } + + invalidateParentIfNeededAndWasQuickRejected(); } } @@ -10128,7 +9893,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public float getPivotX() { - return mTransformationInfo != null ? mTransformationInfo.mPivotX : 0; + return mRenderNode.getPivotX(); } /** @@ -10147,23 +9912,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @attr ref android.R.styleable#View_transformPivotX */ public void setPivotX(float pivotX) { - ensureTransformationInfo(); - final TransformationInfo info = mTransformationInfo; - boolean pivotSet = (mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == - PFLAG_PIVOT_EXPLICITLY_SET; - if (info.mPivotX != pivotX || !pivotSet) { - mPrivateFlags |= PFLAG_PIVOT_EXPLICITLY_SET; + if (mRenderNode.isPivotExplicitlySet() || pivotX != getPivotX()) { invalidateViewProperty(true, false); - info.mPivotX = pivotX; - info.mMatrixDirty = true; + mRenderNode.setPivotX(pivotX); invalidateViewProperty(false, true); - if (mRenderNode != null) { - mRenderNode.setPivotX(pivotX); - } - if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { - // View was rejected last time it was drawn by its parent; this may have changed - invalidateParentIfNeeded(); - } + + invalidateParentIfNeededAndWasQuickRejected(); } } @@ -10181,7 +9935,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public float getPivotY() { - return mTransformationInfo != null ? mTransformationInfo.mPivotY : 0; + return mRenderNode.getPivotY(); } /** @@ -10199,23 +9953,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @attr ref android.R.styleable#View_transformPivotY */ public void setPivotY(float pivotY) { - ensureTransformationInfo(); - final TransformationInfo info = mTransformationInfo; - boolean pivotSet = (mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == - PFLAG_PIVOT_EXPLICITLY_SET; - if (info.mPivotY != pivotY || !pivotSet) { - mPrivateFlags |= PFLAG_PIVOT_EXPLICITLY_SET; + if (mRenderNode.isPivotExplicitlySet() || pivotY != getPivotY()) { invalidateViewProperty(true, false); - info.mPivotY = pivotY; - info.mMatrixDirty = true; + mRenderNode.setPivotY(pivotY); invalidateViewProperty(false, true); - if (mRenderNode != null) { - mRenderNode.setPivotY(pivotY); - } - if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { - // View was rejected last time it was drawn by its parent; this may have changed - invalidateParentIfNeeded(); - } + + invalidateParentIfNeededAndWasQuickRejected(); } } @@ -10293,9 +10036,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } else { mPrivateFlags &= ~PFLAG_ALPHA_SET; invalidateViewProperty(true, false); - if (mRenderNode != null) { - mRenderNode.setAlpha(getFinalAlpha()); - } + mRenderNode.setAlpha(getFinalAlpha()); } } } @@ -10320,9 +10061,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return true; } else { mPrivateFlags &= ~PFLAG_ALPHA_SET; - if (mRenderNode != null) { - mRenderNode.setAlpha(getFinalAlpha()); - } + mRenderNode.setAlpha(getFinalAlpha()); } } return false; @@ -10343,9 +10082,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mTransformationInfo.mTransitionAlpha = alpha; mPrivateFlags &= ~PFLAG_ALPHA_SET; invalidateViewProperty(true, false); - if (mRenderNode != null) { - mRenderNode.setAlpha(getFinalAlpha()); - } + mRenderNode.setAlpha(getFinalAlpha()); } } @@ -10392,9 +10129,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public final void setTop(int top) { if (top != mTop) { - updateMatrix(); - final boolean matrixIsIdentity = mTransformationInfo == null - || mTransformationInfo.mMatrixIsIdentity; + final boolean matrixIsIdentity = hasIdentityMatrix(); if (matrixIsIdentity) { if (mAttachInfo != null) { int minTop; @@ -10417,17 +10152,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, int oldHeight = mBottom - mTop; mTop = top; - if (mRenderNode != null) { - mRenderNode.setTop(mTop); - } + mRenderNode.setTop(mTop); sizeChange(width, mBottom - mTop, width, oldHeight); if (!matrixIsIdentity) { - if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { - // A change in dimension means an auto-centered pivot point changes, too - mTransformationInfo.mMatrixDirty = true; - } mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation invalidate(true); } @@ -10468,9 +10197,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public final void setBottom(int bottom) { if (bottom != mBottom) { - updateMatrix(); - final boolean matrixIsIdentity = mTransformationInfo == null - || mTransformationInfo.mMatrixIsIdentity; + final boolean matrixIsIdentity = hasIdentityMatrix(); if (matrixIsIdentity) { if (mAttachInfo != null) { int maxBottom; @@ -10490,17 +10217,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, int oldHeight = mBottom - mTop; mBottom = bottom; - if (mRenderNode != null) { - mRenderNode.setBottom(mBottom); - } + mRenderNode.setBottom(mBottom); sizeChange(width, mBottom - mTop, width, oldHeight); if (!matrixIsIdentity) { - if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { - // A change in dimension means an auto-centered pivot point changes, too - mTransformationInfo.mMatrixDirty = true; - } mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation invalidate(true); } @@ -10532,9 +10253,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public final void setLeft(int left) { if (left != mLeft) { - updateMatrix(); - final boolean matrixIsIdentity = mTransformationInfo == null - || mTransformationInfo.mMatrixIsIdentity; + final boolean matrixIsIdentity = hasIdentityMatrix(); if (matrixIsIdentity) { if (mAttachInfo != null) { int minLeft; @@ -10557,17 +10276,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, int height = mBottom - mTop; mLeft = left; - if (mRenderNode != null) { - mRenderNode.setLeft(left); - } + mRenderNode.setLeft(left); sizeChange(mRight - mLeft, height, oldWidth, height); if (!matrixIsIdentity) { - if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { - // A change in dimension means an auto-centered pivot point changes, too - mTransformationInfo.mMatrixDirty = true; - } mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation invalidate(true); } @@ -10599,9 +10312,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public final void setRight(int right) { if (right != mRight) { - updateMatrix(); - final boolean matrixIsIdentity = mTransformationInfo == null - || mTransformationInfo.mMatrixIsIdentity; + final boolean matrixIsIdentity = hasIdentityMatrix(); if (matrixIsIdentity) { if (mAttachInfo != null) { int maxRight; @@ -10621,17 +10332,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, int height = mBottom - mTop; mRight = right; - if (mRenderNode != null) { - mRenderNode.setRight(mRight); - } + mRenderNode.setRight(mRight); sizeChange(mRight - mLeft, height, oldWidth, height); if (!matrixIsIdentity) { - if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { - // A change in dimension means an auto-centered pivot point changes, too - mTransformationInfo.mMatrixDirty = true; - } mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation invalidate(true); } @@ -10653,7 +10358,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public float getX() { - return mLeft + (mTransformationInfo != null ? mTransformationInfo.mTranslationX : 0); + return mLeft + getTranslationX(); } /** @@ -10676,7 +10381,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public float getY() { - return mTop + (mTransformationInfo != null ? mTransformationInfo.mTranslationY : 0); + return mTop + getTranslationY(); } /** @@ -10700,7 +10405,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public float getTranslationX() { - return mTransformationInfo != null ? mTransformationInfo.mTranslationX : 0; + return mRenderNode.getTranslationX(); } /** @@ -10714,21 +10419,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @attr ref android.R.styleable#View_translationX */ public void setTranslationX(float translationX) { - ensureTransformationInfo(); - final TransformationInfo info = mTransformationInfo; - if (info.mTranslationX != translationX) { - // Double-invalidation is necessary to capture view's old and new areas + if (translationX != getTranslationX()) { invalidateViewProperty(true, false); - info.mTranslationX = translationX; - info.mMatrixDirty = true; + mRenderNode.setTranslationX(translationX); invalidateViewProperty(false, true); - if (mRenderNode != null) { - mRenderNode.setTranslationX(translationX); - } - if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { - // View was rejected last time it was drawn by its parent; this may have changed - invalidateParentIfNeeded(); - } + + invalidateParentIfNeededAndWasQuickRejected(); } } @@ -10742,7 +10438,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public float getTranslationY() { - return mTransformationInfo != null ? mTransformationInfo.mTranslationY : 0; + return mRenderNode.getTranslationY(); } /** @@ -10756,20 +10452,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @attr ref android.R.styleable#View_translationY */ public void setTranslationY(float translationY) { - ensureTransformationInfo(); - final TransformationInfo info = mTransformationInfo; - if (info.mTranslationY != translationY) { + if (translationY != getTranslationY()) { invalidateViewProperty(true, false); - info.mTranslationY = translationY; - info.mMatrixDirty = true; + mRenderNode.setTranslationY(translationY); invalidateViewProperty(false, true); - if (mRenderNode != null) { - mRenderNode.setTranslationY(translationY); - } - if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { - // View was rejected last time it was drawn by its parent; this may have changed - invalidateParentIfNeeded(); - } + + invalidateParentIfNeededAndWasQuickRejected(); } } @@ -10780,7 +10468,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @ViewDebug.ExportedProperty(category = "drawing") public float getTranslationZ() { - return mTransformationInfo != null ? mTransformationInfo.mTranslationZ : 0; + return mRenderNode.getTranslationZ(); } /** @@ -10789,20 +10477,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @attr ref android.R.styleable#View_translationZ */ public void setTranslationZ(float translationZ) { - ensureTransformationInfo(); - final TransformationInfo info = mTransformationInfo; - if (info.mTranslationZ != translationZ) { + if (translationZ != getTranslationZ()) { invalidateViewProperty(true, false); - info.mTranslationZ = translationZ; - info.mMatrixDirty = true; + mRenderNode.setTranslationZ(translationZ); invalidateViewProperty(false, true); - if (mRenderNode != null) { - mRenderNode.setTranslationZ(translationZ); - } - if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { - // View was rejected last time it was drawn by its parent; this may have changed - invalidateParentIfNeeded(); - } + + invalidateParentIfNeededAndWasQuickRejected(); } } @@ -10872,10 +10552,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } mOutline.set(outline); } - - if (mRenderNode != null) { - mRenderNode.setOutline(mOutline); - } + mRenderNode.setOutline(mOutline); } /** @@ -10910,9 +10587,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } else { mPrivateFlags3 &= ~PFLAG3_CLIP_TO_OUTLINE; } - if (mRenderNode != null) { - mRenderNode.setClipToOutline(clipToOutline); - } + mRenderNode.setClipToOutline(clipToOutline); } } @@ -10923,11 +10598,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void setRevealClip(boolean shouldClip, boolean inverseClip, float x, float y, float radius) { - if (mRenderNode != null) { - mRenderNode.setRevealClip(shouldClip, inverseClip, x, y, radius); - // TODO: Handle this invalidate in a better way, or purely in native. - invalidate(); - } + mRenderNode.setRevealClip(shouldClip, inverseClip, x, y, radius); + // TODO: Handle this invalidate in a better way, or purely in native. + invalidate(); } /** @@ -10936,14 +10609,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param outRect The hit rectangle of the view. */ public void getHitRect(Rect outRect) { - updateMatrix(); - final TransformationInfo info = mTransformationInfo; - if (info == null || info.mMatrixIsIdentity || mAttachInfo == null) { + if (hasIdentityMatrix() || mAttachInfo == null) { outRect.set(mLeft, mTop, mRight, mBottom); } else { final RectF tmpRect = mAttachInfo.mTmpTransformRect; tmpRect.set(0, 0, getWidth(), getHeight()); - info.mMatrix.mapRect(tmpRect); + getMatrix().mapRect(tmpRect); // TODO: mRenderNode.mapRect(tmpRect) outRect.set((int) tmpRect.left + mLeft, (int) tmpRect.top + mTop, (int) tmpRect.right + mLeft, (int) tmpRect.bottom + mTop); } @@ -11032,11 +10703,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void offsetTopAndBottom(int offset) { if (offset != 0) { - updateMatrix(); - final boolean matrixIsIdentity = mTransformationInfo == null - || mTransformationInfo.mMatrixIsIdentity; + final boolean matrixIsIdentity = hasIdentityMatrix(); if (matrixIsIdentity) { - if (mRenderNode != null) { + if (isHardwareAccelerated()) { invalidateViewProperty(false, false); } else { final ViewParent p = mParent; @@ -11064,8 +10733,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mTop += offset; mBottom += offset; - if (mRenderNode != null) { - mRenderNode.offsetTopAndBottom(offset); + mRenderNode.offsetTopAndBottom(offset); + if (isHardwareAccelerated()) { invalidateViewProperty(false, false); } else { if (!matrixIsIdentity) { @@ -11083,11 +10752,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void offsetLeftAndRight(int offset) { if (offset != 0) { - updateMatrix(); - final boolean matrixIsIdentity = mTransformationInfo == null - || mTransformationInfo.mMatrixIsIdentity; + final boolean matrixIsIdentity = hasIdentityMatrix(); if (matrixIsIdentity) { - if (mRenderNode != null) { + if (isHardwareAccelerated()) { invalidateViewProperty(false, false); } else { final ViewParent p = mParent; @@ -11112,8 +10779,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mLeft += offset; mRight += offset; - if (mRenderNode != null) { - mRenderNode.offsetLeftAndRight(offset); + mRenderNode.offsetLeftAndRight(offset); + if (isHardwareAccelerated()) { invalidateViewProperty(false, false); } else { if (!matrixIsIdentity) { @@ -11493,7 +11160,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } // Damage the entire IsolatedZVolume recieving this view's shadow. - if (getTranslationZ() != 0) { + if (isHardwareAccelerated() && getTranslationZ() != 0) { damageShadowReceiver(); } } @@ -11556,7 +11223,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * list properties are not being used in this view */ void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) { - if (mRenderNode == null || (mPrivateFlags & PFLAG_DRAW_ANIMATION) == PFLAG_DRAW_ANIMATION) { + if (!isHardwareAccelerated() + || !mRenderNode.isValid() + || (mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0) { if (invalidateParent) { invalidateParentCaches(); } @@ -11567,7 +11236,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } else { damageInParent(); } - if (invalidateParent && getTranslationZ() != 0) { + if (isHardwareAccelerated() && invalidateParent && getTranslationZ() != 0) { damageShadowReceiver(); } } @@ -11584,7 +11253,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final Rect r = ai.mTmpInvalRect; r.set(0, 0, mRight - mLeft, mBottom - mTop); if (mParent instanceof ViewGroup) { - ((ViewGroup) mParent).invalidateChildFast(this, r); + ((ViewGroup) mParent).damageChild(this, r); } else { mParent.invalidateChild(this, r); } @@ -11637,6 +11306,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * @hide + */ + protected void invalidateParentIfNeededAndWasQuickRejected() { + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) != 0) { + // View was rejected last time it was drawn by its parent; this may have changed + invalidateParentIfNeeded(); + } + } + + /** * Indicates whether this View is opaque. An opaque View guarantees that it will * draw all the pixels overlapping its bounds using a fully opaque color. * @@ -13979,13 +13658,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public RenderNode getDisplayList() { - ensureRenderNode(); updateDisplayListIfDirty(mRenderNode, false); return mRenderNode; } private void resetDisplayList() { - if (mRenderNode != null && mRenderNode.isValid()) { + if (mRenderNode.isValid()) { mRenderNode.destroyDisplayListData(); } @@ -14580,21 +14258,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * This method is called by getDisplayList() when a display list is created or re-rendered. - * It sets or resets the current value of all properties on that display list (resetting is - * necessary when a display list is being re-created, because we need to make sure that - * previously-set transform values + * This method is called by getDisplayList() when a display list is recorded for a View. + * It pushes any properties to the RenderNode that aren't managed by the RenderNode. */ - void setDisplayListProperties(RenderNode displayList) { - if (displayList != null) { - displayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); - displayList.setHasOverlappingRendering(hasOverlappingRendering()); + void setDisplayListProperties(RenderNode renderNode) { + if (renderNode != null) { + renderNode.setHasOverlappingRendering(hasOverlappingRendering()); if (mParent instanceof ViewGroup) { - displayList.setClipToBounds( + renderNode.setClipToBounds( (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0); } - displayList.setOutline(mOutline); - displayList.setClipToOutline(getClipToOutline()); float alpha = 1; if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) { @@ -14607,7 +14280,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, alpha = t.getAlpha(); } if ((transformType & Transformation.TYPE_MATRIX) != 0) { - displayList.setStaticMatrix(t.getMatrix()); + renderNode.setStaticMatrix(t.getMatrix()); } } } @@ -14620,23 +14293,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, alpha = 1; } } - displayList.setTransformationInfo(alpha, - mTransformationInfo.mTranslationX, mTransformationInfo.mTranslationY, - mTransformationInfo.mTranslationZ, - mTransformationInfo.mRotation, mTransformationInfo.mRotationX, - mTransformationInfo.mRotationY, mTransformationInfo.mScaleX, - mTransformationInfo.mScaleY); - if (mTransformationInfo.mCamera == null) { - mTransformationInfo.mCamera = new Camera(); - mTransformationInfo.matrix3D = new Matrix(); - } - displayList.setCameraDistance(mTransformationInfo.mCamera.getLocationZ()); - if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == PFLAG_PIVOT_EXPLICITLY_SET) { - displayList.setPivotX(getPivotX()); - displayList.setPivotY(getPivotY()); - } + renderNode.setAlpha(alpha); } else if (alpha < 1) { - displayList.setAlpha(alpha); + renderNode.setAlpha(alpha); } } } @@ -14683,8 +14342,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } transformToApply = parent.getChildTransformation(); } else { - if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) == - PFLAG3_VIEW_IS_ANIMATING_TRANSFORM && mRenderNode != null) { + if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) != 0) { // No longer animating: clear out old animation matrix mRenderNode.setAnimationMatrix(null); mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_TRANSFORM; @@ -15199,9 +14857,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((mPrivateFlags3 & PFLAG3_OUTLINE_DEFINED) == 0) { // Outline not currently define, query from background mOutline = background.getOutline(); - if (mRenderNode != null) { - mRenderNode.setOutline(mOutline); - } + mRenderNode.setOutline(mOutline); } } @@ -15536,20 +15192,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mTop = top; mRight = right; mBottom = bottom; - if (mRenderNode != null) { - mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); - } + mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); mPrivateFlags |= PFLAG_HAS_BOUNDS; if (sizeChanged) { - if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { - // A change in dimension means an auto-centered pivot point changes, too - if (mTransformationInfo != null) { - mTransformationInfo.mMatrixDirty = true; - } - } sizeChange(newWidth, newHeight, oldWidth, oldHeight); } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index bcc82fb..d2c6302 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -4449,7 +4449,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * * @hide */ - public void invalidateChildFast(View child, final Rect dirty) { + public void damageChild(View child, final Rect dirty) { ViewParent parent = this; final AttachInfo attachInfo = mAttachInfo; @@ -4472,7 +4472,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager parentVG.invalidate(); parent = null; } else { - parent = parentVG.invalidateChildInParentFast(left, top, dirty); + parent = parentVG.damageChildInParent(left, top, dirty); left = parentVG.mLeft; top = parentVG.mTop; } @@ -4494,9 +4494,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * * @hide */ - protected ViewParent invalidateChildInParentFast(int left, int top, final Rect dirty) { - if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN || - (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) { + protected ViewParent damageChildInParent(int left, int top, final Rect dirty) { + if ((mPrivateFlags & PFLAG_DRAWN) != 0 + || (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) != 0) { dirty.offset(left - mScrollX, top - mScrollY); if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0) { dirty.union(0, 0, mRight - mLeft, mBottom - mTop); diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java index 47de780..0cf9ddd 100644 --- a/core/java/android/view/ViewOverlay.java +++ b/core/java/android/view/ViewOverlay.java @@ -290,7 +290,11 @@ public class ViewOverlay { } } - public void invalidateChildFast(View child, final Rect dirty) { + /** + * @hide + */ + @Override + public void damageChild(View child, final Rect dirty) { if (mHostView != null) { // Note: This is not a "fast" invalidation. Would be nice to instead invalidate // using DisplayList properties and a dirty rect instead of causing a real @@ -309,9 +313,9 @@ public class ViewOverlay { * @hide */ @Override - protected ViewParent invalidateChildInParentFast(int left, int top, Rect dirty) { + protected ViewParent damageChildInParent(int left, int top, Rect dirty) { if (mHostView instanceof ViewGroup) { - return ((ViewGroup) mHostView).invalidateChildInParentFast(left, top, dirty); + return ((ViewGroup) mHostView).damageChildInParent(left, top, dirty); } return null; } diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index bbae0ca..6b21451 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -928,48 +928,38 @@ public class ViewPropertyAnimator { final RenderNode renderNode = mView.mRenderNode; switch (propertyConstant) { case TRANSLATION_X: - info.mTranslationX = value; - if (renderNode != null) renderNode.setTranslationX(value); + renderNode.setTranslationX(value); break; case TRANSLATION_Y: - info.mTranslationY = value; - if (renderNode != null) renderNode.setTranslationY(value); + renderNode.setTranslationY(value); break; case TRANSLATION_Z: - info.mTranslationZ = value; - if (renderNode != null) renderNode.setTranslationZ(value); + renderNode.setTranslationZ(value); break; case ROTATION: - info.mRotation = value; - if (renderNode != null) renderNode.setRotation(value); + renderNode.setRotation(value); break; case ROTATION_X: - info.mRotationX = value; - if (renderNode != null) renderNode.setRotationX(value); + renderNode.setRotationX(value); break; case ROTATION_Y: - info.mRotationY = value; - if (renderNode != null) renderNode.setRotationY(value); + renderNode.setRotationY(value); break; case SCALE_X: - info.mScaleX = value; - if (renderNode != null) renderNode.setScaleX(value); + renderNode.setScaleX(value); break; case SCALE_Y: - info.mScaleY = value; - if (renderNode != null) renderNode.setScaleY(value); + renderNode.setScaleY(value); break; case X: - info.mTranslationX = value - mView.mLeft; - if (renderNode != null) renderNode.setTranslationX(value - mView.mLeft); + renderNode.setTranslationX(value - mView.mLeft); break; case Y: - info.mTranslationY = value - mView.mTop; - if (renderNode != null) renderNode.setTranslationY(value - mView.mTop); + renderNode.setTranslationY(value - mView.mTop); break; case ALPHA: info.mAlpha = value; - if (renderNode != null) renderNode.setAlpha(value); + renderNode.setAlpha(value); break; } } @@ -981,30 +971,30 @@ public class ViewPropertyAnimator { * @return float The value of the named property */ private float getValue(int propertyConstant) { - final View.TransformationInfo info = mView.mTransformationInfo; + final RenderNode node = mView.mRenderNode; switch (propertyConstant) { case TRANSLATION_X: - return info.mTranslationX; + return node.getTranslationX(); case TRANSLATION_Y: - return info.mTranslationY; + return node.getTranslationY(); case TRANSLATION_Z: - return info.mTranslationZ; + return node.getTranslationZ(); case ROTATION: - return info.mRotation; + return node.getRotation(); case ROTATION_X: - return info.mRotationX; + return node.getRotationX(); case ROTATION_Y: - return info.mRotationY; + return node.getRotationY(); case SCALE_X: - return info.mScaleX; + return node.getScaleX(); case SCALE_Y: - return info.mScaleY; + return node.getScaleY(); case X: - return mView.mLeft + info.mTranslationX; + return mView.mLeft + node.getTranslationX(); case Y: - return mView.mTop + info.mTranslationY; + return mView.mTop + node.getTranslationY(); case ALPHA: - return info.mAlpha; + return mView.mTransformationInfo.mAlpha; } return 0; } @@ -1123,7 +1113,6 @@ public class ViewPropertyAnimator { } } if ((propertyMask & TRANSFORM_MASK) != 0) { - mView.mTransformationInfo.mMatrixDirty = true; if (!useRenderNodeProperties) { mView.mPrivateFlags |= View.PFLAG_DRAWN; // force another invalidation } diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp index 3e359d4..d079349 100644 --- a/core/jni/android_view_RenderNode.cpp +++ b/core/jni/android_view_RenderNode.cpp @@ -69,7 +69,7 @@ static void android_view_RenderNode_destroyDisplayList(JNIEnv* env, } // ---------------------------------------------------------------------------- -// RenderProperties +// RenderProperties - setters // ---------------------------------------------------------------------------- static void android_view_RenderNode_setCaching(JNIEnv* env, @@ -209,22 +209,6 @@ static void android_view_RenderNode_setScaleY(JNIEnv* env, displayList->mutateStagingProperties().setScaleY(sy); } -static void android_view_RenderNode_setTransformationInfo(JNIEnv* env, - jobject clazz, jlong displayListPtr, float alpha, - float translationX, float translationY, float translationZ, - float rotation, float rotationX, float rotationY, float scaleX, float scaleY) { - RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); - displayList->mutateStagingProperties().setAlpha(alpha); - displayList->mutateStagingProperties().setTranslationX(translationX); - displayList->mutateStagingProperties().setTranslationY(translationY); - displayList->mutateStagingProperties().setTranslationZ(translationZ); - displayList->mutateStagingProperties().setRotation(rotation); - displayList->mutateStagingProperties().setRotationX(rotationX); - displayList->mutateStagingProperties().setRotationY(rotationY); - displayList->mutateStagingProperties().setScaleX(scaleX); - displayList->mutateStagingProperties().setScaleY(scaleY); -} - static void android_view_RenderNode_setPivotX(JNIEnv* env, jobject clazz, jlong displayListPtr, float px) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); @@ -286,6 +270,10 @@ static void android_view_RenderNode_offsetTopAndBottom(JNIEnv* env, displayList->mutateStagingProperties().offsetTopBottom(offset); } +// ---------------------------------------------------------------------------- +// RenderProperties - getters +// ---------------------------------------------------------------------------- + static jboolean android_view_RenderNode_hasOverlappingRendering(JNIEnv* env, jobject clazz, jlong displayListPtr) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); @@ -352,6 +340,12 @@ static jfloat android_view_RenderNode_getTranslationY(JNIEnv* env, return displayList->stagingProperties().getTranslationY(); } +static jfloat android_view_RenderNode_getTranslationZ(JNIEnv* env, + jobject clazz, jlong displayListPtr) { + RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); + return displayList->stagingProperties().getTranslationZ(); +} + static jfloat android_view_RenderNode_getRotation(JNIEnv* env, jobject clazz, jlong displayListPtr) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); @@ -370,6 +364,53 @@ static jfloat android_view_RenderNode_getRotationY(JNIEnv* env, return displayList->stagingProperties().getRotationY(); } +static jboolean android_view_RenderNode_isPivotExplicitlySet(JNIEnv* env, + jobject clazz, jlong displayListPtr) { + RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); + return displayList->stagingProperties().isPivotExplicitlySet(); +} + +static jboolean android_view_RenderNode_hasIdentityMatrix(JNIEnv* env, + jobject clazz, jlong displayListPtr) { + RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); + return displayList->stagingProperties().getMatrixFlags() == 0; +} + +// ---------------------------------------------------------------------------- +// RenderProperties - computed getters +// ---------------------------------------------------------------------------- + +static void android_view_RenderNode_getTransformMatrix(JNIEnv* env, + jobject clazz, jlong displayListPtr, jlong outMatrixPtr) { + RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); + SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr); + + displayList->mutateStagingProperties().updateMatrix(); + const SkMatrix* transformMatrix = displayList->stagingProperties().getTransformMatrix(); + + if (displayList->stagingProperties().getMatrixFlags() == TRANSLATION) { + outMatrix->setTranslate(displayList->stagingProperties().getTranslationX(), + displayList->stagingProperties().getTranslationY()); + } else if (transformMatrix) { + *outMatrix = *transformMatrix; + } else { + outMatrix->setIdentity(); + } +} + +static void android_view_RenderNode_getInverseTransformMatrix(JNIEnv* env, + jobject clazz, jlong displayListPtr, jlong outMatrixPtr) { + // load transform matrix + android_view_RenderNode_getTransformMatrix(env, clazz, displayListPtr, outMatrixPtr); + SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr); + + // return it inverted + if (!outMatrix->invert(outMatrix)) { + // failed to load inverse, pass back identity + outMatrix->setIdentity(); + } +} + static jfloat android_view_RenderNode_getPivotX(JNIEnv* env, jobject clazz, jlong displayListPtr) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); @@ -424,8 +465,6 @@ static JNINativeMethod gMethods[] = { { "nSetRotationY", "(JF)V", (void*) android_view_RenderNode_setRotationY }, { "nSetScaleX", "(JF)V", (void*) android_view_RenderNode_setScaleX }, { "nSetScaleY", "(JF)V", (void*) android_view_RenderNode_setScaleY }, - { "nSetTransformationInfo","(JFFFFFFFFF)V", - (void*) android_view_RenderNode_setTransformationInfo }, { "nSetPivotX", "(JF)V", (void*) android_view_RenderNode_setPivotX }, { "nSetPivotY", "(JF)V", (void*) android_view_RenderNode_setPivotY }, { "nSetCameraDistance", "(JF)V", (void*) android_view_RenderNode_setCameraDistance }, @@ -448,11 +487,18 @@ static JNINativeMethod gMethods[] = { { "nGetScaleY", "(J)F", (void*) android_view_RenderNode_getScaleY }, { "nGetTranslationX", "(J)F", (void*) android_view_RenderNode_getTranslationX }, { "nGetTranslationY", "(J)F", (void*) android_view_RenderNode_getTranslationY }, + { "nGetTranslationZ", "(J)F", (void*) android_view_RenderNode_getTranslationZ }, { "nGetRotation", "(J)F", (void*) android_view_RenderNode_getRotation }, { "nGetRotationX", "(J)F", (void*) android_view_RenderNode_getRotationX }, { "nGetRotationY", "(J)F", (void*) android_view_RenderNode_getRotationY }, - { "nGetPivotX", "(J)F", (void*) android_view_RenderNode_getPivotX }, - { "nGetPivotY", "(J)F", (void*) android_view_RenderNode_getPivotY }, + { "nIsPivotExplicitlySet", "(J)Z", (void*) android_view_RenderNode_isPivotExplicitlySet }, + { "nHasIdentityMatrix", "(J)Z", (void*) android_view_RenderNode_hasIdentityMatrix }, + + { "nGetTransformMatrix", "(JJ)V", (void*) android_view_RenderNode_getTransformMatrix }, + { "nGetInverseTransformMatrix","(JJ)V", (void*) android_view_RenderNode_getInverseTransformMatrix }, + + { "nGetPivotX", "(J)F", (void*) android_view_RenderNode_getPivotX }, + { "nGetPivotY", "(J)F", (void*) android_view_RenderNode_getPivotY }, #endif }; diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 34d98a1..663b67e 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -61,8 +61,12 @@ RenderNode::~RenderNode() { void RenderNode::destroyDisplayListDeferred(RenderNode* displayList) { if (displayList) { - DISPLAY_LIST_LOGD("Deferring display list destruction"); - Caches::getInstance().deleteDisplayListDeferred(displayList); + if (Caches::hasInstance()) { + DISPLAY_LIST_LOGD("Deferring display list destruction"); + Caches::getInstance().deleteDisplayListDeferred(displayList); + } else { + delete displayList; + } } } diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp index 3975a76..e7e7768 100644 --- a/libs/hwui/RenderProperties.cpp +++ b/libs/hwui/RenderProperties.cpp @@ -45,28 +45,24 @@ RenderProperties::PrimitiveFields::PrimitiveFields() , mPrevWidth(-1), mPrevHeight(-1) , mPivotExplicitlySet(false) , mMatrixDirty(false) - , mMatrixIsIdentity(true) , mMatrixFlags(0) , mCaching(false) { } RenderProperties::ComputedFields::ComputedFields() : mTransformMatrix(NULL) - , mTransformCamera(NULL) , mTransformMatrix3D(NULL) , mClipPath(NULL) { } RenderProperties::ComputedFields::~ComputedFields() { delete mTransformMatrix; - delete mTransformCamera; delete mTransformMatrix3D; delete mClipPath; } RenderProperties::RenderProperties() - : mCameraDistance(0) - , mStaticMatrix(NULL) + : mStaticMatrix(NULL) , mAnimationMatrix(NULL) { } @@ -82,9 +78,12 @@ RenderProperties& RenderProperties::operator=(const RenderProperties& other) { setAnimationMatrix(other.getAnimationMatrix()); setCameraDistance(other.getCameraDistance()); - // Update the computed fields - updateMatrix(); + // Update the computed clip path updateClipPath(); + + // Force recalculation of the matrix, since other's dirty bit may be clear + mPrimitiveFields.mMatrixDirty = true; + updateMatrix(); } return *this; } @@ -106,8 +105,8 @@ void RenderProperties::debugOutputProperties(const int level) const { ALOGD("%*sTranslate %.2f, %.2f, %.2f", level * 2, "", mPrimitiveFields.mTranslationX, mPrimitiveFields.mTranslationY, mPrimitiveFields.mTranslationZ); } else { - ALOGD("%*sConcatMatrix %p: " MATRIX_4_STRING, - level * 2, "", mComputedFields.mTransformMatrix, MATRIX_4_ARGS(mComputedFields.mTransformMatrix)); + ALOGD("%*sConcatMatrix %p: " SK_MATRIX_STRING, + level * 2, "", mComputedFields.mTransformMatrix, SK_MATRIX_ARGS(mComputedFields.mTransformMatrix)); } } @@ -141,7 +140,7 @@ void RenderProperties::updateMatrix() { if (mPrimitiveFields.mMatrixFlags && mPrimitiveFields.mMatrixFlags != TRANSLATION) { if (!mComputedFields.mTransformMatrix) { // only allocate a mPrimitiveFields.matrix if we have a complex transform - mComputedFields.mTransformMatrix = new Matrix4(); + mComputedFields.mTransformMatrix = new SkMatrix(); } if (!mPrimitiveFields.mPivotExplicitlySet) { if (mPrimitiveFields.mWidth != mPrimitiveFields.mPrevWidth || mPrimitiveFields.mHeight != mPrimitiveFields.mPrevHeight) { @@ -153,33 +152,31 @@ void RenderProperties::updateMatrix() { } if ((mPrimitiveFields.mMatrixFlags & ROTATION_3D) == 0) { - mComputedFields.mTransformMatrix->loadTranslate( - mPrimitiveFields.mPivotX + mPrimitiveFields.mTranslationX, - mPrimitiveFields.mPivotY + mPrimitiveFields.mTranslationY, - 0); - mComputedFields.mTransformMatrix->rotate(mPrimitiveFields.mRotation, 0, 0, 1); - mComputedFields.mTransformMatrix->scale(mPrimitiveFields.mScaleX, mPrimitiveFields.mScaleY, 1); - mComputedFields.mTransformMatrix->translate(-mPrimitiveFields.mPivotX, -mPrimitiveFields.mPivotY); + mComputedFields.mTransformMatrix->setTranslate( + mPrimitiveFields.mTranslationX, mPrimitiveFields.mTranslationY); + mComputedFields.mTransformMatrix->preRotate(mPrimitiveFields.mRotation, + mPrimitiveFields.mPivotX, mPrimitiveFields.mPivotY); + mComputedFields.mTransformMatrix->preScale( + mPrimitiveFields.mScaleX, mPrimitiveFields.mScaleY, + mPrimitiveFields.mPivotX, mPrimitiveFields.mPivotY); } else { - if (!mComputedFields.mTransformCamera) { - mComputedFields.mTransformCamera = new Sk3DView(); + if (!mComputedFields.mTransformMatrix3D) { mComputedFields.mTransformMatrix3D = new SkMatrix(); } - SkMatrix transformMatrix; - transformMatrix.reset(); - mComputedFields.mTransformCamera->save(); - transformMatrix.preScale(mPrimitiveFields.mScaleX, mPrimitiveFields.mScaleY, mPrimitiveFields.mPivotX, mPrimitiveFields.mPivotY); - mComputedFields.mTransformCamera->rotateX(mPrimitiveFields.mRotationX); - mComputedFields.mTransformCamera->rotateY(mPrimitiveFields.mRotationY); - mComputedFields.mTransformCamera->rotateZ(-mPrimitiveFields.mRotation); - mComputedFields.mTransformCamera->getMatrix(mComputedFields.mTransformMatrix3D); + mComputedFields.mTransformMatrix->reset(); + mComputedFields.mTransformCamera.save(); + mComputedFields.mTransformMatrix->preScale( + mPrimitiveFields.mScaleX, mPrimitiveFields.mScaleY, + mPrimitiveFields.mPivotX, mPrimitiveFields.mPivotY); + mComputedFields.mTransformCamera.rotateX(mPrimitiveFields.mRotationX); + mComputedFields.mTransformCamera.rotateY(mPrimitiveFields.mRotationY); + mComputedFields.mTransformCamera.rotateZ(-mPrimitiveFields.mRotation); + mComputedFields.mTransformCamera.getMatrix(mComputedFields.mTransformMatrix3D); mComputedFields.mTransformMatrix3D->preTranslate(-mPrimitiveFields.mPivotX, -mPrimitiveFields.mPivotY); mComputedFields.mTransformMatrix3D->postTranslate(mPrimitiveFields.mPivotX + mPrimitiveFields.mTranslationX, mPrimitiveFields.mPivotY + mPrimitiveFields.mTranslationY); - transformMatrix.postConcat(*mComputedFields.mTransformMatrix3D); - mComputedFields.mTransformCamera->restore(); - - mComputedFields.mTransformMatrix->load(transformMatrix); + mComputedFields.mTransformMatrix->postConcat(*mComputedFields.mTransformMatrix3D); + mComputedFields.mTransformCamera.restore(); } } mPrimitiveFields.mMatrixDirty = false; diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h index 061e469..dd68210 100644 --- a/libs/hwui/RenderProperties.h +++ b/libs/hwui/RenderProperties.h @@ -258,20 +258,20 @@ public: return mPrimitiveFields.mPivotY; } + bool isPivotExplicitlySet() const { + return mPrimitiveFields.mPivotExplicitlySet; + } + void setCameraDistance(float distance) { - if (distance != mCameraDistance) { - mCameraDistance = distance; + if (distance != getCameraDistance()) { mPrimitiveFields.mMatrixDirty = true; - if (!mComputedFields.mTransformCamera) { - mComputedFields.mTransformCamera = new Sk3DView(); - mComputedFields.mTransformMatrix3D = new SkMatrix(); - } - mComputedFields.mTransformCamera->setCameraLocation(0, 0, distance); + mComputedFields.mTransformCamera.setCameraLocation(0, 0, distance); } } float getCameraDistance() const { - return mCameraDistance; + // TODO: update getCameraLocationZ() to be const + return const_cast<Sk3DView*>(&mComputedFields.mTransformCamera)->getCameraLocationZ(); } void setLeft(int left) { @@ -396,7 +396,7 @@ public: return mPrimitiveFields.mMatrixFlags; } - const Matrix4* getTransformMatrix() const { + const SkMatrix* getTransformMatrix() const { return mComputedFields.mTransformMatrix; } @@ -481,13 +481,11 @@ private: int mPrevWidth, mPrevHeight; bool mPivotExplicitlySet; bool mMatrixDirty; - bool mMatrixIsIdentity; uint32_t mMatrixFlags; bool mCaching; } mPrimitiveFields; // mCameraDistance isn't in mPrimitiveFields as it has a complex setter - float mCameraDistance; SkMatrix* mStaticMatrix; SkMatrix* mAnimationMatrix; @@ -502,11 +500,12 @@ private: * Stores the total transformation of the DisplayList based upon its scalar * translate/rotate/scale properties. * - * In the common translation-only case, the matrix isn't allocated and the mTranslation - * properties are used directly. + * In the common translation-only case, the matrix isn't necessarily allocated, + * and the mTranslation properties are used directly. */ - Matrix4* mTransformMatrix; - Sk3DView* mTransformCamera; + SkMatrix* mTransformMatrix; + + Sk3DView mTransformCamera; SkMatrix* mTransformMatrix3D; SkPath* mClipPath; // TODO: remove this, create new ops for efficient/special case clipping SkRegion::Op mClipPathOp; |