• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 HardwareCanvas}. 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 HardwareCanvas}. 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  *         HardwareCanvas 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  *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
71  *             hardwareCanvas.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  *         HardwareCanvas 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  *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
109  *             hardwareCanvas.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 HardwareCanvas#drawRenderNode(RenderNode, android.graphics.Rect, int)}
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 HardwareCanvas#drawRenderNode(RenderNode, android.graphics.Rect, 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 HardwareCanvas#drawRenderNode(RenderNode, android.graphics.Rect, 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 HardwareCanvas#drawRenderNode(RenderNode, android.graphics.Rect, int)
158      * @see HardwareCanvas#callDrawGLFunction(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 HardwareCanvas#drawRenderNode(RenderNode, android.graphics.Rect, 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(HardwareCanvas)} 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(HardwareCanvas)
225      * @see #isValid()
226      */
start(int width, int height)227     public HardwareCanvas start(int width, int height) {
228         HardwareCanvas canvas = GLES20RecordingCanvas.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(HardwareCanvas endCanvas)243     public void end(HardwareCanvas endCanvas) {
244         if (!(endCanvas instanceof GLES20RecordingCanvas)) {
245             throw new IllegalArgumentException("Passed an invalid canvas to end!");
246         }
247 
248         GLES20RecordingCanvas canvas = (GLES20RecordingCanvas) endCanvas;
249         canvas.onPostDraw();
250         long renderNodeData = canvas.finishRecording();
251         nSetDisplayListData(mNativeRenderNode, renderNodeData);
252         canvas.recycle();
253         mValid = true;
254     }
255 
256     /**
257      * Reset native resources. This is called when cleaning up the state of display lists
258      * during destruction of hardware resources, to ensure that we do not hold onto
259      * obsolete resources after related resources are gone.
260      */
destroyDisplayListData()261     public void destroyDisplayListData() {
262         if (!mValid) return;
263 
264         nSetDisplayListData(mNativeRenderNode, 0);
265         mValid = false;
266     }
267 
268     /**
269      * Returns whether the RenderNode's display list content is currently usable.
270      * If this returns false, the display list should be re-recorded prior to replaying it.
271      *
272      * @return boolean true if the display list is able to be replayed, false otherwise.
273      */
isValid()274     public boolean isValid() { return mValid; }
275 
getNativeDisplayList()276     long getNativeDisplayList() {
277         if (!mValid) {
278             throw new IllegalStateException("The display list is not valid.");
279         }
280         return mNativeRenderNode;
281     }
282 
283     ///////////////////////////////////////////////////////////////////////////
284     // Matrix manipulation
285     ///////////////////////////////////////////////////////////////////////////
286 
hasIdentityMatrix()287     public boolean hasIdentityMatrix() {
288         return nHasIdentityMatrix(mNativeRenderNode);
289     }
290 
getMatrix(@onNull Matrix outMatrix)291     public void getMatrix(@NonNull Matrix outMatrix) {
292         nGetTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
293     }
294 
getInverseMatrix(@onNull Matrix outMatrix)295     public void getInverseMatrix(@NonNull Matrix outMatrix) {
296         nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
297     }
298 
299     ///////////////////////////////////////////////////////////////////////////
300     // RenderProperty Setters
301     ///////////////////////////////////////////////////////////////////////////
302 
setLayerType(int layerType)303     public boolean setLayerType(int layerType) {
304         return nSetLayerType(mNativeRenderNode, layerType);
305     }
306 
setLayerPaint(Paint paint)307     public boolean setLayerPaint(Paint paint) {
308         return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.mNativePaint : 0);
309     }
310 
setClipBounds(@ullable Rect rect)311     public boolean setClipBounds(@Nullable Rect rect) {
312         if (rect == null) {
313             return nSetClipBoundsEmpty(mNativeRenderNode);
314         } else {
315             return nSetClipBounds(mNativeRenderNode, rect.left, rect.top, rect.right, rect.bottom);
316         }
317     }
318 
319     /**
320      * Set whether the Render node should clip itself to its bounds. This property is controlled by
321      * the view's parent.
322      *
323      * @param clipToBounds true if the display list should clip to its bounds
324      */
setClipToBounds(boolean clipToBounds)325     public boolean setClipToBounds(boolean clipToBounds) {
326         return nSetClipToBounds(mNativeRenderNode, clipToBounds);
327     }
328 
329     /**
330      * Sets whether the display list should be drawn immediately after the
331      * closest ancestor display list containing a projection receiver.
332      *
333      * @param shouldProject true if the display list should be projected onto a
334      *            containing volume.
335      */
setProjectBackwards(boolean shouldProject)336     public boolean setProjectBackwards(boolean shouldProject) {
337         return nSetProjectBackwards(mNativeRenderNode, shouldProject);
338     }
339 
340     /**
341      * Sets whether the display list is a projection receiver - that its parent
342      * DisplayList should draw any descendent DisplayLists with
343      * ProjectBackwards=true directly on top of it. Default value is false.
344      */
setProjectionReceiver(boolean shouldRecieve)345     public boolean setProjectionReceiver(boolean shouldRecieve) {
346         return nSetProjectionReceiver(mNativeRenderNode, shouldRecieve);
347     }
348 
349     /**
350      * Sets the outline, defining the shape that casts a shadow, and the path to
351      * be clipped if setClipToOutline is set.
352      *
353      * Deep copies the data into native to simplify reference ownership.
354      */
setOutline(Outline outline)355     public boolean setOutline(Outline outline) {
356         if (outline == null) {
357             return nSetOutlineNone(mNativeRenderNode);
358         } else if (outline.isEmpty()) {
359             return nSetOutlineEmpty(mNativeRenderNode);
360         } else if (outline.mRect != null) {
361             return nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top,
362                     outline.mRect.right, outline.mRect.bottom, outline.mRadius, outline.mAlpha);
363         } else if (outline.mPath != null) {
364             return nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath,
365                     outline.mAlpha);
366         }
367         throw new IllegalArgumentException("Unrecognized outline?");
368     }
369 
hasShadow()370     public boolean hasShadow() {
371         return nHasShadow(mNativeRenderNode);
372     }
373 
374     /**
375      * Enables or disables clipping to the outline.
376      *
377      * @param clipToOutline true if clipping to the outline.
378      */
setClipToOutline(boolean clipToOutline)379     public boolean setClipToOutline(boolean clipToOutline) {
380         return nSetClipToOutline(mNativeRenderNode, clipToOutline);
381     }
382 
getClipToOutline()383     public boolean getClipToOutline() {
384         return nGetClipToOutline(mNativeRenderNode);
385     }
386 
387     /**
388      * Controls the RenderNode's circular reveal clip.
389      */
setRevealClip(boolean shouldClip, float x, float y, float radius)390     public boolean setRevealClip(boolean shouldClip,
391             float x, float y, float radius) {
392         return nSetRevealClip(mNativeRenderNode, shouldClip, x, y, radius);
393     }
394 
395     /**
396      * Set the static matrix on the display list. The specified matrix is combined with other
397      * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
398      *
399      * @param matrix A transform matrix to apply to this display list
400      */
setStaticMatrix(Matrix matrix)401     public boolean setStaticMatrix(Matrix matrix) {
402         return nSetStaticMatrix(mNativeRenderNode, matrix.native_instance);
403     }
404 
405     /**
406      * Set the Animation matrix on the display list. This matrix exists if an Animation is
407      * currently playing on a View, and is set on the display list during at draw() time. When
408      * the Animation finishes, the matrix should be cleared by sending <code>null</code>
409      * for the matrix parameter.
410      *
411      * @param matrix The matrix, null indicates that the matrix should be cleared.
412      */
setAnimationMatrix(Matrix matrix)413     public boolean setAnimationMatrix(Matrix matrix) {
414         return nSetAnimationMatrix(mNativeRenderNode,
415                 (matrix != null) ? matrix.native_instance : 0);
416     }
417 
418     /**
419      * Sets the translucency level for the display list.
420      *
421      * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
422      *
423      * @see View#setAlpha(float)
424      * @see #getAlpha()
425      */
setAlpha(float alpha)426     public boolean setAlpha(float alpha) {
427         return nSetAlpha(mNativeRenderNode, alpha);
428     }
429 
430     /**
431      * Returns the translucency level of this display list.
432      *
433      * @return A value between 0.0f and 1.0f
434      *
435      * @see #setAlpha(float)
436      */
getAlpha()437     public float getAlpha() {
438         return nGetAlpha(mNativeRenderNode);
439     }
440 
441     /**
442      * Sets whether the display list renders content which overlaps. Non-overlapping rendering
443      * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default
444      * display lists consider they do not have overlapping content.
445      *
446      * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping,
447      *                                true otherwise.
448      *
449      * @see android.view.View#hasOverlappingRendering()
450      * @see #hasOverlappingRendering()
451      */
setHasOverlappingRendering(boolean hasOverlappingRendering)452     public boolean setHasOverlappingRendering(boolean hasOverlappingRendering) {
453         return nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering);
454     }
455 
456     /**
457      * Indicates whether the content of this display list overlaps.
458      *
459      * @return True if this display list renders content which overlaps, false otherwise.
460      *
461      * @see #setHasOverlappingRendering(boolean)
462      */
hasOverlappingRendering()463     public boolean hasOverlappingRendering() {
464         //noinspection SimplifiableIfStatement
465         return nHasOverlappingRendering(mNativeRenderNode);
466     }
467 
setElevation(float lift)468     public boolean setElevation(float lift) {
469         return nSetElevation(mNativeRenderNode, lift);
470     }
471 
getElevation()472     public float getElevation() {
473         return nGetElevation(mNativeRenderNode);
474     }
475 
476     /**
477      * Sets the translation value for the display list on the X axis.
478      *
479      * @param translationX The X axis translation value of the display list, in pixels
480      *
481      * @see View#setTranslationX(float)
482      * @see #getTranslationX()
483      */
setTranslationX(float translationX)484     public boolean setTranslationX(float translationX) {
485         return nSetTranslationX(mNativeRenderNode, translationX);
486     }
487 
488     /**
489      * Returns the translation value for this display list on the X axis, in pixels.
490      *
491      * @see #setTranslationX(float)
492      */
getTranslationX()493     public float getTranslationX() {
494         return nGetTranslationX(mNativeRenderNode);
495     }
496 
497     /**
498      * Sets the translation value for the display list on the Y axis.
499      *
500      * @param translationY The Y axis translation value of the display list, in pixels
501      *
502      * @see View#setTranslationY(float)
503      * @see #getTranslationY()
504      */
setTranslationY(float translationY)505     public boolean setTranslationY(float translationY) {
506         return nSetTranslationY(mNativeRenderNode, translationY);
507     }
508 
509     /**
510      * Returns the translation value for this display list on the Y axis, in pixels.
511      *
512      * @see #setTranslationY(float)
513      */
getTranslationY()514     public float getTranslationY() {
515         return nGetTranslationY(mNativeRenderNode);
516     }
517 
518     /**
519      * Sets the translation value for the display list on the Z axis.
520      *
521      * @see View#setTranslationZ(float)
522      * @see #getTranslationZ()
523      */
setTranslationZ(float translationZ)524     public boolean setTranslationZ(float translationZ) {
525         return nSetTranslationZ(mNativeRenderNode, translationZ);
526     }
527 
528     /**
529      * Returns the translation value for this display list on the Z axis.
530      *
531      * @see #setTranslationZ(float)
532      */
getTranslationZ()533     public float getTranslationZ() {
534         return nGetTranslationZ(mNativeRenderNode);
535     }
536 
537     /**
538      * Sets the rotation value for the display list around the Z axis.
539      *
540      * @param rotation The rotation value of the display list, in degrees
541      *
542      * @see View#setRotation(float)
543      * @see #getRotation()
544      */
setRotation(float rotation)545     public boolean setRotation(float rotation) {
546         return nSetRotation(mNativeRenderNode, rotation);
547     }
548 
549     /**
550      * Returns the rotation value for this display list around the Z axis, in degrees.
551      *
552      * @see #setRotation(float)
553      */
getRotation()554     public float getRotation() {
555         return nGetRotation(mNativeRenderNode);
556     }
557 
558     /**
559      * Sets the rotation value for the display list around the X axis.
560      *
561      * @param rotationX The rotation value of the display list, in degrees
562      *
563      * @see View#setRotationX(float)
564      * @see #getRotationX()
565      */
setRotationX(float rotationX)566     public boolean setRotationX(float rotationX) {
567         return nSetRotationX(mNativeRenderNode, rotationX);
568     }
569 
570     /**
571      * Returns the rotation value for this display list around the X axis, in degrees.
572      *
573      * @see #setRotationX(float)
574      */
getRotationX()575     public float getRotationX() {
576         return nGetRotationX(mNativeRenderNode);
577     }
578 
579     /**
580      * Sets the rotation value for the display list around the Y axis.
581      *
582      * @param rotationY The rotation value of the display list, in degrees
583      *
584      * @see View#setRotationY(float)
585      * @see #getRotationY()
586      */
setRotationY(float rotationY)587     public boolean setRotationY(float rotationY) {
588         return nSetRotationY(mNativeRenderNode, rotationY);
589     }
590 
591     /**
592      * Returns the rotation value for this display list around the Y axis, in degrees.
593      *
594      * @see #setRotationY(float)
595      */
getRotationY()596     public float getRotationY() {
597         return nGetRotationY(mNativeRenderNode);
598     }
599 
600     /**
601      * Sets the scale value for the display list on the X axis.
602      *
603      * @param scaleX The scale value of the display list
604      *
605      * @see View#setScaleX(float)
606      * @see #getScaleX()
607      */
setScaleX(float scaleX)608     public boolean setScaleX(float scaleX) {
609         return nSetScaleX(mNativeRenderNode, scaleX);
610     }
611 
612     /**
613      * Returns the scale value for this display list on the X axis.
614      *
615      * @see #setScaleX(float)
616      */
getScaleX()617     public float getScaleX() {
618         return nGetScaleX(mNativeRenderNode);
619     }
620 
621     /**
622      * Sets the scale value for the display list on the Y axis.
623      *
624      * @param scaleY The scale value of the display list
625      *
626      * @see View#setScaleY(float)
627      * @see #getScaleY()
628      */
setScaleY(float scaleY)629     public boolean setScaleY(float scaleY) {
630         return nSetScaleY(mNativeRenderNode, scaleY);
631     }
632 
633     /**
634      * Returns the scale value for this display list on the Y axis.
635      *
636      * @see #setScaleY(float)
637      */
getScaleY()638     public float getScaleY() {
639         return nGetScaleY(mNativeRenderNode);
640     }
641 
642     /**
643      * Sets the pivot value for the display list on the X axis
644      *
645      * @param pivotX The pivot value of the display list on the X axis, in pixels
646      *
647      * @see View#setPivotX(float)
648      * @see #getPivotX()
649      */
setPivotX(float pivotX)650     public boolean setPivotX(float pivotX) {
651         return nSetPivotX(mNativeRenderNode, pivotX);
652     }
653 
654     /**
655      * Returns the pivot value for this display list on the X axis, in pixels.
656      *
657      * @see #setPivotX(float)
658      */
getPivotX()659     public float getPivotX() {
660         return nGetPivotX(mNativeRenderNode);
661     }
662 
663     /**
664      * Sets the pivot value for the display list on the Y axis
665      *
666      * @param pivotY The pivot value of the display list on the Y axis, in pixels
667      *
668      * @see View#setPivotY(float)
669      * @see #getPivotY()
670      */
setPivotY(float pivotY)671     public boolean setPivotY(float pivotY) {
672         return nSetPivotY(mNativeRenderNode, pivotY);
673     }
674 
675     /**
676      * Returns the pivot value for this display list on the Y axis, in pixels.
677      *
678      * @see #setPivotY(float)
679      */
getPivotY()680     public float getPivotY() {
681         return nGetPivotY(mNativeRenderNode);
682     }
683 
isPivotExplicitlySet()684     public boolean isPivotExplicitlySet() {
685         return nIsPivotExplicitlySet(mNativeRenderNode);
686     }
687 
688     /**
689      * Sets the camera distance for the display list. Refer to
690      * {@link View#setCameraDistance(float)} for more information on how to
691      * use this property.
692      *
693      * @param distance The distance in Z of the camera of the display list
694      *
695      * @see View#setCameraDistance(float)
696      * @see #getCameraDistance()
697      */
setCameraDistance(float distance)698     public boolean setCameraDistance(float distance) {
699         return nSetCameraDistance(mNativeRenderNode, distance);
700     }
701 
702     /**
703      * Returns the distance in Z of the camera of the display list.
704      *
705      * @see #setCameraDistance(float)
706      */
getCameraDistance()707     public float getCameraDistance() {
708         return nGetCameraDistance(mNativeRenderNode);
709     }
710 
711     /**
712      * Sets the left position for the display list.
713      *
714      * @param left The left position, in pixels, of the display list
715      *
716      * @see View#setLeft(int)
717      */
setLeft(int left)718     public boolean setLeft(int left) {
719         return nSetLeft(mNativeRenderNode, left);
720     }
721 
722     /**
723      * Sets the top position for the display list.
724      *
725      * @param top The top position, in pixels, of the display list
726      *
727      * @see View#setTop(int)
728      */
setTop(int top)729     public boolean setTop(int top) {
730         return nSetTop(mNativeRenderNode, top);
731     }
732 
733     /**
734      * Sets the right position for the display list.
735      *
736      * @param right The right position, in pixels, of the display list
737      *
738      * @see View#setRight(int)
739      */
setRight(int right)740     public boolean setRight(int right) {
741         return nSetRight(mNativeRenderNode, right);
742     }
743 
744     /**
745      * Sets the bottom position for the display list.
746      *
747      * @param bottom The bottom position, in pixels, of the display list
748      *
749      * @see View#setBottom(int)
750      */
setBottom(int bottom)751     public boolean setBottom(int bottom) {
752         return nSetBottom(mNativeRenderNode, bottom);
753     }
754 
755     /**
756      * Sets the left and top positions for the display list
757      *
758      * @param left The left position of the display list, in pixels
759      * @param top The top position of the display list, in pixels
760      * @param right The right position of the display list, in pixels
761      * @param bottom The bottom position of the display list, in pixels
762      *
763      * @see View#setLeft(int)
764      * @see View#setTop(int)
765      * @see View#setRight(int)
766      * @see View#setBottom(int)
767      */
setLeftTopRightBottom(int left, int top, int right, int bottom)768     public boolean setLeftTopRightBottom(int left, int top, int right, int bottom) {
769         return nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom);
770     }
771 
772     /**
773      * Offsets the left and right positions for the display list
774      *
775      * @param offset The amount that the left and right positions of the display
776      *               list are offset, in pixels
777      *
778      * @see View#offsetLeftAndRight(int)
779      */
offsetLeftAndRight(int offset)780     public boolean offsetLeftAndRight(int offset) {
781         return nOffsetLeftAndRight(mNativeRenderNode, offset);
782     }
783 
784     /**
785      * Offsets the top and bottom values for the display list
786      *
787      * @param offset The amount that the top and bottom positions of the display
788      *               list are offset, in pixels
789      *
790      * @see View#offsetTopAndBottom(int)
791      */
offsetTopAndBottom(int offset)792     public boolean offsetTopAndBottom(int offset) {
793         return nOffsetTopAndBottom(mNativeRenderNode, offset);
794     }
795 
796     /**
797      * Outputs the display list to the log. This method exists for use by
798      * tools to output display lists for selected nodes to the log.
799      */
output()800     public void output() {
801         nOutput(mNativeRenderNode);
802     }
803 
804     /**
805      * Gets the size of the DisplayList for debug purposes.
806      */
getDebugSize()807     public int getDebugSize() {
808         return nGetDebugSize(mNativeRenderNode);
809     }
810 
811     ///////////////////////////////////////////////////////////////////////////
812     // Animations
813     ///////////////////////////////////////////////////////////////////////////
814 
addAnimator(RenderNodeAnimator animator)815     public void addAnimator(RenderNodeAnimator animator) {
816         if (mOwningView == null || mOwningView.mAttachInfo == null) {
817             throw new IllegalStateException("Cannot start this animator on a detached view!");
818         }
819         nAddAnimator(mNativeRenderNode, animator.getNativeAnimator());
820         mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this);
821     }
822 
endAllAnimators()823     public void endAllAnimators() {
824         nEndAllAnimators(mNativeRenderNode);
825     }
826 
827     ///////////////////////////////////////////////////////////////////////////
828     // Native methods
829     ///////////////////////////////////////////////////////////////////////////
830 
nCreate(String name)831     private static native long nCreate(String name);
nDestroyRenderNode(long renderNode)832     private static native void nDestroyRenderNode(long renderNode);
nSetDisplayListData(long renderNode, long newData)833     private static native void nSetDisplayListData(long renderNode, long newData);
834 
835     // Matrix
836 
nGetTransformMatrix(long renderNode, long nativeMatrix)837     private static native void nGetTransformMatrix(long renderNode, long nativeMatrix);
nGetInverseTransformMatrix(long renderNode, long nativeMatrix)838     private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix);
nHasIdentityMatrix(long renderNode)839     private static native boolean nHasIdentityMatrix(long renderNode);
840 
841     // Properties
842 
nOffsetTopAndBottom(long renderNode, int offset)843     private static native boolean nOffsetTopAndBottom(long renderNode, int offset);
nOffsetLeftAndRight(long renderNode, int offset)844     private static native boolean nOffsetLeftAndRight(long renderNode, int offset);
nSetLeftTopRightBottom(long renderNode, int left, int top, int right, int bottom)845     private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top,
846             int right, int bottom);
nSetBottom(long renderNode, int bottom)847     private static native boolean nSetBottom(long renderNode, int bottom);
nSetRight(long renderNode, int right)848     private static native boolean nSetRight(long renderNode, int right);
nSetTop(long renderNode, int top)849     private static native boolean nSetTop(long renderNode, int top);
nSetLeft(long renderNode, int left)850     private static native boolean nSetLeft(long renderNode, int left);
nSetCameraDistance(long renderNode, float distance)851     private static native boolean nSetCameraDistance(long renderNode, float distance);
nSetPivotY(long renderNode, float pivotY)852     private static native boolean nSetPivotY(long renderNode, float pivotY);
nSetPivotX(long renderNode, float pivotX)853     private static native boolean nSetPivotX(long renderNode, float pivotX);
nSetLayerType(long renderNode, int layerType)854     private static native boolean nSetLayerType(long renderNode, int layerType);
nSetLayerPaint(long renderNode, long paint)855     private static native boolean nSetLayerPaint(long renderNode, long paint);
nSetClipToBounds(long renderNode, boolean clipToBounds)856     private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds);
nSetClipBounds(long renderNode, int left, int top, int right, int bottom)857     private static native boolean nSetClipBounds(long renderNode, int left, int top,
858             int right, int bottom);
nSetClipBoundsEmpty(long renderNode)859     private static native boolean nSetClipBoundsEmpty(long renderNode);
nSetProjectBackwards(long renderNode, boolean shouldProject)860     private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject);
nSetProjectionReceiver(long renderNode, boolean shouldRecieve)861     private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve);
nSetOutlineRoundRect(long renderNode, int left, int top, int right, int bottom, float radius, float alpha)862     private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top,
863             int right, int bottom, float radius, float alpha);
nSetOutlineConvexPath(long renderNode, long nativePath, float alpha)864     private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath,
865             float alpha);
nSetOutlineEmpty(long renderNode)866     private static native boolean nSetOutlineEmpty(long renderNode);
nSetOutlineNone(long renderNode)867     private static native boolean nSetOutlineNone(long renderNode);
nHasShadow(long renderNode)868     private static native boolean nHasShadow(long renderNode);
nSetClipToOutline(long renderNode, boolean clipToOutline)869     private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline);
nSetRevealClip(long renderNode, boolean shouldClip, float x, float y, float radius)870     private static native boolean nSetRevealClip(long renderNode,
871             boolean shouldClip, float x, float y, float radius);
nSetAlpha(long renderNode, float alpha)872     private static native boolean nSetAlpha(long renderNode, float alpha);
nSetHasOverlappingRendering(long renderNode, boolean hasOverlappingRendering)873     private static native boolean nSetHasOverlappingRendering(long renderNode,
874             boolean hasOverlappingRendering);
nSetElevation(long renderNode, float lift)875     private static native boolean nSetElevation(long renderNode, float lift);
nSetTranslationX(long renderNode, float translationX)876     private static native boolean nSetTranslationX(long renderNode, float translationX);
nSetTranslationY(long renderNode, float translationY)877     private static native boolean nSetTranslationY(long renderNode, float translationY);
nSetTranslationZ(long renderNode, float translationZ)878     private static native boolean nSetTranslationZ(long renderNode, float translationZ);
nSetRotation(long renderNode, float rotation)879     private static native boolean nSetRotation(long renderNode, float rotation);
nSetRotationX(long renderNode, float rotationX)880     private static native boolean nSetRotationX(long renderNode, float rotationX);
nSetRotationY(long renderNode, float rotationY)881     private static native boolean nSetRotationY(long renderNode, float rotationY);
nSetScaleX(long renderNode, float scaleX)882     private static native boolean nSetScaleX(long renderNode, float scaleX);
nSetScaleY(long renderNode, float scaleY)883     private static native boolean nSetScaleY(long renderNode, float scaleY);
nSetStaticMatrix(long renderNode, long nativeMatrix)884     private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix);
nSetAnimationMatrix(long renderNode, long animationMatrix)885     private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix);
886 
nHasOverlappingRendering(long renderNode)887     private static native boolean nHasOverlappingRendering(long renderNode);
nGetClipToOutline(long renderNode)888     private static native boolean nGetClipToOutline(long renderNode);
nGetAlpha(long renderNode)889     private static native float nGetAlpha(long renderNode);
nGetCameraDistance(long renderNode)890     private static native float nGetCameraDistance(long renderNode);
nGetScaleX(long renderNode)891     private static native float nGetScaleX(long renderNode);
nGetScaleY(long renderNode)892     private static native float nGetScaleY(long renderNode);
nGetElevation(long renderNode)893     private static native float nGetElevation(long renderNode);
nGetTranslationX(long renderNode)894     private static native float nGetTranslationX(long renderNode);
nGetTranslationY(long renderNode)895     private static native float nGetTranslationY(long renderNode);
nGetTranslationZ(long renderNode)896     private static native float nGetTranslationZ(long renderNode);
nGetRotation(long renderNode)897     private static native float nGetRotation(long renderNode);
nGetRotationX(long renderNode)898     private static native float nGetRotationX(long renderNode);
nGetRotationY(long renderNode)899     private static native float nGetRotationY(long renderNode);
nIsPivotExplicitlySet(long renderNode)900     private static native boolean nIsPivotExplicitlySet(long renderNode);
nGetPivotX(long renderNode)901     private static native float nGetPivotX(long renderNode);
nGetPivotY(long renderNode)902     private static native float nGetPivotY(long renderNode);
nOutput(long renderNode)903     private static native void nOutput(long renderNode);
nGetDebugSize(long renderNode)904     private static native int nGetDebugSize(long renderNode);
905 
906     ///////////////////////////////////////////////////////////////////////////
907     // Animations
908     ///////////////////////////////////////////////////////////////////////////
909 
nAddAnimator(long renderNode, long animatorPtr)910     private static native void nAddAnimator(long renderNode, long animatorPtr);
nEndAllAnimators(long renderNode)911     private static native void nEndAllAnimators(long renderNode);
912 
913     ///////////////////////////////////////////////////////////////////////////
914     // Finalization
915     ///////////////////////////////////////////////////////////////////////////
916 
917     @Override
finalize()918     protected void finalize() throws Throwable {
919         try {
920             nDestroyRenderNode(mNativeRenderNode);
921         } finally {
922             super.finalize();
923         }
924     }
925 }
926