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.graphics;
18 
19 import android.animation.Animator;
20 import android.annotation.BytesLong;
21 import android.annotation.ColorInt;
22 import android.annotation.FloatRange;
23 import android.annotation.IntDef;
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.graphics.animation.RenderNodeAnimator;
27 import android.view.NativeVectorDrawableAnimator;
28 import android.view.Surface;
29 import android.view.View;
30 
31 import com.android.internal.util.ArrayUtils;
32 
33 import dalvik.annotation.optimization.CriticalNative;
34 
35 import libcore.util.NativeAllocationRegistry;
36 
37 import java.lang.annotation.Retention;
38 import java.lang.annotation.RetentionPolicy;
39 import java.lang.ref.WeakReference;
40 
41 /**
42  * <p>RenderNode is used to build hardware accelerated rendering hierarchies. Each RenderNode
43  * contains both a display list as well as a set of properties that affect the rendering of the
44  * display list. RenderNodes are used internally for all Views by default and are not typically
45  * used directly.</p>
46  *
47  * <p>RenderNodes are used to divide up the rendering content of a complex scene into smaller
48  * pieces that can then be updated individually more cheaply. Updating part of the scene only needs
49  * to update the display list or properties of a small number of RenderNode instead of redrawing
50  * everything from scratch. A RenderNode only needs its display list re-recorded when its content
51  * alone should be changed. RenderNodes can also be transformed without re-recording the display
52  * list through the transform properties.</p>
53  *
54  * <p>A text editor might for instance store each paragraph into its own RenderNode.
55  * Thus when the user inserts or removes characters, only the display list of the
56  * affected paragraph needs to be recorded again.</p>
57  *
58  * <h3>Hardware acceleration</h3>
59  * <p>RenderNodes can be drawn using a {@link RecordingCanvas}. They are not
60  * supported in software. Always make sure that the {@link android.graphics.Canvas}
61  * you are using to render a display list is hardware accelerated using
62  * {@link android.graphics.Canvas#isHardwareAccelerated()}.</p>
63  *
64  * <h3>Creating a RenderNode</h3>
65  * <pre class="prettyprint">
66  *     RenderNode renderNode = new RenderNode("myRenderNode");
67  *     renderNode.setPosition(0, 0, 50, 50); // Set the size to 50x50
68  *     RecordingCanvas canvas = renderNode.beginRecording();
69  *     try {
70  *         // Draw with the canvas
71  *         canvas.drawRect(...);
72  *     } finally {
73  *         renderNode.endRecording();
74  *     }</pre>
75  *
76  * <h3>Drawing a RenderNode in a View</h3>
77  * <pre class="prettyprint">
78  *     protected void onDraw(Canvas canvas) {
79  *         if (canvas.isHardwareAccelerated()) {
80  *             // Check that the RenderNode has a display list, re-recording it if it does not.
81  *             if (!myRenderNode.hasDisplayList()) {
82  *                 updateDisplayList(myRenderNode);
83  *             }
84  *             // Draw the RenderNode into this canvas.
85  *             canvas.drawRenderNode(myRenderNode);
86  *         }
87  *     }</pre>
88  *
89  * <h3>Releasing resources</h3>
90  * <p>This step is not mandatory but recommended if you want to release resources
91  * held by a display list as soon as possible. Most significantly any bitmaps it may contain.</p>
92  * <pre class="prettyprint">
93  *     // Discards the display list content allowing for any held resources to be released.
94  *     // After calling this
95  *     renderNode.discardDisplayList();</pre>
96  *
97  *
98  * <h3>Properties</h3>
99  * <p>In addition, a RenderNode offers several properties, such as
100  * {@link #setScaleX(float)} or {@link #setTranslationX(float)}, that can be used to affect all
101  * the drawing commands recorded within. For instance, these properties can be used
102  * to move around a large number of images without re-issuing all the individual
103  * <code>canvas.drawBitmap()</code> calls.</p>
104  *
105  * <pre class="prettyprint">
106  *     private void createDisplayList() {
107  *         mRenderNode = new RenderNode("MyRenderNode");
108  *         mRenderNode.setPosition(0, 0, width, height);
109  *         RecordingCanvas canvas = mRenderNode.beginRecording();
110  *         try {
111  *             for (Bitmap b : mBitmaps) {
112  *                 canvas.drawBitmap(b, 0.0f, 0.0f, null);
113  *                 canvas.translate(0.0f, b.getHeight());
114  *             }
115  *         } finally {
116  *             mRenderNode.endRecording();
117  *         }
118  *     }
119  *
120  *     protected void onDraw(Canvas canvas) {
121  *         if (canvas.isHardwareAccelerated())
122  *             canvas.drawRenderNode(mRenderNode);
123  *         }
124  *     }
125  *
126  *     private void moveContentBy(int x) {
127  *          // This will move all the bitmaps recorded inside the display list
128  *          // by x pixels to the right and redraw this view. All the commands
129  *          // recorded in createDisplayList() won't be re-issued, only onDraw()
130  *          // will be invoked and will execute very quickly
131  *          mRenderNode.offsetLeftAndRight(x);
132  *          invalidate();
133  *     }</pre>
134  *
135  * <p>A few of the properties may at first appear redundant, such as {@link #setElevation(float)}
136  * and {@link #setTranslationZ(float)}. The reason for these duplicates are to allow for a
137  * separation between static & transient usages. For example consider a button that raises from 2dp
138  * to 8dp when pressed. To achieve that an application may decide to setElevation(2dip), and then
139  * on press to animate setTranslationZ to 6dip. Combined this achieves the final desired 8dip
140  * value, but the animation need only concern itself with animating the lift from press without
141  * needing to know the initial starting value. {@link #setTranslationX(float)} and
142  * {@link #setTranslationY(float)} are similarly provided for animation uses despite the functional
143  * overlap with {@link #setPosition(Rect)}.
144  *
145  * <p>The RenderNode's transform matrix is computed at render time as follows:
146  * <pre class="prettyprint">
147  *     Matrix transform = new Matrix();
148  *     transform.setTranslate(renderNode.getTranslationX(), renderNode.getTranslationY());
149  *     transform.preRotate(renderNode.getRotationZ(),
150  *             renderNode.getPivotX(), renderNode.getPivotY());
151  *     transform.preScale(renderNode.getScaleX(), renderNode.getScaleY(),
152  *             renderNode.getPivotX(), renderNode.getPivotY());</pre>
153  * The current canvas transform matrix, which is translated to the RenderNode's position,
154  * is then multiplied by the RenderNode's transform matrix. Therefore the ordering of calling
155  * property setters does not affect the result. That is to say that:
156  *
157  * <pre class="prettyprint">
158  *     renderNode.setTranslationX(100);
159  *     renderNode.setScaleX(100);</pre>
160  *
161  * is equivalent to:
162  *
163  * <pre class="prettyprint">
164  *     renderNode.setScaleX(100);
165  *     renderNode.setTranslationX(100);</pre>
166  *
167  * <h3>Threading</h3>
168  * <p>RenderNode may be created and used on any thread but they are not thread-safe. Only
169  * a single thread may interact with a RenderNode at any given time. It is critical
170  * that the RenderNode is only used on the same thread it is drawn with. For example when using
171  * RenderNode with a custom View, then that RenderNode must only be used from the UI thread.</p>
172  *
173  * <h3>When to re-render</h3>
174  * <p>Many of the RenderNode mutation methods, such as {@link #setTranslationX(float)}, return
175  * a boolean indicating if the value actually changed or not. This is useful in detecting
176  * if a new frame should be rendered or not. A typical usage would look like:
177  * <pre class="prettyprint">
178  *     public void translateTo(int x, int y) {
179  *         boolean needsUpdate = myRenderNode.setTranslationX(x);
180  *         needsUpdate |= myRenderNode.setTranslationY(y);
181  *         if (needsUpdate) {
182  *             myOwningView.invalidate();
183  *         }
184  *     }</pre>
185  * This is marginally faster than doing a more explicit up-front check if the value changed by
186  * comparing the desired value against {@link #getTranslationX()} as it minimizes JNI transitions.
187  * The actual mechanism of requesting a new frame to be rendered will depend on how this
188  * RenderNode is being drawn. If it's drawn to a containing View, as in the above snippet,
189  * then simply invalidating that View works. If instead the RenderNode is being drawn to a Canvas
190  * directly such as with {@link Surface#lockHardwareCanvas()} then a new frame needs to be drawn
191  * by calling {@link Surface#lockHardwareCanvas()}, re-drawing the root RenderNode or whatever
192  * top-level content is desired, and finally calling {@link Surface#unlockCanvasAndPost(Canvas)}.
193  * </p>
194  */
195 public final class RenderNode {
196 
197     // Use a Holder to allow static initialization in the boot image.
198     private static class NoImagePreloadHolder {
199         public static final NativeAllocationRegistry sRegistry =
200                 NativeAllocationRegistry.createMalloced(
201                 RenderNode.class.getClassLoader(), nGetNativeFinalizer());
202     }
203 
204     /**
205      * Not for general use; use only if you are ThreadedRenderer or RecordingCanvas.
206      *
207      * @hide
208      */
209     public final long mNativeRenderNode;
210     private final AnimationHost mAnimationHost;
211     private RecordingCanvas mCurrentRecordingCanvas;
212 
213     // Will be null if not currently registered
214     @Nullable
215     private CompositePositionUpdateListener mCompositePositionUpdateListener;
216 
217     /**
218      * Creates a new RenderNode that can be used to record batches of
219      * drawing operations, and store / apply render properties when drawn.
220      *
221      * @param name The name of the RenderNode, used for debugging purpose. May be null.
222      */
RenderNode(@ullable String name)223     public RenderNode(@Nullable String name) {
224         this(name, null);
225     }
226 
RenderNode(String name, AnimationHost animationHost)227     private RenderNode(String name, AnimationHost animationHost) {
228         mNativeRenderNode = nCreate(name);
229         NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
230         mAnimationHost = animationHost;
231     }
232 
233     /**
234      * @see RenderNode#adopt(long)
235      */
RenderNode(long nativePtr)236     private RenderNode(long nativePtr) {
237         mNativeRenderNode = nativePtr;
238         NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
239         mAnimationHost = null;
240     }
241 
242     /** @hide */
create(String name, @Nullable AnimationHost animationHost)243     public static RenderNode create(String name, @Nullable AnimationHost animationHost) {
244         return new RenderNode(name, animationHost);
245     }
246 
247     /**
248      * Adopts an existing native render node.
249      *
250      * Note: This will *NOT* incRef() on the native object, however it will
251      * decRef() when it is destroyed. The caller should have already incRef'd it
252      *
253      * @hide
254      */
adopt(long nativePtr)255     public static RenderNode adopt(long nativePtr) {
256         return new RenderNode(nativePtr);
257     }
258 
259     /**
260      * Listens for RenderNode position updates for synchronous window movement.
261      *
262      * This is not suitable for generic position listening, it is only designed & intended
263      * for use by things which require external position events like SurfaceView, PopupWindow, etc..
264      *
265      * @hide
266      */
267     public interface PositionUpdateListener {
268         /**
269          * Called by native by a Rendering Worker thread to update window position
270          *
271          * @hide
272          */
positionChanged(long frameNumber, int left, int top, int right, int bottom)273         void positionChanged(long frameNumber, int left, int top, int right, int bottom);
274 
275         /**
276          * Called by native by a Rendering Worker thread to update window position; includes
277          * the local rect that represents the clipped area of the RenderNode's bounds.
278          *
279          * @hide
280          */
positionChanged(long frameNumber, int left, int top, int right, int bottom, int clipLeft, int clipTop, int clipRight, int clipBottom)281         default void positionChanged(long frameNumber, int left, int top, int right, int bottom,
282                 int clipLeft, int clipTop, int clipRight, int clipBottom) {
283             positionChanged(frameNumber, left, top, right, bottom);
284         }
285 
286         /**
287          * Called by JNI
288          *
289          * @hide */
callPositionChanged(WeakReference<PositionUpdateListener> weakListener, long frameNumber, int left, int top, int right, int bottom)290         static boolean callPositionChanged(WeakReference<PositionUpdateListener> weakListener,
291                 long frameNumber, int left, int top, int right, int bottom) {
292             final PositionUpdateListener listener = weakListener.get();
293             if (listener != null) {
294                 listener.positionChanged(frameNumber, left, top, right, bottom);
295                 return true;
296             } else {
297                 return false;
298             }
299         }
300 
301         /**
302          * Called by JNI
303          *
304          * @hide */
callPositionChanged2(WeakReference<PositionUpdateListener> weakListener, long frameNumber, int left, int top, int right, int bottom, int clipLeft, int clipTop, int clipRight, int clipBottom)305         static boolean callPositionChanged2(WeakReference<PositionUpdateListener> weakListener,
306                 long frameNumber, int left, int top, int right, int bottom,
307                 int clipLeft, int clipTop, int clipRight, int clipBottom) {
308             final PositionUpdateListener listener = weakListener.get();
309             if (listener != null) {
310                 listener.positionChanged(frameNumber, left, top, right, bottom, clipLeft,
311                         clipTop, clipRight, clipBottom);
312                 return true;
313             } else {
314                 return false;
315             }
316         }
317 
318         /**
319          * Call to apply a stretch effect to any child SurfaceControl layers
320          *
321          * TODO: Fold this into positionChanged & have HWUI do the ASurfaceControl calls?
322          *   (njawad) update to consume different stretch parameters for horizontal/vertical stretch
323          *   to ensure SkiaGLRenderEngine can also apply the same stretch to a surface
324          *
325          * @hide
326          */
applyStretch(long frameNumber, float width, float height, float vecX, float vecY, float maxStretchX, float maxStretchY, float childRelativeLeft, float childRelativeTop, float childRelativeRight, float childRelativeBottom)327         default void applyStretch(long frameNumber, float width, float height,
328                 float vecX, float vecY,
329                 float maxStretchX, float maxStretchY, float childRelativeLeft,
330                 float childRelativeTop, float childRelativeRight, float childRelativeBottom) { }
331 
332         /**
333          * Called by JNI
334          *
335          * @hide */
callApplyStretch(WeakReference<PositionUpdateListener> weakListener, long frameNumber, float width, float height, float vecX, float vecY, float maxStretchX, float maxStretchY, float childRelativeLeft, float childRelativeTop, float childRelativeRight, float childRelativeBottom)336         static boolean callApplyStretch(WeakReference<PositionUpdateListener> weakListener,
337                 long frameNumber, float width, float height,
338                 float vecX, float vecY,
339                 float maxStretchX, float maxStretchY, float childRelativeLeft,
340                 float childRelativeTop, float childRelativeRight, float childRelativeBottom) {
341             final PositionUpdateListener listener = weakListener.get();
342             if (listener != null) {
343                 listener.applyStretch(frameNumber, width, height, vecX, vecY, maxStretchX,
344                         maxStretchY, childRelativeLeft, childRelativeTop, childRelativeRight,
345                         childRelativeBottom);
346                 return true;
347             } else {
348                 return false;
349             }
350         }
351 
352         /**
353          * Called by native on RenderThread to notify that the view is no longer in the
354          * draw tree. UI thread is blocked at this point.
355          *
356          * @hide
357          */
positionLost(long frameNumber)358         void positionLost(long frameNumber);
359 
360         /**
361          * Called by JNI
362          *
363          * @hide */
callPositionLost(WeakReference<PositionUpdateListener> weakListener, long frameNumber)364         static boolean callPositionLost(WeakReference<PositionUpdateListener> weakListener,
365                 long frameNumber) {
366             final PositionUpdateListener listener = weakListener.get();
367             if (listener != null) {
368                 listener.positionLost(frameNumber);
369                 return true;
370             } else {
371                 return false;
372             }
373         }
374 
375     }
376 
377     private static final class CompositePositionUpdateListener implements PositionUpdateListener {
378         private final PositionUpdateListener[] mListeners;
379         private static final PositionUpdateListener[] sEmpty = new PositionUpdateListener[0];
380 
CompositePositionUpdateListener(PositionUpdateListener... listeners)381         CompositePositionUpdateListener(PositionUpdateListener... listeners) {
382             mListeners = listeners != null ? listeners : sEmpty;
383         }
384 
with(PositionUpdateListener listener)385         public CompositePositionUpdateListener with(PositionUpdateListener listener) {
386             return new CompositePositionUpdateListener(
387                     ArrayUtils.appendElement(PositionUpdateListener.class, mListeners, listener));
388         }
389 
without(PositionUpdateListener listener)390         public CompositePositionUpdateListener without(PositionUpdateListener listener) {
391             return new CompositePositionUpdateListener(
392                     ArrayUtils.removeElement(PositionUpdateListener.class, mListeners, listener));
393         }
394 
395         @Override
positionChanged(long frameNumber, int left, int top, int right, int bottom)396         public void positionChanged(long frameNumber, int left, int top, int right, int bottom) {
397             for (PositionUpdateListener pul : mListeners) {
398                 pul.positionChanged(frameNumber, left, top, right, bottom);
399             }
400         }
401 
402         @Override
positionChanged(long frameNumber, int left, int top, int right, int bottom, int clipLeft, int clipTop, int clipRight, int clipBottom)403         public void positionChanged(long frameNumber, int left, int top, int right, int bottom,
404                 int clipLeft, int clipTop, int clipRight, int clipBottom) {
405             for (PositionUpdateListener pul : mListeners) {
406                 pul.positionChanged(frameNumber, left, top, right, bottom, clipLeft, clipTop,
407                         clipRight, clipBottom);
408             }
409         }
410 
411         @Override
positionLost(long frameNumber)412         public void positionLost(long frameNumber) {
413             for (PositionUpdateListener pul : mListeners) {
414                 pul.positionLost(frameNumber);
415             }
416         }
417 
418         @Override
applyStretch(long frameNumber, float width, float height, float vecX, float vecY, float maxStretchX, float maxStretchY, float childRelativeLeft, float childRelativeTop, float childRelativeRight, float childRelativeBottom)419         public void applyStretch(long frameNumber, float width, float height,
420                 float vecX, float vecY, float maxStretchX, float maxStretchY, float childRelativeLeft,
421                 float childRelativeTop, float childRelativeRight, float childRelativeBottom) {
422             for (PositionUpdateListener pul : mListeners) {
423                 pul.applyStretch(frameNumber, width, height, vecX, vecY, maxStretchX,
424                         maxStretchY, childRelativeLeft, childRelativeTop, childRelativeRight,
425                         childRelativeBottom);
426             }
427         }
428     }
429 
430     /**
431      * Enable callbacks for position changes. Call only from the UI thread or with
432      * external synchronization.
433      *
434      * @hide
435      */
addPositionUpdateListener(@onNull PositionUpdateListener listener)436     public void addPositionUpdateListener(@NonNull PositionUpdateListener listener) {
437         CompositePositionUpdateListener comp = mCompositePositionUpdateListener;
438         if (comp == null) {
439             comp = new CompositePositionUpdateListener(listener);
440         } else {
441             comp = comp.with(listener);
442         }
443         mCompositePositionUpdateListener = comp;
444         nRequestPositionUpdates(mNativeRenderNode, new WeakReference<>(comp));
445     }
446 
447     /**
448      * Disable a callback for position changes. Call only from the UI thread or with
449      * external synchronization.
450      *
451      * @param listener Callback to remove
452      * @hide
453      */
removePositionUpdateListener(@onNull PositionUpdateListener listener)454     public void removePositionUpdateListener(@NonNull PositionUpdateListener listener) {
455         CompositePositionUpdateListener comp = mCompositePositionUpdateListener;
456         if (comp != null) {
457             comp = comp.without(listener);
458             mCompositePositionUpdateListener = comp;
459             nRequestPositionUpdates(mNativeRenderNode, new WeakReference<>(comp));
460         }
461     }
462 
463     /**
464      * Starts recording a display list for the render node. All
465      * operations performed on the returned canvas are recorded and
466      * stored in this display list.
467      *
468      * {@link #endRecording()} must be called when the recording is finished in order to apply
469      * the updated display list. Failing to call {@link #endRecording()} will result in an
470      * {@link IllegalStateException} if {@link #beginRecording(int, int)} is called again.
471      *
472      * @param width  The width of the recording viewport. This will not alter the width of the
473      *               RenderNode itself, that must be set with {@link #setPosition(Rect)}.
474      * @param height The height of the recording viewport. This will not alter the height of the
475      *               RenderNode itself, that must be set with {@link #setPosition(Rect)}.
476      * @return A canvas to record drawing operations.
477      * @throws IllegalStateException If a recording is already in progress. That is, the previous
478      * call to {@link #beginRecording(int, int)} did not call {@link #endRecording()}.
479      * @see #endRecording()
480      * @see #hasDisplayList()
481      */
beginRecording(int width, int height)482     public @NonNull RecordingCanvas beginRecording(int width, int height) {
483         if (mCurrentRecordingCanvas != null) {
484             throw new IllegalStateException(
485                     "Recording currently in progress - missing #endRecording() call?");
486         }
487         mCurrentRecordingCanvas = RecordingCanvas.obtain(this, width, height);
488         return mCurrentRecordingCanvas;
489     }
490 
491     /**
492      * Same as {@link #beginRecording(int, int)} with the width & height set
493      * to the RenderNode's own width & height. The RenderNode's width & height may be set
494      * with {@link #setPosition(int, int, int, int)}.
495      *
496      * @return A canvas to record drawing operations.
497      * @throws IllegalStateException If a recording is already in progress. That is, the previous
498      * call to {@link #beginRecording(int, int)} did not call {@link #endRecording()}.
499      * @see #endRecording()
500      * @see #hasDisplayList()
501      */
beginRecording()502     public @NonNull RecordingCanvas beginRecording() {
503         return beginRecording(nGetWidth(mNativeRenderNode), nGetHeight(mNativeRenderNode));
504     }
505 
506     /**
507      * `
508      * Ends the recording for this display list. Calling this method marks
509      * the display list valid and {@link #hasDisplayList()} will return true.
510      *
511      * @see #beginRecording(int, int)
512      * @see #hasDisplayList()
513      */
endRecording()514     public void endRecording() {
515         if (mCurrentRecordingCanvas == null) {
516             throw new IllegalStateException(
517                     "No recording in progress, forgot to call #beginRecording()?");
518         }
519         RecordingCanvas canvas = mCurrentRecordingCanvas;
520         mCurrentRecordingCanvas = null;
521         canvas.finishRecording(this);
522         canvas.recycle();
523     }
524 
525     /**
526      * @hide
527      * @deprecated use {@link #beginRecording(int, int)} instead
528      */
529     @Deprecated
start(int width, int height)530     public RecordingCanvas start(int width, int height) {
531         return beginRecording(width, height);
532     }
533 
534     /**
535      * @hide
536      * @deprecated use {@link #endRecording()} instead
537      */
538     @Deprecated
end(RecordingCanvas canvas)539     public void end(RecordingCanvas canvas) {
540         if (canvas != mCurrentRecordingCanvas) {
541             throw new IllegalArgumentException("Wrong canvas");
542         }
543         endRecording();
544     }
545 
546     /**
547      * Reset native resources. This is called when cleaning up the state of display lists
548      * during destruction of hardware resources, to ensure that we do not hold onto
549      * obsolete resources after related resources are gone.
550      */
discardDisplayList()551     public void discardDisplayList() {
552         nDiscardDisplayList(mNativeRenderNode);
553     }
554 
555     /**
556      * Returns whether the RenderNode has a display list. If this returns false, the RenderNode
557      * should be re-recorded with {@link #beginRecording()} and {@link #endRecording()}.
558      *
559      * A RenderNode without a display list may still be drawn, however it will have no impact
560      * on the rendering content until its display list is updated.
561      *
562      * When a RenderNode is no longer drawn by anything the system may automatically
563      * invoke {@link #discardDisplayList()}. It is therefore important to ensure that
564      * {@link #hasDisplayList()} is true on a RenderNode prior to drawing it.
565      *
566      * See {@link #discardDisplayList()}
567      *
568      * @return boolean true if this RenderNode has a display list, false otherwise.
569      */
hasDisplayList()570     public boolean hasDisplayList() {
571         return nIsValid(mNativeRenderNode);
572     }
573 
574     ///////////////////////////////////////////////////////////////////////////
575     // Matrix manipulation
576     ///////////////////////////////////////////////////////////////////////////
577 
578     /**
579      * Whether or not the RenderNode has an identity transform. This is a faster
580      * way to do the otherwise equivalent {@link #getMatrix(Matrix)} {@link Matrix#isIdentity()}
581      * as it doesn't require copying the Matrix first, thus minimizing overhead.
582      *
583      * @return true if the RenderNode has an identity transform, false otherwise
584      */
hasIdentityMatrix()585     public boolean hasIdentityMatrix() {
586         return nHasIdentityMatrix(mNativeRenderNode);
587     }
588 
589     /**
590      * Gets the current transform matrix
591      *
592      * @param outMatrix The matrix to store the transform of the RenderNode
593      */
getMatrix(@onNull Matrix outMatrix)594     public void getMatrix(@NonNull Matrix outMatrix) {
595         nGetTransformMatrix(mNativeRenderNode, outMatrix.ni());
596     }
597 
598     /**
599      * Gets the current transform inverted. This is a faster way to do the otherwise
600      * equivalent {@link #getMatrix(Matrix)} followed by {@link Matrix#invert(Matrix)}
601      *
602      * @param outMatrix The matrix to store the inverse transform of the RenderNode
603      */
getInverseMatrix(@onNull Matrix outMatrix)604     public void getInverseMatrix(@NonNull Matrix outMatrix) {
605         nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.ni());
606     }
607 
608     ///////////////////////////////////////////////////////////////////////////
609     // RenderProperty Setters
610     ///////////////////////////////////////////////////////////////////////////
611 
612     /**
613      * @hide
614      * @deprecated use {@link #setUseCompositingLayer(boolean, Paint)} instead
615      */
616     @Deprecated
setLayerType(int layerType)617     public boolean setLayerType(int layerType) {
618         return nSetLayerType(mNativeRenderNode, layerType);
619     }
620 
621     /**
622      * @hide
623      * @deprecated use {@link #setUseCompositingLayer(boolean, Paint)} instead
624      */
625     @Deprecated
setLayerPaint(@ullable Paint paint)626     public boolean setLayerPaint(@Nullable Paint paint) {
627         return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.getNativeInstance() : 0);
628     }
629 
630     /**
631      * Controls whether or not to force this RenderNode to render to an intermediate buffer.
632      * Internally RenderNode will already promote itself to a composition layer if it's useful
633      * for performance or required for the current combination of {@link #setAlpha(float)} and
634      * {@link #setHasOverlappingRendering(boolean)}.
635      *
636      * <p>The usage of this is instead to allow for either overriding of the internal behavior
637      * if it's measured to be necessary for the particular rendering content in question or, more
638      * usefully, to add a composition effect to the RenderNode via the optional paint parameter.
639      *
640      * <p>Note: When a RenderNode is using a compositing layer it will also result in
641      * clipToBounds=true behavior.
642      *
643      * @param forceToLayer if true this forces the RenderNode to use an intermediate buffer.
644      *                     Default & generally recommended value is false.
645      * @param paint        The blend mode, alpha, and ColorFilter to apply to the compositing layer.
646      *                     Only applies if forceToLayer is true. The paint's alpha is multiplied
647      *                     with {@link #getAlpha()} to resolve the final alpha of the RenderNode.
648      *                     If null then no additional composition effects are applied on top of the
649      *                     composition layer.
650      * @return True if the value changed, false if the new value was the same as the previous value.
651      */
setUseCompositingLayer(boolean forceToLayer, @Nullable Paint paint)652     public boolean setUseCompositingLayer(boolean forceToLayer, @Nullable Paint paint) {
653         boolean didChange = nSetLayerType(mNativeRenderNode, forceToLayer ? 2 : 0);
654         didChange |= nSetLayerPaint(mNativeRenderNode,
655                 paint != null ? paint.getNativeInstance() : 0);
656         return didChange;
657     }
658 
659     /**
660      * Gets whether or not a compositing layer is forced to be used. The default & recommended
661      * is false, as it is typically faster to avoid using compositing layers.
662      * See {@link #setUseCompositingLayer(boolean, Paint)}.
663      *
664      * @return true if a compositing layer is forced, false otherwise
665      */
getUseCompositingLayer()666     public boolean getUseCompositingLayer() {
667         return nGetLayerType(mNativeRenderNode) != 0;
668     }
669 
670     /**
671      * Sets an additional clip on the RenderNode. If null, the extra clip is removed from the
672      * RenderNode. If non-null, the RenderNode will be clipped to this rect. In addition  if
673      * {@link #setClipToBounds(boolean)} is true, then the RenderNode will be clipped to the
674      * intersection of this rectangle and the bounds of the render node, which is set with
675      * {@link #setPosition(Rect)}.
676      *
677      * <p>This is equivalent to do a {@link Canvas#clipRect(Rect)} at the start of this
678      * RenderNode's display list. However, as this is a property of the RenderNode instead
679      * of part of the display list it can be more easily animated for transient additional
680      * clipping. An example usage of this would be the {@link android.transition.ChangeBounds}
681      * transition animation with the resizeClip=true option.
682      *
683      * @param rect the bounds to clip to. If null, the additional clip is removed.
684      * @return True if the value changed, false if the new value was the same as the previous value.
685      */
setClipRect(@ullable Rect rect)686     public boolean setClipRect(@Nullable Rect rect) {
687         if (rect == null) {
688             return nSetClipBoundsEmpty(mNativeRenderNode);
689         } else {
690             return nSetClipBounds(mNativeRenderNode, rect.left, rect.top, rect.right, rect.bottom);
691         }
692     }
693 
694     /**
695      * Set whether the Render node should clip itself to its bounds. This defaults to true,
696      * and is useful to the renderer in enable quick-rejection of chunks of the tree as well as
697      * better partial invalidation support. Clipping can be further restricted or controlled
698      * through the combination of this property as well as {@link #setClipRect(Rect)}, which
699      * allows for a different clipping rectangle to be used in addition to or instead of the
700      * {@link #setPosition(int, int, int, int)} or the RenderNode.
701      *
702      * @param clipToBounds true if the display list should clip to its bounds, false otherwise.
703      * @return True if the value changed, false if the new value was the same as the previous value.
704      */
setClipToBounds(boolean clipToBounds)705     public boolean setClipToBounds(boolean clipToBounds) {
706         return nSetClipToBounds(mNativeRenderNode, clipToBounds);
707     }
708 
709     /**
710      * Returns whether or not the RenderNode is clipping to its bounds. See
711      * {@link #setClipToBounds(boolean)} and {@link #setPosition(int, int, int, int)}
712      *
713      * @return true if the render node clips to its bounds, false otherwise.
714      */
getClipToBounds()715     public boolean getClipToBounds() {
716         return nGetClipToBounds(mNativeRenderNode);
717     }
718 
719     /**
720      * <p>Sets whether the RenderNode should be drawn immediately after the
721      * closest ancestor RenderNode containing a projection receiver.
722      *
723      * <p>The default is false, and the rendering of this node happens in the typical draw order.
724      *
725      * <p>If true, then at rendering time this rendernode will not be drawn in order with the
726      * {@link Canvas#drawRenderNode(RenderNode)} command that drew this RenderNode, but instead
727      * it will be re-positioned in the RenderNode tree to be drawn on the closet ancestor with a
728      * child rendernode that has {@link #setProjectionReceiver(boolean)} as true.
729      *
730      * <p>The typical usage of this is to allow a child RenderNode to draw on a parent's background,
731      * such as the platform's usage with {@link android.graphics.drawable.RippleDrawable}. Consider
732      * the following structure, built out of which RenderNode called drawRenderNode on a different
733      * RenderNode:
734      *
735      * <pre>
736      *        +-------------+
737      *        |RenderNode: P|
738      *        +-+----------++
739      *          |          |
740      *          v          v
741      *  +-------+-----+  +-+--------------+
742      *  |RenderNode: C|  |RenderNode: P'BG|
743      *  +-------+-----+  +----------------+
744      *          |
745      *          |
746      * +--------+-------+
747      * |RenderNode: C'BG|
748      * +----------------+
749      * </pre>
750      *
751      * If P'BG is a projection receiver, and C'BG is set to project backwards then C'BG will
752      * behave as if it was drawn directly by P'BG instead of by C. This includes inheriting P'BG's
753      * clip instead of C's clip.
754      *
755      * @param shouldProject true if the display list should be projected onto a
756      *                      containing volume. Default is false.
757      * @return True if the value changed, false if the new value was the same as the previous value.
758      */
setProjectBackwards(boolean shouldProject)759     public boolean setProjectBackwards(boolean shouldProject) {
760         return nSetProjectBackwards(mNativeRenderNode, shouldProject);
761     }
762 
763     /**
764      * Sets whether the RenderNode is a projection receiver. If true then this RenderNode's parent
765      * should draw any descendant RenderNodes with ProjectBackwards=true directly on top of it.
766      * Default value is false. See
767      * {@link #setProjectBackwards(boolean)} for a description of what this entails.
768      *
769      * @param shouldReceive True if this RenderNode is a projection receiver, false otherwise.
770      *                      Default is false.
771      * @return True if the value changed, false if the new value was the same as the previous value.
772      */
setProjectionReceiver(boolean shouldReceive)773     public boolean setProjectionReceiver(boolean shouldReceive) {
774         return nSetProjectionReceiver(mNativeRenderNode, shouldReceive);
775     }
776 
777     /**
778      * Sets the outline, defining the shape that casts a shadow, and the path to
779      * be clipped if setClipToOutline is set.
780      *
781      * This will make a copy of the provided {@link Outline}, so any future modifications
782      * to the outline will need to call {@link #setOutline(Outline)} with the modified
783      * outline for those changes to be applied.
784      *
785      * @param outline The outline to use for this RenderNode.
786      * @return True if the value changed, false if the new value was the same as the previous value.
787      */
setOutline(@ullable Outline outline)788     public boolean setOutline(@Nullable Outline outline) {
789         if (outline == null) {
790             return nSetOutlineNone(mNativeRenderNode);
791         }
792 
793         switch (outline.mMode) {
794             case Outline.MODE_EMPTY:
795                 return nSetOutlineEmpty(mNativeRenderNode);
796             case Outline.MODE_ROUND_RECT:
797                 return nSetOutlineRoundRect(mNativeRenderNode,
798                         outline.mRect.left, outline.mRect.top,
799                         outline.mRect.right, outline.mRect.bottom,
800                         outline.mRadius, outline.mAlpha);
801             case Outline.MODE_PATH:
802                 return nSetOutlinePath(mNativeRenderNode, outline.mPath.mNativePath,
803                         outline.mAlpha);
804         }
805 
806         throw new IllegalArgumentException("Unrecognized outline?");
807     }
808 
809     /** @hide */
clearStretch()810     public boolean clearStretch() {
811         return nClearStretch(mNativeRenderNode);
812     }
813 
814     /** @hide */
stretch(float vecX, float vecY, float maxStretchAmountX, float maxStretchAmountY)815     public boolean stretch(float vecX, float vecY,
816         float maxStretchAmountX, float maxStretchAmountY) {
817         if (Float.isInfinite(vecX) || Float.isNaN(vecX)) {
818             throw new IllegalArgumentException("vecX must be a finite, non-NaN value " + vecX);
819         }
820         if (Float.isInfinite(vecY) || Float.isNaN(vecY)) {
821             throw new IllegalArgumentException("vecY must be a finite, non-NaN value " + vecY);
822         }
823 
824         if (maxStretchAmountX <= 0.0f) {
825             throw new IllegalArgumentException(
826                     "The max horizontal stretch amount must be >0, got " + maxStretchAmountX);
827         }
828         if (maxStretchAmountY <= 0.0f) {
829             throw new IllegalArgumentException(
830                     "The max vertical stretch amount must be >0, got " + maxStretchAmountY);
831         }
832         return nStretch(
833                 mNativeRenderNode,
834                 vecX,
835                 vecY,
836                 maxStretchAmountX,
837                 maxStretchAmountY
838         );
839     }
840 
841     /**
842      * Checks if the RenderNode has a shadow. That is, if the combination of {@link #getElevation()}
843      * and {@link #getTranslationZ()} is greater than zero, there is an {@link Outline} set with
844      * a valid shadow caster path, and the provided outline has a non-zero
845      * {@link Outline#getAlpha()}.
846      *
847      * @return True if this RenderNode has a shadow, false otherwise
848      */
hasShadow()849     public boolean hasShadow() {
850         return nHasShadow(mNativeRenderNode);
851     }
852 
853     /**
854      * Sets the color of the spot shadow that is drawn when the RenderNode has a positive Z or
855      * elevation value and is drawn inside of a {@link Canvas#enableZ()} section.
856      * <p>
857      * By default the shadow color is black. Generally, this color will be opaque so the intensity
858      * of the shadow is consistent between different RenderNodes with different colors.
859      * <p>
860      * The opacity of the final spot shadow is a function of the shadow caster height, the
861      * alpha channel of the outlineSpotShadowColor (typically opaque), and the
862      * {@link android.R.attr#spotShadowAlpha} theme attribute
863      *
864      * @param color The color this RenderNode will cast for its elevation spot shadow.
865      * @return True if the value changed, false if the new value was the same as the previous value.
866      */
setSpotShadowColor(@olorInt int color)867     public boolean setSpotShadowColor(@ColorInt int color) {
868         return nSetSpotShadowColor(mNativeRenderNode, color);
869     }
870 
871     /**
872      * @return The shadow color set by {@link #setSpotShadowColor(int)}, or black if nothing
873      * was set
874      */
getSpotShadowColor()875     public @ColorInt int getSpotShadowColor() {
876         return nGetSpotShadowColor(mNativeRenderNode);
877     }
878 
879     /**
880      * Sets the color of the ambient shadow that is drawn when the RenderNode has a positive Z or
881      * elevation value and is drawn inside of a {@link Canvas#enableZ()} section.
882      * <p>
883      * By default the shadow color is black. Generally, this color will be opaque so the intensity
884      * of the shadow is consistent between different RenderNodes with different colors.
885      * <p>
886      * The opacity of the final ambient shadow is a function of the shadow caster height, the
887      * alpha channel of the outlineAmbientShadowColor (typically opaque), and the
888      * {@link android.R.attr#ambientShadowAlpha} theme attribute.
889      *
890      * @param color The color this RenderNode will cast for its elevation shadow.
891      * @return True if the value changed, false if the new value was the same as the previous value.
892      */
setAmbientShadowColor(@olorInt int color)893     public boolean setAmbientShadowColor(@ColorInt int color) {
894         return nSetAmbientShadowColor(mNativeRenderNode, color);
895     }
896 
897     /**
898      * @return The shadow color set by {@link #setAmbientShadowColor(int)}, or black if
899      * nothing was set
900      */
getAmbientShadowColor()901     public @ColorInt int getAmbientShadowColor() {
902         return nGetAmbientShadowColor(mNativeRenderNode);
903     }
904 
905     /**
906      * Enables or disables clipping to the outline.
907      *
908      * @param clipToOutline true if clipping to the outline.
909      * @return True if the clipToOutline value changed, false if previous value matched the new
910      *         value.
911      */
setClipToOutline(boolean clipToOutline)912     public boolean setClipToOutline(boolean clipToOutline) {
913         return nSetClipToOutline(mNativeRenderNode, clipToOutline);
914     }
915 
916     /**
917      * See {@link #setClipToOutline(boolean)}
918      *
919      * @return True if this RenderNode clips to its outline, false otherwise
920      */
getClipToOutline()921     public boolean getClipToOutline() {
922         return nGetClipToOutline(mNativeRenderNode);
923     }
924 
925     /**
926      * Controls the RenderNode's circular reveal clip.
927      *
928      * @hide
929      */
setRevealClip(boolean shouldClip, float x, float y, float radius)930     public boolean setRevealClip(boolean shouldClip,
931             float x, float y, float radius) {
932         return nSetRevealClip(mNativeRenderNode, shouldClip, x, y, radius);
933     }
934 
935     /**
936      * Set the static matrix on the display list. The specified matrix is combined with other
937      * transforms (such as {@link #setScaleX(float)}, {@link #setRotationZ(float)}, etc.)
938      *
939      * @param matrix A transform matrix to apply to this display list
940      * @hide TODO Do we want this?
941      */
setStaticMatrix(Matrix matrix)942     public boolean setStaticMatrix(Matrix matrix) {
943         return nSetStaticMatrix(mNativeRenderNode, matrix.ni());
944     }
945 
946     /**
947      * Set the Animation matrix on the display list. This matrix exists if an Animation is
948      * currently playing on a View, and is set on the display list during at draw() time. When
949      * the Animation finishes, the matrix should be cleared by sending <code>null</code>
950      * for the matrix parameter.
951      *
952      * @param matrix The matrix, null indicates that the matrix should be cleared.
953      * @see #getAnimationMatrix()
954      *
955      * @hide TODO Do we want this?
956      */
setAnimationMatrix(@ullable Matrix matrix)957     public boolean setAnimationMatrix(@Nullable Matrix matrix) {
958         return nSetAnimationMatrix(mNativeRenderNode,
959                 (matrix != null) ? matrix.ni() : 0);
960     }
961 
962     /**
963      * Returns the previously set Animation matrix. This matrix exists if an Animation is
964      * currently playing on a View, and is set on the display list during at draw() time.
965      * Returns <code>null</code> when there is no transformation provided by
966      * {@link #setAnimationMatrix(Matrix)}.
967      *
968      * @return the current Animation matrix.
969      * @see #setAnimationMatrix(Matrix)
970      *
971      * @hide
972      */
973     @Nullable
getAnimationMatrix()974     public Matrix getAnimationMatrix() {
975         Matrix output = new Matrix();
976         if (nGetAnimationMatrix(mNativeRenderNode, output.ni())) {
977             return output;
978         } else {
979             return null;
980         }
981     }
982 
983     /**
984      * Sets the translucency level for the display list.
985      *
986      * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
987      * @see View#setAlpha(float)
988      * @see #getAlpha()
989      * @return True if the value changed, false if the new value was the same as the previous value.
990      */
setAlpha(float alpha)991     public boolean setAlpha(float alpha) {
992         return nSetAlpha(mNativeRenderNode, alpha);
993     }
994 
995     /**
996      * Configure the {@link android.graphics.RenderEffect} to apply to this RenderNode. This
997      * will apply a visual effect to the end result of the contents of this RenderNode before
998      * it is drawn into the destination. For example if
999      * {@link RenderEffect#createBlurEffect(float, float, RenderEffect, Shader.TileMode)}
1000      * is provided, the contents will be drawn in a separate layer, then this layer will
1001      * be blurred when this RenderNode is drawn into the destination.
1002      * @param renderEffect to be applied to the RenderNode. Passing null clears all previously
1003      *          configured RenderEffects
1004      * @return True if the value changed, false if the new value was the same as the previous value.
1005      */
setRenderEffect(@ullable RenderEffect renderEffect)1006     public boolean setRenderEffect(@Nullable RenderEffect renderEffect) {
1007         return nSetRenderEffect(mNativeRenderNode,
1008                 renderEffect != null ? renderEffect.getNativeInstance() : 0);
1009     }
1010 
1011     /**
1012      * Configure the {@link android.graphics.RenderEffect} to apply to the backdrop contents of
1013      * this RenderNode. This will apply a visual effect to the result of the backdrop contents
1014      * of this RenderNode before the RenderNode is drawn into the destination. For example if
1015      * {@link RenderEffect#createBlurEffect(float, float, RenderEffect, Shader.TileMode)}
1016      * is provided, the previous content behind this RenderNode will be blurred before the
1017      * RenderNode is drawn in to the destination.
1018      * @param renderEffect to be applied to the backdrop contents of this RenderNode. Passing
1019      *          null clears all previously configured RenderEffects
1020      * @return True if the value changed, false if the new value was the same as the previous value.
1021      * @hide
1022      */
setBackdropRenderEffect(@ullable RenderEffect renderEffect)1023     public boolean setBackdropRenderEffect(@Nullable RenderEffect renderEffect) {
1024         return nSetBackdropRenderEffect(mNativeRenderNode,
1025                 renderEffect != null ? renderEffect.getNativeInstance() : 0);
1026     }
1027 
1028     /**
1029      * Returns the translucency level of this display list.
1030      *
1031      * @return A value between 0.0f and 1.0f
1032      * @see #setAlpha(float)
1033      */
getAlpha()1034     public float getAlpha() {
1035         return nGetAlpha(mNativeRenderNode);
1036     }
1037 
1038     /**
1039      * Sets whether the display list renders content which overlaps. Non-overlapping rendering
1040      * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default
1041      * display lists consider they do not have overlapping content.
1042      *
1043      * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping,
1044      *                                true otherwise.
1045      * @see android.view.View#hasOverlappingRendering()
1046      * @see #hasOverlappingRendering()
1047      */
setHasOverlappingRendering(boolean hasOverlappingRendering)1048     public boolean setHasOverlappingRendering(boolean hasOverlappingRendering) {
1049         return nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering);
1050     }
1051 
1052     /** @hide */
1053     @IntDef({USAGE_BACKGROUND})
1054     @Retention(RetentionPolicy.SOURCE)
1055     public @interface UsageHint {
1056     }
1057 
1058     /**
1059      * The default usage hint
1060      *
1061      * @hide
1062      */
1063     public static final int USAGE_UNKNOWN = 0;
1064 
1065     /**
1066      * Usage is background content
1067      *
1068      * @hide
1069      */
1070     public static final int USAGE_BACKGROUND = 1;
1071 
1072     /**
1073      * Provides a hint on what this RenderNode's display list content contains. This hint is used
1074      * for automatic content transforms to improve accessibility or similar.
1075      *
1076      * @hide
1077      */
setUsageHint(@sageHint int usageHint)1078     public void setUsageHint(@UsageHint int usageHint) {
1079         nSetUsageHint(mNativeRenderNode, usageHint);
1080     }
1081 
1082     /**
1083      * Indicates whether the content of this display list overlaps.
1084      *
1085      * @return True if this display list renders content which overlaps, false otherwise.
1086      * @see #setHasOverlappingRendering(boolean)
1087      */
hasOverlappingRendering()1088     public boolean hasOverlappingRendering() {
1089         return nHasOverlappingRendering(mNativeRenderNode);
1090     }
1091 
1092     /**
1093      * Sets the base elevation of this RenderNode in pixels
1094      *
1095      * @param lift the elevation in pixels
1096      * @return True if the value changed, false if the new value was the same as the previous value.
1097      */
setElevation(float lift)1098     public boolean setElevation(float lift) {
1099         return nSetElevation(mNativeRenderNode, lift);
1100     }
1101 
1102     /**
1103      * See {@link #setElevation(float)}
1104      *
1105      * @return The RenderNode's current elevation
1106      */
getElevation()1107     public float getElevation() {
1108         return nGetElevation(mNativeRenderNode);
1109     }
1110 
1111     /**
1112      * Sets the translation value for the display list on the X axis.
1113      *
1114      * @param translationX The X axis translation value of the display list, in pixels
1115      * @see View#setTranslationX(float)
1116      * @see #getTranslationX()
1117      * @return True if the value changed, false if the new value was the same as the previous value.
1118      */
setTranslationX(float translationX)1119     public boolean setTranslationX(float translationX) {
1120         return nSetTranslationX(mNativeRenderNode, translationX);
1121     }
1122 
1123     /**
1124      * Returns the translation value for this display list on the X axis, in pixels.
1125      *
1126      * @see #setTranslationX(float)
1127      */
getTranslationX()1128     public float getTranslationX() {
1129         return nGetTranslationX(mNativeRenderNode);
1130     }
1131 
1132     /**
1133      * Sets the translation value for the display list on the Y axis.
1134      *
1135      * @param translationY The Y axis translation value of the display list, in pixels
1136      * @see View#setTranslationY(float)
1137      * @see #getTranslationY()
1138      * @return True if the value changed, false if the new value was the same as the previous value.
1139      */
setTranslationY(float translationY)1140     public boolean setTranslationY(float translationY) {
1141         return nSetTranslationY(mNativeRenderNode, translationY);
1142     }
1143 
1144     /**
1145      * Returns the translation value for this display list on the Y axis, in pixels.
1146      *
1147      * @see #setTranslationY(float)
1148      */
getTranslationY()1149     public float getTranslationY() {
1150         return nGetTranslationY(mNativeRenderNode);
1151     }
1152 
1153     /**
1154      * Sets the translation value for the display list on the Z axis.
1155      *
1156      * @see View#setTranslationZ(float)
1157      * @see #getTranslationZ()
1158      * @return True if the value changed, false if the new value was the same as the previous value.
1159      */
setTranslationZ(float translationZ)1160     public boolean setTranslationZ(float translationZ) {
1161         return nSetTranslationZ(mNativeRenderNode, translationZ);
1162     }
1163 
1164     /**
1165      * Returns the translation value for this display list on the Z axis.
1166      *
1167      * @see #setTranslationZ(float)
1168      */
getTranslationZ()1169     public float getTranslationZ() {
1170         return nGetTranslationZ(mNativeRenderNode);
1171     }
1172 
1173     /**
1174      * Sets the rotation value for the display list around the Z axis.
1175      *
1176      * @param rotation The rotation value of the display list, in degrees
1177      * @see View#setRotation(float)
1178      * @see #getRotationZ()
1179      * @return True if the value changed, false if the new value was the same as the previous value.
1180      */
setRotationZ(float rotation)1181     public boolean setRotationZ(float rotation) {
1182         return nSetRotation(mNativeRenderNode, rotation);
1183     }
1184 
1185     /**
1186      * Returns the rotation value for this display list around the Z axis, in degrees.
1187      *
1188      * @see #setRotationZ(float)
1189      */
getRotationZ()1190     public float getRotationZ() {
1191         return nGetRotation(mNativeRenderNode);
1192     }
1193 
1194     /**
1195      * Sets the rotation value for the display list around the X axis.
1196      *
1197      * @param rotationX The rotation value of the display list, in degrees
1198      * @see View#setRotationX(float)
1199      * @see #getRotationX()
1200      * @return True if the value changed, false if the new value was the same as the previous value.
1201      */
setRotationX(float rotationX)1202     public boolean setRotationX(float rotationX) {
1203         return nSetRotationX(mNativeRenderNode, rotationX);
1204     }
1205 
1206     /**
1207      * Returns the rotation value for this display list around the X axis, in degrees.
1208      *
1209      * @see #setRotationX(float)
1210      */
getRotationX()1211     public float getRotationX() {
1212         return nGetRotationX(mNativeRenderNode);
1213     }
1214 
1215     /**
1216      * Sets the rotation value for the display list around the Y axis.
1217      *
1218      * @param rotationY The rotation value of the display list, in degrees
1219      * @see View#setRotationY(float)
1220      * @see #getRotationY()
1221      * @return True if the value changed, false if the new value was the same as the previous value.
1222      */
setRotationY(float rotationY)1223     public boolean setRotationY(float rotationY) {
1224         return nSetRotationY(mNativeRenderNode, rotationY);
1225     }
1226 
1227     /**
1228      * Returns the rotation value for this display list around the Y axis, in degrees.
1229      *
1230      * @see #setRotationY(float)
1231      */
getRotationY()1232     public float getRotationY() {
1233         return nGetRotationY(mNativeRenderNode);
1234     }
1235 
1236     /**
1237      * Sets the scale value for the display list on the X axis.
1238      *
1239      * @param scaleX The scale value of the display list
1240      * @see View#setScaleX(float)
1241      * @see #getScaleX()
1242      * @return True if the value changed, false if the new value was the same as the previous value.
1243      */
setScaleX(float scaleX)1244     public boolean setScaleX(float scaleX) {
1245         return nSetScaleX(mNativeRenderNode, scaleX);
1246     }
1247 
1248     /**
1249      * Returns the scale value for this display list on the X axis.
1250      *
1251      * @see #setScaleX(float)
1252      */
getScaleX()1253     public float getScaleX() {
1254         return nGetScaleX(mNativeRenderNode);
1255     }
1256 
1257     /**
1258      * Sets the scale value for the display list on the Y axis.
1259      *
1260      * @param scaleY The scale value of the display list
1261      * @see View#setScaleY(float)
1262      * @see #getScaleY()
1263      * @return True if the value changed, false if the new value was the same as the previous value.
1264      */
setScaleY(float scaleY)1265     public boolean setScaleY(float scaleY) {
1266         return nSetScaleY(mNativeRenderNode, scaleY);
1267     }
1268 
1269     /**
1270      * Returns the scale value for this display list on the Y axis.
1271      *
1272      * @see #setScaleY(float)
1273      */
getScaleY()1274     public float getScaleY() {
1275         return nGetScaleY(mNativeRenderNode);
1276     }
1277 
1278     /**
1279      * Sets the pivot value for the display list on the X axis
1280      *
1281      * @param pivotX The pivot value of the display list on the X axis, in pixels
1282      * @see View#setPivotX(float)
1283      * @see #getPivotX()
1284      * @return True if the value changed, false if the new value was the same as the previous value.
1285      */
setPivotX(float pivotX)1286     public boolean setPivotX(float pivotX) {
1287         return nSetPivotX(mNativeRenderNode, pivotX);
1288     }
1289 
1290     /**
1291      * Returns the pivot value for this display list on the X axis, in pixels.
1292      *
1293      * @see #setPivotX(float)
1294      */
getPivotX()1295     public float getPivotX() {
1296         return nGetPivotX(mNativeRenderNode);
1297     }
1298 
1299     /**
1300      * Sets the pivot value for the display list on the Y axis
1301      *
1302      * @param pivotY The pivot value of the display list on the Y axis, in pixels
1303      * @see View#setPivotY(float)
1304      * @see #getPivotY()
1305      * @return True if the value changed, false if the new value was the same as the previous value.
1306      */
setPivotY(float pivotY)1307     public boolean setPivotY(float pivotY) {
1308         return nSetPivotY(mNativeRenderNode, pivotY);
1309     }
1310 
1311     /**
1312      * Returns the pivot value for this display list on the Y axis, in pixels.
1313      *
1314      * @see #setPivotY(float)
1315      */
getPivotY()1316     public float getPivotY() {
1317         return nGetPivotY(mNativeRenderNode);
1318     }
1319 
1320     /**
1321      * @return Whether or not a pivot was explicitly set with {@link #setPivotX(float)} or
1322      * {@link #setPivotY(float)}. If no pivot has been set then the pivot will be the center
1323      * of the RenderNode.
1324      */
isPivotExplicitlySet()1325     public boolean isPivotExplicitlySet() {
1326         return nIsPivotExplicitlySet(mNativeRenderNode);
1327     }
1328 
1329     /**
1330      * Clears any pivot previously set by a call to  {@link #setPivotX(float)} or
1331      * {@link #setPivotY(float)}. After calling this {@link #isPivotExplicitlySet()} will be false
1332      * and the pivot used for rotation will return to default of being centered on the view.
1333      *
1334      * @return True if the value changed, false if the new value was the same as the previous value.
1335      */
resetPivot()1336     public boolean resetPivot() {
1337         return nResetPivot(mNativeRenderNode);
1338     }
1339 
1340     /**
1341      * <p>Sets the distance along the Z axis (orthogonal to the X/Y plane on which
1342      * RenderNodes are drawn) from the camera to this RenderNode. The camera's distance
1343      * affects 3D transformations, for instance rotations around the X and Y
1344      * axis. If the rotationX or rotationY properties are changed and this view is
1345      * large (more than half the size of the screen), it is recommended to always
1346      * use a camera distance that's greater than the height (X axis rotation) or
1347      * the width (Y axis rotation) of this view.</p>
1348      *
1349      * <p>The distance of the camera from the drawing plane can have an affect on the
1350      * perspective distortion of the RenderNode when it is rotated around the x or y axis.
1351      * For example, a large distance will result in a large viewing angle, and there
1352      * will not be much perspective distortion of the view as it rotates. A short
1353      * distance may cause much more perspective distortion upon rotation, and can
1354      * also result in some drawing artifacts if the rotated view ends up partially
1355      * behind the camera (which is why the recommendation is to use a distance at
1356      * least as far as the size of the view, if the view is to be rotated.)</p>
1357      *
1358      * <p>The distance is expressed in pixels and must always be positive</p>
1359      *
1360      * @param distance The distance in pixels, must always be positive
1361      * @see #setRotationX(float)
1362      * @see #setRotationY(float)
1363      * @return True if the value changed, false if the new value was the same as the previous value.
1364      */
setCameraDistance( @loatRangefrom = 0.0f, to = Float.MAX_VALUE) float distance)1365     public boolean setCameraDistance(
1366             @FloatRange(from = 0.0f, to = Float.MAX_VALUE) float distance) {
1367         if (!Float.isFinite(distance) || distance < 0.0f) {
1368             throw new IllegalArgumentException("distance must be finite & positive, given="
1369                     + distance);
1370         }
1371         // Native actually wants this to be negative not positive, so we flip it.
1372         return nSetCameraDistance(mNativeRenderNode, -distance);
1373     }
1374 
1375     /**
1376      * Returns the distance in Z of the camera for this RenderNode
1377      *
1378      * @return the distance along the Z axis in pixels.
1379      * @see #setCameraDistance(float)
1380      */
getCameraDistance()1381     public @FloatRange(from = 0.0f, to = Float.MAX_VALUE) float getCameraDistance() {
1382         return -nGetCameraDistance(mNativeRenderNode);
1383     }
1384 
1385     /**
1386      * Sets the left position for the RenderNode.
1387      *
1388      * @param left The left position, in pixels, of the RenderNode
1389      * @return true if the value changed, false otherwise
1390      * @hide
1391      */
setLeft(int left)1392     public boolean setLeft(int left) {
1393         return nSetLeft(mNativeRenderNode, left);
1394     }
1395 
1396     /**
1397      * Sets the top position for the RenderNode.
1398      *
1399      * @param top The top position, in pixels, of the RenderNode
1400      * @return true if the value changed, false otherwise.
1401      * @hide
1402      */
setTop(int top)1403     public boolean setTop(int top) {
1404         return nSetTop(mNativeRenderNode, top);
1405     }
1406 
1407     /**
1408      * Sets the right position for the RenderNode.
1409      *
1410      * @param right The right position, in pixels, of the RenderNode
1411      * @return true if the value changed, false otherwise.
1412      * @hide
1413      */
setRight(int right)1414     public boolean setRight(int right) {
1415         return nSetRight(mNativeRenderNode, right);
1416     }
1417 
1418     /**
1419      * Sets the bottom position for the RenderNode.
1420      *
1421      * @param bottom The bottom position, in pixels, of the RenderNode
1422      * @return true if the value changed, false otherwise.
1423      * @hide
1424      */
setBottom(int bottom)1425     public boolean setBottom(int bottom) {
1426         return nSetBottom(mNativeRenderNode, bottom);
1427     }
1428 
1429     /**
1430      * Gets the left position for the RenderNode.
1431      *
1432      * @return the left position in pixels
1433      */
getLeft()1434     public int getLeft() {
1435         return nGetLeft(mNativeRenderNode);
1436     }
1437 
1438     /**
1439      * Gets the top position for the RenderNode.
1440      *
1441      * @return the top position in pixels
1442      */
getTop()1443     public int getTop() {
1444         return nGetTop(mNativeRenderNode);
1445     }
1446 
1447     /**
1448      * Gets the right position for the RenderNode.
1449      *
1450      * @return the right position in pixels
1451      */
getRight()1452     public int getRight() {
1453         return nGetRight(mNativeRenderNode);
1454     }
1455 
1456     /**
1457      * Gets the bottom position for the RenderNode.
1458      *
1459      * @return the bottom position in pixels
1460      */
getBottom()1461     public int getBottom() {
1462         return nGetBottom(mNativeRenderNode);
1463     }
1464 
1465     /**
1466      * Gets the width of the RenderNode, which is the right - left.
1467      *
1468      * @return the width of the RenderNode
1469      */
getWidth()1470     public int getWidth() {
1471         return nGetWidth(mNativeRenderNode);
1472     }
1473 
1474     /**
1475      * Gets the height of the RenderNode, which is the bottom - top.
1476      *
1477      * @return the height of the RenderNode
1478      */
getHeight()1479     public int getHeight() {
1480         return nGetHeight(mNativeRenderNode);
1481     }
1482 
1483     /**
1484      * Sets the left, top, right, and bottom of the RenderNode.
1485      *
1486      * @param left   The left position of the RenderNode, in pixels
1487      * @param top    The top position of the RenderNode, in pixels
1488      * @param right  The right position of the RenderNode, in pixels
1489      * @param bottom The bottom position of the RenderNode, in pixels
1490      * @return true if any values changed, false otherwise.
1491      * @hide
1492      */
setLeftTopRightBottom(int left, int top, int right, int bottom)1493     public boolean setLeftTopRightBottom(int left, int top, int right, int bottom) {
1494         return nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom);
1495     }
1496 
1497     /**
1498      * Sets the position of the RenderNode.
1499      *
1500      * @param left   The left position of the RenderNode, in pixels
1501      * @param top    The top position of the RenderNode, in pixels
1502      * @param right  The right position of the RenderNode, in pixels
1503      * @param bottom The bottom position of the RenderNode, in pixels
1504      * @return True if the value changed, false if the new value was the same as the previous value.
1505      */
setPosition(int left, int top, int right, int bottom)1506     public boolean setPosition(int left, int top, int right, int bottom) {
1507         return nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom);
1508     }
1509 
1510     /**
1511      * Sets the position of the RenderNode.
1512      *
1513      * @param position The position rectangle in pixels
1514      * @return True if the value changed, false if the new value was the same as the previous value.
1515      */
setPosition(@onNull Rect position)1516     public boolean setPosition(@NonNull Rect position) {
1517         return nSetLeftTopRightBottom(mNativeRenderNode,
1518                 position.left, position.top, position.right, position.bottom);
1519     }
1520 
1521     /**
1522      * Offsets the left and right positions for the RenderNode
1523      *
1524      * @param offset The amount that the left and right positions are offset in pixels
1525      * @return True if the value changed, false if the new value was the same as the previous value.
1526      */
offsetLeftAndRight(int offset)1527     public boolean offsetLeftAndRight(int offset) {
1528         return nOffsetLeftAndRight(mNativeRenderNode, offset);
1529     }
1530 
1531     /**
1532      * Offsets the top and bottom values for the RenderNode
1533      *
1534      * @param offset The amount that the left and right positions are offset in pixels
1535      * @return True if the value changed, false if the new value was the same as the previous value.
1536      */
offsetTopAndBottom(int offset)1537     public boolean offsetTopAndBottom(int offset) {
1538         return nOffsetTopAndBottom(mNativeRenderNode, offset);
1539     }
1540 
1541     /**
1542      * Outputs the RenderNode to the log. This method exists for use by
1543      * tools to output display lists for selected nodes to the log.
1544      *
1545      * @hide TODO: Expose? Should the shape of this be different than forced dump to logcat?
1546      */
output()1547     public void output() {
1548         nOutput(mNativeRenderNode);
1549     }
1550 
1551     /**
1552      * Gets the approximate memory usage of the RenderNode for debug purposes. Does not include
1553      * the memory usage of any child RenderNodes nor any bitmaps, only the memory usage of
1554      * this RenderNode and any data it owns.
1555      *
1556      * @return Approximate memory usage in bytes.
1557      */
computeApproximateMemoryUsage()1558     public @BytesLong long computeApproximateMemoryUsage() {
1559         return nGetUsageSize(mNativeRenderNode);
1560     }
1561 
1562     /**
1563      * Gets the approximate amount of memory allocated for the RenderNode for debug purposes.
1564      * Does not include the memory allocated by any child RenderNodes nor any bitmaps, only the
1565      * memory allocated for this RenderNode and any data it owns.
1566      *
1567      * The difference between this and {@link #computeApproximateMemoryUsage()} is this includes
1568      * memory allocated but not used. In particular structures such as DisplayLists are similar
1569      * to things like ArrayLists - they need to resize as commands are added to them. As such,
1570      * memory used can be less than memory allocated.
1571      *
1572      * @hide */
computeApproximateMemoryAllocated()1573     public @BytesLong long computeApproximateMemoryAllocated() {
1574         return nGetAllocatedSize(mNativeRenderNode);
1575     }
1576 
1577     /**
1578      * Sets whether or not to allow force dark to apply to this RenderNode.
1579      *
1580      * Setting this to false will disable the auto-dark feature on everything this RenderNode
1581      * draws, including any descendants.
1582      *
1583      * Setting this to true will allow this RenderNode to be automatically made dark, however
1584      * a value of 'true' will not override any 'false' value in its parent chain nor will
1585      * it prevent any 'false' in any of its children.
1586      *
1587      * @param allow Whether or not to allow force dark.
1588      * @return True if the value changed, false if the new value was the same as the previous value.
1589      */
setForceDarkAllowed(boolean allow)1590     public boolean setForceDarkAllowed(boolean allow) {
1591         return nSetAllowForceDark(mNativeRenderNode, allow);
1592     }
1593 
1594     /**
1595      * See {@link #setForceDarkAllowed(boolean)}
1596      *
1597      * @return true if force dark is allowed (default), false if it is disabled
1598      */
isForceDarkAllowed()1599     public boolean isForceDarkAllowed() {
1600         return nGetAllowForceDark(mNativeRenderNode);
1601     }
1602 
1603     /**
1604      * Returns the unique ID that identifies this RenderNode. This ID is unique for the
1605      * lifetime of the process. IDs are reset on process death, and are unique only within
1606      * the process.
1607      *
1608      * This ID is intended to be used with debugging tools to associate a particular
1609      * RenderNode across different debug dumping & inspection tools. For example
1610      * a View layout inspector should include the unique ID for any RenderNodes that it owns
1611      * to associate the drawing content with the layout content.
1612      *
1613      * @return the unique ID for this RenderNode
1614      */
getUniqueId()1615     public long getUniqueId() {
1616         return nGetUniqueId(mNativeRenderNode);
1617     }
1618 
1619     /**
1620      * Captures whether this RenderNote represents a TextureView
1621      * TODO(b/281695725): Clean this up once TextureView use setFrameRate API
1622      *
1623      * @hide
1624      */
setIsTextureView()1625     public void setIsTextureView() {
1626         nSetIsTextureView(mNativeRenderNode);
1627     }
1628 
1629     ///////////////////////////////////////////////////////////////////////////
1630     // Animations
1631     ///////////////////////////////////////////////////////////////////////////
1632 
1633     /**
1634      * TODO: Figure out if this can be eliminated/refactored away
1635      *
1636      * For now this interface exists to de-couple RenderNode from anything View-specific in a
1637      * bit of a kludge.
1638      *
1639      * @hide
1640      */
1641     public interface AnimationHost {
1642         /** @hide */
registerAnimatingRenderNode(RenderNode renderNode, Animator animator)1643         void registerAnimatingRenderNode(RenderNode renderNode, Animator animator);
1644 
1645         /** @hide */
registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator)1646         void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator);
1647 
1648         /** @hide */
isAttached()1649         boolean isAttached();
1650     }
1651 
1652     /** @hide */
addAnimator(RenderNodeAnimator animator)1653     public void addAnimator(RenderNodeAnimator animator) {
1654         if (!isAttached()) {
1655             throw new IllegalStateException("Cannot start this animator on a detached view!");
1656         }
1657         nAddAnimator(mNativeRenderNode, animator.getNativeAnimator());
1658         mAnimationHost.registerAnimatingRenderNode(this, animator);
1659     }
1660 
1661     /** @hide */
isAttached()1662     public boolean isAttached() {
1663         return mAnimationHost != null && mAnimationHost.isAttached();
1664     }
1665 
1666     /** @hide */
registerVectorDrawableAnimator(NativeVectorDrawableAnimator animatorSet)1667     public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animatorSet) {
1668         if (!isAttached()) {
1669             throw new IllegalStateException("Cannot start this animator on a detached view!");
1670         }
1671         mAnimationHost.registerVectorDrawableAnimator(animatorSet);
1672     }
1673 
1674     /** @hide */
endAllAnimators()1675     public void endAllAnimators() {
1676         nEndAllAnimators(mNativeRenderNode);
1677     }
1678 
1679     /** @hide */
forceEndAnimators()1680     public void forceEndAnimators() {
1681         nForceEndAnimators(mNativeRenderNode);
1682     }
1683 
1684     ///////////////////////////////////////////////////////////////////////////
1685     // Regular JNI methods
1686     ///////////////////////////////////////////////////////////////////////////
1687 
nCreate(String name)1688     private static native long nCreate(String name);
1689 
nGetNativeFinalizer()1690     private static native long nGetNativeFinalizer();
1691 
nOutput(long renderNode)1692     private static native void nOutput(long renderNode);
1693 
nGetUsageSize(long renderNode)1694     private static native int nGetUsageSize(long renderNode);
nGetAllocatedSize(long renderNode)1695     private static native int nGetAllocatedSize(long renderNode);
1696 
nRequestPositionUpdates(long renderNode, WeakReference<PositionUpdateListener> callback)1697     private static native void nRequestPositionUpdates(long renderNode,
1698             WeakReference<PositionUpdateListener> callback);
1699 
1700     // Animations
1701 
nAddAnimator(long renderNode, long animatorPtr)1702     private static native void nAddAnimator(long renderNode, long animatorPtr);
1703 
nEndAllAnimators(long renderNode)1704     private static native void nEndAllAnimators(long renderNode);
1705 
nForceEndAnimators(long renderNode)1706     private static native void nForceEndAnimators(long renderNode);
1707 
1708     ///////////////////////////////////////////////////////////////////////////
1709     // @CriticalNative methods
1710     ///////////////////////////////////////////////////////////////////////////
1711 
1712     @CriticalNative
nDiscardDisplayList(long renderNode)1713     private static native void nDiscardDisplayList(long renderNode);
1714 
1715     @CriticalNative
nIsValid(long renderNode)1716     private static native boolean nIsValid(long renderNode);
1717 
1718     // Matrix
1719 
1720     @CriticalNative
nGetTransformMatrix(long renderNode, long nativeMatrix)1721     private static native void nGetTransformMatrix(long renderNode, long nativeMatrix);
1722 
1723     @CriticalNative
nGetInverseTransformMatrix(long renderNode, long nativeMatrix)1724     private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix);
1725 
1726     @CriticalNative
nHasIdentityMatrix(long renderNode)1727     private static native boolean nHasIdentityMatrix(long renderNode);
1728 
1729     // Properties
1730 
1731     @CriticalNative
nOffsetTopAndBottom(long renderNode, int offset)1732     private static native boolean nOffsetTopAndBottom(long renderNode, int offset);
1733 
1734     @CriticalNative
nOffsetLeftAndRight(long renderNode, int offset)1735     private static native boolean nOffsetLeftAndRight(long renderNode, int offset);
1736 
1737     @CriticalNative
nSetLeftTopRightBottom(long renderNode, int left, int top, int right, int bottom)1738     private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top,
1739             int right, int bottom);
1740 
1741     @CriticalNative
nSetLeft(long renderNode, int left)1742     private static native boolean nSetLeft(long renderNode, int left);
1743 
1744     @CriticalNative
nSetTop(long renderNode, int top)1745     private static native boolean nSetTop(long renderNode, int top);
1746 
1747     @CriticalNative
nSetRight(long renderNode, int right)1748     private static native boolean nSetRight(long renderNode, int right);
1749 
1750     @CriticalNative
nSetBottom(long renderNode, int bottom)1751     private static native boolean nSetBottom(long renderNode, int bottom);
1752 
1753     @CriticalNative
nGetLeft(long renderNode)1754     private static native int nGetLeft(long renderNode);
1755 
1756     @CriticalNative
nGetTop(long renderNode)1757     private static native int nGetTop(long renderNode);
1758 
1759     @CriticalNative
nGetRight(long renderNode)1760     private static native int nGetRight(long renderNode);
1761 
1762     @CriticalNative
nGetBottom(long renderNode)1763     private static native int nGetBottom(long renderNode);
1764 
1765     @CriticalNative
nSetCameraDistance(long renderNode, float distance)1766     private static native boolean nSetCameraDistance(long renderNode, float distance);
1767 
1768     @CriticalNative
nSetPivotY(long renderNode, float pivotY)1769     private static native boolean nSetPivotY(long renderNode, float pivotY);
1770 
1771     @CriticalNative
nSetPivotX(long renderNode, float pivotX)1772     private static native boolean nSetPivotX(long renderNode, float pivotX);
1773 
1774     @CriticalNative
nResetPivot(long renderNode)1775     private static native boolean nResetPivot(long renderNode);
1776 
1777     @CriticalNative
nSetLayerType(long renderNode, int layerType)1778     private static native boolean nSetLayerType(long renderNode, int layerType);
1779 
1780     @CriticalNative
nGetLayerType(long renderNode)1781     private static native int nGetLayerType(long renderNode);
1782 
1783     @CriticalNative
nSetLayerPaint(long renderNode, long paint)1784     private static native boolean nSetLayerPaint(long renderNode, long paint);
1785 
1786     @CriticalNative
nSetClipToBounds(long renderNode, boolean clipToBounds)1787     private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds);
1788 
1789     @CriticalNative
nGetClipToBounds(long renderNode)1790     private static native boolean nGetClipToBounds(long renderNode);
1791 
1792     @CriticalNative
nSetClipBounds(long renderNode, int left, int top, int right, int bottom)1793     private static native boolean nSetClipBounds(long renderNode, int left, int top,
1794             int right, int bottom);
1795 
1796     @CriticalNative
nSetClipBoundsEmpty(long renderNode)1797     private static native boolean nSetClipBoundsEmpty(long renderNode);
1798 
1799     @CriticalNative
nSetProjectBackwards(long renderNode, boolean shouldProject)1800     private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject);
1801 
1802     @CriticalNative
nSetProjectionReceiver(long renderNode, boolean shouldReceive)1803     private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldReceive);
1804 
1805     @CriticalNative
nSetOutlineRoundRect(long renderNode, int left, int top, int right, int bottom, float radius, float alpha)1806     private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top,
1807             int right, int bottom, float radius, float alpha);
1808 
1809     @CriticalNative
nSetOutlinePath(long renderNode, long nativePath, float alpha)1810     private static native boolean nSetOutlinePath(long renderNode, long nativePath,
1811             float alpha);
1812 
1813     @CriticalNative
nSetOutlineEmpty(long renderNode)1814     private static native boolean nSetOutlineEmpty(long renderNode);
1815 
1816     @CriticalNative
nSetOutlineNone(long renderNode)1817     private static native boolean nSetOutlineNone(long renderNode);
1818 
1819     @CriticalNative
nClearStretch(long renderNode)1820     private static native boolean nClearStretch(long renderNode);
1821 
1822     @CriticalNative
nStretch(long renderNode, float vecX, float vecY, float maxStretchX, float maxStretchY)1823     private static native boolean nStretch(long renderNode, float vecX, float vecY,
1824             float maxStretchX, float maxStretchY);
1825 
1826     @CriticalNative
nHasShadow(long renderNode)1827     private static native boolean nHasShadow(long renderNode);
1828 
1829     @CriticalNative
nSetSpotShadowColor(long renderNode, int color)1830     private static native boolean nSetSpotShadowColor(long renderNode, int color);
1831 
1832     @CriticalNative
nSetAmbientShadowColor(long renderNode, int color)1833     private static native boolean nSetAmbientShadowColor(long renderNode, int color);
1834 
1835     @CriticalNative
nGetSpotShadowColor(long renderNode)1836     private static native int nGetSpotShadowColor(long renderNode);
1837 
1838     @CriticalNative
nGetAmbientShadowColor(long renderNode)1839     private static native int nGetAmbientShadowColor(long renderNode);
1840 
1841     @CriticalNative
nSetClipToOutline(long renderNode, boolean clipToOutline)1842     private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline);
1843 
1844     @CriticalNative
nSetRevealClip(long renderNode, boolean shouldClip, float x, float y, float radius)1845     private static native boolean nSetRevealClip(long renderNode,
1846             boolean shouldClip, float x, float y, float radius);
1847 
1848     @CriticalNative
nSetAlpha(long renderNode, float alpha)1849     private static native boolean nSetAlpha(long renderNode, float alpha);
1850 
1851     @CriticalNative
nSetRenderEffect(long renderNode, long renderEffect)1852     private static native boolean nSetRenderEffect(long renderNode, long renderEffect);
1853 
1854     @CriticalNative
nSetBackdropRenderEffect(long renderNode, long renderEffect)1855     private static native boolean nSetBackdropRenderEffect(long renderNode, long renderEffect);
1856 
1857     @CriticalNative
nSetHasOverlappingRendering(long renderNode, boolean hasOverlappingRendering)1858     private static native boolean nSetHasOverlappingRendering(long renderNode,
1859             boolean hasOverlappingRendering);
1860 
1861     @CriticalNative
nSetUsageHint(long renderNode, int usageHint)1862     private static native void nSetUsageHint(long renderNode, int usageHint);
1863 
1864     @CriticalNative
nSetElevation(long renderNode, float lift)1865     private static native boolean nSetElevation(long renderNode, float lift);
1866 
1867     @CriticalNative
nSetTranslationX(long renderNode, float translationX)1868     private static native boolean nSetTranslationX(long renderNode, float translationX);
1869 
1870     @CriticalNative
nSetTranslationY(long renderNode, float translationY)1871     private static native boolean nSetTranslationY(long renderNode, float translationY);
1872 
1873     @CriticalNative
nSetTranslationZ(long renderNode, float translationZ)1874     private static native boolean nSetTranslationZ(long renderNode, float translationZ);
1875 
1876     @CriticalNative
nSetRotation(long renderNode, float rotation)1877     private static native boolean nSetRotation(long renderNode, float rotation);
1878 
1879     @CriticalNative
nSetRotationX(long renderNode, float rotationX)1880     private static native boolean nSetRotationX(long renderNode, float rotationX);
1881 
1882     @CriticalNative
nSetRotationY(long renderNode, float rotationY)1883     private static native boolean nSetRotationY(long renderNode, float rotationY);
1884 
1885     @CriticalNative
nSetScaleX(long renderNode, float scaleX)1886     private static native boolean nSetScaleX(long renderNode, float scaleX);
1887 
1888     @CriticalNative
nSetScaleY(long renderNode, float scaleY)1889     private static native boolean nSetScaleY(long renderNode, float scaleY);
1890 
1891     @CriticalNative
nSetStaticMatrix(long renderNode, long nativeMatrix)1892     private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix);
1893 
1894     @CriticalNative
nSetAnimationMatrix(long renderNode, long animationMatrix)1895     private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix);
1896 
1897     @CriticalNative
nHasOverlappingRendering(long renderNode)1898     private static native boolean nHasOverlappingRendering(long renderNode);
1899 
1900     @CriticalNative
nGetAnimationMatrix(long renderNode, long animationMatrix)1901     private static native boolean nGetAnimationMatrix(long renderNode, long animationMatrix);
1902 
1903     @CriticalNative
nGetClipToOutline(long renderNode)1904     private static native boolean nGetClipToOutline(long renderNode);
1905 
1906     @CriticalNative
nGetAlpha(long renderNode)1907     private static native float nGetAlpha(long renderNode);
1908 
1909     @CriticalNative
nGetCameraDistance(long renderNode)1910     private static native float nGetCameraDistance(long renderNode);
1911 
1912     @CriticalNative
nGetScaleX(long renderNode)1913     private static native float nGetScaleX(long renderNode);
1914 
1915     @CriticalNative
nGetScaleY(long renderNode)1916     private static native float nGetScaleY(long renderNode);
1917 
1918     @CriticalNative
nGetElevation(long renderNode)1919     private static native float nGetElevation(long renderNode);
1920 
1921     @CriticalNative
nGetTranslationX(long renderNode)1922     private static native float nGetTranslationX(long renderNode);
1923 
1924     @CriticalNative
nGetTranslationY(long renderNode)1925     private static native float nGetTranslationY(long renderNode);
1926 
1927     @CriticalNative
nGetTranslationZ(long renderNode)1928     private static native float nGetTranslationZ(long renderNode);
1929 
1930     @CriticalNative
nGetRotation(long renderNode)1931     private static native float nGetRotation(long renderNode);
1932 
1933     @CriticalNative
nGetRotationX(long renderNode)1934     private static native float nGetRotationX(long renderNode);
1935 
1936     @CriticalNative
nGetRotationY(long renderNode)1937     private static native float nGetRotationY(long renderNode);
1938 
1939     @CriticalNative
nIsPivotExplicitlySet(long renderNode)1940     private static native boolean nIsPivotExplicitlySet(long renderNode);
1941 
1942     @CriticalNative
nGetPivotX(long renderNode)1943     private static native float nGetPivotX(long renderNode);
1944 
1945     @CriticalNative
nGetPivotY(long renderNode)1946     private static native float nGetPivotY(long renderNode);
1947 
1948     @CriticalNative
nGetWidth(long renderNode)1949     private static native int nGetWidth(long renderNode);
1950 
1951     @CriticalNative
nGetHeight(long renderNode)1952     private static native int nGetHeight(long renderNode);
1953 
1954     @CriticalNative
nSetAllowForceDark(long renderNode, boolean allowForceDark)1955     private static native boolean nSetAllowForceDark(long renderNode, boolean allowForceDark);
1956 
1957     @CriticalNative
nGetAllowForceDark(long renderNode)1958     private static native boolean nGetAllowForceDark(long renderNode);
1959 
1960     @CriticalNative
nGetUniqueId(long renderNode)1961     private static native long nGetUniqueId(long renderNode);
1962 
1963     @CriticalNative
nSetIsTextureView(long renderNode)1964     private static native void nSetIsTextureView(long renderNode);
1965 }
1966