OSDN Git Service

Add initial APIs for 3d view manipulation.
authorChris Craik <ccraik@google.com>
Thu, 19 Dec 2013 21:31:15 +0000 (13:31 -0800)
committerChris Craik <ccraik@google.com>
Fri, 20 Dec 2013 23:15:01 +0000 (15:15 -0800)
Change-Id: I6de00bc577d5b3a1fbc9ca3a3b3668fcfa32b867

api/current.txt
core/java/android/view/DisplayList.java
core/java/android/view/View.java
core/java/android/view/ViewGroup.java
core/java/android/view/ViewPropertyAnimator.java
core/jni/android_view_DisplayList.cpp
core/res/res/values/attrs.xml
core/res/res/values/public.xml
libs/hwui/DisplayList.cpp
libs/hwui/DisplayList.h

index 401fdf6..e6aebd2 100644 (file)
@@ -1152,6 +1152,7 @@ package android {
     field public static final int transitionOrdering = 16843744; // 0x10103e0
     field public static final int translationX = 16843554; // 0x1010322
     field public static final int translationY = 16843555; // 0x1010323
+    field public static final int translationZ = 16843766; // 0x10103f6
     field public static final int type = 16843169; // 0x10101a1
     field public static final int typeface = 16842902; // 0x1010096
     field public static final int uiOptions = 16843672; // 0x1010398
@@ -28474,6 +28475,7 @@ package android.view {
     method public java.util.ArrayList<android.view.View> getTouchables();
     method public float getTranslationX();
     method public float getTranslationY();
+    method public float getTranslationZ();
     method public int getVerticalFadingEdgeLength();
     method public int getVerticalScrollbarPosition();
     method public int getVerticalScrollbarWidth();
@@ -28721,6 +28723,7 @@ package android.view {
     method public void setTouchDelegate(android.view.TouchDelegate);
     method public void setTranslationX(float);
     method public void setTranslationY(float);
+    method public void setTranslationZ(float);
     method public void setVerticalFadingEdgeEnabled(boolean);
     method public void setVerticalScrollBarEnabled(boolean);
     method public void setVerticalScrollbarPosition(int);
@@ -28851,6 +28854,7 @@ package android.view {
     field public static final int TEXT_DIRECTION_RTL = 4; // 0x4
     field public static final android.util.Property TRANSLATION_X;
     field public static final android.util.Property TRANSLATION_Y;
+    field public static final android.util.Property TRANSLATION_Z;
     field protected static final java.lang.String VIEW_LOG_TAG = "View";
     field public static final int VISIBLE = 0; // 0x0
     field protected static final int[] WINDOW_FOCUSED_STATE_SET;
@@ -29274,6 +29278,8 @@ package android.view {
     method public android.view.ViewPropertyAnimator translationXBy(float);
     method public android.view.ViewPropertyAnimator translationY(float);
     method public android.view.ViewPropertyAnimator translationYBy(float);
+    method public android.view.ViewPropertyAnimator translationZ(float);
+    method public android.view.ViewPropertyAnimator translationZBy(float);
     method public android.view.ViewPropertyAnimator withEndAction(java.lang.Runnable);
     method public android.view.ViewPropertyAnimator withLayer();
     method public android.view.ViewPropertyAnimator withStartAction(java.lang.Runnable);
index bb09c90..cf2a9da 100644 (file)
@@ -403,6 +403,18 @@ public class DisplayList {
     }
 
     /**
+     * Set whether the display list should collect and Z order all 3d composited descendents, and
+     * draw them in order with the default Z=0 content.
+     *
+     * @param isContainedVolume true if the display list should collect and Z order descendents.
+     */
+    public void setIsContainedVolume(boolean isContainedVolume) {
+        if (hasNativeDisplayList()) {
+            nSetIsContainedVolume(mFinalizer.mNativeDisplayList, isContainedVolume);
+        }
+    }
+
+    /**
      * Set the static matrix on the display list. The specified matrix is combined with other
      * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
      *
@@ -526,7 +538,7 @@ public class DisplayList {
     }
 
     /**
-     * Sets the translation value for the display list on the X axis
+     * Sets the translation value for the display list on the X axis.
      *
      * @param translationX The X axis translation value of the display list, in pixels
      *
@@ -552,7 +564,7 @@ public class DisplayList {
     }
 
     /**
-     * Sets the translation value for the display list on the Y axis
+     * Sets the translation value for the display list on the Y axis.
      *
      * @param translationY The Y axis translation value of the display list, in pixels
      *
@@ -578,7 +590,7 @@ public class DisplayList {
     }
 
     /**
-     * Sets the translation value for the display list on the Z axis
+     * Sets the translation value for the display list on the Z axis.
      *
      * @see View#setTranslationZ(float)
      * @see #getTranslationZ()
@@ -602,7 +614,7 @@ public class DisplayList {
     }
 
     /**
-     * Sets the rotation value for the display list around the Z axis
+     * Sets the rotation value for the display list around the Z axis.
      *
      * @param rotation The rotation value of the display list, in degrees
      *
@@ -628,7 +640,7 @@ public class DisplayList {
     }
 
     /**
-     * Sets the rotation value for the display list around the X axis
+     * Sets the rotation value for the display list around the X axis.
      *
      * @param rotationX The rotation value of the display list, in degrees
      *
@@ -654,7 +666,7 @@ public class DisplayList {
     }
 
     /**
-     * Sets the rotation value for the display list around the Y axis
+     * Sets the rotation value for the display list around the Y axis.
      *
      * @param rotationY The rotation value of the display list, in degrees
      *
@@ -680,7 +692,7 @@ public class DisplayList {
     }
 
     /**
-     * Sets the scale value for the display list on the X axis
+     * Sets the scale value for the display list on the X axis.
      *
      * @param scaleX The scale value of the display list
      *
@@ -706,7 +718,7 @@ public class DisplayList {
     }
 
     /**
-     * Sets the scale value for the display list on the Y axis
+     * Sets the scale value for the display list on the Y axis.
      *
      * @param scaleY The scale value of the display list
      *
@@ -1022,6 +1034,7 @@ public class DisplayList {
     private static native void nSetPivotX(int displayList, float pivotX);
     private static native void nSetCaching(int displayList, boolean caching);
     private static native void nSetClipToBounds(int displayList, boolean clipToBounds);
+    private static native void nSetIsContainedVolume(int displayList, boolean isContainedVolume);
     private static native void nSetAlpha(int displayList, float alpha);
     private static native void nSetHasOverlappingRendering(int displayList,
             boolean hasOverlappingRendering);
index 073e8bd..a382600 100644 (file)
@@ -57,7 +57,6 @@ import android.util.FloatProperty;
 import android.util.LayoutDirection;
 import android.util.Log;
 import android.util.LongSparseLongArray;
-import android.util.MathUtils;
 import android.util.Pools.SynchronizedPool;
 import android.util.Property;
 import android.util.SparseArray;
@@ -673,6 +672,7 @@ import java.util.concurrent.atomic.AtomicInteger;
  * @attr ref android.R.styleable#View_transformPivotY
  * @attr ref android.R.styleable#View_translationX
  * @attr ref android.R.styleable#View_translationY
+ * @attr ref android.R.styleable#View_translationZ
  * @attr ref android.R.styleable#View_visibility
  *
  * @see android.view.ViewGroup
@@ -3664,6 +3664,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
 
         float tx = 0;
         float ty = 0;
+        float tz = 0;
         float rotation = 0;
         float rotationX = 0;
         float rotationY = 0;
@@ -3743,6 +3744,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                     ty = a.getDimensionPixelOffset(attr, 0);
                     transformSet = true;
                     break;
+                case com.android.internal.R.styleable.View_translationZ:
+                    tz = a.getDimensionPixelOffset(attr, 0);
+                    transformSet = true;
+                    break;
                 case com.android.internal.R.styleable.View_rotation:
                     rotation = a.getFloat(attr, 0);
                     transformSet = true;
@@ -4084,6 +4089,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
         if (transformSet) {
             setTranslationX(tx);
             setTranslationY(ty);
+            setTranslationZ(tz);
             setRotation(rotation);
             setRotationX(rotationX);
             setRotationY(rotationY);
@@ -10585,7 +10591,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     }
 
     /**
-     * @hide
+     * The depth location of this view relative to its parent.
+     *
+     * @return The depth of this view relative to its parent.
      */
     @ViewDebug.ExportedProperty(category = "drawing")
     public float getTranslationZ() {
@@ -10593,7 +10601,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     }
 
     /**
-     * @hide
+     * Sets the depth location of this view relative to its parent.
+     *
+     * @attr ref android.R.styleable#View_translationZ
      */
     public void setTranslationZ(float translationZ) {
         ensureTransformationInfo();
@@ -14252,6 +14262,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                 displayList.setClipToBounds(
                         (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
             }
+            if (this instanceof ViewGroup) {
+                displayList.setIsContainedVolume(
+                        (((ViewGroup) this).mGroupFlags & ViewGroup.FLAG_IS_CONTAINED_VOLUME) != 0);
+            }
             float alpha = 1;
             if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
                     ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
@@ -18394,6 +18408,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     };
 
     /**
+     * A Property wrapper around the <code>translationZ</code> functionality handled by the
+     * {@link View#setTranslationZ(float)} and {@link View#getTranslationZ()} methods.
+     */
+    public static final Property<View, Float> TRANSLATION_Z = new FloatProperty<View>("translationZ") {
+        @Override
+        public void setValue(View object, float value) {
+            object.setTranslationZ(value);
+        }
+
+        @Override
+        public Float get(View object) {
+            return object.getTranslationZ();
+        }
+    };
+
+    /**
      * A Property wrapper around the <code>x</code> functionality handled by the
      * {@link View#setX(float)} and {@link View#getX()} methods.
      */
index 3ee3057..241b1a7 100644 (file)
@@ -355,6 +355,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     private static final int FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET = 0x800000;
 
     /**
+     * When true, indicates that all 3d composited descendents are contained within this group, and
+     * will not be interleaved with other 3d composited content.
+     */
+    static final int FLAG_IS_CONTAINED_VOLUME = 0x1000000;
+
+    /**
      * Indicates which types of drawing caches are to be kept in memory.
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
@@ -486,6 +492,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
         mGroupFlags |= FLAG_ANIMATION_DONE;
         mGroupFlags |= FLAG_ANIMATION_CACHE;
         mGroupFlags |= FLAG_ALWAYS_DRAWN_WITH_CACHE;
+        mGroupFlags |= FLAG_IS_CONTAINED_VOLUME;
 
         if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
             mGroupFlags |= FLAG_SPLIT_MOTION_EVENTS;
@@ -3104,7 +3111,44 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     }
 
     /**
-     * Returns whether ths group's children are clipped to their bounds before drawing.
+     * Returns whether this group's descendents are drawn in their own
+     * independent Z volume. Views drawn in one contained volume will not
+     * interleave with views in another, even if their Z values are interleaved.
+     * The default value is true.
+     * @see #setIsContainedVolume(boolean)
+     *
+     * @return True if the ViewGroup is a contained volume.
+     *
+     * @hide
+     */
+    public boolean isContainedVolume() {
+        return ((mGroupFlags & FLAG_IS_CONTAINED_VOLUME) != 0);
+    }
+
+    /**
+     * By default, only direct children of a group can interleave with
+     * interleaved Z values. Set to false on individual groups to enable Z
+     * interleaving of views that aren't direct siblings.
+     *
+     * @return True if the group should be a contained volume with its own Z
+     *         ordering space, false if its decendents should join the current Z
+     *         ordering volume.
+     * @attr ref android.R.styleable#ViewGroup_isContainedVolume
+     *
+     * @hide
+     */
+    public void setIsContainedVolume(boolean isContainedVolume) {
+        boolean previousValue = (mGroupFlags & FLAG_IS_CONTAINED_VOLUME) == FLAG_IS_CONTAINED_VOLUME;
+        if (isContainedVolume != previousValue) {
+            setBooleanFlag(FLAG_IS_CONTAINED_VOLUME, isContainedVolume);
+            if (mDisplayList != null) {
+                mDisplayList.setIsContainedVolume(isContainedVolume);
+            }
+        }
+    }
+
+    /**
+     * Returns whether this group's children are clipped to their bounds before drawing.
      * The default value is true.
      * @see #setClipChildren(boolean)
      *
index 391b345..1892aa7 100644 (file)
@@ -136,15 +136,15 @@ public class ViewPropertyAnimator {
     private static final int NONE           = 0x0000;
     private static final int TRANSLATION_X  = 0x0001;
     private static final int TRANSLATION_Y  = 0x0002;
-    private static final int SCALE_X        = 0x0004;
-    private static final int SCALE_Y        = 0x0008;
-    private static final int ROTATION       = 0x0010;
-    private static final int ROTATION_X     = 0x0020;
-    private static final int ROTATION_Y     = 0x0040;
-    private static final int X              = 0x0080;
-    private static final int Y              = 0x0100;
-    private static final int ALPHA          = 0x0200;
-    private static final int TRANSLATION_Z  = 0x0400;
+    private static final int TRANSLATION_Z  = 0x0004;
+    private static final int SCALE_X        = 0x0008;
+    private static final int SCALE_Y        = 0x0010;
+    private static final int ROTATION       = 0x0020;
+    private static final int ROTATION_X     = 0x0040;
+    private static final int ROTATION_Y     = 0x0080;
+    private static final int X              = 0x0100;
+    private static final int Y              = 0x0200;
+    private static final int ALPHA          = 0x0400;
 
     private static final int TRANSFORM_MASK = TRANSLATION_X | TRANSLATION_Y | TRANSLATION_Z |
             SCALE_X | SCALE_Y | ROTATION | ROTATION_X | ROTATION_Y | X | Y;
@@ -574,47 +574,56 @@ public class ViewPropertyAnimator {
     }
 
     /**
-     * @hide
+     * This method will cause the View's <code>translationY</code> property to be animated to the
+     * specified value. Animations already running on the property will be canceled.
+     *
+     * @param value The value to be animated to.
+     * @see View#setTranslationY(float)
+     * @return This object, allowing calls to methods in this class to be chained.
      */
-    public ViewPropertyAnimator translationZ(float value) {
-        animateProperty(TRANSLATION_Z, value);
+    public ViewPropertyAnimator translationY(float value) {
+        animateProperty(TRANSLATION_Y, value);
         return this;
     }
 
     /**
-     * @hide
+     * This method will cause the View's <code>translationY</code> property to be animated by the
+     * specified value. Animations already running on the property will be canceled.
+     *
+     * @param value The amount to be animated by, as an offset from the current value.
+     * @see View#setTranslationY(float)
+     * @return This object, allowing calls to methods in this class to be chained.
      */
-    public ViewPropertyAnimator translationZBy(float value) {
-        animatePropertyBy(TRANSLATION_Z, value);
+    public ViewPropertyAnimator translationYBy(float value) {
+        animatePropertyBy(TRANSLATION_Y, value);
         return this;
     }
 
     /**
-     * This method will cause the View's <code>translationY</code> property to be animated to the
+     * This method will cause the View's <code>translationZ</code> property to be animated to the
      * specified value. Animations already running on the property will be canceled.
      *
      * @param value The value to be animated to.
-     * @see View#setTranslationY(float)
+     * @see View#setTranslationZ(float)
      * @return This object, allowing calls to methods in this class to be chained.
      */
-    public ViewPropertyAnimator translationY(float value) {
-        animateProperty(TRANSLATION_Y, value);
+    public ViewPropertyAnimator translationZ(float value) {
+        animateProperty(TRANSLATION_Z, value);
         return this;
     }
 
     /**
-     * This method will cause the View's <code>translationY</code> property to be animated by the
+     * This method will cause the View's <code>translationZ</code> property to be animated by the
      * specified value. Animations already running on the property will be canceled.
      *
      * @param value The amount to be animated by, as an offset from the current value.
-     * @see View#setTranslationY(float)
+     * @see View#setTranslationZ(float)
      * @return This object, allowing calls to methods in this class to be chained.
      */
-    public ViewPropertyAnimator translationYBy(float value) {
-        animatePropertyBy(TRANSLATION_Y, value);
+    public ViewPropertyAnimator translationZBy(float value) {
+        animatePropertyBy(TRANSLATION_Z, value);
         return this;
     }
-
     /**
      * This method will cause the View's <code>scaleX</code> property to be animated to the
      * specified value. Animations already running on the property will be canceled.
index fc12ec4..a1f5ffc 100644 (file)
@@ -94,6 +94,11 @@ static void android_view_DisplayList_setClipToBounds(JNIEnv* env,
     displayList->setClipToBounds(clipToBounds);
 }
 
+static void android_view_DisplayList_setIsContainedVolume(JNIEnv* env,
+        jobject clazz, DisplayList* displayList, jboolean isContainedVolume) {
+    displayList->setIsContainedVolume(isContainedVolume);
+}
+
 static void android_view_DisplayList_setAlpha(JNIEnv* env,
         jobject clazz, DisplayList* displayList, float alpha) {
     displayList->setAlpha(alpha);
@@ -321,6 +326,7 @@ static JNINativeMethod gMethods[] = {
     { "nSetStaticMatrix",      "(II)V",  (void*) android_view_DisplayList_setStaticMatrix },
     { "nSetAnimationMatrix",   "(II)V",  (void*) android_view_DisplayList_setAnimationMatrix },
     { "nSetClipToBounds",      "(IZ)V",  (void*) android_view_DisplayList_setClipToBounds },
+    { "nSetIsContainedVolume", "(IZ)V",  (void*) android_view_DisplayList_setIsContainedVolume },
     { "nSetAlpha",             "(IF)V",  (void*) android_view_DisplayList_setAlpha },
     { "nSetHasOverlappingRendering", "(IZ)V",
             (void*) android_view_DisplayList_setHasOverlappingRendering },
index 5ba749a..0f812f1 100644 (file)
              property of the view, which is set by its layout. -->
         <attr name="translationX" format="dimension" />
 
-        <!-- translation in y of the view. This value is added post-layout to the left
+        <!-- translation in y of the view. This value is added post-layout to the top
              property of the view, which is set by its layout. -->
         <attr name="translationY" format="dimension" />
 
+        <!-- translation in z of the view. This value is added post-layout to its position. -->
+        <attr name="translationZ" format="dimension" />
+
         <!-- x location of the pivot point around which the view will rotate and scale.
              This xml attribute sets the pivotX property of the View. -->
         <attr name="transformPivotX" format="dimension" />
index f250428..a0d84c9 100644 (file)
   <public type="attr" name="fastScrollStyle" />
   <public type="attr" name="windowContentTransitions" />
   <public type="attr" name="windowContentTransitionManager" />
+  <public type="attr" name="translationZ" />
 
   <public type="style" name="Widget.Holo.FragmentBreadCrumbs" />
   <public type="style" name="Widget.Holo.Light.FragmentBreadCrumbs" />
index d2aa061..3853d31 100644 (file)
@@ -237,6 +237,7 @@ void DisplayList::init() {
     mRight = 0;
     mBottom = 0;
     mClipToBounds = true;
+    mIsContainedVolume = true;
     mAlpha = 1;
     mHasOverlappingRendering = true;
     mTranslationX = 0;
@@ -258,7 +259,6 @@ void DisplayList::init() {
     mHeight = 0;
     mPivotExplicitlySet = false;
     mCaching = false;
-    mIs3dRoot = true; // TODO: setter, java side impl
 }
 
 size_t DisplayList::getSize() {
@@ -531,7 +531,7 @@ void DisplayList::computeOrderingImpl(
     }
 
     m3dNodes.clear();
-    if (mIs3dRoot) {
+    if (mIsContainedVolume) {
         // create a new 3d space for children by separating their ordering
         compositedChildrenOf3dRoot = &m3dNodes;
         transformFrom3dRoot = &mat4::identity();
index 4bd79eb..9933d9d 100644 (file)
@@ -185,6 +185,10 @@ public:
         mClipToBounds = clipToBounds;
     }
 
+    void setIsContainedVolume(bool isContainedVolume) {
+        mIsContainedVolume = isContainedVolume;
+    }
+
     void setStaticMatrix(SkMatrix* matrix) {
         delete mStaticMatrix;
         mStaticMatrix = new SkMatrix(*matrix);
@@ -570,6 +574,7 @@ private:
 
     // View properties
     bool mClipToBounds;
+    bool mIsContainedVolume;
     float mAlpha;
     bool mHasOverlappingRendering;
     float mTranslationX, mTranslationY, mTranslationZ;
@@ -591,8 +596,6 @@ private:
     SkMatrix* mAnimationMatrix;
     Matrix4 mTransform;
     bool mCaching;
-    bool mIs3dRoot;
-
 
     /**
      * Draw time state - these properties are only set and used during rendering