1 /*
2  * Copyright (C) 2018 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.FloatRange;
20 import android.annotation.IntDef;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.app.Activity;
24 import android.app.ActivityManager;
25 import android.os.IBinder;
26 import android.os.ParcelFileDescriptor;
27 import android.os.RemoteException;
28 import android.os.ServiceManager;
29 import android.util.Log;
30 import android.util.TimeUtils;
31 import android.view.IGraphicsStats;
32 import android.view.IGraphicsStatsCallback;
33 import android.view.NativeVectorDrawableAnimator;
34 import android.view.PixelCopy;
35 import android.view.Surface;
36 import android.view.SurfaceHolder;
37 import android.view.TextureLayer;
38 import android.view.animation.AnimationUtils;
39 
40 import java.io.File;
41 import java.io.FileDescriptor;
42 import java.lang.annotation.Retention;
43 import java.lang.annotation.RetentionPolicy;
44 import java.util.concurrent.Executor;
45 
46 import sun.misc.Cleaner;
47 
48 /**
49  * <p>Creates an instance of a hardware-accelerated renderer. This is used to render a scene built
50  * from {@link RenderNode}'s to an output {@link android.view.Surface}. There can be as many
51  * HardwareRenderer instances as desired.</p>
52  *
53  * <h3>Resources & lifecycle</h3>
54  *
55  * <p>All HardwareRenderer instances share a common render thread. The render thread contains
56  * the GPU context & resources necessary to do GPU-accelerated rendering. As such, the first
57  * HardwareRenderer created comes with the cost of also creating the associated GPU contexts,
58  * however each incremental HardwareRenderer thereafter is fairly cheap. The expected usage
59  * is to have a HardwareRenderer instance for every active {@link Surface}. For example
60  * when an Activity shows a Dialog the system internally will use 2 hardware renderers, both
61  * of which may be drawing at the same time.</p>
62  *
63  * <p>NOTE: Due to the shared, cooperative nature of the render thread it is critical that
64  * any {@link Surface} used must have a prompt, reliable consuming side. System-provided
65  * consumers such as {@link android.view.SurfaceView},
66  * {@link android.view.Window#takeSurface(SurfaceHolder.Callback2)},
67  * or {@link android.view.TextureView} all fit this requirement. However if custom consumers
68  * are used such as when using {@link SurfaceTexture} or {@link android.media.ImageReader}
69  * it is the app's responsibility to ensure that they consume updates promptly and rapidly.
70  * Failure to do so will cause the render thread to stall on that surface, blocking all
71  * HardwareRenderer instances.</p>
72  */
73 public class HardwareRenderer {
74     private static final String LOG_TAG = "HardwareRenderer";
75 
76     // Keep in sync with DrawFrameTask.h SYNC_* flags
77     /**
78      * Nothing interesting to report. Sync & draw kicked off
79      */
80     public static final int SYNC_OK = 0;
81 
82     /**
83      * The renderer is requesting a redraw. This can occur if there's an animation that's running
84      * in the RenderNode tree and the hardware renderer is unable to self-animate.
85      *
86      * <p>If this is returned from syncAndDraw the expectation is that syncAndDraw
87      * will be called again on the next vsync signal.
88      */
89     public static final int SYNC_REDRAW_REQUESTED = 1 << 0;
90 
91     /**
92      * The hardware renderer no longer has a valid {@link android.view.Surface} to render to.
93      * This can happen if {@link Surface#release()} was called. The user should no longer
94      * attempt to call syncAndDraw until a new surface has been provided by calling
95      * setSurface.
96      *
97      * <p>Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
98      */
99     public static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
100 
101     /**
102      * The hardware renderer has been set to a "stopped" state. If this is returned then the
103      * rendering content has been synced, however a frame was not produced.
104      */
105     public static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2;
106 
107     /**
108      * The content was synced but the renderer has declined to produce a frame in this vsync
109      * interval. This can happen if a frame was already drawn in this vsync or if the renderer
110      * is outrunning the frame consumer. The renderer will internally re-schedule itself
111      * to render a frame in the next vsync signal, so the caller does not need to do anything
112      * in response to this signal.
113      */
114     public static final int SYNC_FRAME_DROPPED = 1 << 3;
115 
116     /** @hide */
117     @IntDef(value = {
118             SYNC_OK, SYNC_REDRAW_REQUESTED, SYNC_LOST_SURFACE_REWARD_IF_FOUND,
119             SYNC_CONTEXT_IS_STOPPED, SYNC_FRAME_DROPPED})
120     @Retention(RetentionPolicy.SOURCE)
121     public @interface SyncAndDrawResult {
122     }
123 
124     /** @hide */
125     public static final int FLAG_DUMP_FRAMESTATS = 1 << 0;
126     /** @hide */
127     public static final int FLAG_DUMP_RESET = 1 << 1;
128     /** @hide */
129     public static final int FLAG_DUMP_ALL = FLAG_DUMP_FRAMESTATS;
130 
131     /** @hide */
132     @IntDef(flag = true, prefix = {"FLAG_DUMP_"}, value = {
133             FLAG_DUMP_FRAMESTATS,
134             FLAG_DUMP_RESET
135     })
136     @Retention(RetentionPolicy.SOURCE)
137     public @interface DumpFlags {
138     }
139 
140     /**
141      * Name of the file that holds the shaders cache.
142      */
143     private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
144     private static final String CACHE_PATH_SKIASHADERS = "com.android.skia.shaders_cache";
145 
146     private final long mNativeProxy;
147     /** @hide */
148     protected RenderNode mRootNode;
149     private boolean mOpaque = true;
150     private boolean mForceDark = false;
151     private boolean mIsWideGamut = false;
152 
153     /**
154      * Creates a new instance of a HardwareRenderer. The HardwareRenderer will default
155      * to opaque with no light source configured.
156      */
HardwareRenderer()157     public HardwareRenderer() {
158         mRootNode = RenderNode.adopt(nCreateRootRenderNode());
159         mRootNode.setClipToBounds(false);
160         mNativeProxy = nCreateProxy(!mOpaque, mIsWideGamut, mRootNode.mNativeRenderNode);
161         if (mNativeProxy == 0) {
162             throw new OutOfMemoryError("Unable to create hardware renderer");
163         }
164         Cleaner.create(this, new DestroyContextRunnable(mNativeProxy));
165         ProcessInitializer.sInstance.init(mNativeProxy);
166     }
167 
168     /**
169      * Destroys the rendering context of this HardwareRenderer. This destroys the resources
170      * associated with this renderer and releases the currently set {@link Surface}. This must
171      * be called when this HardwareRenderer is no longer needed.
172      *
173      * <p>The renderer may be restored from this state by setting a new {@link Surface}, setting
174      * new rendering content with {@link #setContentRoot(RenderNode)}, and resuming
175      * rendering by issuing a new {@link FrameRenderRequest}.
176      *
177      * <p>It is recommended to call this in response to callbacks such as
178      * {@link android.view.SurfaceHolder.Callback#surfaceDestroyed(SurfaceHolder)}.
179      *
180      * <p>Note that if there are any outstanding frame commit callbacks they may never being
181      * invoked if the frame was deferred to a later vsync.
182      */
destroy()183     public void destroy() {
184         nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
185     }
186 
187     /**
188      * Sets a name for this renderer. This is used to identify this renderer instance
189      * when reporting debug information such as the per-window frame time metrics
190      * reported by 'adb shell dumpsys gfxinfo [package] framestats'
191      *
192      * @param name The debug name to use for this HardwareRenderer instance
193      */
setName(@onNull String name)194     public void setName(@NonNull String name) {
195         nSetName(mNativeProxy, name);
196     }
197 
198     /**
199      * Sets the center of the light source. The light source point controls the directionality
200      * and shape of shadows rendered by RenderNode Z & elevation.
201      *
202      * <p>The platform's recommendation is to set lightX to 'displayWidth / 2f - windowLeft', set
203      * lightY to 0 - windowTop, lightZ set to 600dp, and lightRadius to 800dp.
204      *
205      * <p>The light source should be setup both as part of initial configuration, and whenever
206      * the window moves to ensure the light source stays anchored in display space instead
207      * of in window space.
208      *
209      * <p>This must be set at least once along with {@link #setLightSourceAlpha(float, float)}
210      * before shadows will work.
211      *
212      * @param lightX      The X position of the light source
213      * @param lightY      The Y position of the light source
214      * @param lightZ      The Z position of the light source. Must be >= 0.
215      * @param lightRadius The radius of the light source. Smaller radius will have sharper edges,
216      *                    larger radius will have softer shadows.
217      */
setLightSourceGeometry(float lightX, float lightY, float lightZ, float lightRadius)218     public void setLightSourceGeometry(float lightX, float lightY, float lightZ,
219             float lightRadius) {
220         validateFinite(lightX, "lightX");
221         validateFinite(lightY, "lightY");
222         validatePositive(lightZ, "lightZ");
223         validatePositive(lightRadius, "lightRadius");
224         nSetLightGeometry(mNativeProxy, lightX, lightY, lightZ, lightRadius);
225     }
226 
227     /**
228      * Configures the ambient & spot shadow alphas. This is the alpha used when the shadow
229      * has max alpha, and ramps down from the values provided to zero.
230      *
231      * <p>These values are typically provided by the current theme, see
232      * {@link android.R.attr#spotShadowAlpha} and {@link android.R.attr#ambientShadowAlpha}.
233      *
234      * <p>This must be set at least once along with
235      * {@link #setLightSourceGeometry(float, float, float, float)} before shadows will work.
236      *
237      * @param ambientShadowAlpha The alpha for the ambient shadow. If unsure, a reasonable default
238      *                           is 0.039f.
239      * @param spotShadowAlpha    The alpha for the spot shadow. If unsure, a reasonable default is
240      *                           0.19f.
241      */
setLightSourceAlpha(@loatRangefrom = 0.0f, to = 1.0f) float ambientShadowAlpha, @FloatRange(from = 0.0f, to = 1.0f) float spotShadowAlpha)242     public void setLightSourceAlpha(@FloatRange(from = 0.0f, to = 1.0f) float ambientShadowAlpha,
243             @FloatRange(from = 0.0f, to = 1.0f) float spotShadowAlpha) {
244         validateAlpha(ambientShadowAlpha, "ambientShadowAlpha");
245         validateAlpha(spotShadowAlpha, "spotShadowAlpha");
246         nSetLightAlpha(mNativeProxy, ambientShadowAlpha, spotShadowAlpha);
247     }
248 
249     /**
250      * Sets the content root to render. It is not necessary to call this whenever the content
251      * recording changes. Any mutations to the RenderNode content, or any of the RenderNode's
252      * contained within the content node, will be applied whenever a new {@link FrameRenderRequest}
253      * is issued via {@link #createRenderRequest()} and {@link FrameRenderRequest#syncAndDraw()}.
254      *
255      * @param content The content to set as the root RenderNode. If null the content root is removed
256      *                and the renderer will draw nothing.
257      */
setContentRoot(@ullable RenderNode content)258     public void setContentRoot(@Nullable RenderNode content) {
259         RecordingCanvas canvas = mRootNode.beginRecording();
260         if (content != null) {
261             canvas.drawRenderNode(content);
262         }
263         mRootNode.endRecording();
264     }
265 
266     /**
267      * <p>The surface to render into. The surface is assumed to be associated with the display and
268      * as such is still driven by vsync signals such as those from
269      * {@link android.view.Choreographer} and that it has a native refresh rate matching that of
270      * the display's (typically 60hz).</p>
271      *
272      * <p>NOTE: Due to the shared, cooperative nature of the render thread it is critical that
273      * any {@link Surface} used must have a prompt, reliable consuming side. System-provided
274      * consumers such as {@link android.view.SurfaceView},
275      * {@link android.view.Window#takeSurface(SurfaceHolder.Callback2)},
276      * or {@link android.view.TextureView} all fit this requirement. However if custom consumers
277      * are used such as when using {@link SurfaceTexture} or {@link android.media.ImageReader}
278      * it is the app's responsibility to ensure that they consume updates promptly and rapidly.
279      * Failure to do so will cause the render thread to stall on that surface, blocking all
280      * HardwareRenderer instances.</p>
281      *
282      * @param surface The surface to render into. If null then rendering will be stopped. If
283      *                non-null then {@link Surface#isValid()} must be true.
284      */
setSurface(@ullable Surface surface)285     public void setSurface(@Nullable Surface surface) {
286         setSurface(surface, false);
287     }
288 
289     /**
290      * See {@link #setSurface(Surface)}
291      *
292      * @hide
293      * @param discardBuffer determines whether the surface will attempt to preserve its contents
294      *                      between frames.  If set to true the renderer will attempt to preserve
295      *                      the contents of the buffer between frames if the implementation allows
296      *                      it.  If set to false no attempt will be made to preserve the buffer's
297      *                      contents between frames.
298      */
setSurface(@ullable Surface surface, boolean discardBuffer)299     public void setSurface(@Nullable Surface surface, boolean discardBuffer) {
300         if (surface != null && !surface.isValid()) {
301             throw new IllegalArgumentException("Surface is invalid. surface.isValid() == false.");
302         }
303         nSetSurface(mNativeProxy, surface, discardBuffer);
304     }
305 
306     /**
307      * Sets the parameters that can be used to control a render request for a
308      * {@link HardwareRenderer}. This is not thread-safe and must not be held on to for longer
309      * than a single frame request.
310      */
311     public final class FrameRenderRequest {
312         private FrameInfo mFrameInfo = new FrameInfo();
313         private boolean mWaitForPresent;
314 
FrameRenderRequest()315         private FrameRenderRequest() { }
316 
reset()317         private void reset() {
318             mWaitForPresent = false;
319             // Default to the animation time which, if choreographer is in play, will default to the
320             // current vsync time. Otherwise it will be 'now'.
321             mRenderRequest.setVsyncTime(
322                     AnimationUtils.currentAnimationTimeMillis() * TimeUtils.NANOS_PER_MS);
323         }
324 
325         /** @hide */
setFrameInfo(FrameInfo info)326         public void setFrameInfo(FrameInfo info) {
327             System.arraycopy(info.frameInfo, 0, mFrameInfo.frameInfo, 0, info.frameInfo.length);
328         }
329 
330         /**
331          * Sets the vsync time that represents the start point of this frame. Typically this
332          * comes from {@link android.view.Choreographer.FrameCallback}. Other compatible time
333          * sources include {@link System#nanoTime()}, however if the result is being displayed
334          * on-screen then using {@link android.view.Choreographer} is strongly recommended to
335          * ensure smooth animations.
336          *
337          * <p>If the clock source is not from a CLOCK_MONOTONIC source then any animations driven
338          * directly by RenderThread will not be synchronized properly with the current frame.
339          *
340          * @param vsyncTime The vsync timestamp for this frame. The timestamp is in nanoseconds
341          *                  and should come from a CLOCK_MONOTONIC source.
342          *
343          * @return this instance
344          */
setVsyncTime(long vsyncTime)345         public @NonNull FrameRenderRequest setVsyncTime(long vsyncTime) {
346             mFrameInfo.setVsync(vsyncTime, vsyncTime);
347             mFrameInfo.addFlags(FrameInfo.FLAG_SURFACE_CANVAS);
348             return this;
349         }
350 
351         /**
352          * Adds a frame commit callback. This callback will be invoked when the current rendering
353          * content has been rendered into a frame and submitted to the swap chain. The frame may
354          * not currently be visible on the display when this is invoked, but it has been submitted.
355          * This callback is useful in combination with {@link PixelCopy} to capture the current
356          * rendered content of the UI reliably.
357          *
358          * @param executor The executor to run the callback on. It is strongly recommended that
359          *                 this executor post to a different thread, as the calling thread is
360          *                 highly sensitive to being blocked.
361          * @param frameCommitCallback The callback to invoke when the frame content has been drawn.
362          *                            Will be invoked on the given {@link Executor}.
363          *
364          * @return this instance
365          */
setFrameCommitCallback(@onNull Executor executor, @NonNull Runnable frameCommitCallback)366         public @NonNull FrameRenderRequest setFrameCommitCallback(@NonNull Executor executor,
367                 @NonNull Runnable frameCommitCallback) {
368             setFrameCompleteCallback(frameNr -> executor.execute(frameCommitCallback));
369             return this;
370         }
371 
372         /**
373          * Sets whether or not {@link #syncAndDraw()} should block until the frame has been
374          * presented. If this is true and {@link #syncAndDraw()} does not return
375          * {@link #SYNC_FRAME_DROPPED} or an error then when {@link #syncAndDraw()} has returned
376          * the frame has been submitted to the {@link Surface}. The default and typically
377          * recommended value is false, as blocking for present will prevent pipelining from
378          * happening, reducing overall throughput. This is useful for situations such as
379          * {@link SurfaceHolder.Callback2#surfaceRedrawNeeded(SurfaceHolder)} where it is desired
380          * to block until a frame has been presented to ensure first-frame consistency with
381          * other Surfaces.
382          *
383          * @param shouldWait If true the next call to {@link #syncAndDraw()} will block until
384          *                   completion.
385          * @return this instance
386          */
setWaitForPresent(boolean shouldWait)387         public @NonNull FrameRenderRequest setWaitForPresent(boolean shouldWait) {
388             mWaitForPresent = shouldWait;
389             return this;
390         }
391 
392         /**
393          * Syncs the RenderNode tree to the render thread and requests a frame to be drawn. This
394          * {@link FrameRenderRequest} instance should no longer be used after calling this method.
395          * The system internally may reuse instances of {@link FrameRenderRequest} to reduce
396          * allocation churn.
397          *
398          * @return The result of the sync operation.
399          */
400         @SyncAndDrawResult
syncAndDraw()401         public int syncAndDraw() {
402             int syncResult = syncAndDrawFrame(mFrameInfo);
403             if (mWaitForPresent && (syncResult & SYNC_FRAME_DROPPED) == 0) {
404                 fence();
405             }
406             return syncResult;
407         }
408     }
409 
410     private FrameRenderRequest mRenderRequest = new FrameRenderRequest();
411 
412     /**
413      * Returns a {@link FrameRenderRequest} that can be used to render a new frame. This is used
414      * to synchronize the RenderNode content provided by {@link #setContentRoot(RenderNode)} with
415      * the RenderThread and then renders a single frame to the Surface set with
416      * {@link #setSurface(Surface)}.
417      *
418      * @return An instance of {@link FrameRenderRequest}. The instance may be reused for every
419      * frame, so the caller should not hold onto it for longer than a single render request.
420      */
createRenderRequest()421     public @NonNull FrameRenderRequest createRenderRequest() {
422         mRenderRequest.reset();
423         return mRenderRequest;
424     }
425 
426     /**
427      * Syncs the RenderNode tree to the render thread and requests a frame to be drawn.
428      *
429      * @hide
430      */
431     @SyncAndDrawResult
syncAndDrawFrame(@onNull FrameInfo frameInfo)432     public int syncAndDrawFrame(@NonNull FrameInfo frameInfo) {
433         return nSyncAndDrawFrame(mNativeProxy, frameInfo.frameInfo, frameInfo.frameInfo.length);
434     }
435 
436     /**
437      * Suspends any current rendering into the surface but do not do any destruction. This
438      * is useful to temporarily suspend using the active Surface in order to do any Surface
439      * mutations necessary.
440      *
441      * <p>Any subsequent draws will override the pause, resuming normal operation.
442      *
443      * @return true if there was an outstanding render request, false otherwise. If this is true
444      * the caller should ensure that {@link #createRenderRequest()}
445      * and {@link FrameRenderRequest#syncAndDraw()} is called at the soonest
446      * possible time to resume normal operation.
447      *
448      * TODO Should this be exposed? ViewRootImpl needs it because it destroys the old
449      * Surface before getting a new one. However things like SurfaceView will ensure that
450      * the old surface remains un-destroyed until after a new frame has been produced with
451      * the new surface.
452      * @hide
453      */
pause()454     public boolean pause() {
455         return nPause(mNativeProxy);
456     }
457 
458     /**
459      * Hard stops rendering into the surface. If the renderer is stopped it will
460      * block any attempt to render. Calls to {@link FrameRenderRequest#syncAndDraw()} will
461      * still sync over the latest rendering content, however they will not render and instead
462      * {@link #SYNC_CONTEXT_IS_STOPPED} will be returned.
463      *
464      * <p>If false is passed then rendering will resume as normal. Any pending rendering requests
465      * will produce a new frame at the next vsync signal.
466      *
467      * <p>This is useful in combination with lifecycle events such as {@link Activity#onStop()}
468      * and {@link Activity#onStart()}.
469      *
470      * @param stopped true to stop all rendering, false to resume
471      * @hide
472      */
setStopped(boolean stopped)473     public void setStopped(boolean stopped) {
474         nSetStopped(mNativeProxy, stopped);
475     }
476 
477     /**
478      * Hard stops rendering into the surface. If the renderer is stopped it will
479      * block any attempt to render. Calls to {@link FrameRenderRequest#syncAndDraw()} will
480      * still sync over the latest rendering content, however they will not render and instead
481      * {@link #SYNC_CONTEXT_IS_STOPPED} will be returned.
482      *
483      * <p>This is useful in combination with lifecycle events such as {@link Activity#onStop()}.
484      * See {@link #start()} for resuming rendering.
485      */
stop()486     public void stop() {
487         nSetStopped(mNativeProxy, true);
488     }
489 
490     /**
491      * Resumes rendering into the surface. Any pending rendering requests
492      * will produce a new frame at the next vsync signal.
493      *
494      * <p>This is useful in combination with lifecycle events such as {@link Activity#onStart()}.
495      * See {@link #stop()} for stopping rendering.
496      */
start()497     public void start() {
498         nSetStopped(mNativeProxy, false);
499     }
500 
501     /**
502      * Destroys all the display lists associated with the current rendering content.
503      * This includes releasing a reference to the current content root RenderNode. It will
504      * therefore be necessary to call {@link #setContentRoot(RenderNode)} in order to resume
505      * rendering after calling this, along with re-recording the display lists for the
506      * RenderNode tree.
507      *
508      * <p>It is recommended, but not necessary, to use this in combination with lifecycle events
509      * such as {@link Activity#onStop()} and {@link Activity#onStart()} or in response to
510      * {@link android.content.ComponentCallbacks2#onTrimMemory(int)} signals such as
511      * {@link android.content.ComponentCallbacks2#TRIM_MEMORY_UI_HIDDEN}
512      *
513      * See also {@link #stop()}.
514      */
clearContent()515     public void clearContent() {
516         nDestroyHardwareResources(mNativeProxy);
517     }
518 
519     /**
520      * Whether or not the force-dark feature should be used for this renderer.
521      * @hide
522      */
setForceDark(boolean enable)523     public boolean setForceDark(boolean enable) {
524         if (mForceDark != enable) {
525             mForceDark = enable;
526             nSetForceDark(mNativeProxy, enable);
527             return true;
528         }
529         return false;
530     }
531 
532     /**
533      * Allocate buffers ahead of time to avoid allocation delays during rendering.
534      *
535      * <p>Typically a Surface will allocate buffers lazily. This is usually fine and reduces the
536      * memory usage of Surfaces that render rarely or never hit triple buffering. However
537      * for UI it can result in a slight bit of jank on first launch. This hint will
538      * tell the HardwareRenderer that now is a good time to allocate the 3 buffers
539      * necessary for typical rendering.
540      *
541      * <p>Must be called after a {@link Surface} has been set.
542      *
543      * TODO: Figure out if we even need/want this. Should HWUI just be doing this in response
544      * to setSurface anyway? Vulkan swapchain makes this murky, so delay making it public
545      * @hide
546      */
allocateBuffers()547     public void allocateBuffers() {
548         nAllocateBuffers(mNativeProxy);
549     }
550 
551     /**
552      * Notifies the hardware renderer that a call to {@link FrameRenderRequest#syncAndDraw()} will
553      * be coming soon. This is used to help schedule when RenderThread-driven animations will
554      * happen as the renderer wants to avoid producing more than one frame per vsync signal.
555      */
notifyFramePending()556     public void notifyFramePending() {
557         nNotifyFramePending(mNativeProxy);
558     }
559 
560     /**
561      * Change the HardwareRenderer's opacity. Will take effect on the next frame produced.
562      *
563      * <p>If the renderer is set to opaque it is the app's responsibility to ensure that the
564      * content renders to every pixel of the Surface, otherwise corruption may result. Note that
565      * this includes ensuring that the first draw of any given pixel does not attempt to blend
566      * against the destination. If this is false then the hardware renderer will clear to
567      * transparent at the start of every frame.
568      *
569      * @param opaque true if the content rendered is opaque, false if the renderer should clear
570      *               to transparent before rendering
571      */
setOpaque(boolean opaque)572     public void setOpaque(boolean opaque) {
573         if (mOpaque != opaque) {
574             mOpaque = opaque;
575             nSetOpaque(mNativeProxy, mOpaque);
576         }
577     }
578 
579     /**
580      * Whether or not the renderer is set to be opaque. See {@link #setOpaque(boolean)}
581      *
582      * @return true if the renderer is opaque, false otherwise
583      */
isOpaque()584     public boolean isOpaque() {
585         return mOpaque;
586     }
587 
588     /** @hide */
setFrameCompleteCallback(FrameCompleteCallback callback)589     public void setFrameCompleteCallback(FrameCompleteCallback callback) {
590         nSetFrameCompleteCallback(mNativeProxy, callback);
591     }
592 
593     /**
594      * TODO: Public API this?
595      *
596      * @hide
597      */
addObserver(HardwareRendererObserver observer)598     public void addObserver(HardwareRendererObserver observer) {
599         nAddObserver(mNativeProxy, observer.getNativeInstance());
600     }
601 
602     /**
603      * TODO: Public API this?
604      *
605      * @hide
606      */
removeObserver(HardwareRendererObserver observer)607     public void removeObserver(HardwareRendererObserver observer) {
608         nRemoveObserver(mNativeProxy, observer.getNativeInstance());
609     }
610 
611     /**
612      * Enable/disable wide gamut rendering on this renderer. Whether or not the actual rendering
613      * will be wide gamut depends on the hardware support for such rendering.
614      *
615      * @param wideGamut true if this renderer should render in wide gamut, false if it should
616      *                  render in sRGB
617      *                  TODO: Figure out color...
618      * @hide
619      */
setWideGamut(boolean wideGamut)620     public void setWideGamut(boolean wideGamut) {
621         mIsWideGamut = wideGamut;
622         nSetWideGamut(mNativeProxy, wideGamut);
623     }
624 
625     /**
626      * Blocks until all previously queued work has completed.
627      *
628      * TODO: Only used for draw finished listeners, but the FrameCompleteCallback does that
629      * better
630      *
631      * @hide
632      */
fence()633     public void fence() {
634         nFence(mNativeProxy);
635     }
636 
637     /** @hide */
registerAnimatingRenderNode(RenderNode animator)638     public void registerAnimatingRenderNode(RenderNode animator) {
639         nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
640     }
641 
642     /** @hide */
registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator)643     public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator) {
644         nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
645                 animator.getAnimatorNativePtr());
646     }
647 
648     /**
649      * Prevents any further drawing until {@link FrameRenderRequest#syncAndDraw()} is called.
650      * This is a signal that the contents of the RenderNode tree are no longer safe to play back.
651      * In practice this usually means that there are Functor pointers in the
652      * display list that are no longer valid.
653      *
654      * TODO: Can we get webview off of this?
655      *
656      * @hide
657      */
stopDrawing()658     public void stopDrawing() {
659         nStopDrawing(mNativeProxy);
660     }
661 
662     /**
663      * Creates a new hardware layer. A hardware layer built by calling this
664      * method will be treated as a texture layer, instead of as a render target.
665      *
666      * @return A hardware layer
667      * @hide
668      */
createTextureLayer()669     public TextureLayer createTextureLayer() {
670         long layer = nCreateTextureLayer(mNativeProxy);
671         return TextureLayer.adoptTextureLayer(this, layer);
672     }
673 
674     /**
675      * Detaches the layer's surface texture from the GL context and releases
676      * the texture id
677      *
678      * @hide
679      */
detachSurfaceTexture(long hardwareLayer)680     public void detachSurfaceTexture(long hardwareLayer) {
681         nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
682     }
683 
684 
685     /** @hide */
buildLayer(RenderNode node)686     public void buildLayer(RenderNode node) {
687         if (node.hasDisplayList()) {
688             nBuildLayer(mNativeProxy, node.mNativeRenderNode);
689         }
690     }
691 
692     /** @hide */
copyLayerInto(final TextureLayer layer, final Bitmap bitmap)693     public boolean copyLayerInto(final TextureLayer layer, final Bitmap bitmap) {
694         return nCopyLayerInto(mNativeProxy, layer.getDeferredLayerUpdater(),
695             bitmap.getNativeInstance());
696     }
697 
698     /**
699      * Indicates that the specified hardware layer needs to be updated
700      * as soon as possible.
701      *
702      * @param layer The hardware layer that needs an update
703      * @hide
704      */
pushLayerUpdate(TextureLayer layer)705     public void pushLayerUpdate(TextureLayer layer) {
706         nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
707     }
708 
709     /**
710      * Tells the HardwareRenderer that the layer is destroyed. The renderer
711      * should remove the layer from any update queues.
712      *
713      * @hide
714      */
onLayerDestroyed(TextureLayer layer)715     public void onLayerDestroyed(TextureLayer layer) {
716         nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
717     }
718 
719     /** @hide */
setFrameCallback(FrameDrawingCallback callback)720     public void setFrameCallback(FrameDrawingCallback callback) {
721         nSetFrameCallback(mNativeProxy, callback);
722     }
723 
724     /**
725      * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
726      * rendernode of the UI thread.
727      *
728      * @param node       The node to add.
729      * @param placeFront If true, the render node will be placed in front of the content node,
730      *                   otherwise behind the content node.
731      * @hide
732      */
addRenderNode(RenderNode node, boolean placeFront)733     public void addRenderNode(RenderNode node, boolean placeFront) {
734         nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
735     }
736 
737     /**
738      * Only especially added render nodes can be removed.
739      *
740      * @param node The node which was added via addRenderNode which should get removed again.
741      * @hide
742      */
removeRenderNode(RenderNode node)743     public void removeRenderNode(RenderNode node) {
744         nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
745     }
746 
747     /**
748      * Draws a particular render node. If the node is not the content node, only the additional
749      * nodes will get drawn and the content remains untouched.
750      *
751      * @param node The node to be drawn.
752      * @hide
753      */
drawRenderNode(RenderNode node)754     public void drawRenderNode(RenderNode node) {
755         nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
756     }
757 
758     /**
759      * Loads system properties used by the renderer. This method is invoked
760      * whenever system properties are modified. Implementations can use this
761      * to trigger live updates of the renderer based on properties.
762      *
763      * @return True if a property has changed.
764      * @hide
765      */
loadSystemProperties()766     public boolean loadSystemProperties() {
767         return nLoadSystemProperties(mNativeProxy);
768     }
769 
770     /**
771      * @hide
772      */
dumpProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags)773     public void dumpProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags) {
774         nDumpProfileInfo(mNativeProxy, fd, dumpFlags);
775     }
776 
777     /**
778      * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
779      * will be prevented to overdraw this area. It will be synchronized with the draw call.
780      * This should be updated in the content view's draw call.
781      *
782      * @param left   The left side of the protected bounds.
783      * @param top    The top side of the protected bounds.
784      * @param right  The right side of the protected bounds.
785      * @param bottom The bottom side of the protected bounds.
786      * @hide
787      */
setContentDrawBounds(int left, int top, int right, int bottom)788     public void setContentDrawBounds(int left, int top, int right, int bottom) {
789         nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
790     }
791 
792     /** @hide */
setPictureCaptureCallback(@ullable PictureCapturedCallback callback)793     public void setPictureCaptureCallback(@Nullable PictureCapturedCallback callback) {
794         nSetPictureCaptureCallback(mNativeProxy, callback);
795     }
796 
797     /** @hide */
isWideGamut()798     public boolean isWideGamut() {
799         return mIsWideGamut;
800     }
801 
802     /** called by native */
invokePictureCapturedCallback(long picturePtr, PictureCapturedCallback callback)803     static void invokePictureCapturedCallback(long picturePtr, PictureCapturedCallback callback) {
804         Picture picture = new Picture(picturePtr);
805         callback.onPictureCaptured(picture);
806     }
807 
808     /**
809      * Interface used to receive callbacks when a frame is being drawn.
810      *
811      * @hide
812      */
813     public interface FrameDrawingCallback {
814         /**
815          * Invoked during a frame drawing.
816          *
817          * @param frame The id of the frame being drawn.
818          */
onFrameDraw(long frame)819         void onFrameDraw(long frame);
820     }
821 
822     /**
823      * Interface used to be notified when a frame has finished rendering
824      *
825      * @hide
826      */
827     public interface FrameCompleteCallback {
828         /**
829          * Invoked after a frame draw
830          *
831          * @param frameNr The id of the frame that was drawn.
832          */
onFrameComplete(long frameNr)833         void onFrameComplete(long frameNr);
834     }
835 
836     /**
837      * Interface for listening to picture captures
838      * @hide
839      */
840     public interface PictureCapturedCallback {
841         /** @hide */
onPictureCaptured(Picture picture)842         void onPictureCaptured(Picture picture);
843     }
844 
validateAlpha(float alpha, String argumentName)845     private static void validateAlpha(float alpha, String argumentName) {
846         if (!(alpha >= 0.0f && alpha <= 1.0f)) {
847             throw new IllegalArgumentException(argumentName + " must be a valid alpha, "
848                     + alpha + " is not in the range of 0.0f to 1.0f");
849         }
850     }
851 
validatePositive(float f, String argumentName)852     private static void validatePositive(float f, String argumentName) {
853         if (!(Float.isFinite(f) && f >= 0.0f)) {
854             throw new IllegalArgumentException(argumentName
855                     + " must be a finite positive, given=" + f);
856         }
857     }
858 
validateFinite(float f, String argumentName)859     private static void validateFinite(float f, String argumentName) {
860         if (!Float.isFinite(f)) {
861             throw new IllegalArgumentException(argumentName + " must be finite, given=" + f);
862         }
863     }
864 
865     /** @hide */
invokeFunctor(long functor, boolean waitForCompletion)866     public static void invokeFunctor(long functor, boolean waitForCompletion) {
867         nInvokeFunctor(functor, waitForCompletion);
868     }
869 
870     /**
871      * b/68769804: For low FPS experiments.
872      *
873      * @hide
874      */
setFPSDivisor(int divisor)875     public static void setFPSDivisor(int divisor) {
876         nHackySetRTAnimationsEnabled(divisor <= 1);
877     }
878 
879     /**
880      * Changes the OpenGL context priority if IMG_context_priority extension is available. Must be
881      * called before any OpenGL context is created.
882      *
883      * @param priority The priority to use. Must be one of EGL_CONTEXT_PRIORITY_* values.
884      * @hide
885      */
setContextPriority(int priority)886     public static void setContextPriority(int priority) {
887         nSetContextPriority(priority);
888     }
889 
890     /**
891      * Sets whether or not high contrast text rendering is enabled. The setting is global
892      * but only affects content rendered after the change is made.
893      *
894      * @hide
895      */
setHighContrastText(boolean highContrastText)896     public static void setHighContrastText(boolean highContrastText) {
897         nSetHighContrastText(highContrastText);
898     }
899 
900     /**
901      * If set RenderThread will avoid doing any IPC using instead a fake vsync & DisplayInfo source
902      *
903      * @hide
904      */
setIsolatedProcess(boolean isIsolated)905     public static void setIsolatedProcess(boolean isIsolated) {
906         nSetIsolatedProcess(isIsolated);
907     }
908 
909     /**
910      * If set extra graphics debugging abilities will be enabled such as dumping skp
911      *
912      * @hide
913      */
setDebuggingEnabled(boolean enable)914     public static void setDebuggingEnabled(boolean enable) {
915         nSetDebuggingEnabled(enable);
916     }
917 
918     /** @hide */
copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap)919     public static int copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap) {
920         if (srcRect == null) {
921             // Empty rect means entire surface
922             return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap.getNativeInstance());
923         } else {
924             return nCopySurfaceInto(surface, srcRect.left, srcRect.top,
925                     srcRect.right, srcRect.bottom, bitmap.getNativeInstance());
926         }
927     }
928 
929     /**
930      * Creates a {@link android.graphics.Bitmap.Config#HARDWARE} bitmap from the given
931      * RenderNode. Note that the RenderNode should be created as a root node (so x/y of 0,0), and
932      * not the RenderNode from a View.
933      *
934      * @hide
935      **/
createHardwareBitmap(RenderNode node, int width, int height)936     public static Bitmap createHardwareBitmap(RenderNode node, int width, int height) {
937         return nCreateHardwareBitmap(node.mNativeRenderNode, width, height);
938     }
939 
940     /**
941      * Invoke this method when the system is running out of memory. This
942      * method will attempt to recover as much memory as possible, based on
943      * the specified hint.
944      *
945      * @param level Hint about the amount of memory that should be trimmed,
946      *              see {@link android.content.ComponentCallbacks}
947      * @hide
948      */
trimMemory(int level)949     public static void trimMemory(int level) {
950         nTrimMemory(level);
951     }
952 
953     /** @hide */
overrideProperty(@onNull String name, @NonNull String value)954     public static void overrideProperty(@NonNull String name, @NonNull String value) {
955         if (name == null || value == null) {
956             throw new IllegalArgumentException("name and value must be non-null");
957         }
958         nOverrideProperty(name, value);
959     }
960 
961     /**
962      * Sets the directory to use as a persistent storage for threaded rendering
963      * resources.
964      *
965      * @param cacheDir A directory the current process can write to
966      * @hide
967      */
setupDiskCache(File cacheDir)968     public static void setupDiskCache(File cacheDir) {
969         setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath(),
970                 new File(cacheDir, CACHE_PATH_SKIASHADERS).getAbsolutePath());
971     }
972 
973     /** @hide */
setPackageName(String packageName)974     public static void setPackageName(String packageName) {
975         ProcessInitializer.sInstance.setPackageName(packageName);
976     }
977 
978     private static final class DestroyContextRunnable implements Runnable {
979         private final long mNativeInstance;
980 
DestroyContextRunnable(long nativeInstance)981         DestroyContextRunnable(long nativeInstance) {
982             mNativeInstance = nativeInstance;
983         }
984 
985         @Override
run()986         public void run() {
987             nDeleteProxy(mNativeInstance);
988         }
989     }
990 
991     private static class ProcessInitializer {
992         static ProcessInitializer sInstance = new ProcessInitializer();
993 
994         private boolean mInitialized = false;
995 
996         private String mPackageName;
997         private IGraphicsStats mGraphicsStatsService;
998         private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() {
999             @Override
1000             public void onRotateGraphicsStatsBuffer() throws RemoteException {
1001                 rotateBuffer();
1002             }
1003         };
1004 
ProcessInitializer()1005         private ProcessInitializer() {
1006         }
1007 
setPackageName(String name)1008         synchronized void setPackageName(String name) {
1009             if (mInitialized) return;
1010             mPackageName = name;
1011         }
1012 
init(long renderProxy)1013         synchronized void init(long renderProxy) {
1014             if (mInitialized) return;
1015             mInitialized = true;
1016 
1017             initSched(renderProxy);
1018             initGraphicsStats();
1019         }
1020 
initSched(long renderProxy)1021         private void initSched(long renderProxy) {
1022             try {
1023                 int tid = nGetRenderThreadTid(renderProxy);
1024                 ActivityManager.getService().setRenderThread(tid);
1025             } catch (Throwable t) {
1026                 Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
1027             }
1028         }
1029 
initGraphicsStats()1030         private void initGraphicsStats() {
1031             if (mPackageName == null) return;
1032 
1033             try {
1034                 IBinder binder = ServiceManager.getService("graphicsstats");
1035                 if (binder == null) return;
1036                 mGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
1037                 requestBuffer();
1038             } catch (Throwable t) {
1039                 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
1040             }
1041         }
1042 
rotateBuffer()1043         private void rotateBuffer() {
1044             nRotateProcessStatsBuffer();
1045             requestBuffer();
1046         }
1047 
requestBuffer()1048         private void requestBuffer() {
1049             try {
1050                 ParcelFileDescriptor pfd = mGraphicsStatsService
1051                         .requestBufferForProcess(mPackageName, mGraphicsStatsCallback);
1052                 nSetProcessStatsBuffer(pfd.getFd());
1053                 pfd.close();
1054             } catch (Throwable t) {
1055                 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
1056             }
1057         }
1058     }
1059 
1060     /**
1061      * @hide
1062      */
disableVsync()1063     public static native void disableVsync();
1064 
1065     /**
1066      * Start render thread and initialize EGL or Vulkan.
1067      *
1068      * Initializing EGL involves loading and initializing the graphics driver. Some drivers take
1069      * several 10s of milliseconds to do this, so doing it on-demand when an app tries to render
1070      * its first frame adds directly to user-visible app launch latency.
1071      *
1072      * Should only be called after GraphicsEnvironment.chooseDriver().
1073      * @hide
1074      */
preload()1075     public static native void preload();
1076 
1077     /** @hide */
setupShadersDiskCache(String cacheFile, String skiaCacheFile)1078     protected static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile);
1079 
nRotateProcessStatsBuffer()1080     private static native void nRotateProcessStatsBuffer();
1081 
nSetProcessStatsBuffer(int fd)1082     private static native void nSetProcessStatsBuffer(int fd);
1083 
nGetRenderThreadTid(long nativeProxy)1084     private static native int nGetRenderThreadTid(long nativeProxy);
1085 
nCreateRootRenderNode()1086     private static native long nCreateRootRenderNode();
1087 
nCreateProxy(boolean translucent, boolean isWideGamut, long rootRenderNode)1088     private static native long nCreateProxy(boolean translucent, boolean isWideGamut,
1089             long rootRenderNode);
1090 
nDeleteProxy(long nativeProxy)1091     private static native void nDeleteProxy(long nativeProxy);
1092 
nLoadSystemProperties(long nativeProxy)1093     private static native boolean nLoadSystemProperties(long nativeProxy);
1094 
nSetName(long nativeProxy, String name)1095     private static native void nSetName(long nativeProxy, String name);
1096 
nSetSurface(long nativeProxy, Surface window, boolean discardBuffer)1097     private static native void nSetSurface(long nativeProxy, Surface window, boolean discardBuffer);
1098 
nPause(long nativeProxy)1099     private static native boolean nPause(long nativeProxy);
1100 
nSetStopped(long nativeProxy, boolean stopped)1101     private static native void nSetStopped(long nativeProxy, boolean stopped);
1102 
nSetLightGeometry(long nativeProxy, float lightX, float lightY, float lightZ, float lightRadius)1103     private static native void nSetLightGeometry(long nativeProxy,
1104             float lightX, float lightY, float lightZ, float lightRadius);
1105 
nSetLightAlpha(long nativeProxy, float ambientShadowAlpha, float spotShadowAlpha)1106     private static native void nSetLightAlpha(long nativeProxy, float ambientShadowAlpha,
1107             float spotShadowAlpha);
1108 
nSetOpaque(long nativeProxy, boolean opaque)1109     private static native void nSetOpaque(long nativeProxy, boolean opaque);
1110 
nSetWideGamut(long nativeProxy, boolean wideGamut)1111     private static native void nSetWideGamut(long nativeProxy, boolean wideGamut);
1112 
nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size)1113     private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
1114 
nDestroy(long nativeProxy, long rootRenderNode)1115     private static native void nDestroy(long nativeProxy, long rootRenderNode);
1116 
nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode)1117     private static native void nRegisterAnimatingRenderNode(long rootRenderNode,
1118             long animatingNode);
1119 
nRegisterVectorDrawableAnimator(long rootRenderNode, long animator)1120     private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
1121 
nInvokeFunctor(long functor, boolean waitForCompletion)1122     private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
1123 
nCreateTextureLayer(long nativeProxy)1124     private static native long nCreateTextureLayer(long nativeProxy);
1125 
nBuildLayer(long nativeProxy, long node)1126     private static native void nBuildLayer(long nativeProxy, long node);
1127 
nCopyLayerInto(long nativeProxy, long layer, long bitmapHandle)1128     private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmapHandle);
1129 
nPushLayerUpdate(long nativeProxy, long layer)1130     private static native void nPushLayerUpdate(long nativeProxy, long layer);
1131 
nCancelLayerUpdate(long nativeProxy, long layer)1132     private static native void nCancelLayerUpdate(long nativeProxy, long layer);
1133 
nDetachSurfaceTexture(long nativeProxy, long layer)1134     private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
1135 
nDestroyHardwareResources(long nativeProxy)1136     private static native void nDestroyHardwareResources(long nativeProxy);
1137 
nTrimMemory(int level)1138     private static native void nTrimMemory(int level);
1139 
nOverrideProperty(String name, String value)1140     private static native void nOverrideProperty(String name, String value);
1141 
nFence(long nativeProxy)1142     private static native void nFence(long nativeProxy);
1143 
nStopDrawing(long nativeProxy)1144     private static native void nStopDrawing(long nativeProxy);
1145 
nNotifyFramePending(long nativeProxy)1146     private static native void nNotifyFramePending(long nativeProxy);
1147 
nDumpProfileInfo(long nativeProxy, FileDescriptor fd, @DumpFlags int dumpFlags)1148     private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
1149             @DumpFlags int dumpFlags);
1150 
nAddRenderNode(long nativeProxy, long rootRenderNode, boolean placeFront)1151     private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
1152             boolean placeFront);
1153 
nRemoveRenderNode(long nativeProxy, long rootRenderNode)1154     private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
1155 
nDrawRenderNode(long nativeProxy, long rootRenderNode)1156     private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
1157 
nSetContentDrawBounds(long nativeProxy, int left, int top, int right, int bottom)1158     private static native void nSetContentDrawBounds(long nativeProxy, int left,
1159             int top, int right, int bottom);
1160 
nSetPictureCaptureCallback(long nativeProxy, PictureCapturedCallback callback)1161     private static native void nSetPictureCaptureCallback(long nativeProxy,
1162             PictureCapturedCallback callback);
1163 
nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback)1164     private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);
1165 
nSetFrameCompleteCallback(long nativeProxy, FrameCompleteCallback callback)1166     private static native void nSetFrameCompleteCallback(long nativeProxy,
1167             FrameCompleteCallback callback);
1168 
nAddObserver(long nativeProxy, long nativeObserver)1169     private static native void nAddObserver(long nativeProxy, long nativeObserver);
1170 
nRemoveObserver(long nativeProxy, long nativeObserver)1171     private static native void nRemoveObserver(long nativeProxy, long nativeObserver);
1172 
nCopySurfaceInto(Surface surface, int srcLeft, int srcTop, int srcRight, int srcBottom, long bitmapHandle)1173     private static native int nCopySurfaceInto(Surface surface,
1174             int srcLeft, int srcTop, int srcRight, int srcBottom, long bitmapHandle);
1175 
nCreateHardwareBitmap(long renderNode, int width, int height)1176     private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
1177 
nSetHighContrastText(boolean enabled)1178     private static native void nSetHighContrastText(boolean enabled);
1179 
1180     // For temporary experimentation b/66945974
nHackySetRTAnimationsEnabled(boolean enabled)1181     private static native void nHackySetRTAnimationsEnabled(boolean enabled);
1182 
nSetDebuggingEnabled(boolean enabled)1183     private static native void nSetDebuggingEnabled(boolean enabled);
1184 
nSetIsolatedProcess(boolean enabled)1185     private static native void nSetIsolatedProcess(boolean enabled);
1186 
nSetContextPriority(int priority)1187     private static native void nSetContextPriority(int priority);
1188 
nAllocateBuffers(long nativeProxy)1189     private static native void nAllocateBuffers(long nativeProxy);
1190 
nSetForceDark(long nativeProxy, boolean enabled)1191     private static native void nSetForceDark(long nativeProxy, boolean enabled);
1192 }
1193