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