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 
RenderNode(String name, View owningView)174     private RenderNode(String name, View owningView) {
175         mNativeRenderNode = nCreate(name);
176         mOwningView = owningView;
177     }
178 
179     /**
180      * @see RenderNode#adopt(long)
181      */
RenderNode(long nativePtr)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      */
create(String name, @Nullable View owningView)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      */
adopt(long nativePtr)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      */
start(int width, int height)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      */
end(DisplayListCanvas canvas)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      */
destroyDisplayListData()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      */
isValid()269     public boolean isValid() { return mValid; }
270 
getNativeDisplayList()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 
hasIdentityMatrix()282     public boolean hasIdentityMatrix() {
283         return nHasIdentityMatrix(mNativeRenderNode);
284     }
285 
getMatrix(@onNull Matrix outMatrix)286     public void getMatrix(@NonNull Matrix outMatrix) {
287         nGetTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
288     }
289 
getInverseMatrix(@onNull Matrix outMatrix)290     public void getInverseMatrix(@NonNull Matrix outMatrix) {
291         nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
292     }
293 
294     ///////////////////////////////////////////////////////////////////////////
295     // RenderProperty Setters
296     ///////////////////////////////////////////////////////////////////////////
297 
setLayerType(int layerType)298     public boolean setLayerType(int layerType) {
299         return nSetLayerType(mNativeRenderNode, layerType);
300     }
301 
setLayerPaint(Paint paint)302     public boolean setLayerPaint(Paint paint) {
303         return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.getNativeInstance() : 0);
304     }
305 
setClipBounds(@ullable Rect rect)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      */
setClipToBounds(boolean clipToBounds)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      */
setProjectBackwards(boolean shouldProject)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      */
setProjectionReceiver(boolean shouldRecieve)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      */
setOutline(Outline outline)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 
hasShadow()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      */
setClipToOutline(boolean clipToOutline)374     public boolean setClipToOutline(boolean clipToOutline) {
375         return nSetClipToOutline(mNativeRenderNode, clipToOutline);
376     }
377 
getClipToOutline()378     public boolean getClipToOutline() {
379         return nGetClipToOutline(mNativeRenderNode);
380     }
381 
382     /**
383      * Controls the RenderNode's circular reveal clip.
384      */
setRevealClip(boolean shouldClip, float x, float y, float radius)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      */
setStaticMatrix(Matrix matrix)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      */
setAnimationMatrix(Matrix matrix)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      */
setAlpha(float alpha)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      */
getAlpha()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      */
setHasOverlappingRendering(boolean hasOverlappingRendering)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      */
hasOverlappingRendering()458     public boolean hasOverlappingRendering() {
459         //noinspection SimplifiableIfStatement
460         return nHasOverlappingRendering(mNativeRenderNode);
461     }
462 
setElevation(float lift)463     public boolean setElevation(float lift) {
464         return nSetElevation(mNativeRenderNode, lift);
465     }
466 
getElevation()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      */
setTranslationX(float translationX)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      */
getTranslationX()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      */
setTranslationY(float translationY)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      */
getTranslationY()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      */
setTranslationZ(float translationZ)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      */
getTranslationZ()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      */
setRotation(float rotation)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      */
getRotation()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      */
setRotationX(float rotationX)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      */
getRotationX()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      */
setRotationY(float rotationY)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      */
getRotationY()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      */
setScaleX(float scaleX)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      */
getScaleX()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      */
setScaleY(float scaleY)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      */
getScaleY()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      */
setPivotX(float pivotX)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      */
getPivotX()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      */
setPivotY(float pivotY)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      */
getPivotY()675     public float getPivotY() {
676         return nGetPivotY(mNativeRenderNode);
677     }
678 
isPivotExplicitlySet()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      */
setCameraDistance(float distance)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      */
getCameraDistance()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      */
setLeft(int left)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      */
setTop(int top)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      */
setRight(int right)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      */
setBottom(int bottom)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      */
setLeftTopRightBottom(int left, int top, int right, int bottom)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      */
offsetLeftAndRight(int offset)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      */
offsetTopAndBottom(int offset)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      */
output()795     public void output() {
796         nOutput(mNativeRenderNode);
797     }
798 
799     /**
800      * Gets the size of the DisplayList for debug purposes.
801      */
getDebugSize()802     public int getDebugSize() {
803         return nGetDebugSize(mNativeRenderNode);
804     }
805 
806     ///////////////////////////////////////////////////////////////////////////
807     // Animations
808     ///////////////////////////////////////////////////////////////////////////
809 
addAnimator(RenderNodeAnimator animator)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 
endAllAnimators()818     public void endAllAnimators() {
819         nEndAllAnimators(mNativeRenderNode);
820     }
821 
822     ///////////////////////////////////////////////////////////////////////////
823     // Native methods
824     ///////////////////////////////////////////////////////////////////////////
825 
nCreate(String name)826     private static native long nCreate(String name);
nDestroyRenderNode(long renderNode)827     private static native void nDestroyRenderNode(long renderNode);
nSetDisplayListData(long renderNode, long newData)828     private static native void nSetDisplayListData(long renderNode, long newData);
829 
830     // Matrix
831 
nGetTransformMatrix(long renderNode, long nativeMatrix)832     private static native void nGetTransformMatrix(long renderNode, long nativeMatrix);
nGetInverseTransformMatrix(long renderNode, long nativeMatrix)833     private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix);
nHasIdentityMatrix(long renderNode)834     private static native boolean nHasIdentityMatrix(long renderNode);
835 
836     // Properties
837 
nOffsetTopAndBottom(long renderNode, int offset)838     private static native boolean nOffsetTopAndBottom(long renderNode, int offset);
nOffsetLeftAndRight(long renderNode, int offset)839     private static native boolean nOffsetLeftAndRight(long renderNode, int offset);
nSetLeftTopRightBottom(long renderNode, int left, int top, int right, int bottom)840     private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top,
841             int right, int bottom);
nSetBottom(long renderNode, int bottom)842     private static native boolean nSetBottom(long renderNode, int bottom);
nSetRight(long renderNode, int right)843     private static native boolean nSetRight(long renderNode, int right);
nSetTop(long renderNode, int top)844     private static native boolean nSetTop(long renderNode, int top);
nSetLeft(long renderNode, int left)845     private static native boolean nSetLeft(long renderNode, int left);
nSetCameraDistance(long renderNode, float distance)846     private static native boolean nSetCameraDistance(long renderNode, float distance);
nSetPivotY(long renderNode, float pivotY)847     private static native boolean nSetPivotY(long renderNode, float pivotY);
nSetPivotX(long renderNode, float pivotX)848     private static native boolean nSetPivotX(long renderNode, float pivotX);
nSetLayerType(long renderNode, int layerType)849     private static native boolean nSetLayerType(long renderNode, int layerType);
nSetLayerPaint(long renderNode, long paint)850     private static native boolean nSetLayerPaint(long renderNode, long paint);
nSetClipToBounds(long renderNode, boolean clipToBounds)851     private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds);
nSetClipBounds(long renderNode, int left, int top, int right, int bottom)852     private static native boolean nSetClipBounds(long renderNode, int left, int top,
853             int right, int bottom);
nSetClipBoundsEmpty(long renderNode)854     private static native boolean nSetClipBoundsEmpty(long renderNode);
nSetProjectBackwards(long renderNode, boolean shouldProject)855     private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject);
nSetProjectionReceiver(long renderNode, boolean shouldRecieve)856     private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve);
nSetOutlineRoundRect(long renderNode, int left, int top, int right, int bottom, float radius, float alpha)857     private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top,
858             int right, int bottom, float radius, float alpha);
nSetOutlineConvexPath(long renderNode, long nativePath, float alpha)859     private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath,
860             float alpha);
nSetOutlineEmpty(long renderNode)861     private static native boolean nSetOutlineEmpty(long renderNode);
nSetOutlineNone(long renderNode)862     private static native boolean nSetOutlineNone(long renderNode);
nHasShadow(long renderNode)863     private static native boolean nHasShadow(long renderNode);
nSetClipToOutline(long renderNode, boolean clipToOutline)864     private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline);
nSetRevealClip(long renderNode, boolean shouldClip, float x, float y, float radius)865     private static native boolean nSetRevealClip(long renderNode,
866             boolean shouldClip, float x, float y, float radius);
nSetAlpha(long renderNode, float alpha)867     private static native boolean nSetAlpha(long renderNode, float alpha);
nSetHasOverlappingRendering(long renderNode, boolean hasOverlappingRendering)868     private static native boolean nSetHasOverlappingRendering(long renderNode,
869             boolean hasOverlappingRendering);
nSetElevation(long renderNode, float lift)870     private static native boolean nSetElevation(long renderNode, float lift);
nSetTranslationX(long renderNode, float translationX)871     private static native boolean nSetTranslationX(long renderNode, float translationX);
nSetTranslationY(long renderNode, float translationY)872     private static native boolean nSetTranslationY(long renderNode, float translationY);
nSetTranslationZ(long renderNode, float translationZ)873     private static native boolean nSetTranslationZ(long renderNode, float translationZ);
nSetRotation(long renderNode, float rotation)874     private static native boolean nSetRotation(long renderNode, float rotation);
nSetRotationX(long renderNode, float rotationX)875     private static native boolean nSetRotationX(long renderNode, float rotationX);
nSetRotationY(long renderNode, float rotationY)876     private static native boolean nSetRotationY(long renderNode, float rotationY);
nSetScaleX(long renderNode, float scaleX)877     private static native boolean nSetScaleX(long renderNode, float scaleX);
nSetScaleY(long renderNode, float scaleY)878     private static native boolean nSetScaleY(long renderNode, float scaleY);
nSetStaticMatrix(long renderNode, long nativeMatrix)879     private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix);
nSetAnimationMatrix(long renderNode, long animationMatrix)880     private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix);
881 
nHasOverlappingRendering(long renderNode)882     private static native boolean nHasOverlappingRendering(long renderNode);
nGetClipToOutline(long renderNode)883     private static native boolean nGetClipToOutline(long renderNode);
nGetAlpha(long renderNode)884     private static native float nGetAlpha(long renderNode);
nGetCameraDistance(long renderNode)885     private static native float nGetCameraDistance(long renderNode);
nGetScaleX(long renderNode)886     private static native float nGetScaleX(long renderNode);
nGetScaleY(long renderNode)887     private static native float nGetScaleY(long renderNode);
nGetElevation(long renderNode)888     private static native float nGetElevation(long renderNode);
nGetTranslationX(long renderNode)889     private static native float nGetTranslationX(long renderNode);
nGetTranslationY(long renderNode)890     private static native float nGetTranslationY(long renderNode);
nGetTranslationZ(long renderNode)891     private static native float nGetTranslationZ(long renderNode);
nGetRotation(long renderNode)892     private static native float nGetRotation(long renderNode);
nGetRotationX(long renderNode)893     private static native float nGetRotationX(long renderNode);
nGetRotationY(long renderNode)894     private static native float nGetRotationY(long renderNode);
nIsPivotExplicitlySet(long renderNode)895     private static native boolean nIsPivotExplicitlySet(long renderNode);
nGetPivotX(long renderNode)896     private static native float nGetPivotX(long renderNode);
nGetPivotY(long renderNode)897     private static native float nGetPivotY(long renderNode);
nOutput(long renderNode)898     private static native void nOutput(long renderNode);
nGetDebugSize(long renderNode)899     private static native int nGetDebugSize(long renderNode);
900 
901     ///////////////////////////////////////////////////////////////////////////
902     // Animations
903     ///////////////////////////////////////////////////////////////////////////
904 
nAddAnimator(long renderNode, long animatorPtr)905     private static native void nAddAnimator(long renderNode, long animatorPtr);
nEndAllAnimators(long renderNode)906     private static native void nEndAllAnimators(long renderNode);
907 
908     ///////////////////////////////////////////////////////////////////////////
909     // Finalization
910     ///////////////////////////////////////////////////////////////////////////
911 
912     @Override
finalize()913     protected void finalize() throws Throwable {
914         try {
915             nDestroyRenderNode(mNativeRenderNode);
916         } finally {
917             super.finalize();
918         }
919     }
920 }
921