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