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