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.content.Context;
26 import android.content.pm.ActivityInfo;
27 import android.content.res.Configuration;
28 import android.hardware.DataSpace;
29 import android.hardware.HardwareBuffer;
30 import android.hardware.OverlayProperties;
31 import android.hardware.display.DisplayManager;
32 import android.os.IBinder;
33 import android.os.ParcelFileDescriptor;
34 import android.os.RemoteException;
35 import android.os.ServiceManager;
36 import android.util.Log;
37 import android.util.TimeUtils;
38 import android.view.Display;
39 import android.view.Display.Mode;
40 import android.view.IGraphicsStats;
41 import android.view.IGraphicsStatsCallback;
42 import android.view.NativeVectorDrawableAnimator;
43 import android.view.PixelCopy;
44 import android.view.Surface;
45 import android.view.SurfaceControl;
46 import android.view.SurfaceHolder;
47 import android.view.animation.AnimationUtils;
48 
49 import java.io.File;
50 import java.io.FileDescriptor;
51 import java.lang.annotation.Retention;
52 import java.lang.annotation.RetentionPolicy;
53 import java.util.concurrent.Executor;
54 
55 import sun.misc.Cleaner;
56 
57 /**
58  * <p>Creates an instance of a hardware-accelerated renderer. This is used to render a scene built
59  * from {@link RenderNode}'s to an output {@link android.view.Surface}. There can be as many
60  * HardwareRenderer instances as desired.</p>
61  *
62  * <h3>Resources & lifecycle</h3>
63  *
64  * <p>All HardwareRenderer instances share a common render thread. The render thread contains
65  * the GPU context & resources necessary to do GPU-accelerated rendering. As such, the first
66  * HardwareRenderer created comes with the cost of also creating the associated GPU contexts,
67  * however each incremental HardwareRenderer thereafter is fairly cheap. The expected usage
68  * is to have a HardwareRenderer instance for every active {@link Surface}. For example
69  * when an Activity shows a Dialog the system internally will use 2 hardware renderers, both
70  * of which may be drawing at the same time.</p>
71  *
72  * <p>NOTE: Due to the shared, cooperative nature of the render thread it is critical that
73  * any {@link Surface} used must have a prompt, reliable consuming side. System-provided
74  * consumers such as {@link android.view.SurfaceView},
75  * {@link android.view.Window#takeSurface(SurfaceHolder.Callback2)},
76  * or {@link android.view.TextureView} all fit this requirement. However if custom consumers
77  * are used such as when using {@link SurfaceTexture} or {@link android.media.ImageReader}
78  * it is the app's responsibility to ensure that they consume updates promptly and rapidly.
79  * Failure to do so will cause the render thread to stall on that surface, blocking all
80  * HardwareRenderer instances.</p>
81  */
82 public class HardwareRenderer {
83     private static final String LOG_TAG = "HardwareRenderer";
84 
85     // Keep in sync with DrawFrameTask.h SYNC_* flags
86     /**
87      * Nothing interesting to report. Sync & draw kicked off
88      */
89     public static final int SYNC_OK = 0;
90 
91     /**
92      * The renderer is requesting a redraw. This can occur if there's an animation that's running
93      * in the RenderNode tree and the hardware renderer is unable to self-animate.
94      *
95      * <p>If this is returned from syncAndDraw the expectation is that syncAndDraw
96      * will be called again on the next vsync signal.
97      */
98     public static final int SYNC_REDRAW_REQUESTED = 1 << 0;
99 
100     /**
101      * The hardware renderer no longer has a valid {@link android.view.Surface} to render to.
102      * This can happen if {@link Surface#release()} was called. The user should no longer
103      * attempt to call syncAndDraw until a new surface has been provided by calling
104      * setSurface.
105      *
106      * <p>Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
107      */
108     public static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
109 
110     /**
111      * The hardware renderer has been set to a "stopped" state. If this is returned then the
112      * rendering content has been synced, however a frame was not produced.
113      */
114     public static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2;
115 
116     /**
117      * The content was synced but the renderer has declined to produce a frame in this vsync
118      * interval. This can happen if a frame was already drawn in this vsync or if the renderer
119      * is outrunning the frame consumer. The renderer will internally re-schedule itself
120      * to render a frame in the next vsync signal, so the caller does not need to do anything
121      * in response to this signal.
122      */
123     public static final int SYNC_FRAME_DROPPED = 1 << 3;
124 
125     /** @hide */
126     @IntDef(value = {
127             SYNC_OK, SYNC_REDRAW_REQUESTED, SYNC_LOST_SURFACE_REWARD_IF_FOUND,
128             SYNC_CONTEXT_IS_STOPPED, SYNC_FRAME_DROPPED})
129     @Retention(RetentionPolicy.SOURCE)
130     public @interface SyncAndDrawResult {
131     }
132 
133     /** @hide */
134     public static final int FLAG_DUMP_FRAMESTATS = 1 << 0;
135     /** @hide */
136     public static final int FLAG_DUMP_RESET = 1 << 1;
137     /** @hide */
138     public static final int FLAG_DUMP_ALL = FLAG_DUMP_FRAMESTATS;
139 
140     /** @hide */
141     @IntDef(flag = true, prefix = {"FLAG_DUMP_"}, value = {
142             FLAG_DUMP_FRAMESTATS,
143             FLAG_DUMP_RESET
144     })
145     @Retention(RetentionPolicy.SOURCE)
146     public @interface DumpFlags {
147     }
148 
149 
150     /**
151      * Trims all Skia caches.
152      * @hide
153      */
154     public static final int CACHE_TRIM_ALL = 0;
155     /**
156      * Trims Skia font caches.
157      * @hide
158      */
159     public static final int CACHE_TRIM_FONT = 1;
160     /**
161      * Trims Skia resource caches.
162      * @hide
163      */
164     public static final int CACHE_TRIM_RESOURCES = 2;
165 
166     /** @hide */
167     @IntDef(prefix = {"CACHE_TRIM_"}, value = {
168             CACHE_TRIM_ALL,
169             CACHE_TRIM_FONT,
170             CACHE_TRIM_RESOURCES
171     })
172     @Retention(RetentionPolicy.SOURCE)
173     public @interface CacheTrimLevel {}
174 
175     /**
176      * Name of the file that holds the shaders cache.
177      */
178     private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
179     private static final String CACHE_PATH_SKIASHADERS = "com.android.skia.shaders_cache";
180 
181     private static int sDensityDpi = 0;
182 
183     private final long mNativeProxy;
184     /** @hide */
185     protected RenderNode mRootNode;
186     private boolean mOpaque = true;
187     private int mForceDark = ForceDarkType.NONE;
188     private @ActivityInfo.ColorMode int mColorMode = ActivityInfo.COLOR_MODE_DEFAULT;
189     private float mDesiredSdrHdrRatio = 1f;
190 
191     /**
192      * Creates a new instance of a HardwareRenderer. The HardwareRenderer will default
193      * to opaque with no light source configured.
194      */
HardwareRenderer()195     public HardwareRenderer() {
196         ProcessInitializer.sInstance.initUsingContext();
197         mRootNode = RenderNode.adopt(nCreateRootRenderNode());
198         mRootNode.setClipToBounds(false);
199         mNativeProxy = nCreateProxy(!mOpaque, mRootNode.mNativeRenderNode);
200         if (mNativeProxy == 0) {
201             throw new OutOfMemoryError("Unable to create hardware renderer");
202         }
203         Cleaner.create(this, new DestroyContextRunnable(mNativeProxy));
204         ProcessInitializer.sInstance.init(mNativeProxy);
205     }
206 
207     /**
208      * Destroys the rendering context of this HardwareRenderer. This destroys the resources
209      * associated with this renderer and releases the currently set {@link Surface}. This must
210      * be called when this HardwareRenderer is no longer needed.
211      *
212      * <p>The renderer may be restored from this state by setting a new {@link Surface}, setting
213      * new rendering content with {@link #setContentRoot(RenderNode)}, and resuming
214      * rendering by issuing a new {@link FrameRenderRequest}.
215      *
216      * <p>It is recommended to call this in response to callbacks such as
217      * {@link android.view.SurfaceHolder.Callback#surfaceDestroyed(SurfaceHolder)}.
218      *
219      * <p>Note that if there are any outstanding frame commit callbacks they may never being
220      * invoked if the frame was deferred to a later vsync.
221      */
destroy()222     public void destroy() {
223         nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
224     }
225 
226     /**
227      * Sets a name for this renderer. This is used to identify this renderer instance
228      * when reporting debug information such as the per-window frame time metrics
229      * reported by 'adb shell dumpsys gfxinfo [package] framestats'
230      *
231      * @param name The debug name to use for this HardwareRenderer instance
232      */
setName(@onNull String name)233     public void setName(@NonNull String name) {
234         nSetName(mNativeProxy, name);
235     }
236 
237     /**
238      * Sets the center of the light source. The light source point controls the directionality
239      * and shape of shadows rendered by RenderNode Z & elevation.
240      *
241      * <p>The platform's recommendation is to set lightX to 'displayWidth / 2f - windowLeft', set
242      * lightY to 0 - windowTop, lightZ set to 600dp, and lightRadius to 800dp.
243      *
244      * <p>The light source should be setup both as part of initial configuration, and whenever
245      * the window moves to ensure the light source stays anchored in display space instead
246      * of in window space.
247      *
248      * <p>This must be set at least once along with {@link #setLightSourceAlpha(float, float)}
249      * before shadows will work.
250      *
251      * @param lightX      The X position of the light source
252      * @param lightY      The Y position of the light source
253      * @param lightZ      The Z position of the light source. Must be >= 0.
254      * @param lightRadius The radius of the light source. Smaller radius will have sharper edges,
255      *                    larger radius will have softer shadows.
256      */
setLightSourceGeometry(float lightX, float lightY, float lightZ, float lightRadius)257     public void setLightSourceGeometry(float lightX, float lightY, float lightZ,
258             float lightRadius) {
259         validateFinite(lightX, "lightX");
260         validateFinite(lightY, "lightY");
261         validatePositive(lightZ, "lightZ");
262         validatePositive(lightRadius, "lightRadius");
263         nSetLightGeometry(mNativeProxy, lightX, lightY, lightZ, lightRadius);
264     }
265 
266     /**
267      * Configures the ambient & spot shadow alphas. This is the alpha used when the shadow
268      * has max alpha, and ramps down from the values provided to zero.
269      *
270      * <p>These values are typically provided by the current theme, see
271      * {@link android.R.attr#spotShadowAlpha} and {@link android.R.attr#ambientShadowAlpha}.
272      *
273      * <p>This must be set at least once along with
274      * {@link #setLightSourceGeometry(float, float, float, float)} before shadows will work.
275      *
276      * @param ambientShadowAlpha The alpha for the ambient shadow. If unsure, a reasonable default
277      *                           is 0.039f.
278      * @param spotShadowAlpha    The alpha for the spot shadow. If unsure, a reasonable default is
279      *                           0.19f.
280      */
setLightSourceAlpha(@loatRangefrom = 0.0f, to = 1.0f) float ambientShadowAlpha, @FloatRange(from = 0.0f, to = 1.0f) float spotShadowAlpha)281     public void setLightSourceAlpha(@FloatRange(from = 0.0f, to = 1.0f) float ambientShadowAlpha,
282             @FloatRange(from = 0.0f, to = 1.0f) float spotShadowAlpha) {
283         validateAlpha(ambientShadowAlpha, "ambientShadowAlpha");
284         validateAlpha(spotShadowAlpha, "spotShadowAlpha");
285         nSetLightAlpha(mNativeProxy, ambientShadowAlpha, spotShadowAlpha);
286     }
287 
288     /**
289      * Sets the content root to render. It is not necessary to call this whenever the content
290      * recording changes. Any mutations to the RenderNode content, or any of the RenderNode's
291      * contained within the content node, will be applied whenever a new {@link FrameRenderRequest}
292      * is issued via {@link #createRenderRequest()} and {@link FrameRenderRequest#syncAndDraw()}.
293      *
294      * @param content The content to set as the root RenderNode. If null the content root is removed
295      *                and the renderer will draw nothing.
296      */
setContentRoot(@ullable RenderNode content)297     public void setContentRoot(@Nullable RenderNode content) {
298         RecordingCanvas canvas = mRootNode.beginRecording();
299         if (content != null) {
300             canvas.drawRenderNode(content);
301         }
302         mRootNode.endRecording();
303     }
304 
305     /**
306      * <p>The surface to render into. The surface is assumed to be associated with the display and
307      * as such is still driven by vsync signals such as those from
308      * {@link android.view.Choreographer} and that it has a native refresh rate matching that of
309      * the display's (typically 60hz).</p>
310      *
311      * <p>NOTE: Due to the shared, cooperative nature of the render thread it is critical that
312      * any {@link Surface} used must have a prompt, reliable consuming side. System-provided
313      * consumers such as {@link android.view.SurfaceView},
314      * {@link android.view.Window#takeSurface(SurfaceHolder.Callback2)},
315      * or {@link android.view.TextureView} all fit this requirement. However if custom consumers
316      * are used such as when using {@link SurfaceTexture} or {@link android.media.ImageReader}
317      * it is the app's responsibility to ensure that they consume updates promptly and rapidly.
318      * Failure to do so will cause the render thread to stall on that surface, blocking all
319      * HardwareRenderer instances.</p>
320      *
321      * @param surface The surface to render into. If null then rendering will be stopped. If
322      *                non-null then {@link Surface#isValid()} must be true.
323      */
setSurface(@ullable Surface surface)324     public void setSurface(@Nullable Surface surface) {
325         setSurface(surface, false);
326     }
327 
328     /**
329      * See {@link #setSurface(Surface)}
330      *
331      * @hide
332      * @param discardBuffer determines whether the surface will attempt to preserve its contents
333      *                      between frames.  If set to true the renderer will attempt to preserve
334      *                      the contents of the buffer between frames if the implementation allows
335      *                      it.  If set to false no attempt will be made to preserve the buffer's
336      *                      contents between frames.
337      */
setSurface(@ullable Surface surface, boolean discardBuffer)338     public void setSurface(@Nullable Surface surface, boolean discardBuffer) {
339         if (surface != null && !surface.isValid()) {
340             throw new IllegalArgumentException("Surface is invalid. surface.isValid() == false.");
341         }
342         nSetSurface(mNativeProxy, surface, discardBuffer);
343     }
344 
345     /**
346      * Sets the SurfaceControl to be used internally inside render thread
347      * @hide
348      * @param surfaceControl The surface control to pass to render thread in hwui.
349      *        If null, any previous references held in render thread will be discarded.
350     */
setSurfaceControl(@ullable SurfaceControl surfaceControl, @Nullable BLASTBufferQueue blastBufferQueue)351     public void setSurfaceControl(@Nullable SurfaceControl surfaceControl,
352             @Nullable BLASTBufferQueue blastBufferQueue) {
353         nSetSurfaceControl(mNativeProxy, surfaceControl != null ? surfaceControl.mNativeObject : 0);
354     }
355 
356     /**
357      * Sets the parameters that can be used to control a render request for a
358      * {@link HardwareRenderer}. This is not thread-safe and must not be held on to for longer
359      * than a single frame request.
360      */
361     public final class FrameRenderRequest {
362         private FrameInfo mFrameInfo = new FrameInfo();
363         private boolean mWaitForPresent;
364 
FrameRenderRequest()365         private FrameRenderRequest() { }
366 
reset()367         private void reset() {
368             mWaitForPresent = false;
369             // Default to the animation time which, if choreographer is in play, will default to the
370             // current vsync time. Otherwise it will be 'now'.
371             mRenderRequest.setVsyncTime(
372                     AnimationUtils.currentAnimationTimeMillis() * TimeUtils.NANOS_PER_MS);
373         }
374 
375         /** @hide */
setFrameInfo(FrameInfo info)376         public void setFrameInfo(FrameInfo info) {
377             System.arraycopy(info.frameInfo, 0, mFrameInfo.frameInfo, 0, info.frameInfo.length);
378         }
379 
380         /**
381          * Sets the vsync time that represents the start point of this frame. Typically this
382          * comes from {@link android.view.Choreographer.FrameCallback}. Other compatible time
383          * sources include {@link System#nanoTime()}, however if the result is being displayed
384          * on-screen then using {@link android.view.Choreographer} is strongly recommended to
385          * ensure smooth animations.
386          *
387          * <p>If the clock source is not from a CLOCK_MONOTONIC source then any animations driven
388          * directly by RenderThread will not be synchronized properly with the current frame.
389          *
390          * @param vsyncTime The vsync timestamp for this frame. The timestamp is in nanoseconds
391          *                  and should come from a CLOCK_MONOTONIC source.
392          *
393          * @return this instance
394          */
setVsyncTime(long vsyncTime)395         public @NonNull FrameRenderRequest setVsyncTime(long vsyncTime) {
396             // TODO(b/168552873): populate vsync Id once available to Choreographer public API
397             mFrameInfo.setVsync(vsyncTime, vsyncTime, FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE,
398                     vsyncTime, -1);
399             mFrameInfo.addFlags(FrameInfo.FLAG_SURFACE_CANVAS);
400             return this;
401         }
402 
403         /**
404          * Adds a frame commit callback. This callback will be invoked when the current rendering
405          * content has been rendered into a frame and submitted to the swap chain. The frame may
406          * not currently be visible on the display when this is invoked, but it has been submitted.
407          * This callback is useful in combination with {@link PixelCopy} to capture the current
408          * rendered content of the UI reliably.
409          *
410          * @param executor The executor to run the callback on. It is strongly recommended that
411          *                 this executor post to a different thread, as the calling thread is
412          *                 highly sensitive to being blocked.
413          * @param frameCommitCallback The callback to invoke when the frame content has been drawn.
414          *                            Will be invoked on the given {@link Executor}.
415          *
416          * @return this instance
417          */
setFrameCommitCallback(@onNull Executor executor, @NonNull Runnable frameCommitCallback)418         public @NonNull FrameRenderRequest setFrameCommitCallback(@NonNull Executor executor,
419                 @NonNull Runnable frameCommitCallback) {
420             nSetFrameCommitCallback(mNativeProxy,
421                     didProduceBuffer -> executor.execute(frameCommitCallback));
422             return this;
423         }
424 
425         /**
426          * Sets whether or not {@link #syncAndDraw()} should block until the frame has been
427          * presented. If this is true and {@link #syncAndDraw()} does not return
428          * {@link #SYNC_FRAME_DROPPED} or an error then when {@link #syncAndDraw()} has returned
429          * the frame has been submitted to the {@link Surface}. The default and typically
430          * recommended value is false, as blocking for present will prevent pipelining from
431          * happening, reducing overall throughput. This is useful for situations such as
432          * {@link SurfaceHolder.Callback2#surfaceRedrawNeeded(SurfaceHolder)} where it is desired
433          * to block until a frame has been presented to ensure first-frame consistency with
434          * other Surfaces.
435          *
436          * @param shouldWait If true the next call to {@link #syncAndDraw()} will block until
437          *                   completion.
438          * @return this instance
439          */
setWaitForPresent(boolean shouldWait)440         public @NonNull FrameRenderRequest setWaitForPresent(boolean shouldWait) {
441             mWaitForPresent = shouldWait;
442             return this;
443         }
444 
445         /**
446          * Syncs the RenderNode tree to the render thread and requests a frame to be drawn. This
447          * {@link FrameRenderRequest} instance should no longer be used after calling this method.
448          * The system internally may reuse instances of {@link FrameRenderRequest} to reduce
449          * allocation churn.
450          *
451          * @return The result of the sync operation.
452          */
453         @SyncAndDrawResult
syncAndDraw()454         public int syncAndDraw() {
455             int syncResult = syncAndDrawFrame(mFrameInfo);
456             if (mWaitForPresent && (syncResult & SYNC_FRAME_DROPPED) == 0) {
457                 fence();
458             }
459             return syncResult;
460         }
461     }
462 
463     private FrameRenderRequest mRenderRequest = new FrameRenderRequest();
464 
465     /**
466      * Returns a {@link FrameRenderRequest} that can be used to render a new frame. This is used
467      * to synchronize the RenderNode content provided by {@link #setContentRoot(RenderNode)} with
468      * the RenderThread and then renders a single frame to the Surface set with
469      * {@link #setSurface(Surface)}.
470      *
471      * @return An instance of {@link FrameRenderRequest}. The instance may be reused for every
472      * frame, so the caller should not hold onto it for longer than a single render request.
473      */
createRenderRequest()474     public @NonNull FrameRenderRequest createRenderRequest() {
475         mRenderRequest.reset();
476         return mRenderRequest;
477     }
478 
479     /**
480      * Syncs the RenderNode tree to the render thread and requests a frame to be drawn.
481      *
482      * @hide
483      */
484     @SyncAndDrawResult
syncAndDrawFrame(@onNull FrameInfo frameInfo)485     public int syncAndDrawFrame(@NonNull FrameInfo frameInfo) {
486         return nSyncAndDrawFrame(mNativeProxy, frameInfo.frameInfo, frameInfo.frameInfo.length);
487     }
488 
489     /**
490      * Suspends any current rendering into the surface but do not do any destruction. This
491      * is useful to temporarily suspend using the active Surface in order to do any Surface
492      * mutations necessary.
493      *
494      * <p>Any subsequent draws will override the pause, resuming normal operation.
495      *
496      * @return true if there was an outstanding render request, false otherwise. If this is true
497      * the caller should ensure that {@link #createRenderRequest()}
498      * and {@link FrameRenderRequest#syncAndDraw()} is called at the soonest
499      * possible time to resume normal operation.
500      *
501      * TODO Should this be exposed? ViewRootImpl needs it because it destroys the old
502      * Surface before getting a new one. However things like SurfaceView will ensure that
503      * the old surface remains un-destroyed until after a new frame has been produced with
504      * the new surface.
505      * @hide
506      */
pause()507     public boolean pause() {
508         return nPause(mNativeProxy);
509     }
510 
511     /**
512      * Hard stops rendering into the surface. If the renderer is stopped it will
513      * block any attempt to render. Calls to {@link FrameRenderRequest#syncAndDraw()} will
514      * still sync over the latest rendering content, however they will not render and instead
515      * {@link #SYNC_CONTEXT_IS_STOPPED} will be returned.
516      *
517      * <p>If false is passed then rendering will resume as normal. Any pending rendering requests
518      * will produce a new frame at the next vsync signal.
519      *
520      * <p>This is useful in combination with lifecycle events such as {@link Activity#onStop()}
521      * and {@link Activity#onStart()}.
522      *
523      * @param stopped true to stop all rendering, false to resume
524      * @hide
525      */
setStopped(boolean stopped)526     public void setStopped(boolean stopped) {
527         nSetStopped(mNativeProxy, stopped);
528     }
529 
530     /**
531      * Hard stops rendering into the surface. If the renderer is stopped it will
532      * block any attempt to render. Calls to {@link FrameRenderRequest#syncAndDraw()} will
533      * still sync over the latest rendering content, however they will not render and instead
534      * {@link #SYNC_CONTEXT_IS_STOPPED} will be returned.
535      *
536      * <p>This is useful in combination with lifecycle events such as {@link Activity#onStop()}.
537      * See {@link #start()} for resuming rendering.
538      */
stop()539     public void stop() {
540         nSetStopped(mNativeProxy, true);
541     }
542 
543     /**
544      * Resumes rendering into the surface. Any pending rendering requests
545      * will produce a new frame at the next vsync signal.
546      *
547      * <p>This is useful in combination with lifecycle events such as {@link Activity#onStart()}.
548      * See {@link #stop()} for stopping rendering.
549      */
start()550     public void start() {
551         nSetStopped(mNativeProxy, false);
552     }
553 
554     /**
555      * Destroys all the display lists associated with the current rendering content.
556      * This includes releasing a reference to the current content root RenderNode. It will
557      * therefore be necessary to call {@link #setContentRoot(RenderNode)} in order to resume
558      * rendering after calling this, along with re-recording the display lists for the
559      * RenderNode tree.
560      *
561      * <p>It is recommended, but not necessary, to use this in combination with lifecycle events
562      * such as {@link Activity#onStop()} and {@link Activity#onStart()} or in response to
563      * {@link android.content.ComponentCallbacks2#onTrimMemory(int)} signals such as
564      * {@link android.content.ComponentCallbacks2#TRIM_MEMORY_UI_HIDDEN}
565      *
566      * See also {@link #stop()}.
567      */
clearContent()568     public void clearContent() {
569         nDestroyHardwareResources(mNativeProxy);
570     }
571 
572     /**
573      * Whether or not the force-dark feature should be used for this renderer.
574      * @hide
575      */
setForceDark(@orceDarkType.ForceDarkTypeDef int type)576     public boolean setForceDark(@ForceDarkType.ForceDarkTypeDef int type) {
577         if (mForceDark != type) {
578             mForceDark = type;
579             nSetForceDark(mNativeProxy, type);
580             return true;
581         }
582         return false;
583     }
584 
585     /**
586      * Allocate buffers ahead of time to avoid allocation delays during rendering.
587      *
588      * <p>Typically a Surface will allocate buffers lazily. This is usually fine and reduces the
589      * memory usage of Surfaces that render rarely or never hit triple buffering. However
590      * for UI it can result in a slight bit of jank on first launch. This hint will
591      * tell the HardwareRenderer that now is a good time to allocate the 3 buffers
592      * necessary for typical rendering.
593      *
594      * <p>Must be called after a {@link Surface} has been set.
595      *
596      * TODO: Figure out if we even need/want this. Should HWUI just be doing this in response
597      * to setSurface anyway? Vulkan swapchain makes this murky, so delay making it public
598      * @hide
599      */
allocateBuffers()600     public void allocateBuffers() {
601         nAllocateBuffers(mNativeProxy);
602     }
603 
604     /**
605      * Notifies the hardware renderer that a call to {@link FrameRenderRequest#syncAndDraw()} will
606      * be coming soon. This is used to help schedule when RenderThread-driven animations will
607      * happen as the renderer wants to avoid producing more than one frame per vsync signal.
608      */
notifyFramePending()609     public void notifyFramePending() {
610         nNotifyFramePending(mNativeProxy);
611     }
612 
613     /**
614      * Change the HardwareRenderer's opacity. Will take effect on the next frame produced.
615      *
616      * <p>If the renderer is set to opaque it is the app's responsibility to ensure that the
617      * content renders to every pixel of the Surface, otherwise corruption may result. Note that
618      * this includes ensuring that the first draw of any given pixel does not attempt to blend
619      * against the destination. If this is false then the hardware renderer will clear to
620      * transparent at the start of every frame.
621      *
622      * @param opaque true if the content rendered is opaque, false if the renderer should clear
623      *               to transparent before rendering
624      */
setOpaque(boolean opaque)625     public void setOpaque(boolean opaque) {
626         if (mOpaque != opaque) {
627             mOpaque = opaque;
628             nSetOpaque(mNativeProxy, mOpaque);
629         }
630     }
631 
632     /**
633      * Whether or not the renderer is set to be opaque. See {@link #setOpaque(boolean)}
634      *
635      * @return true if the renderer is opaque, false otherwise
636      */
isOpaque()637     public boolean isOpaque() {
638         return mOpaque;
639     }
640 
641     /** @hide */
setFrameCommitCallback(FrameCommitCallback callback)642     public void setFrameCommitCallback(FrameCommitCallback callback) {
643         nSetFrameCommitCallback(mNativeProxy, callback);
644     }
645 
646     /** @hide */
setFrameCompleteCallback(FrameCompleteCallback callback)647     public void setFrameCompleteCallback(FrameCompleteCallback callback) {
648         nSetFrameCompleteCallback(mNativeProxy, callback);
649     }
650 
651     /**
652      * TODO: Public API this?
653      *
654      * @hide
655      */
addObserver(HardwareRendererObserver observer)656     public void addObserver(HardwareRendererObserver observer) {
657         nAddObserver(mNativeProxy, observer.getNativeInstance());
658     }
659 
660     /**
661      * TODO: Public API this?
662      *
663      * @hide
664      */
removeObserver(HardwareRendererObserver observer)665     public void removeObserver(HardwareRendererObserver observer) {
666         nRemoveObserver(mNativeProxy, observer.getNativeInstance());
667     }
668 
669     /**
670      * Sets the desired color mode on this renderer. Whether or not the actual rendering
671      * will use the requested colorMode depends on the hardware support for such rendering.
672      *
673      * @param colorMode The @{@link ActivityInfo.ColorMode} to request
674      * @hide
675      */
setColorMode(@ctivityInfo.ColorMode int colorMode)676     public float setColorMode(@ActivityInfo.ColorMode int colorMode) {
677         if (mColorMode != colorMode) {
678             mColorMode = colorMode;
679             mDesiredSdrHdrRatio = nSetColorMode(mNativeProxy, colorMode);
680         }
681         return mDesiredSdrHdrRatio;
682     }
683 
684     /**
685      * Sets the colormode with the desired SDR white point.
686      *
687      * The white point only applies if the color mode is an HDR mode
688      *
689      * @hide
690      */
setColorMode(@ctivityInfo.ColorMode int colorMode, float whitePoint)691     public void setColorMode(@ActivityInfo.ColorMode int colorMode, float whitePoint) {
692         nSetSdrWhitePoint(mNativeProxy, whitePoint);
693         mColorMode = colorMode;
694         nSetColorMode(mNativeProxy, colorMode);
695     }
696 
697     /** @hide */
setTargetHdrSdrRatio(float ratio)698     public void setTargetHdrSdrRatio(float ratio) {
699         if (ratio < 1.f || !Float.isFinite(ratio)) ratio = 1.f;
700         nSetTargetSdrHdrRatio(mNativeProxy, ratio);
701     }
702 
703     /**
704      * Blocks until all previously queued work has completed.
705      *
706      * TODO: Only used for draw finished listeners, but the FrameCompleteCallback does that
707      * better
708      *
709      * @hide
710      */
fence()711     public void fence() {
712         nFence(mNativeProxy);
713     }
714 
715     /** @hide */
registerAnimatingRenderNode(RenderNode animator)716     public void registerAnimatingRenderNode(RenderNode animator) {
717         nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
718     }
719 
720     /** @hide */
registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator)721     public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator) {
722         nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
723                 animator.getAnimatorNativePtr());
724     }
725 
726     /**
727      * Prevents any further drawing until {@link FrameRenderRequest#syncAndDraw()} is called.
728      * This is a signal that the contents of the RenderNode tree are no longer safe to play back.
729      * In practice this usually means that there are Functor pointers in the
730      * display list that are no longer valid.
731      *
732      * TODO: Can we get webview off of this?
733      *
734      * @hide
735      */
stopDrawing()736     public void stopDrawing() {
737         nStopDrawing(mNativeProxy);
738     }
739 
740     /**
741      * Creates a new hardware layer. A hardware layer built by calling this
742      * method will be treated as a texture layer, instead of as a render target.
743      *
744      * @return A hardware layer
745      * @hide
746      */
createTextureLayer()747     public TextureLayer createTextureLayer() {
748         long layer = nCreateTextureLayer(mNativeProxy);
749         return TextureLayer.adoptTextureLayer(this, layer);
750     }
751 
752     /**
753      * Detaches the layer's surface texture from the GL context and releases
754      * the texture id
755      *
756      * @hide
757      */
detachSurfaceTexture(long hardwareLayer)758     public void detachSurfaceTexture(long hardwareLayer) {
759         nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
760     }
761 
762 
763     /** @hide */
buildLayer(RenderNode node)764     public void buildLayer(RenderNode node) {
765         if (node.hasDisplayList()) {
766             nBuildLayer(mNativeProxy, node.mNativeRenderNode);
767         }
768     }
769 
770     /** @hide */
copyLayerInto(final TextureLayer layer, final Bitmap bitmap)771     public boolean copyLayerInto(final TextureLayer layer, final Bitmap bitmap) {
772         return nCopyLayerInto(mNativeProxy, layer.getDeferredLayerUpdater(),
773             bitmap.getNativeInstance());
774     }
775 
776     /**
777      * Indicates that the specified hardware layer needs to be updated
778      * as soon as possible.
779      *
780      * @param layer The hardware layer that needs an update
781      * @hide
782      */
pushLayerUpdate(TextureLayer layer)783     public void pushLayerUpdate(TextureLayer layer) {
784         nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
785     }
786 
787     /**
788      * Tells the HardwareRenderer that the layer is destroyed. The renderer
789      * should remove the layer from any update queues.
790      *
791      * @hide
792      */
onLayerDestroyed(TextureLayer layer)793     public void onLayerDestroyed(TextureLayer layer) {
794         nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
795     }
796 
797     /** @hide */
setASurfaceTransactionCallback(ASurfaceTransactionCallback callback)798     protected void setASurfaceTransactionCallback(ASurfaceTransactionCallback callback) {
799         nSetASurfaceTransactionCallback(mNativeProxy, callback);
800     }
801 
802     /** @hide */
setPrepareSurfaceControlForWebviewCallback( PrepareSurfaceControlForWebviewCallback callback)803     protected void setPrepareSurfaceControlForWebviewCallback(
804             PrepareSurfaceControlForWebviewCallback callback) {
805         nSetPrepareSurfaceControlForWebviewCallback(mNativeProxy, callback);
806     }
807 
808     /** @hide */
setFrameCallback(FrameDrawingCallback callback)809     public void setFrameCallback(FrameDrawingCallback callback) {
810         nSetFrameCallback(mNativeProxy, callback);
811     }
812 
813     /**
814      * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
815      * rendernode of the UI thread.
816      *
817      * @param node       The node to add.
818      * @param placeFront If true, the render node will be placed in front of the content node,
819      *                   otherwise behind the content node.
820      * @hide
821      */
addRenderNode(RenderNode node, boolean placeFront)822     public void addRenderNode(RenderNode node, boolean placeFront) {
823         nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
824     }
825 
826     /**
827      * Only especially added render nodes can be removed.
828      *
829      * @param node The node which was added via addRenderNode which should get removed again.
830      * @hide
831      */
removeRenderNode(RenderNode node)832     public void removeRenderNode(RenderNode node) {
833         nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
834     }
835 
836     /**
837      * Draws a particular render node. If the node is not the content node, only the additional
838      * nodes will get drawn and the content remains untouched.
839      *
840      * @param node The node to be drawn.
841      * @hide
842      */
drawRenderNode(RenderNode node)843     public void drawRenderNode(RenderNode node) {
844         nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
845     }
846 
847     /**
848      * Loads system properties used by the renderer. This method is invoked
849      * whenever system properties are modified. Implementations can use this
850      * to trigger live updates of the renderer based on properties.
851      *
852      * @return True if a property has changed.
853      * @hide
854      */
loadSystemProperties()855     public boolean loadSystemProperties() {
856         return nLoadSystemProperties(mNativeProxy);
857     }
858 
859     /**
860      * @hide
861      */
dumpGlobalProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags)862     public static void dumpGlobalProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags) {
863         nDumpGlobalProfileInfo(fd, dumpFlags);
864     }
865 
866     /**
867      * @hide
868      */
dumpProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags)869     public void dumpProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags) {
870         nDumpProfileInfo(mNativeProxy, fd, dumpFlags);
871     }
872 
873     /**
874      * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
875      * will be prevented to overdraw this area. It will be synchronized with the draw call.
876      * This should be updated in the content view's draw call.
877      *
878      * @param left   The left side of the protected bounds.
879      * @param top    The top side of the protected bounds.
880      * @param right  The right side of the protected bounds.
881      * @param bottom The bottom side of the protected bounds.
882      * @hide
883      */
setContentDrawBounds(int left, int top, int right, int bottom)884     public void setContentDrawBounds(int left, int top, int right, int bottom) {
885         nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
886     }
887 
888     /**
889      * Force the new frame to draw, ensuring the UI draw request will attempt a draw this vsync.
890      * @hide
891      */
forceDrawNextFrame()892     public void forceDrawNextFrame() {
893         nForceDrawNextFrame(mNativeProxy);
894     }
895 
896     /** @hide */
setPictureCaptureCallback(@ullable PictureCapturedCallback callback)897     public void setPictureCaptureCallback(@Nullable PictureCapturedCallback callback) {
898         nSetPictureCaptureCallback(mNativeProxy, callback);
899     }
900 
901     /** called by native */
invokePictureCapturedCallback(long picturePtr, PictureCapturedCallback callback)902     static void invokePictureCapturedCallback(long picturePtr, PictureCapturedCallback callback) {
903         Picture picture = new Picture(picturePtr);
904         callback.onPictureCaptured(picture);
905     }
906 
907    /**
908      * Interface used to receive callbacks when Webview requests a surface control.
909      *
910      * @hide
911      */
912     public interface PrepareSurfaceControlForWebviewCallback {
913         /**
914          * Invoked when Webview calls to get a surface control.
915          *
916          */
prepare()917         void prepare();
918     }
919 
920     /**
921      * Interface used to receive callbacks when a transaction needs to be merged.
922      *
923      * @hide
924      */
925     public interface ASurfaceTransactionCallback {
926         /**
927          * Invoked during a frame drawing.
928          *
929          * @param aSurfaceTranactionNativeObj the ASurfaceTransaction native object handle
930          * @param aSurfaceControlNativeObj ASurfaceControl native object handle
931          * @param frame The id of the frame being drawn.
932          */
onMergeTransaction(long aSurfaceTranactionNativeObj, long aSurfaceControlNativeObj, long frame)933         boolean onMergeTransaction(long aSurfaceTranactionNativeObj,
934                                 long aSurfaceControlNativeObj, long frame);
935     }
936 
937     /**
938      * Interface used to receive callbacks when a frame is being drawn.
939      *
940      * @hide
941      */
942     public interface FrameDrawingCallback {
943         /**
944          * Invoked during a frame drawing.
945          *
946          * @param frame The id of the frame being drawn.
947          */
onFrameDraw(long frame)948         void onFrameDraw(long frame);
949 
950         /**
951          * Invoked during a frame drawing.
952          *
953          * @param syncResult The result of the draw. Should be a value or a combination of values
954          *                   from {@link SyncAndDrawResult}
955          * @param frame The id of the frame being drawn.
956          *
957          * @return A {@link FrameCommitCallback} that will report back if the current vsync draws.
958          */
onFrameDraw(@yncAndDrawResult int syncResult, long frame)959         default FrameCommitCallback onFrameDraw(@SyncAndDrawResult int syncResult, long frame) {
960             onFrameDraw(frame);
961             return null;
962         }
963     }
964 
965     /**
966      * Interface used to be notified when a frame has finished rendering
967      *
968      * @hide
969      */
970     public interface FrameCommitCallback {
971         /**
972          * Invoked after a new frame was drawn
973          *
974          * @param didProduceBuffer The draw successfully produced a new buffer.
975          */
onFrameCommit(boolean didProduceBuffer)976         void onFrameCommit(boolean didProduceBuffer);
977     }
978 
979     /**
980      * Interface used to be notified when RenderThread has finished an attempt to draw. This doesn't
981      * mean a new frame has drawn, specifically if there's nothing new to draw, but only that
982      * RenderThread had a chance to draw a frame.
983      *
984      * @hide
985      */
986     public interface FrameCompleteCallback {
987         /**
988          * Invoked after a frame draw was attempted.
989          */
onFrameComplete()990         void onFrameComplete();
991     }
992 
993     /**
994      * Interface for listening to picture captures
995      * @hide
996      */
997     public interface PictureCapturedCallback {
998         /** @hide */
onPictureCaptured(Picture picture)999         void onPictureCaptured(Picture picture);
1000     }
1001 
validateAlpha(float alpha, String argumentName)1002     private static void validateAlpha(float alpha, String argumentName) {
1003         if (!(alpha >= 0.0f && alpha <= 1.0f)) {
1004             throw new IllegalArgumentException(argumentName + " must be a valid alpha, "
1005                     + alpha + " is not in the range of 0.0f to 1.0f");
1006         }
1007     }
1008 
validatePositive(float f, String argumentName)1009     private static void validatePositive(float f, String argumentName) {
1010         if (!(Float.isFinite(f) && f >= 0.0f)) {
1011             throw new IllegalArgumentException(argumentName
1012                     + " must be a finite positive, given=" + f);
1013         }
1014     }
1015 
validateFinite(float f, String argumentName)1016     private static void validateFinite(float f, String argumentName) {
1017         if (!Float.isFinite(f)) {
1018             throw new IllegalArgumentException(argumentName + " must be finite, given=" + f);
1019         }
1020     }
1021 
1022     /**
1023      * Notifies the hardware renderer about pending choreographer callbacks.
1024      *
1025      * @hide
1026      */
notifyCallbackPending()1027     public void notifyCallbackPending() {
1028         nNotifyCallbackPending(mNativeProxy);
1029     }
1030 
1031     /**
1032      * Notifies the hardware renderer about upcoming expensive frames.
1033      *
1034      * @hide
1035      */
notifyExpensiveFrame()1036     public void notifyExpensiveFrame() {
1037         nNotifyExpensiveFrame(mNativeProxy);
1038     }
1039 
1040     /**
1041      * b/68769804, b/66945974: For low FPS experiments.
1042      *
1043      * @hide
1044      */
setFPSDivisor(int divisor)1045     public static void setFPSDivisor(int divisor) {
1046         nSetRtAnimationsEnabled(divisor <= 1);
1047     }
1048 
1049     /**
1050      * Changes the OpenGL context priority if IMG_context_priority extension is available. Must be
1051      * called before any OpenGL context is created.
1052      *
1053      * @param priority The priority to use. Must be one of EGL_CONTEXT_PRIORITY_* values.
1054      * @hide
1055      */
setContextPriority(int priority)1056     public static void setContextPriority(int priority) {
1057         nSetContextPriority(priority);
1058     }
1059 
1060     /**
1061      * Sets whether or not high contrast text rendering is enabled. The setting is global
1062      * but only affects content rendered after the change is made.
1063      *
1064      * @hide
1065      */
setHighContrastText(boolean highContrastText)1066     public static void setHighContrastText(boolean highContrastText) {
1067         nSetHighContrastText(highContrastText);
1068     }
1069 
1070     /**
1071      * If set RenderThread will avoid doing any IPC using instead a fake vsync & DisplayInfo source
1072      *
1073      * @hide
1074      */
setIsolatedProcess(boolean isIsolated)1075     public static void setIsolatedProcess(boolean isIsolated) {
1076         nSetIsolatedProcess(isIsolated);
1077         ProcessInitializer.sInstance.setIsolated(isIsolated);
1078     }
1079 
1080     /**
1081      * Sends device configuration changes to the render thread, for rendering profiling views.
1082      *
1083      * @hide
1084      */
sendDeviceConfigurationForDebugging(Configuration config)1085     public static void sendDeviceConfigurationForDebugging(Configuration config) {
1086         if (config.densityDpi != Configuration.DENSITY_DPI_UNDEFINED
1087                 && config.densityDpi != sDensityDpi) {
1088             sDensityDpi = config.densityDpi;
1089             nSetDisplayDensityDpi(config.densityDpi);
1090         }
1091     }
1092 
1093     /**
1094      * If set extra graphics debugging abilities will be enabled such as dumping skp
1095      *
1096      * @hide
1097      */
setDebuggingEnabled(boolean enable)1098     public static void setDebuggingEnabled(boolean enable) {
1099         nSetDebuggingEnabled(enable);
1100     }
1101 
1102     /** @hide */
1103     public abstract static class CopyRequest {
1104         protected Bitmap mDestinationBitmap;
1105         final Rect mSrcRect;
1106 
CopyRequest(Rect srcRect, Bitmap destinationBitmap)1107         protected CopyRequest(Rect srcRect, Bitmap destinationBitmap) {
1108             mDestinationBitmap = destinationBitmap;
1109             if (srcRect != null) {
1110                 mSrcRect = srcRect;
1111             } else {
1112                 mSrcRect = new Rect();
1113             }
1114         }
1115 
1116         /**
1117          * Retrieve the bitmap in which to store the result of the copy request
1118          */
getDestinationBitmap(int srcWidth, int srcHeight)1119         public long getDestinationBitmap(int srcWidth, int srcHeight) {
1120             if (mDestinationBitmap == null) {
1121                 mDestinationBitmap =
1122                         Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
1123             }
1124             return mDestinationBitmap.getNativeInstance();
1125         }
1126 
1127         /** Called when the copy is completed */
onCopyFinished(int result)1128         public abstract void onCopyFinished(int result);
1129     }
1130 
1131     /** @hide */
copySurfaceInto(Surface surface, CopyRequest copyRequest)1132     public static void copySurfaceInto(Surface surface, CopyRequest copyRequest) {
1133         final Rect srcRect = copyRequest.mSrcRect;
1134         nCopySurfaceInto(surface, srcRect.left, srcRect.top, srcRect.right, srcRect.bottom,
1135                 copyRequest);
1136     }
1137 
1138     /**
1139      * Creates a {@link android.graphics.Bitmap.Config#HARDWARE} bitmap from the given
1140      * RenderNode. Note that the RenderNode should be created as a root node (so x/y of 0,0), and
1141      * not the RenderNode from a View.
1142      *
1143      * @hide
1144      **/
createHardwareBitmap(RenderNode node, int width, int height)1145     public static Bitmap createHardwareBitmap(RenderNode node, int width, int height) {
1146         return nCreateHardwareBitmap(node.mNativeRenderNode, width, height);
1147     }
1148 
1149     /**
1150      * Invoke this method when the system is running out of memory. This
1151      * method will attempt to recover as much memory as possible, based on
1152      * the specified hint.
1153      *
1154      * @param level Hint about the amount of memory that should be trimmed,
1155      *              see {@link android.content.ComponentCallbacks}
1156      * @hide
1157      */
trimMemory(int level)1158     public static void trimMemory(int level) {
1159         nTrimMemory(level);
1160     }
1161 
1162     /**
1163      * Invoke this when all font caches should be flushed. This can cause jank on next render
1164      * commands so use it only after expensive font allocation operations which would
1165      * allocate large amount of temporary memory.
1166      *
1167      * @param level Hint about which caches to trim. See {@link #CACHE_TRIM_ALL},
1168      *              {@link #CACHE_TRIM_FONT}, {@link #CACHE_TRIM_RESOURCES}
1169      *
1170      * @hide
1171      */
trimCaches(@acheTrimLevel int level)1172     public static void trimCaches(@CacheTrimLevel int level) {
1173         nTrimCaches(level);
1174     }
1175 
1176     /** @hide */
overrideProperty(@onNull String name, @NonNull String value)1177     public static void overrideProperty(@NonNull String name, @NonNull String value) {
1178         if (name == null || value == null) {
1179             throw new IllegalArgumentException("name and value must be non-null");
1180         }
1181         nOverrideProperty(name, value);
1182     }
1183 
1184     /**
1185      * Sets the directory to use as a persistent storage for threaded rendering
1186      * resources.
1187      *
1188      * @param cacheDir A directory the current process can write to
1189      * @hide
1190      */
setupDiskCache(File cacheDir)1191     public static void setupDiskCache(File cacheDir) {
1192         setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath(),
1193                 new File(cacheDir, CACHE_PATH_SKIASHADERS).getAbsolutePath());
1194     }
1195 
1196     /** @hide */
setPackageName(String packageName)1197     public static void setPackageName(String packageName) {
1198         ProcessInitializer.sInstance.setPackageName(packageName);
1199     }
1200 
1201     /**
1202      * Gets a context for process initialization
1203      *
1204      * TODO: Remove this once there is a static method for retrieving an application's context.
1205      *
1206      * @hide
1207      */
setContextForInit(Context context)1208     public static void setContextForInit(Context context) {
1209         ProcessInitializer.sInstance.setContext(context);
1210     }
1211 
1212     /**
1213      * Sets whether or not the current process is a system or persistent process. Used to influence
1214      * the chosen memory usage policy.
1215      *
1216      * @hide
1217      **/
setIsSystemOrPersistent()1218     public static void setIsSystemOrPersistent() {
1219         nSetIsSystemOrPersistent(true);
1220     }
1221 
1222     /**
1223      * Returns true if HardwareRender will produce output.
1224      *
1225      * This value is global to the process and affects all uses of HardwareRenderer,
1226      * including
1227      * those created by the system such as those used by the View tree when using hardware
1228      * accelerated rendering.
1229      *
1230      * Default is true in all production environments, but may be false in testing-focused
1231      * emulators or if {@link #setDrawingEnabled(boolean)} is used.
1232      */
isDrawingEnabled()1233     public static boolean isDrawingEnabled() {
1234         return nIsDrawingEnabled();
1235     }
1236 
1237     /**
1238      * Toggles whether or not HardwareRenderer will produce drawing output globally in the current
1239      * process.
1240      *
1241      * This applies to all HardwareRenderer instances, including those created by the platform such
1242      * as those used by the system for hardware accelerated View rendering.
1243      *
1244      * The capability to disable drawing output is intended for test environments, primarily
1245      * headless ones. By setting this to false, tests that launch activities or interact with Views
1246      * can be quicker with less RAM usage by skipping the final step of View drawing. All View
1247      * lifecycle events will occur as normal, only the final step of rendering on the GPU to the
1248      * display will be skipped.
1249      *
1250      * This can be toggled on and off at will, so screenshot tests can also run in this same
1251      * environment by toggling drawing back on and forcing a frame to be drawn such as by calling
1252      * view#invalidate(). Once drawn and the screenshot captured, this can then be turned back off.
1253      */
1254     // TODO(b/194195794): Add link to androidx's Screenshot library for help with this
setDrawingEnabled(boolean drawingEnabled)1255     public static void setDrawingEnabled(boolean drawingEnabled) {
1256         nSetDrawingEnabled(drawingEnabled);
1257     }
1258 
1259     /**
1260      * Disable RenderThread animations that schedule draws directly from RenderThread. This is used
1261      * when we don't want to de-schedule draw requests that come from the UI thread.
1262      *
1263      * @hide
1264      */
setRtAnimationsEnabled(boolean enabled)1265     public static void setRtAnimationsEnabled(boolean enabled) {
1266         nSetRtAnimationsEnabled(enabled);
1267     }
1268 
1269     private static final class DestroyContextRunnable implements Runnable {
1270         private final long mNativeInstance;
1271 
DestroyContextRunnable(long nativeInstance)1272         DestroyContextRunnable(long nativeInstance) {
1273             mNativeInstance = nativeInstance;
1274         }
1275 
1276         @Override
run()1277         public void run() {
1278             nDeleteProxy(mNativeInstance);
1279         }
1280     }
1281 
1282     private static class ProcessInitializer {
1283         static ProcessInitializer sInstance = new ProcessInitializer();
1284 
1285         private boolean mInitialized = false;
1286         private boolean mDisplayInitialized = false;
1287 
1288         private boolean mIsolated = false;
1289         private Context mContext;
1290         private String mPackageName;
1291         private IGraphicsStats mGraphicsStatsService;
1292         private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() {
1293             @Override
1294             public void onRotateGraphicsStatsBuffer() throws RemoteException {
1295                 rotateBuffer();
1296             }
1297         };
1298 
ProcessInitializer()1299         private ProcessInitializer() {
1300         }
1301 
setPackageName(String name)1302         synchronized void setPackageName(String name) {
1303             if (mInitialized) return;
1304             mPackageName = name;
1305         }
1306 
setIsolated(boolean isolated)1307         synchronized void setIsolated(boolean isolated) {
1308             if (mInitialized) return;
1309             mIsolated = isolated;
1310         }
1311 
setContext(Context context)1312         synchronized void setContext(Context context) {
1313             if (mInitialized) return;
1314             mContext = context;
1315         }
1316 
init(long renderProxy)1317         synchronized void init(long renderProxy) {
1318             if (mInitialized) return;
1319             mInitialized = true;
1320 
1321             initSched(renderProxy);
1322             initGraphicsStats();
1323         }
1324 
initSched(long renderProxy)1325         private void initSched(long renderProxy) {
1326             try {
1327                 int tid = nGetRenderThreadTid(renderProxy);
1328                 ActivityManager.getService().setRenderThread(tid);
1329             } catch (Throwable t) {
1330                 Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
1331             }
1332         }
1333 
initGraphicsStats()1334         private void initGraphicsStats() {
1335             if (mPackageName == null) return;
1336 
1337             try {
1338                 IBinder binder = ServiceManager.getService("graphicsstats");
1339                 if (binder == null) return;
1340                 mGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
1341                 requestBuffer();
1342             } catch (Throwable t) {
1343                 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
1344             }
1345         }
1346 
initUsingContext()1347         synchronized void initUsingContext() {
1348             if (mContext == null) return;
1349 
1350             initDisplayInfo();
1351 
1352             nSetIsHighEndGfx(ActivityManager.isHighEndGfx());
1353             nSetIsLowRam(ActivityManager.isLowRamDeviceStatic());
1354             // Defensively clear out the context in case we were passed a context that can leak
1355             // if we live longer than it, e.g. an activity context.
1356             mContext = null;
1357         }
1358 
initDisplayInfo()1359         private void initDisplayInfo() {
1360             if (mDisplayInitialized) return;
1361             if (mIsolated) {
1362                 mDisplayInitialized = true;
1363                 return;
1364             }
1365 
1366             DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
1367             if (dm == null) {
1368                 Log.d(LOG_TAG, "Failed to find DisplayManager for display-based configuration");
1369                 return;
1370             }
1371 
1372             final Display defaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
1373             if (defaultDisplay == null) {
1374                 Log.d(LOG_TAG, "Failed to find default display for display-based configuration");
1375                 return;
1376             }
1377 
1378             final Display[] allDisplays = dm.getDisplays();
1379             if (allDisplays.length == 0) {
1380                 Log.d(LOG_TAG, "Failed to query displays");
1381                 return;
1382             }
1383 
1384             final Mode activeMode = defaultDisplay.getMode();
1385             final ColorSpace defaultWideColorSpace =
1386                     defaultDisplay.getPreferredWideGamutColorSpace();
1387             int wideColorDataspace = defaultWideColorSpace != null
1388                     ? defaultWideColorSpace.getDataSpace() : 0;
1389             // largest width & height are used to size the default HWUI cache sizes. So find the
1390             // largest display resolution we could encounter & use that as the guidance. The actual
1391             // memory policy in play will interpret these values differently.
1392             int largestWidth = activeMode.getPhysicalWidth();
1393             int largestHeight = activeMode.getPhysicalHeight();
1394             final OverlayProperties overlayProperties = defaultDisplay.getOverlaySupport();
1395 
1396             for (int i = 0; i < allDisplays.length; i++) {
1397                 final Display display = allDisplays[i];
1398                 // Take the first wide gamut dataspace as the source of truth
1399                 // Possibly should do per-HardwareRenderer wide gamut dataspace so we can use the
1400                 // target display's ideal instead
1401                 if (wideColorDataspace == 0) {
1402                     ColorSpace cs = display.getPreferredWideGamutColorSpace();
1403                     if (cs != null) {
1404                         wideColorDataspace = cs.getDataSpace();
1405                     }
1406                 }
1407                 Mode[] modes = display.getSupportedModes();
1408                 for (int j = 0; j < modes.length; j++) {
1409                     Mode mode = modes[j];
1410                     int width = mode.getPhysicalWidth();
1411                     int height = mode.getPhysicalHeight();
1412                     if ((width * height) > (largestWidth * largestHeight)) {
1413                         largestWidth = width;
1414                         largestHeight = height;
1415                     }
1416                 }
1417             }
1418 
1419             nInitDisplayInfo(largestWidth, largestHeight, defaultDisplay.getRefreshRate(),
1420                     wideColorDataspace, defaultDisplay.getAppVsyncOffsetNanos(),
1421                     defaultDisplay.getPresentationDeadlineNanos(),
1422                     overlayProperties.isCombinationSupported(
1423                             DataSpace.DATASPACE_SCRGB, HardwareBuffer.RGBA_FP16),
1424                     overlayProperties.isCombinationSupported(
1425                             DataSpace.pack(
1426                                     DataSpace.STANDARD_DCI_P3,
1427                                     DataSpace.TRANSFER_SRGB,
1428                                     DataSpace.RANGE_EXTENDED),
1429                             HardwareBuffer.RGBA_10101010),
1430                     overlayProperties.isMixedColorSpacesSupported());
1431 
1432             mDisplayInitialized = true;
1433         }
1434 
rotateBuffer()1435         private void rotateBuffer() {
1436             nRotateProcessStatsBuffer();
1437             requestBuffer();
1438         }
1439 
requestBuffer()1440         private void requestBuffer() {
1441             try {
1442                 ParcelFileDescriptor pfd = mGraphicsStatsService
1443                         .requestBufferForProcess(mPackageName, mGraphicsStatsCallback);
1444                 nSetProcessStatsBuffer(pfd.getFd());
1445                 pfd.close();
1446             } catch (Throwable t) {
1447                 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
1448             }
1449         }
1450     }
1451 
1452     /**
1453      * @hide
1454      */
disableVsync()1455     public static native void disableVsync();
1456 
1457     /**
1458      * Start render thread and initialize EGL or Vulkan.
1459      *
1460      * Initializing EGL involves loading and initializing the graphics driver. Some drivers take
1461      * several 10s of milliseconds to do this, so doing it on-demand when an app tries to render
1462      * its first frame adds directly to user-visible app launch latency.
1463      *
1464      * Should only be called after GraphicsEnvironment.chooseDriver().
1465      * @hide
1466      */
preload()1467     public static native void preload();
1468 
1469     /**
1470      * @hide
1471      */
isWebViewOverlaysEnabled()1472     protected static native boolean isWebViewOverlaysEnabled();
1473 
1474     /** @hide */
setupShadersDiskCache(String cacheFile, String skiaCacheFile)1475     protected static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile);
1476 
nRotateProcessStatsBuffer()1477     private static native void nRotateProcessStatsBuffer();
1478 
nSetProcessStatsBuffer(int fd)1479     private static native void nSetProcessStatsBuffer(int fd);
1480 
nGetRenderThreadTid(long nativeProxy)1481     private static native int nGetRenderThreadTid(long nativeProxy);
1482 
nCreateRootRenderNode()1483     private static native long nCreateRootRenderNode();
1484 
nCreateProxy(boolean translucent, long rootRenderNode)1485     private static native long nCreateProxy(boolean translucent, long rootRenderNode);
1486 
nDeleteProxy(long nativeProxy)1487     private static native void nDeleteProxy(long nativeProxy);
1488 
nLoadSystemProperties(long nativeProxy)1489     private static native boolean nLoadSystemProperties(long nativeProxy);
1490 
nSetName(long nativeProxy, String name)1491     private static native void nSetName(long nativeProxy, String name);
1492 
nSetSurface(long nativeProxy, Surface window, boolean discardBuffer)1493     private static native void nSetSurface(long nativeProxy, Surface window, boolean discardBuffer);
1494 
nSetSurfaceControl(long nativeProxy, long nativeSurfaceControl)1495     private static native void nSetSurfaceControl(long nativeProxy, long nativeSurfaceControl);
1496 
nPause(long nativeProxy)1497     private static native boolean nPause(long nativeProxy);
1498 
nSetStopped(long nativeProxy, boolean stopped)1499     private static native void nSetStopped(long nativeProxy, boolean stopped);
1500 
nSetLightGeometry(long nativeProxy, float lightX, float lightY, float lightZ, float lightRadius)1501     private static native void nSetLightGeometry(long nativeProxy,
1502             float lightX, float lightY, float lightZ, float lightRadius);
1503 
nSetLightAlpha(long nativeProxy, float ambientShadowAlpha, float spotShadowAlpha)1504     private static native void nSetLightAlpha(long nativeProxy, float ambientShadowAlpha,
1505             float spotShadowAlpha);
1506 
nSetOpaque(long nativeProxy, boolean opaque)1507     private static native void nSetOpaque(long nativeProxy, boolean opaque);
1508 
nSetColorMode(long nativeProxy, int colorMode)1509     private static native float nSetColorMode(long nativeProxy, int colorMode);
1510 
nSetTargetSdrHdrRatio(long nativeProxy, float ratio)1511     private static native void nSetTargetSdrHdrRatio(long nativeProxy, float ratio);
1512 
nSetSdrWhitePoint(long nativeProxy, float whitePoint)1513     private static native void nSetSdrWhitePoint(long nativeProxy, float whitePoint);
1514 
nSetIsHighEndGfx(boolean isHighEndGfx)1515     private static native void nSetIsHighEndGfx(boolean isHighEndGfx);
1516 
nSetIsLowRam(boolean isLowRam)1517     private static native void nSetIsLowRam(boolean isLowRam);
1518 
nSetIsSystemOrPersistent(boolean isSystemOrPersistent)1519     private static native void nSetIsSystemOrPersistent(boolean isSystemOrPersistent);
1520 
nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size)1521     private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
1522 
nDestroy(long nativeProxy, long rootRenderNode)1523     private static native void nDestroy(long nativeProxy, long rootRenderNode);
1524 
nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode)1525     private static native void nRegisterAnimatingRenderNode(long rootRenderNode,
1526             long animatingNode);
1527 
nRegisterVectorDrawableAnimator(long rootRenderNode, long animator)1528     private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
1529 
nCreateTextureLayer(long nativeProxy)1530     private static native long nCreateTextureLayer(long nativeProxy);
1531 
nBuildLayer(long nativeProxy, long node)1532     private static native void nBuildLayer(long nativeProxy, long node);
1533 
nCopyLayerInto(long nativeProxy, long layer, long bitmapHandle)1534     private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmapHandle);
1535 
nPushLayerUpdate(long nativeProxy, long layer)1536     private static native void nPushLayerUpdate(long nativeProxy, long layer);
1537 
nCancelLayerUpdate(long nativeProxy, long layer)1538     private static native void nCancelLayerUpdate(long nativeProxy, long layer);
1539 
nDetachSurfaceTexture(long nativeProxy, long layer)1540     private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
1541 
nDestroyHardwareResources(long nativeProxy)1542     private static native void nDestroyHardwareResources(long nativeProxy);
1543 
nTrimMemory(int level)1544     private static native void nTrimMemory(int level);
1545 
nTrimCaches(int level)1546     private static native void nTrimCaches(int level);
1547 
nOverrideProperty(String name, String value)1548     private static native void nOverrideProperty(String name, String value);
1549 
nFence(long nativeProxy)1550     private static native void nFence(long nativeProxy);
1551 
nStopDrawing(long nativeProxy)1552     private static native void nStopDrawing(long nativeProxy);
1553 
nNotifyFramePending(long nativeProxy)1554     private static native void nNotifyFramePending(long nativeProxy);
1555 
nDumpProfileInfo(long nativeProxy, FileDescriptor fd, @DumpFlags int dumpFlags)1556     private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
1557             @DumpFlags int dumpFlags);
1558 
nDumpGlobalProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags)1559     private static native void nDumpGlobalProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags);
1560 
nAddRenderNode(long nativeProxy, long rootRenderNode, boolean placeFront)1561     private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
1562             boolean placeFront);
1563 
nRemoveRenderNode(long nativeProxy, long rootRenderNode)1564     private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
1565 
nDrawRenderNode(long nativeProxy, long rootRenderNode)1566     private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
1567 
nSetContentDrawBounds(long nativeProxy, int left, int top, int right, int bottom)1568     private static native void nSetContentDrawBounds(long nativeProxy, int left,
1569             int top, int right, int bottom);
1570 
nForceDrawNextFrame(long nativeProxy)1571     private static native void nForceDrawNextFrame(long nativeProxy);
1572 
nSetPictureCaptureCallback(long nativeProxy, PictureCapturedCallback callback)1573     private static native void nSetPictureCaptureCallback(long nativeProxy,
1574             PictureCapturedCallback callback);
1575 
nSetASurfaceTransactionCallback(long nativeProxy, ASurfaceTransactionCallback callback)1576     private static native void nSetASurfaceTransactionCallback(long nativeProxy,
1577             ASurfaceTransactionCallback callback);
1578 
nSetPrepareSurfaceControlForWebviewCallback(long nativeProxy, PrepareSurfaceControlForWebviewCallback callback)1579     private static native void nSetPrepareSurfaceControlForWebviewCallback(long nativeProxy,
1580             PrepareSurfaceControlForWebviewCallback callback);
1581 
nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback)1582     private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);
1583 
nSetFrameCommitCallback(long nativeProxy, FrameCommitCallback callback)1584     private static native void nSetFrameCommitCallback(long nativeProxy,
1585             FrameCommitCallback callback);
1586 
nSetFrameCompleteCallback(long nativeProxy, FrameCompleteCallback callback)1587     private static native void nSetFrameCompleteCallback(long nativeProxy,
1588             FrameCompleteCallback callback);
1589 
nAddObserver(long nativeProxy, long nativeObserver)1590     private static native void nAddObserver(long nativeProxy, long nativeObserver);
1591 
nRemoveObserver(long nativeProxy, long nativeObserver)1592     private static native void nRemoveObserver(long nativeProxy, long nativeObserver);
1593 
nCopySurfaceInto(Surface surface, int srcLeft, int srcTop, int srcRight, int srcBottom, CopyRequest request)1594     private static native void nCopySurfaceInto(Surface surface,
1595             int srcLeft, int srcTop, int srcRight, int srcBottom, CopyRequest request);
1596 
nCreateHardwareBitmap(long renderNode, int width, int height)1597     private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
1598 
nSetHighContrastText(boolean enabled)1599     private static native void nSetHighContrastText(boolean enabled);
1600 
nSetDebuggingEnabled(boolean enabled)1601     private static native void nSetDebuggingEnabled(boolean enabled);
1602 
nSetIsolatedProcess(boolean enabled)1603     private static native void nSetIsolatedProcess(boolean enabled);
1604 
nSetContextPriority(int priority)1605     private static native void nSetContextPriority(int priority);
1606 
nAllocateBuffers(long nativeProxy)1607     private static native void nAllocateBuffers(long nativeProxy);
1608 
nSetForceDark(long nativeProxy, int type)1609     private static native void nSetForceDark(long nativeProxy, int type);
1610 
nSetDisplayDensityDpi(int densityDpi)1611     private static native void nSetDisplayDensityDpi(int densityDpi);
1612 
nInitDisplayInfo(int width, int height, float refreshRate, int wideColorDataspace, long appVsyncOffsetNanos, long presentationDeadlineNanos, boolean supportsFp16ForHdr, boolean isRgba10101010SupportedForHdr, boolean nSupportMixedColorSpaces)1613     private static native void nInitDisplayInfo(int width, int height, float refreshRate,
1614             int wideColorDataspace, long appVsyncOffsetNanos, long presentationDeadlineNanos,
1615             boolean supportsFp16ForHdr, boolean isRgba10101010SupportedForHdr,
1616             boolean nSupportMixedColorSpaces);
1617 
nSetDrawingEnabled(boolean drawingEnabled)1618     private static native void nSetDrawingEnabled(boolean drawingEnabled);
1619 
nIsDrawingEnabled()1620     private static native boolean nIsDrawingEnabled();
1621 
nSetRtAnimationsEnabled(boolean rtAnimationsEnabled)1622     private static native void nSetRtAnimationsEnabled(boolean rtAnimationsEnabled);
1623 
nNotifyCallbackPending(long nativeProxy)1624     private static native void nNotifyCallbackPending(long nativeProxy);
1625 
nNotifyExpensiveFrame(long nativeProxy)1626     private static native void nNotifyExpensiveFrame(long nativeProxy);
1627 }
1628