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