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