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     /** setSpotShadowColor */
setSpotShadowColor(int color)357     public boolean setSpotShadowColor(int color) {
358         return nSetSpotShadowColor(mNativeRenderNode, color);
359     }
360 
361     /** setAmbientShadowColor */
setAmbientShadowColor(int color)362     public boolean setAmbientShadowColor(int color) {
363         return nSetAmbientShadowColor(mNativeRenderNode, color);
364     }
365 
366     /** getSpotShadowColor */
getSpotShadowColor()367     public int getSpotShadowColor() {
368         return nGetSpotShadowColor(mNativeRenderNode);
369     }
370 
371     /** getAmbientShadowColor */
getAmbientShadowColor()372     public int getAmbientShadowColor() {
373         return nGetAmbientShadowColor(mNativeRenderNode);
374     }
375 
376     /**
377      * Enables or disables clipping to the outline.
378      *
379      * @param clipToOutline true if clipping to the outline.
380      */
setClipToOutline(boolean clipToOutline)381     public boolean setClipToOutline(boolean clipToOutline) {
382         return nSetClipToOutline(mNativeRenderNode, clipToOutline);
383     }
384 
getClipToOutline()385     public boolean getClipToOutline() {
386         return nGetClipToOutline(mNativeRenderNode);
387     }
388 
389     /**
390      * Controls the RenderNode's circular reveal clip.
391      */
setRevealClip(boolean shouldClip, float x, float y, float radius)392     public boolean setRevealClip(boolean shouldClip,
393             float x, float y, float radius) {
394         return nSetRevealClip(mNativeRenderNode, shouldClip, x, y, radius);
395     }
396 
397     /**
398      * Set the static matrix on the display list. The specified matrix is combined with other
399      * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
400      *
401      * @param matrix A transform matrix to apply to this display list
402      */
setStaticMatrix(Matrix matrix)403     public boolean setStaticMatrix(Matrix matrix) {
404         return nSetStaticMatrix(mNativeRenderNode, matrix.native_instance);
405     }
406 
407     /**
408      * Set the Animation matrix on the display list. This matrix exists if an Animation is
409      * currently playing on a View, and is set on the display list during at draw() time. When
410      * the Animation finishes, the matrix should be cleared by sending <code>null</code>
411      * for the matrix parameter.
412      *
413      * @param matrix The matrix, null indicates that the matrix should be cleared.
414      */
setAnimationMatrix(Matrix matrix)415     public boolean setAnimationMatrix(Matrix matrix) {
416         return nSetAnimationMatrix(mNativeRenderNode,
417                 (matrix != null) ? matrix.native_instance : 0);
418     }
419 
420     /**
421      * Sets the translucency level for the display list.
422      *
423      * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
424      *
425      * @see View#setAlpha(float)
426      * @see #getAlpha()
427      */
setAlpha(float alpha)428     public boolean setAlpha(float alpha) {
429         return nSetAlpha(mNativeRenderNode, alpha);
430     }
431 
432     /**
433      * Returns the translucency level of this display list.
434      *
435      * @return A value between 0.0f and 1.0f
436      *
437      * @see #setAlpha(float)
438      */
getAlpha()439     public float getAlpha() {
440         return nGetAlpha(mNativeRenderNode);
441     }
442 
443     /**
444      * Sets whether the display list renders content which overlaps. Non-overlapping rendering
445      * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default
446      * display lists consider they do not have overlapping content.
447      *
448      * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping,
449      *                                true otherwise.
450      *
451      * @see android.view.View#hasOverlappingRendering()
452      * @see #hasOverlappingRendering()
453      */
setHasOverlappingRendering(boolean hasOverlappingRendering)454     public boolean setHasOverlappingRendering(boolean hasOverlappingRendering) {
455         return nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering);
456     }
457 
458     /**
459      * Indicates whether the content of this display list overlaps.
460      *
461      * @return True if this display list renders content which overlaps, false otherwise.
462      *
463      * @see #setHasOverlappingRendering(boolean)
464      */
hasOverlappingRendering()465     public boolean hasOverlappingRendering() {
466         //noinspection SimplifiableIfStatement
467         return nHasOverlappingRendering(mNativeRenderNode);
468     }
469 
setElevation(float lift)470     public boolean setElevation(float lift) {
471         return nSetElevation(mNativeRenderNode, lift);
472     }
473 
getElevation()474     public float getElevation() {
475         return nGetElevation(mNativeRenderNode);
476     }
477 
478     /**
479      * Sets the translation value for the display list on the X axis.
480      *
481      * @param translationX The X axis translation value of the display list, in pixels
482      *
483      * @see View#setTranslationX(float)
484      * @see #getTranslationX()
485      */
setTranslationX(float translationX)486     public boolean setTranslationX(float translationX) {
487         return nSetTranslationX(mNativeRenderNode, translationX);
488     }
489 
490     /**
491      * Returns the translation value for this display list on the X axis, in pixels.
492      *
493      * @see #setTranslationX(float)
494      */
getTranslationX()495     public float getTranslationX() {
496         return nGetTranslationX(mNativeRenderNode);
497     }
498 
499     /**
500      * Sets the translation value for the display list on the Y axis.
501      *
502      * @param translationY The Y axis translation value of the display list, in pixels
503      *
504      * @see View#setTranslationY(float)
505      * @see #getTranslationY()
506      */
setTranslationY(float translationY)507     public boolean setTranslationY(float translationY) {
508         return nSetTranslationY(mNativeRenderNode, translationY);
509     }
510 
511     /**
512      * Returns the translation value for this display list on the Y axis, in pixels.
513      *
514      * @see #setTranslationY(float)
515      */
getTranslationY()516     public float getTranslationY() {
517         return nGetTranslationY(mNativeRenderNode);
518     }
519 
520     /**
521      * Sets the translation value for the display list on the Z axis.
522      *
523      * @see View#setTranslationZ(float)
524      * @see #getTranslationZ()
525      */
setTranslationZ(float translationZ)526     public boolean setTranslationZ(float translationZ) {
527         return nSetTranslationZ(mNativeRenderNode, translationZ);
528     }
529 
530     /**
531      * Returns the translation value for this display list on the Z axis.
532      *
533      * @see #setTranslationZ(float)
534      */
getTranslationZ()535     public float getTranslationZ() {
536         return nGetTranslationZ(mNativeRenderNode);
537     }
538 
539     /**
540      * Sets the rotation value for the display list around the Z axis.
541      *
542      * @param rotation The rotation value of the display list, in degrees
543      *
544      * @see View#setRotation(float)
545      * @see #getRotation()
546      */
setRotation(float rotation)547     public boolean setRotation(float rotation) {
548         return nSetRotation(mNativeRenderNode, rotation);
549     }
550 
551     /**
552      * Returns the rotation value for this display list around the Z axis, in degrees.
553      *
554      * @see #setRotation(float)
555      */
getRotation()556     public float getRotation() {
557         return nGetRotation(mNativeRenderNode);
558     }
559 
560     /**
561      * Sets the rotation value for the display list around the X axis.
562      *
563      * @param rotationX The rotation value of the display list, in degrees
564      *
565      * @see View#setRotationX(float)
566      * @see #getRotationX()
567      */
setRotationX(float rotationX)568     public boolean setRotationX(float rotationX) {
569         return nSetRotationX(mNativeRenderNode, rotationX);
570     }
571 
572     /**
573      * Returns the rotation value for this display list around the X axis, in degrees.
574      *
575      * @see #setRotationX(float)
576      */
getRotationX()577     public float getRotationX() {
578         return nGetRotationX(mNativeRenderNode);
579     }
580 
581     /**
582      * Sets the rotation value for the display list around the Y axis.
583      *
584      * @param rotationY The rotation value of the display list, in degrees
585      *
586      * @see View#setRotationY(float)
587      * @see #getRotationY()
588      */
setRotationY(float rotationY)589     public boolean setRotationY(float rotationY) {
590         return nSetRotationY(mNativeRenderNode, rotationY);
591     }
592 
593     /**
594      * Returns the rotation value for this display list around the Y axis, in degrees.
595      *
596      * @see #setRotationY(float)
597      */
getRotationY()598     public float getRotationY() {
599         return nGetRotationY(mNativeRenderNode);
600     }
601 
602     /**
603      * Sets the scale value for the display list on the X axis.
604      *
605      * @param scaleX The scale value of the display list
606      *
607      * @see View#setScaleX(float)
608      * @see #getScaleX()
609      */
setScaleX(float scaleX)610     public boolean setScaleX(float scaleX) {
611         return nSetScaleX(mNativeRenderNode, scaleX);
612     }
613 
614     /**
615      * Returns the scale value for this display list on the X axis.
616      *
617      * @see #setScaleX(float)
618      */
getScaleX()619     public float getScaleX() {
620         return nGetScaleX(mNativeRenderNode);
621     }
622 
623     /**
624      * Sets the scale value for the display list on the Y axis.
625      *
626      * @param scaleY The scale value of the display list
627      *
628      * @see View#setScaleY(float)
629      * @see #getScaleY()
630      */
setScaleY(float scaleY)631     public boolean setScaleY(float scaleY) {
632         return nSetScaleY(mNativeRenderNode, scaleY);
633     }
634 
635     /**
636      * Returns the scale value for this display list on the Y axis.
637      *
638      * @see #setScaleY(float)
639      */
getScaleY()640     public float getScaleY() {
641         return nGetScaleY(mNativeRenderNode);
642     }
643 
644     /**
645      * Sets the pivot value for the display list on the X axis
646      *
647      * @param pivotX The pivot value of the display list on the X axis, in pixels
648      *
649      * @see View#setPivotX(float)
650      * @see #getPivotX()
651      */
setPivotX(float pivotX)652     public boolean setPivotX(float pivotX) {
653         return nSetPivotX(mNativeRenderNode, pivotX);
654     }
655 
656     /**
657      * Returns the pivot value for this display list on the X axis, in pixels.
658      *
659      * @see #setPivotX(float)
660      */
getPivotX()661     public float getPivotX() {
662         return nGetPivotX(mNativeRenderNode);
663     }
664 
665     /**
666      * Sets the pivot value for the display list on the Y axis
667      *
668      * @param pivotY The pivot value of the display list on the Y axis, in pixels
669      *
670      * @see View#setPivotY(float)
671      * @see #getPivotY()
672      */
setPivotY(float pivotY)673     public boolean setPivotY(float pivotY) {
674         return nSetPivotY(mNativeRenderNode, pivotY);
675     }
676 
677     /**
678      * Returns the pivot value for this display list on the Y axis, in pixels.
679      *
680      * @see #setPivotY(float)
681      */
getPivotY()682     public float getPivotY() {
683         return nGetPivotY(mNativeRenderNode);
684     }
685 
isPivotExplicitlySet()686     public boolean isPivotExplicitlySet() {
687         return nIsPivotExplicitlySet(mNativeRenderNode);
688     }
689 
690     /** lint */
resetPivot()691     public boolean resetPivot() {
692         return nResetPivot(mNativeRenderNode);
693     }
694 
695     /**
696      * Sets the camera distance for the display list. Refer to
697      * {@link View#setCameraDistance(float)} for more information on how to
698      * use this property.
699      *
700      * @param distance The distance in Z of the camera of the display list
701      *
702      * @see View#setCameraDistance(float)
703      * @see #getCameraDistance()
704      */
setCameraDistance(float distance)705     public boolean setCameraDistance(float distance) {
706         return nSetCameraDistance(mNativeRenderNode, distance);
707     }
708 
709     /**
710      * Returns the distance in Z of the camera of the display list.
711      *
712      * @see #setCameraDistance(float)
713      */
getCameraDistance()714     public float getCameraDistance() {
715         return nGetCameraDistance(mNativeRenderNode);
716     }
717 
718     /**
719      * Sets the left position for the display list.
720      *
721      * @param left The left position, in pixels, of the display list
722      *
723      * @see View#setLeft(int)
724      */
setLeft(int left)725     public boolean setLeft(int left) {
726         return nSetLeft(mNativeRenderNode, left);
727     }
728 
729     /**
730      * Sets the top position for the display list.
731      *
732      * @param top The top position, in pixels, of the display list
733      *
734      * @see View#setTop(int)
735      */
setTop(int top)736     public boolean setTop(int top) {
737         return nSetTop(mNativeRenderNode, top);
738     }
739 
740     /**
741      * Sets the right position for the display list.
742      *
743      * @param right The right position, in pixels, of the display list
744      *
745      * @see View#setRight(int)
746      */
setRight(int right)747     public boolean setRight(int right) {
748         return nSetRight(mNativeRenderNode, right);
749     }
750 
751     /**
752      * Sets the bottom position for the display list.
753      *
754      * @param bottom The bottom position, in pixels, of the display list
755      *
756      * @see View#setBottom(int)
757      */
setBottom(int bottom)758     public boolean setBottom(int bottom) {
759         return nSetBottom(mNativeRenderNode, bottom);
760     }
761 
762     /**
763      * Sets the left and top positions for the display list
764      *
765      * @param left The left position of the display list, in pixels
766      * @param top The top position of the display list, in pixels
767      * @param right The right position of the display list, in pixels
768      * @param bottom The bottom position of the display list, in pixels
769      *
770      * @see View#setLeft(int)
771      * @see View#setTop(int)
772      * @see View#setRight(int)
773      * @see View#setBottom(int)
774      */
setLeftTopRightBottom(int left, int top, int right, int bottom)775     public boolean setLeftTopRightBottom(int left, int top, int right, int bottom) {
776         return nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom);
777     }
778 
779     /**
780      * Offsets the left and right positions for the display list
781      *
782      * @param offset The amount that the left and right positions of the display
783      *               list are offset, in pixels
784      *
785      * @see View#offsetLeftAndRight(int)
786      */
offsetLeftAndRight(int offset)787     public boolean offsetLeftAndRight(int offset) {
788         return nOffsetLeftAndRight(mNativeRenderNode, offset);
789     }
790 
791     /**
792      * Offsets the top and bottom values for the display list
793      *
794      * @param offset The amount that the top and bottom positions of the display
795      *               list are offset, in pixels
796      *
797      * @see View#offsetTopAndBottom(int)
798      */
offsetTopAndBottom(int offset)799     public boolean offsetTopAndBottom(int offset) {
800         return nOffsetTopAndBottom(mNativeRenderNode, offset);
801     }
802 
803     /**
804      * Outputs the display list to the log. This method exists for use by
805      * tools to output display lists for selected nodes to the log.
806      */
output()807     public void output() {
808         nOutput(mNativeRenderNode);
809     }
810 
811     /**
812      * Gets the size of the DisplayList for debug purposes.
813      */
getDebugSize()814     public int getDebugSize() {
815         return nGetDebugSize(mNativeRenderNode);
816     }
817 
818     ///////////////////////////////////////////////////////////////////////////
819     // Animations
820     ///////////////////////////////////////////////////////////////////////////
821 
addAnimator(RenderNodeAnimator animator)822     public void addAnimator(RenderNodeAnimator animator) {
823         if (mOwningView == null || mOwningView.mAttachInfo == null) {
824             throw new IllegalStateException("Cannot start this animator on a detached view!");
825         }
826         nAddAnimator(mNativeRenderNode, animator.getNativeAnimator());
827         mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this);
828     }
829 
isAttached()830     public boolean isAttached() {
831         return mOwningView != null && mOwningView.mAttachInfo != null;
832     }
833 
registerVectorDrawableAnimator( AnimatedVectorDrawable.VectorDrawableAnimatorRT animatorSet)834     public void registerVectorDrawableAnimator(
835             AnimatedVectorDrawable.VectorDrawableAnimatorRT animatorSet) {
836         if (mOwningView == null || mOwningView.mAttachInfo == null) {
837             throw new IllegalStateException("Cannot start this animator on a detached view!");
838         }
839         mOwningView.mAttachInfo.mViewRootImpl.registerVectorDrawableAnimator(animatorSet);
840     }
841 
endAllAnimators()842     public void endAllAnimators() {
843         nEndAllAnimators(mNativeRenderNode);
844     }
845 
846     ///////////////////////////////////////////////////////////////////////////
847     // Regular JNI methods
848     ///////////////////////////////////////////////////////////////////////////
849 
nCreate(String name)850     private static native long nCreate(String name);
851 
nGetNativeFinalizer()852     private static native long nGetNativeFinalizer();
nOutput(long renderNode)853     private static native void nOutput(long renderNode);
nGetDebugSize(long renderNode)854     private static native int nGetDebugSize(long renderNode);
nRequestPositionUpdates(long renderNode, SurfaceView callback)855     private static native void nRequestPositionUpdates(long renderNode, SurfaceView callback);
856 
857     // Animations
858 
nAddAnimator(long renderNode, long animatorPtr)859     private static native void nAddAnimator(long renderNode, long animatorPtr);
nEndAllAnimators(long renderNode)860     private static native void nEndAllAnimators(long renderNode);
861 
862 
863     ///////////////////////////////////////////////////////////////////////////
864     // @FastNative methods
865     ///////////////////////////////////////////////////////////////////////////
866 
867     @FastNative
nSetDisplayList(long renderNode, long newData)868     private static native void nSetDisplayList(long renderNode, long newData);
869 
870 
871     ///////////////////////////////////////////////////////////////////////////
872     // @CriticalNative methods
873     ///////////////////////////////////////////////////////////////////////////
874 
875     @CriticalNative
nIsValid(long renderNode)876     private static native boolean nIsValid(long renderNode);
877 
878     // Matrix
879 
880     @CriticalNative
nGetTransformMatrix(long renderNode, long nativeMatrix)881     private static native void nGetTransformMatrix(long renderNode, long nativeMatrix);
882     @CriticalNative
nGetInverseTransformMatrix(long renderNode, long nativeMatrix)883     private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix);
884     @CriticalNative
nHasIdentityMatrix(long renderNode)885     private static native boolean nHasIdentityMatrix(long renderNode);
886 
887     // Properties
888 
889     @CriticalNative
nOffsetTopAndBottom(long renderNode, int offset)890     private static native boolean nOffsetTopAndBottom(long renderNode, int offset);
891     @CriticalNative
nOffsetLeftAndRight(long renderNode, int offset)892     private static native boolean nOffsetLeftAndRight(long renderNode, int offset);
893     @CriticalNative
nSetLeftTopRightBottom(long renderNode, int left, int top, int right, int bottom)894     private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top,
895             int right, int bottom);
896     @CriticalNative
nSetBottom(long renderNode, int bottom)897     private static native boolean nSetBottom(long renderNode, int bottom);
898     @CriticalNative
nSetRight(long renderNode, int right)899     private static native boolean nSetRight(long renderNode, int right);
900     @CriticalNative
nSetTop(long renderNode, int top)901     private static native boolean nSetTop(long renderNode, int top);
902     @CriticalNative
nSetLeft(long renderNode, int left)903     private static native boolean nSetLeft(long renderNode, int left);
904     @CriticalNative
nSetCameraDistance(long renderNode, float distance)905     private static native boolean nSetCameraDistance(long renderNode, float distance);
906     @CriticalNative
nSetPivotY(long renderNode, float pivotY)907     private static native boolean nSetPivotY(long renderNode, float pivotY);
908     @CriticalNative
nSetPivotX(long renderNode, float pivotX)909     private static native boolean nSetPivotX(long renderNode, float pivotX);
910     @CriticalNative
nResetPivot(long renderNode)911     private static native boolean nResetPivot(long renderNode);
912     @CriticalNative
nSetLayerType(long renderNode, int layerType)913     private static native boolean nSetLayerType(long renderNode, int layerType);
914     @CriticalNative
nSetLayerPaint(long renderNode, long paint)915     private static native boolean nSetLayerPaint(long renderNode, long paint);
916     @CriticalNative
nSetClipToBounds(long renderNode, boolean clipToBounds)917     private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds);
918     @CriticalNative
nSetClipBounds(long renderNode, int left, int top, int right, int bottom)919     private static native boolean nSetClipBounds(long renderNode, int left, int top,
920             int right, int bottom);
921     @CriticalNative
nSetClipBoundsEmpty(long renderNode)922     private static native boolean nSetClipBoundsEmpty(long renderNode);
923     @CriticalNative
nSetProjectBackwards(long renderNode, boolean shouldProject)924     private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject);
925     @CriticalNative
nSetProjectionReceiver(long renderNode, boolean shouldRecieve)926     private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve);
927     @CriticalNative
nSetOutlineRoundRect(long renderNode, int left, int top, int right, int bottom, float radius, float alpha)928     private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top,
929             int right, int bottom, float radius, float alpha);
930     @CriticalNative
nSetOutlineConvexPath(long renderNode, long nativePath, float alpha)931     private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath,
932             float alpha);
933     @CriticalNative
nSetOutlineEmpty(long renderNode)934     private static native boolean nSetOutlineEmpty(long renderNode);
935     @CriticalNative
nSetOutlineNone(long renderNode)936     private static native boolean nSetOutlineNone(long renderNode);
937     @CriticalNative
nHasShadow(long renderNode)938     private static native boolean nHasShadow(long renderNode);
939     @CriticalNative
nSetSpotShadowColor(long renderNode, int color)940     private static native boolean nSetSpotShadowColor(long renderNode, int color);
941     @CriticalNative
nSetAmbientShadowColor(long renderNode, int color)942     private static native boolean nSetAmbientShadowColor(long renderNode, int color);
943     @CriticalNative
nGetSpotShadowColor(long renderNode)944     private static native int nGetSpotShadowColor(long renderNode);
945     @CriticalNative
nGetAmbientShadowColor(long renderNode)946     private static native int nGetAmbientShadowColor(long renderNode);
947     @CriticalNative
nSetClipToOutline(long renderNode, boolean clipToOutline)948     private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline);
949     @CriticalNative
nSetRevealClip(long renderNode, boolean shouldClip, float x, float y, float radius)950     private static native boolean nSetRevealClip(long renderNode,
951             boolean shouldClip, float x, float y, float radius);
952     @CriticalNative
nSetAlpha(long renderNode, float alpha)953     private static native boolean nSetAlpha(long renderNode, float alpha);
954     @CriticalNative
nSetHasOverlappingRendering(long renderNode, boolean hasOverlappingRendering)955     private static native boolean nSetHasOverlappingRendering(long renderNode,
956             boolean hasOverlappingRendering);
957     @CriticalNative
nSetElevation(long renderNode, float lift)958     private static native boolean nSetElevation(long renderNode, float lift);
959     @CriticalNative
nSetTranslationX(long renderNode, float translationX)960     private static native boolean nSetTranslationX(long renderNode, float translationX);
961     @CriticalNative
nSetTranslationY(long renderNode, float translationY)962     private static native boolean nSetTranslationY(long renderNode, float translationY);
963     @CriticalNative
nSetTranslationZ(long renderNode, float translationZ)964     private static native boolean nSetTranslationZ(long renderNode, float translationZ);
965     @CriticalNative
nSetRotation(long renderNode, float rotation)966     private static native boolean nSetRotation(long renderNode, float rotation);
967     @CriticalNative
nSetRotationX(long renderNode, float rotationX)968     private static native boolean nSetRotationX(long renderNode, float rotationX);
969     @CriticalNative
nSetRotationY(long renderNode, float rotationY)970     private static native boolean nSetRotationY(long renderNode, float rotationY);
971     @CriticalNative
nSetScaleX(long renderNode, float scaleX)972     private static native boolean nSetScaleX(long renderNode, float scaleX);
973     @CriticalNative
nSetScaleY(long renderNode, float scaleY)974     private static native boolean nSetScaleY(long renderNode, float scaleY);
975     @CriticalNative
nSetStaticMatrix(long renderNode, long nativeMatrix)976     private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix);
977     @CriticalNative
nSetAnimationMatrix(long renderNode, long animationMatrix)978     private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix);
979 
980     @CriticalNative
nHasOverlappingRendering(long renderNode)981     private static native boolean nHasOverlappingRendering(long renderNode);
982     @CriticalNative
nGetClipToOutline(long renderNode)983     private static native boolean nGetClipToOutline(long renderNode);
984     @CriticalNative
nGetAlpha(long renderNode)985     private static native float nGetAlpha(long renderNode);
986     @CriticalNative
nGetCameraDistance(long renderNode)987     private static native float nGetCameraDistance(long renderNode);
988     @CriticalNative
nGetScaleX(long renderNode)989     private static native float nGetScaleX(long renderNode);
990     @CriticalNative
nGetScaleY(long renderNode)991     private static native float nGetScaleY(long renderNode);
992     @CriticalNative
nGetElevation(long renderNode)993     private static native float nGetElevation(long renderNode);
994     @CriticalNative
nGetTranslationX(long renderNode)995     private static native float nGetTranslationX(long renderNode);
996     @CriticalNative
nGetTranslationY(long renderNode)997     private static native float nGetTranslationY(long renderNode);
998     @CriticalNative
nGetTranslationZ(long renderNode)999     private static native float nGetTranslationZ(long renderNode);
1000     @CriticalNative
nGetRotation(long renderNode)1001     private static native float nGetRotation(long renderNode);
1002     @CriticalNative
nGetRotationX(long renderNode)1003     private static native float nGetRotationX(long renderNode);
1004     @CriticalNative
nGetRotationY(long renderNode)1005     private static native float nGetRotationY(long renderNode);
1006     @CriticalNative
nIsPivotExplicitlySet(long renderNode)1007     private static native boolean nIsPivotExplicitlySet(long renderNode);
1008     @CriticalNative
nGetPivotX(long renderNode)1009     private static native float nGetPivotX(long renderNode);
1010     @CriticalNative
nGetPivotY(long renderNode)1011     private static native float nGetPivotY(long renderNode);
1012 }
1013