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