Home | History | Annotate | Download | only in view
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.view;
     18 
     19 import android.annotation.NonNull;
     20 import android.annotation.Nullable;
     21 import android.graphics.Matrix;
     22 import android.graphics.Outline;
     23 import android.graphics.Paint;
     24 import android.graphics.Rect;
     25 
     26 /**
     27  * <p>A display list records a series of graphics related operations and can replay
     28  * them later. Display lists are usually built by recording operations on a
     29  * {@link DisplayListCanvas}. Replaying the operations from a display list avoids
     30  * executing application code on every frame, and is thus much more efficient.</p>
     31  *
     32  * <p>Display lists are used internally for all views by default, and are not
     33  * typically used directly. One reason to consider using a display is a custom
     34  * {@link View} implementation that needs to issue a large number of drawing commands.
     35  * When the view invalidates, all the drawing commands must be reissued, even if
     36  * large portions of the drawing command stream stay the same frame to frame, which
     37  * can become a performance bottleneck. To solve this issue, a custom View might split
     38  * its content into several display lists. A display list is updated only when its
     39  * content, and only its content, needs to be updated.</p>
     40  *
     41  * <p>A text editor might for instance store each paragraph into its own display list.
     42  * Thus when the user inserts or removes characters, only the display list of the
     43  * affected paragraph needs to be recorded again.</p>
     44  *
     45  * <h3>Hardware acceleration</h3>
     46  * <p>Display lists can only be replayed using a {@link DisplayListCanvas}. They are not
     47  * supported in software. Always make sure that the {@link android.graphics.Canvas}
     48  * you are using to render a display list is hardware accelerated using
     49  * {@link android.graphics.Canvas#isHardwareAccelerated()}.</p>
     50  *
     51  * <h3>Creating a display list</h3>
     52  * <pre class="prettyprint">
     53  *     HardwareRenderer renderer = myView.getHardwareRenderer();
     54  *     if (renderer != null) {
     55  *         DisplayList displayList = renderer.createDisplayList();
     56  *         DisplayListCanvas canvas = displayList.start(width, height);
     57  *         try {
     58  *             // Draw onto the canvas
     59  *             // For instance: canvas.drawBitmap(...);
     60  *         } finally {
     61  *             displayList.end();
     62  *         }
     63  *     }
     64  * </pre>
     65  *
     66  * <h3>Rendering a display list on a View</h3>
     67  * <pre class="prettyprint">
     68  *     protected void onDraw(Canvas canvas) {
     69  *         if (canvas.isHardwareAccelerated()) {
     70  *             DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
     71  *             displayListCanvas.drawDisplayList(mDisplayList);
     72  *         }
     73  *     }
     74  * </pre>
     75  *
     76  * <h3>Releasing resources</h3>
     77  * <p>This step is not mandatory but recommended if you want to release resources
     78  * held by a display list as soon as possible.</p>
     79  * <pre class="prettyprint">
     80  *     // Mark this display list invalid, it cannot be used for drawing anymore,
     81  *     // and release resources held by this display list
     82  *     displayList.clear();
     83  * </pre>
     84  *
     85  * <h3>Properties</h3>
     86  * <p>In addition, a display list offers several properties, such as
     87  * {@link #setScaleX(float)} or {@link #setLeft(int)}, that can be used to affect all
     88  * the drawing commands recorded within. For instance, these properties can be used
     89  * to move around a large number of images without re-issuing all the individual
     90  * <code>drawBitmap()</code> calls.</p>
     91  *
     92  * <pre class="prettyprint">
     93  *     private void createDisplayList() {
     94  *         mDisplayList = DisplayList.create("MyDisplayList");
     95  *         DisplayListCanvas canvas = mDisplayList.start(width, height);
     96  *         try {
     97  *             for (Bitmap b : mBitmaps) {
     98  *                 canvas.drawBitmap(b, 0.0f, 0.0f, null);
     99  *                 canvas.translate(0.0f, b.getHeight());
    100  *             }
    101  *         } finally {
    102  *             displayList.end();
    103  *         }
    104  *     }
    105  *
    106  *     protected void onDraw(Canvas canvas) {
    107  *         if (canvas.isHardwareAccelerated()) {
    108  *             DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
    109  *             displayListCanvas.drawDisplayList(mDisplayList);
    110  *         }
    111  *     }
    112  *
    113  *     private void moveContentBy(int x) {
    114  *          // This will move all the bitmaps recorded inside the display list
    115  *          // by x pixels to the right and redraw this view. All the commands
    116  *          // recorded in createDisplayList() won't be re-issued, only onDraw()
    117  *          // will be invoked and will execute very quickly
    118  *          mDisplayList.offsetLeftAndRight(x);
    119  *          invalidate();
    120  *     }
    121  * </pre>
    122  *
    123  * <h3>Threading</h3>
    124  * <p>Display lists must be created on and manipulated from the UI thread only.</p>
    125  *
    126  * @hide
    127  */
    128 public class RenderNode {
    129     /**
    130      * Flag used when calling
    131      * {@link DisplayListCanvas#drawRenderNode
    132      * When this flag is set, draw operations lying outside of the bounds of the
    133      * display list will be culled early. It is recommeneded to always set this
    134      * flag.
    135      */
    136     public static final int FLAG_CLIP_CHILDREN = 0x1;
    137 
    138     // NOTE: The STATUS_* values *must* match the enum in DrawGlInfo.h
    139 
    140     /**
    141      * Indicates that the display list is done drawing.
    142      *
    143      * @see DisplayListCanvas#drawRenderNode(RenderNode, int)
    144      */
    145     public static final int STATUS_DONE = 0x0;
    146 
    147     /**
    148      * Indicates that the display list needs another drawing pass.
    149      *
    150      * @see DisplayListCanvas#drawRenderNode(RenderNode, int)
    151      */
    152     public static final int STATUS_DRAW = 0x1;
    153 
    154     /**
    155      * Indicates that the display list needs to re-execute its GL functors.
    156      *
    157      * @see DisplayListCanvas#drawRenderNode(RenderNode, int)
    158      * @see DisplayListCanvas#callDrawGLFunction2(long)
    159      */
    160     public static final int STATUS_INVOKE = 0x2;
    161 
    162     /**
    163      * Indicates that the display list performed GL drawing operations.
    164      *
    165      * @see DisplayListCanvas#drawRenderNode(RenderNode, int)
    166      */
    167     public static final int STATUS_DREW = 0x4;
    168 
    169     private boolean mValid;
    170     // Do not access directly unless you are ThreadedRenderer
    171     final long mNativeRenderNode;
    172     private final View mOwningView;
    173 
    174     private RenderNode(String name, View owningView) {
    175         mNativeRenderNode = nCreate(name);
    176         mOwningView = owningView;
    177     }
    178 
    179     /**
    180      * @see RenderNode#adopt(long)
    181      */
    182     private RenderNode(long nativePtr) {
    183         mNativeRenderNode = nativePtr;
    184         mOwningView = null;
    185     }
    186 
    187     /**
    188      * Creates a new RenderNode that can be used to record batches of
    189      * drawing operations, and store / apply render properties when drawn.
    190      *
    191      * @param name The name of the RenderNode, used for debugging purpose. May be null.
    192      *
    193      * @return A new RenderNode.
    194      */
    195     public static RenderNode create(String name, @Nullable View owningView) {
    196         return new RenderNode(name, owningView);
    197     }
    198 
    199     /**
    200      * Adopts an existing native render node.
    201      *
    202      * Note: This will *NOT* incRef() on the native object, however it will
    203      * decRef() when it is destroyed. The caller should have already incRef'd it
    204      */
    205     public static RenderNode adopt(long nativePtr) {
    206         return new RenderNode(nativePtr);
    207     }
    208 
    209 
    210     /**
    211      * Starts recording a display list for the render node. All
    212      * operations performed on the returned canvas are recorded and
    213      * stored in this display list.
    214      *
    215      * Calling this method will mark the render node invalid until
    216      * {@link #end(DisplayListCanvas)} is called.
    217      * Only valid render nodes can be replayed.
    218      *
    219      * @param width The width of the recording viewport
    220      * @param height The height of the recording viewport
    221      *
    222      * @return A canvas to record drawing operations.
    223      *
    224      * @see #end(DisplayListCanvas)
    225      * @see #isValid()
    226      */
    227     public DisplayListCanvas start(int width, int height) {
    228         DisplayListCanvas canvas = DisplayListCanvas.obtain(this);
    229         canvas.setViewport(width, height);
    230         // The dirty rect should always be null for a display list
    231         canvas.onPreDraw(null);
    232         return canvas;
    233     }
    234 
    235     /**
    236      * Ends the recording for this display list. A display list cannot be
    237      * replayed if recording is not finished. Calling this method marks
    238      * the display list valid and {@link #isValid()} will return true.
    239      *
    240      * @see #start(int, int)
    241      * @see #isValid()
    242      */
    243     public void end(DisplayListCanvas canvas) {
    244         canvas.onPostDraw();
    245         long renderNodeData = canvas.finishRecording();
    246         nSetDisplayListData(mNativeRenderNode, renderNodeData);
    247         canvas.recycle();
    248         mValid = true;
    249     }
    250 
    251     /**
    252      * Reset native resources. This is called when cleaning up the state of display lists
    253      * during destruction of hardware resources, to ensure that we do not hold onto
    254      * obsolete resources after related resources are gone.
    255      */
    256     public void destroyDisplayListData() {
    257         if (!mValid) return;
    258 
    259         nSetDisplayListData(mNativeRenderNode, 0);
    260         mValid = false;
    261     }
    262 
    263     /**
    264      * Returns whether the RenderNode's display list content is currently usable.
    265      * If this returns false, the display list should be re-recorded prior to replaying it.
    266      *
    267      * @return boolean true if the display list is able to be replayed, false otherwise.
    268      */
    269     public boolean isValid() { return mValid; }
    270 
    271     long getNativeDisplayList() {
    272         if (!mValid) {
    273             throw new IllegalStateException("The display list is not valid.");
    274         }
    275         return mNativeRenderNode;
    276     }
    277 
    278     ///////////////////////////////////////////////////////////////////////////
    279     // Matrix manipulation
    280     ///////////////////////////////////////////////////////////////////////////
    281 
    282     public boolean hasIdentityMatrix() {
    283         return nHasIdentityMatrix(mNativeRenderNode);
    284     }
    285 
    286     public void getMatrix(@NonNull Matrix outMatrix) {
    287         nGetTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
    288     }
    289 
    290     public void getInverseMatrix(@NonNull Matrix outMatrix) {
    291         nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
    292     }
    293 
    294     ///////////////////////////////////////////////////////////////////////////
    295     // RenderProperty Setters
    296     ///////////////////////////////////////////////////////////////////////////
    297 
    298     public boolean setLayerType(int layerType) {
    299         return nSetLayerType(mNativeRenderNode, layerType);
    300     }
    301 
    302     public boolean setLayerPaint(Paint paint) {
    303         return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.getNativeInstance() : 0);
    304     }
    305 
    306     public boolean setClipBounds(@Nullable Rect rect) {
    307         if (rect == null) {
    308             return nSetClipBoundsEmpty(mNativeRenderNode);
    309         } else {
    310             return nSetClipBounds(mNativeRenderNode, rect.left, rect.top, rect.right, rect.bottom);
    311         }
    312     }
    313 
    314     /**
    315      * Set whether the Render node should clip itself to its bounds. This property is controlled by
    316      * the view's parent.
    317      *
    318      * @param clipToBounds true if the display list should clip to its bounds
    319      */
    320     public boolean setClipToBounds(boolean clipToBounds) {
    321         return nSetClipToBounds(mNativeRenderNode, clipToBounds);
    322     }
    323 
    324     /**
    325      * Sets whether the display list should be drawn immediately after the
    326      * closest ancestor display list containing a projection receiver.
    327      *
    328      * @param shouldProject true if the display list should be projected onto a
    329      *            containing volume.
    330      */
    331     public boolean setProjectBackwards(boolean shouldProject) {
    332         return nSetProjectBackwards(mNativeRenderNode, shouldProject);
    333     }
    334 
    335     /**
    336      * Sets whether the display list is a projection receiver - that its parent
    337      * DisplayList should draw any descendent DisplayLists with
    338      * ProjectBackwards=true directly on top of it. Default value is false.
    339      */
    340     public boolean setProjectionReceiver(boolean shouldRecieve) {
    341         return nSetProjectionReceiver(mNativeRenderNode, shouldRecieve);
    342     }
    343 
    344     /**
    345      * Sets the outline, defining the shape that casts a shadow, and the path to
    346      * be clipped if setClipToOutline is set.
    347      *
    348      * Deep copies the data into native to simplify reference ownership.
    349      */
    350     public boolean setOutline(Outline outline) {
    351         if (outline == null) {
    352             return nSetOutlineNone(mNativeRenderNode);
    353         } else if (outline.isEmpty()) {
    354             return nSetOutlineEmpty(mNativeRenderNode);
    355         } else if (outline.mRect != null) {
    356             return nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top,
    357                     outline.mRect.right, outline.mRect.bottom, outline.mRadius, outline.mAlpha);
    358         } else if (outline.mPath != null) {
    359             return nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath,
    360                     outline.mAlpha);
    361         }
    362         throw new IllegalArgumentException("Unrecognized outline?");
    363     }
    364 
    365     public boolean hasShadow() {
    366         return nHasShadow(mNativeRenderNode);
    367     }
    368 
    369     /**
    370      * Enables or disables clipping to the outline.
    371      *
    372      * @param clipToOutline true if clipping to the outline.
    373      */
    374     public boolean setClipToOutline(boolean clipToOutline) {
    375         return nSetClipToOutline(mNativeRenderNode, clipToOutline);
    376     }
    377 
    378     public boolean getClipToOutline() {
    379         return nGetClipToOutline(mNativeRenderNode);
    380     }
    381 
    382     /**
    383      * Controls the RenderNode's circular reveal clip.
    384      */
    385     public boolean setRevealClip(boolean shouldClip,
    386             float x, float y, float radius) {
    387         return nSetRevealClip(mNativeRenderNode, shouldClip, x, y, radius);
    388     }
    389 
    390     /**
    391      * Set the static matrix on the display list. The specified matrix is combined with other
    392      * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
    393      *
    394      * @param matrix A transform matrix to apply to this display list
    395      */
    396     public boolean setStaticMatrix(Matrix matrix) {
    397         return nSetStaticMatrix(mNativeRenderNode, matrix.native_instance);
    398     }
    399 
    400     /**
    401      * Set the Animation matrix on the display list. This matrix exists if an Animation is
    402      * currently playing on a View, and is set on the display list during at draw() time. When
    403      * the Animation finishes, the matrix should be cleared by sending <code>null</code>
    404      * for the matrix parameter.
    405      *
    406      * @param matrix The matrix, null indicates that the matrix should be cleared.
    407      */
    408     public boolean setAnimationMatrix(Matrix matrix) {
    409         return nSetAnimationMatrix(mNativeRenderNode,
    410                 (matrix != null) ? matrix.native_instance : 0);
    411     }
    412 
    413     /**
    414      * Sets the translucency level for the display list.
    415      *
    416      * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
    417      *
    418      * @see View#setAlpha(float)
    419      * @see #getAlpha()
    420      */
    421     public boolean setAlpha(float alpha) {
    422         return nSetAlpha(mNativeRenderNode, alpha);
    423     }
    424 
    425     /**
    426      * Returns the translucency level of this display list.
    427      *
    428      * @return A value between 0.0f and 1.0f
    429      *
    430      * @see #setAlpha(float)
    431      */
    432     public float getAlpha() {
    433         return nGetAlpha(mNativeRenderNode);
    434     }
    435 
    436     /**
    437      * Sets whether the display list renders content which overlaps. Non-overlapping rendering
    438      * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default
    439      * display lists consider they do not have overlapping content.
    440      *
    441      * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping,
    442      *                                true otherwise.
    443      *
    444      * @see android.view.View#hasOverlappingRendering()
    445      * @see #hasOverlappingRendering()
    446      */
    447     public boolean setHasOverlappingRendering(boolean hasOverlappingRendering) {
    448         return nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering);
    449     }
    450 
    451     /**
    452      * Indicates whether the content of this display list overlaps.
    453      *
    454      * @return True if this display list renders content which overlaps, false otherwise.
    455      *
    456      * @see #setHasOverlappingRendering(boolean)
    457      */
    458     public boolean hasOverlappingRendering() {
    459         //noinspection SimplifiableIfStatement
    460         return nHasOverlappingRendering(mNativeRenderNode);
    461     }
    462 
    463     public boolean setElevation(float lift) {
    464         return nSetElevation(mNativeRenderNode, lift);
    465     }
    466 
    467     public float getElevation() {
    468         return nGetElevation(mNativeRenderNode);
    469     }
    470 
    471     /**
    472      * Sets the translation value for the display list on the X axis.
    473      *
    474      * @param translationX The X axis translation value of the display list, in pixels
    475      *
    476      * @see View#setTranslationX(float)
    477      * @see #getTranslationX()
    478      */
    479     public boolean setTranslationX(float translationX) {
    480         return nSetTranslationX(mNativeRenderNode, translationX);
    481     }
    482 
    483     /**
    484      * Returns the translation value for this display list on the X axis, in pixels.
    485      *
    486      * @see #setTranslationX(float)
    487      */
    488     public float getTranslationX() {
    489         return nGetTranslationX(mNativeRenderNode);
    490     }
    491 
    492     /**
    493      * Sets the translation value for the display list on the Y axis.
    494      *
    495      * @param translationY The Y axis translation value of the display list, in pixels
    496      *
    497      * @see View#setTranslationY(float)
    498      * @see #getTranslationY()
    499      */
    500     public boolean setTranslationY(float translationY) {
    501         return nSetTranslationY(mNativeRenderNode, translationY);
    502     }
    503 
    504     /**
    505      * Returns the translation value for this display list on the Y axis, in pixels.
    506      *
    507      * @see #setTranslationY(float)
    508      */
    509     public float getTranslationY() {
    510         return nGetTranslationY(mNativeRenderNode);
    511     }
    512 
    513     /**
    514      * Sets the translation value for the display list on the Z axis.
    515      *
    516      * @see View#setTranslationZ(float)
    517      * @see #getTranslationZ()
    518      */
    519     public boolean setTranslationZ(float translationZ) {
    520         return nSetTranslationZ(mNativeRenderNode, translationZ);
    521     }
    522 
    523     /**
    524      * Returns the translation value for this display list on the Z axis.
    525      *
    526      * @see #setTranslationZ(float)
    527      */
    528     public float getTranslationZ() {
    529         return nGetTranslationZ(mNativeRenderNode);
    530     }
    531 
    532     /**
    533      * Sets the rotation value for the display list around the Z axis.
    534      *
    535      * @param rotation The rotation value of the display list, in degrees
    536      *
    537      * @see View#setRotation(float)
    538      * @see #getRotation()
    539      */
    540     public boolean setRotation(float rotation) {
    541         return nSetRotation(mNativeRenderNode, rotation);
    542     }
    543 
    544     /**
    545      * Returns the rotation value for this display list around the Z axis, in degrees.
    546      *
    547      * @see #setRotation(float)
    548      */
    549     public float getRotation() {
    550         return nGetRotation(mNativeRenderNode);
    551     }
    552 
    553     /**
    554      * Sets the rotation value for the display list around the X axis.
    555      *
    556      * @param rotationX The rotation value of the display list, in degrees
    557      *
    558      * @see View#setRotationX(float)
    559      * @see #getRotationX()
    560      */
    561     public boolean setRotationX(float rotationX) {
    562         return nSetRotationX(mNativeRenderNode, rotationX);
    563     }
    564 
    565     /**
    566      * Returns the rotation value for this display list around the X axis, in degrees.
    567      *
    568      * @see #setRotationX(float)
    569      */
    570     public float getRotationX() {
    571         return nGetRotationX(mNativeRenderNode);
    572     }
    573 
    574     /**
    575      * Sets the rotation value for the display list around the Y axis.
    576      *
    577      * @param rotationY The rotation value of the display list, in degrees
    578      *
    579      * @see View#setRotationY(float)
    580      * @see #getRotationY()
    581      */
    582     public boolean setRotationY(float rotationY) {
    583         return nSetRotationY(mNativeRenderNode, rotationY);
    584     }
    585 
    586     /**
    587      * Returns the rotation value for this display list around the Y axis, in degrees.
    588      *
    589      * @see #setRotationY(float)
    590      */
    591     public float getRotationY() {
    592         return nGetRotationY(mNativeRenderNode);
    593     }
    594 
    595     /**
    596      * Sets the scale value for the display list on the X axis.
    597      *
    598      * @param scaleX The scale value of the display list
    599      *
    600      * @see View#setScaleX(float)
    601      * @see #getScaleX()
    602      */
    603     public boolean setScaleX(float scaleX) {
    604         return nSetScaleX(mNativeRenderNode, scaleX);
    605     }
    606 
    607     /**
    608      * Returns the scale value for this display list on the X axis.
    609      *
    610      * @see #setScaleX(float)
    611      */
    612     public float getScaleX() {
    613         return nGetScaleX(mNativeRenderNode);
    614     }
    615 
    616     /**
    617      * Sets the scale value for the display list on the Y axis.
    618      *
    619      * @param scaleY The scale value of the display list
    620      *
    621      * @see View#setScaleY(float)
    622      * @see #getScaleY()
    623      */
    624     public boolean setScaleY(float scaleY) {
    625         return nSetScaleY(mNativeRenderNode, scaleY);
    626     }
    627 
    628     /**
    629      * Returns the scale value for this display list on the Y axis.
    630      *
    631      * @see #setScaleY(float)
    632      */
    633     public float getScaleY() {
    634         return nGetScaleY(mNativeRenderNode);
    635     }
    636 
    637     /**
    638      * Sets the pivot value for the display list on the X axis
    639      *
    640      * @param pivotX The pivot value of the display list on the X axis, in pixels
    641      *
    642      * @see View#setPivotX(float)
    643      * @see #getPivotX()
    644      */
    645     public boolean setPivotX(float pivotX) {
    646         return nSetPivotX(mNativeRenderNode, pivotX);
    647     }
    648 
    649     /**
    650      * Returns the pivot value for this display list on the X axis, in pixels.
    651      *
    652      * @see #setPivotX(float)
    653      */
    654     public float getPivotX() {
    655         return nGetPivotX(mNativeRenderNode);
    656     }
    657 
    658     /**
    659      * Sets the pivot value for the display list on the Y axis
    660      *
    661      * @param pivotY The pivot value of the display list on the Y axis, in pixels
    662      *
    663      * @see View#setPivotY(float)
    664      * @see #getPivotY()
    665      */
    666     public boolean setPivotY(float pivotY) {
    667         return nSetPivotY(mNativeRenderNode, pivotY);
    668     }
    669 
    670     /**
    671      * Returns the pivot value for this display list on the Y axis, in pixels.
    672      *
    673      * @see #setPivotY(float)
    674      */
    675     public float getPivotY() {
    676         return nGetPivotY(mNativeRenderNode);
    677     }
    678 
    679     public boolean isPivotExplicitlySet() {
    680         return nIsPivotExplicitlySet(mNativeRenderNode);
    681     }
    682 
    683     /**
    684      * Sets the camera distance for the display list. Refer to
    685      * {@link View#setCameraDistance(float)} for more information on how to
    686      * use this property.
    687      *
    688      * @param distance The distance in Z of the camera of the display list
    689      *
    690      * @see View#setCameraDistance(float)
    691      * @see #getCameraDistance()
    692      */
    693     public boolean setCameraDistance(float distance) {
    694         return nSetCameraDistance(mNativeRenderNode, distance);
    695     }
    696 
    697     /**
    698      * Returns the distance in Z of the camera of the display list.
    699      *
    700      * @see #setCameraDistance(float)
    701      */
    702     public float getCameraDistance() {
    703         return nGetCameraDistance(mNativeRenderNode);
    704     }
    705 
    706     /**
    707      * Sets the left position for the display list.
    708      *
    709      * @param left The left position, in pixels, of the display list
    710      *
    711      * @see View#setLeft(int)
    712      */
    713     public boolean setLeft(int left) {
    714         return nSetLeft(mNativeRenderNode, left);
    715     }
    716 
    717     /**
    718      * Sets the top position for the display list.
    719      *
    720      * @param top The top position, in pixels, of the display list
    721      *
    722      * @see View#setTop(int)
    723      */
    724     public boolean setTop(int top) {
    725         return nSetTop(mNativeRenderNode, top);
    726     }
    727 
    728     /**
    729      * Sets the right position for the display list.
    730      *
    731      * @param right The right position, in pixels, of the display list
    732      *
    733      * @see View#setRight(int)
    734      */
    735     public boolean setRight(int right) {
    736         return nSetRight(mNativeRenderNode, right);
    737     }
    738 
    739     /**
    740      * Sets the bottom position for the display list.
    741      *
    742      * @param bottom The bottom position, in pixels, of the display list
    743      *
    744      * @see View#setBottom(int)
    745      */
    746     public boolean setBottom(int bottom) {
    747         return nSetBottom(mNativeRenderNode, bottom);
    748     }
    749 
    750     /**
    751      * Sets the left and top positions for the display list
    752      *
    753      * @param left The left position of the display list, in pixels
    754      * @param top The top position of the display list, in pixels
    755      * @param right The right position of the display list, in pixels
    756      * @param bottom The bottom position of the display list, in pixels
    757      *
    758      * @see View#setLeft(int)
    759      * @see View#setTop(int)
    760      * @see View#setRight(int)
    761      * @see View#setBottom(int)
    762      */
    763     public boolean setLeftTopRightBottom(int left, int top, int right, int bottom) {
    764         return nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom);
    765     }
    766 
    767     /**
    768      * Offsets the left and right positions for the display list
    769      *
    770      * @param offset The amount that the left and right positions of the display
    771      *               list are offset, in pixels
    772      *
    773      * @see View#offsetLeftAndRight(int)
    774      */
    775     public boolean offsetLeftAndRight(int offset) {
    776         return nOffsetLeftAndRight(mNativeRenderNode, offset);
    777     }
    778 
    779     /**
    780      * Offsets the top and bottom values for the display list
    781      *
    782      * @param offset The amount that the top and bottom positions of the display
    783      *               list are offset, in pixels
    784      *
    785      * @see View#offsetTopAndBottom(int)
    786      */
    787     public boolean offsetTopAndBottom(int offset) {
    788         return nOffsetTopAndBottom(mNativeRenderNode, offset);
    789     }
    790 
    791     /**
    792      * Outputs the display list to the log. This method exists for use by
    793      * tools to output display lists for selected nodes to the log.
    794      */
    795     public void output() {
    796         nOutput(mNativeRenderNode);
    797     }
    798 
    799     /**
    800      * Gets the size of the DisplayList for debug purposes.
    801      */
    802     public int getDebugSize() {
    803         return nGetDebugSize(mNativeRenderNode);
    804     }
    805 
    806     ///////////////////////////////////////////////////////////////////////////
    807     // Animations
    808     ///////////////////////////////////////////////////////////////////////////
    809 
    810     public void addAnimator(RenderNodeAnimator animator) {
    811         if (mOwningView == null || mOwningView.mAttachInfo == null) {
    812             throw new IllegalStateException("Cannot start this animator on a detached view!");
    813         }
    814         nAddAnimator(mNativeRenderNode, animator.getNativeAnimator());
    815         mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this);
    816     }
    817 
    818     public void endAllAnimators() {
    819         nEndAllAnimators(mNativeRenderNode);
    820     }
    821 
    822     ///////////////////////////////////////////////////////////////////////////
    823     // Native methods
    824     ///////////////////////////////////////////////////////////////////////////
    825 
    826     private static native long nCreate(String name);
    827     private static native void nDestroyRenderNode(long renderNode);
    828     private static native void nSetDisplayListData(long renderNode, long newData);
    829 
    830     // Matrix
    831 
    832     private static native void nGetTransformMatrix(long renderNode, long nativeMatrix);
    833     private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix);
    834     private static native boolean nHasIdentityMatrix(long renderNode);
    835 
    836     // Properties
    837 
    838     private static native boolean nOffsetTopAndBottom(long renderNode, int offset);
    839     private static native boolean nOffsetLeftAndRight(long renderNode, int offset);
    840     private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top,
    841             int right, int bottom);
    842     private static native boolean nSetBottom(long renderNode, int bottom);
    843     private static native boolean nSetRight(long renderNode, int right);
    844     private static native boolean nSetTop(long renderNode, int top);
    845     private static native boolean nSetLeft(long renderNode, int left);
    846     private static native boolean nSetCameraDistance(long renderNode, float distance);
    847     private static native boolean nSetPivotY(long renderNode, float pivotY);
    848     private static native boolean nSetPivotX(long renderNode, float pivotX);
    849     private static native boolean nSetLayerType(long renderNode, int layerType);
    850     private static native boolean nSetLayerPaint(long renderNode, long paint);
    851     private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds);
    852     private static native boolean nSetClipBounds(long renderNode, int left, int top,
    853             int right, int bottom);
    854     private static native boolean nSetClipBoundsEmpty(long renderNode);
    855     private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject);
    856     private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve);
    857     private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top,
    858             int right, int bottom, float radius, float alpha);
    859     private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath,
    860             float alpha);
    861     private static native boolean nSetOutlineEmpty(long renderNode);
    862     private static native boolean nSetOutlineNone(long renderNode);
    863     private static native boolean nHasShadow(long renderNode);
    864     private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline);
    865     private static native boolean nSetRevealClip(long renderNode,
    866             boolean shouldClip, float x, float y, float radius);
    867     private static native boolean nSetAlpha(long renderNode, float alpha);
    868     private static native boolean nSetHasOverlappingRendering(long renderNode,
    869             boolean hasOverlappingRendering);
    870     private static native boolean nSetElevation(long renderNode, float lift);
    871     private static native boolean nSetTranslationX(long renderNode, float translationX);
    872     private static native boolean nSetTranslationY(long renderNode, float translationY);
    873     private static native boolean nSetTranslationZ(long renderNode, float translationZ);
    874     private static native boolean nSetRotation(long renderNode, float rotation);
    875     private static native boolean nSetRotationX(long renderNode, float rotationX);
    876     private static native boolean nSetRotationY(long renderNode, float rotationY);
    877     private static native boolean nSetScaleX(long renderNode, float scaleX);
    878     private static native boolean nSetScaleY(long renderNode, float scaleY);
    879     private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix);
    880     private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix);
    881 
    882     private static native boolean nHasOverlappingRendering(long renderNode);
    883     private static native boolean nGetClipToOutline(long renderNode);
    884     private static native float nGetAlpha(long renderNode);
    885     private static native float nGetCameraDistance(long renderNode);
    886     private static native float nGetScaleX(long renderNode);
    887     private static native float nGetScaleY(long renderNode);
    888     private static native float nGetElevation(long renderNode);
    889     private static native float nGetTranslationX(long renderNode);
    890     private static native float nGetTranslationY(long renderNode);
    891     private static native float nGetTranslationZ(long renderNode);
    892     private static native float nGetRotation(long renderNode);
    893     private static native float nGetRotationX(long renderNode);
    894     private static native float nGetRotationY(long renderNode);
    895     private static native boolean nIsPivotExplicitlySet(long renderNode);
    896     private static native float nGetPivotX(long renderNode);
    897     private static native float nGetPivotY(long renderNode);
    898     private static native void nOutput(long renderNode);
    899     private static native int nGetDebugSize(long renderNode);
    900 
    901     ///////////////////////////////////////////////////////////////////////////
    902     // Animations
    903     ///////////////////////////////////////////////////////////////////////////
    904 
    905     private static native void nAddAnimator(long renderNode, long animatorPtr);
    906     private static native void nEndAllAnimators(long renderNode);
    907 
    908     ///////////////////////////////////////////////////////////////////////////
    909     // Finalization
    910     ///////////////////////////////////////////////////////////////////////////
    911 
    912     @Override
    913     protected void finalize() throws Throwable {
    914         try {
    915             nDestroyRenderNode(mNativeRenderNode);
    916         } finally {
    917             super.finalize();
    918         }
    919     }
    920 }
    921