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             nSetFrameCommitCallback(mNativeProxy,
392                     didProduceBuffer -> executor.execute(frameCommitCallback));
393             return this;
394         }
395 
396         /**
397          * Sets whether or not {@link #syncAndDraw()} should block until the frame has been
398          * presented. If this is true and {@link #syncAndDraw()} does not return
399          * {@link #SYNC_FRAME_DROPPED} or an error then when {@link #syncAndDraw()} has returned
400          * the frame has been submitted to the {@link Surface}. The default and typically
401          * recommended value is false, as blocking for present will prevent pipelining from
402          * happening, reducing overall throughput. This is useful for situations such as
403          * {@link SurfaceHolder.Callback2#surfaceRedrawNeeded(SurfaceHolder)} where it is desired
404          * to block until a frame has been presented to ensure first-frame consistency with
405          * other Surfaces.
406          *
407          * @param shouldWait If true the next call to {@link #syncAndDraw()} will block until
408          *                   completion.
409          * @return this instance
410          */
setWaitForPresent(boolean shouldWait)411         public @NonNull FrameRenderRequest setWaitForPresent(boolean shouldWait) {
412             mWaitForPresent = shouldWait;
413             return this;
414         }
415 
416         /**
417          * Syncs the RenderNode tree to the render thread and requests a frame to be drawn. This
418          * {@link FrameRenderRequest} instance should no longer be used after calling this method.
419          * The system internally may reuse instances of {@link FrameRenderRequest} to reduce
420          * allocation churn.
421          *
422          * @return The result of the sync operation.
423          */
424         @SyncAndDrawResult
syncAndDraw()425         public int syncAndDraw() {
426             int syncResult = syncAndDrawFrame(mFrameInfo);
427             if (mWaitForPresent && (syncResult & SYNC_FRAME_DROPPED) == 0) {
428                 fence();
429             }
430             return syncResult;
431         }
432     }
433 
434     private FrameRenderRequest mRenderRequest = new FrameRenderRequest();
435 
436     /**
437      * Returns a {@link FrameRenderRequest} that can be used to render a new frame. This is used
438      * to synchronize the RenderNode content provided by {@link #setContentRoot(RenderNode)} with
439      * the RenderThread and then renders a single frame to the Surface set with
440      * {@link #setSurface(Surface)}.
441      *
442      * @return An instance of {@link FrameRenderRequest}. The instance may be reused for every
443      * frame, so the caller should not hold onto it for longer than a single render request.
444      */
createRenderRequest()445     public @NonNull FrameRenderRequest createRenderRequest() {
446         mRenderRequest.reset();
447         return mRenderRequest;
448     }
449 
450     /**
451      * Syncs the RenderNode tree to the render thread and requests a frame to be drawn.
452      *
453      * @hide
454      */
455     @SyncAndDrawResult
syncAndDrawFrame(@onNull FrameInfo frameInfo)456     public int syncAndDrawFrame(@NonNull FrameInfo frameInfo) {
457         return nSyncAndDrawFrame(mNativeProxy, frameInfo.frameInfo, frameInfo.frameInfo.length);
458     }
459 
460     /**
461      * Suspends any current rendering into the surface but do not do any destruction. This
462      * is useful to temporarily suspend using the active Surface in order to do any Surface
463      * mutations necessary.
464      *
465      * <p>Any subsequent draws will override the pause, resuming normal operation.
466      *
467      * @return true if there was an outstanding render request, false otherwise. If this is true
468      * the caller should ensure that {@link #createRenderRequest()}
469      * and {@link FrameRenderRequest#syncAndDraw()} is called at the soonest
470      * possible time to resume normal operation.
471      *
472      * TODO Should this be exposed? ViewRootImpl needs it because it destroys the old
473      * Surface before getting a new one. However things like SurfaceView will ensure that
474      * the old surface remains un-destroyed until after a new frame has been produced with
475      * the new surface.
476      * @hide
477      */
pause()478     public boolean pause() {
479         return nPause(mNativeProxy);
480     }
481 
482     /**
483      * Hard stops rendering into the surface. If the renderer is stopped it will
484      * block any attempt to render. Calls to {@link FrameRenderRequest#syncAndDraw()} will
485      * still sync over the latest rendering content, however they will not render and instead
486      * {@link #SYNC_CONTEXT_IS_STOPPED} will be returned.
487      *
488      * <p>If false is passed then rendering will resume as normal. Any pending rendering requests
489      * will produce a new frame at the next vsync signal.
490      *
491      * <p>This is useful in combination with lifecycle events such as {@link Activity#onStop()}
492      * and {@link Activity#onStart()}.
493      *
494      * @param stopped true to stop all rendering, false to resume
495      * @hide
496      */
setStopped(boolean stopped)497     public void setStopped(boolean stopped) {
498         nSetStopped(mNativeProxy, stopped);
499     }
500 
501     /**
502      * Hard stops rendering into the surface. If the renderer is stopped it will
503      * block any attempt to render. Calls to {@link FrameRenderRequest#syncAndDraw()} will
504      * still sync over the latest rendering content, however they will not render and instead
505      * {@link #SYNC_CONTEXT_IS_STOPPED} will be returned.
506      *
507      * <p>This is useful in combination with lifecycle events such as {@link Activity#onStop()}.
508      * See {@link #start()} for resuming rendering.
509      */
stop()510     public void stop() {
511         nSetStopped(mNativeProxy, true);
512     }
513 
514     /**
515      * Resumes rendering into the surface. Any pending rendering requests
516      * will produce a new frame at the next vsync signal.
517      *
518      * <p>This is useful in combination with lifecycle events such as {@link Activity#onStart()}.
519      * See {@link #stop()} for stopping rendering.
520      */
start()521     public void start() {
522         nSetStopped(mNativeProxy, false);
523     }
524 
525     /**
526      * Destroys all the display lists associated with the current rendering content.
527      * This includes releasing a reference to the current content root RenderNode. It will
528      * therefore be necessary to call {@link #setContentRoot(RenderNode)} in order to resume
529      * rendering after calling this, along with re-recording the display lists for the
530      * RenderNode tree.
531      *
532      * <p>It is recommended, but not necessary, to use this in combination with lifecycle events
533      * such as {@link Activity#onStop()} and {@link Activity#onStart()} or in response to
534      * {@link android.content.ComponentCallbacks2#onTrimMemory(int)} signals such as
535      * {@link android.content.ComponentCallbacks2#TRIM_MEMORY_UI_HIDDEN}
536      *
537      * See also {@link #stop()}.
538      */
clearContent()539     public void clearContent() {
540         nDestroyHardwareResources(mNativeProxy);
541     }
542 
543     /**
544      * Whether or not the force-dark feature should be used for this renderer.
545      * @hide
546      */
setForceDark(boolean enable)547     public boolean setForceDark(boolean enable) {
548         if (mForceDark != enable) {
549             mForceDark = enable;
550             nSetForceDark(mNativeProxy, enable);
551             return true;
552         }
553         return false;
554     }
555 
556     /**
557      * Allocate buffers ahead of time to avoid allocation delays during rendering.
558      *
559      * <p>Typically a Surface will allocate buffers lazily. This is usually fine and reduces the
560      * memory usage of Surfaces that render rarely or never hit triple buffering. However
561      * for UI it can result in a slight bit of jank on first launch. This hint will
562      * tell the HardwareRenderer that now is a good time to allocate the 3 buffers
563      * necessary for typical rendering.
564      *
565      * <p>Must be called after a {@link Surface} has been set.
566      *
567      * TODO: Figure out if we even need/want this. Should HWUI just be doing this in response
568      * to setSurface anyway? Vulkan swapchain makes this murky, so delay making it public
569      * @hide
570      */
allocateBuffers()571     public void allocateBuffers() {
572         nAllocateBuffers(mNativeProxy);
573     }
574 
575     /**
576      * Notifies the hardware renderer that a call to {@link FrameRenderRequest#syncAndDraw()} will
577      * be coming soon. This is used to help schedule when RenderThread-driven animations will
578      * happen as the renderer wants to avoid producing more than one frame per vsync signal.
579      */
notifyFramePending()580     public void notifyFramePending() {
581         nNotifyFramePending(mNativeProxy);
582     }
583 
584     /**
585      * Change the HardwareRenderer's opacity. Will take effect on the next frame produced.
586      *
587      * <p>If the renderer is set to opaque it is the app's responsibility to ensure that the
588      * content renders to every pixel of the Surface, otherwise corruption may result. Note that
589      * this includes ensuring that the first draw of any given pixel does not attempt to blend
590      * against the destination. If this is false then the hardware renderer will clear to
591      * transparent at the start of every frame.
592      *
593      * @param opaque true if the content rendered is opaque, false if the renderer should clear
594      *               to transparent before rendering
595      */
setOpaque(boolean opaque)596     public void setOpaque(boolean opaque) {
597         if (mOpaque != opaque) {
598             mOpaque = opaque;
599             nSetOpaque(mNativeProxy, mOpaque);
600         }
601     }
602 
603     /**
604      * Whether or not the renderer is set to be opaque. See {@link #setOpaque(boolean)}
605      *
606      * @return true if the renderer is opaque, false otherwise
607      */
isOpaque()608     public boolean isOpaque() {
609         return mOpaque;
610     }
611 
612     /** @hide */
setFrameCommitCallback(FrameCommitCallback callback)613     public void setFrameCommitCallback(FrameCommitCallback callback) {
614         nSetFrameCommitCallback(mNativeProxy, callback);
615     }
616 
617     /** @hide */
setFrameCompleteCallback(FrameCompleteCallback callback)618     public void setFrameCompleteCallback(FrameCompleteCallback callback) {
619         nSetFrameCompleteCallback(mNativeProxy, callback);
620     }
621 
622     /**
623      * TODO: Public API this?
624      *
625      * @hide
626      */
addObserver(HardwareRendererObserver observer)627     public void addObserver(HardwareRendererObserver observer) {
628         nAddObserver(mNativeProxy, observer.getNativeInstance());
629     }
630 
631     /**
632      * TODO: Public API this?
633      *
634      * @hide
635      */
removeObserver(HardwareRendererObserver observer)636     public void removeObserver(HardwareRendererObserver observer) {
637         nRemoveObserver(mNativeProxy, observer.getNativeInstance());
638     }
639 
640     /**
641      * Sets the desired color mode on this renderer. Whether or not the actual rendering
642      * will use the requested colorMode depends on the hardware support for such rendering.
643      *
644      * @param colorMode The @{@link ActivityInfo.ColorMode} to request
645      * @hide
646      */
setColorMode(@ctivityInfo.ColorMode int colorMode)647     public void setColorMode(@ActivityInfo.ColorMode int colorMode) {
648         if (mColorMode != colorMode) {
649             mColorMode = colorMode;
650             nSetColorMode(mNativeProxy, colorMode);
651         }
652     }
653 
654     /**
655      * Sets the colormode with the desired SDR white point.
656      *
657      * The white point only applies if the color mode is an HDR mode
658      *
659      * @hide
660      */
setColorMode(@ctivityInfo.ColorMode int colorMode, float whitePoint)661     public void setColorMode(@ActivityInfo.ColorMode int colorMode, float whitePoint) {
662         nSetSdrWhitePoint(mNativeProxy, whitePoint);
663         mColorMode = colorMode;
664         nSetColorMode(mNativeProxy, colorMode);
665     }
666 
667     /**
668      * Blocks until all previously queued work has completed.
669      *
670      * TODO: Only used for draw finished listeners, but the FrameCompleteCallback does that
671      * better
672      *
673      * @hide
674      */
fence()675     public void fence() {
676         nFence(mNativeProxy);
677     }
678 
679     /** @hide */
registerAnimatingRenderNode(RenderNode animator)680     public void registerAnimatingRenderNode(RenderNode animator) {
681         nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
682     }
683 
684     /** @hide */
registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator)685     public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator) {
686         nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
687                 animator.getAnimatorNativePtr());
688     }
689 
690     /**
691      * Prevents any further drawing until {@link FrameRenderRequest#syncAndDraw()} is called.
692      * This is a signal that the contents of the RenderNode tree are no longer safe to play back.
693      * In practice this usually means that there are Functor pointers in the
694      * display list that are no longer valid.
695      *
696      * TODO: Can we get webview off of this?
697      *
698      * @hide
699      */
stopDrawing()700     public void stopDrawing() {
701         nStopDrawing(mNativeProxy);
702     }
703 
704     /**
705      * Creates a new hardware layer. A hardware layer built by calling this
706      * method will be treated as a texture layer, instead of as a render target.
707      *
708      * @return A hardware layer
709      * @hide
710      */
createTextureLayer()711     public TextureLayer createTextureLayer() {
712         long layer = nCreateTextureLayer(mNativeProxy);
713         return TextureLayer.adoptTextureLayer(this, layer);
714     }
715 
716     /**
717      * Detaches the layer's surface texture from the GL context and releases
718      * the texture id
719      *
720      * @hide
721      */
detachSurfaceTexture(long hardwareLayer)722     public void detachSurfaceTexture(long hardwareLayer) {
723         nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
724     }
725 
726 
727     /** @hide */
buildLayer(RenderNode node)728     public void buildLayer(RenderNode node) {
729         if (node.hasDisplayList()) {
730             nBuildLayer(mNativeProxy, node.mNativeRenderNode);
731         }
732     }
733 
734     /** @hide */
copyLayerInto(final TextureLayer layer, final Bitmap bitmap)735     public boolean copyLayerInto(final TextureLayer layer, final Bitmap bitmap) {
736         return nCopyLayerInto(mNativeProxy, layer.getDeferredLayerUpdater(),
737             bitmap.getNativeInstance());
738     }
739 
740     /**
741      * Indicates that the specified hardware layer needs to be updated
742      * as soon as possible.
743      *
744      * @param layer The hardware layer that needs an update
745      * @hide
746      */
pushLayerUpdate(TextureLayer layer)747     public void pushLayerUpdate(TextureLayer layer) {
748         nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
749     }
750 
751     /**
752      * Tells the HardwareRenderer that the layer is destroyed. The renderer
753      * should remove the layer from any update queues.
754      *
755      * @hide
756      */
onLayerDestroyed(TextureLayer layer)757     public void onLayerDestroyed(TextureLayer layer) {
758         nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
759     }
760 
761     private ASurfaceTransactionCallback mASurfaceTransactionCallback;
762 
763     /** @hide */
setASurfaceTransactionCallback(ASurfaceTransactionCallback callback)764     public void setASurfaceTransactionCallback(ASurfaceTransactionCallback callback) {
765         // ensure callback is kept alive on the java side since weak ref is used in native code
766         mASurfaceTransactionCallback = callback;
767         nSetASurfaceTransactionCallback(mNativeProxy, callback);
768     }
769 
770     private PrepareSurfaceControlForWebviewCallback mAPrepareSurfaceControlForWebviewCallback;
771 
772     /** @hide */
setPrepareSurfaceControlForWebviewCallback( PrepareSurfaceControlForWebviewCallback callback)773     public void setPrepareSurfaceControlForWebviewCallback(
774             PrepareSurfaceControlForWebviewCallback callback) {
775         // ensure callback is kept alive on the java side since weak ref is used in native code
776         mAPrepareSurfaceControlForWebviewCallback = callback;
777         nSetPrepareSurfaceControlForWebviewCallback(mNativeProxy, callback);
778     }
779 
780     /** @hide */
setFrameCallback(FrameDrawingCallback callback)781     public void setFrameCallback(FrameDrawingCallback callback) {
782         nSetFrameCallback(mNativeProxy, callback);
783     }
784 
785     /**
786      * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
787      * rendernode of the UI thread.
788      *
789      * @param node       The node to add.
790      * @param placeFront If true, the render node will be placed in front of the content node,
791      *                   otherwise behind the content node.
792      * @hide
793      */
addRenderNode(RenderNode node, boolean placeFront)794     public void addRenderNode(RenderNode node, boolean placeFront) {
795         nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
796     }
797 
798     /**
799      * Only especially added render nodes can be removed.
800      *
801      * @param node The node which was added via addRenderNode which should get removed again.
802      * @hide
803      */
removeRenderNode(RenderNode node)804     public void removeRenderNode(RenderNode node) {
805         nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
806     }
807 
808     /**
809      * Draws a particular render node. If the node is not the content node, only the additional
810      * nodes will get drawn and the content remains untouched.
811      *
812      * @param node The node to be drawn.
813      * @hide
814      */
drawRenderNode(RenderNode node)815     public void drawRenderNode(RenderNode node) {
816         nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
817     }
818 
819     /**
820      * Loads system properties used by the renderer. This method is invoked
821      * whenever system properties are modified. Implementations can use this
822      * to trigger live updates of the renderer based on properties.
823      *
824      * @return True if a property has changed.
825      * @hide
826      */
loadSystemProperties()827     public boolean loadSystemProperties() {
828         return nLoadSystemProperties(mNativeProxy);
829     }
830 
831     /**
832      * @hide
833      */
dumpProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags)834     public void dumpProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags) {
835         nDumpProfileInfo(mNativeProxy, fd, dumpFlags);
836     }
837 
838     /**
839      * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
840      * will be prevented to overdraw this area. It will be synchronized with the draw call.
841      * This should be updated in the content view's draw call.
842      *
843      * @param left   The left side of the protected bounds.
844      * @param top    The top side of the protected bounds.
845      * @param right  The right side of the protected bounds.
846      * @param bottom The bottom side of the protected bounds.
847      * @hide
848      */
setContentDrawBounds(int left, int top, int right, int bottom)849     public void setContentDrawBounds(int left, int top, int right, int bottom) {
850         nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
851     }
852 
853     /** @hide */
setPictureCaptureCallback(@ullable PictureCapturedCallback callback)854     public void setPictureCaptureCallback(@Nullable PictureCapturedCallback callback) {
855         nSetPictureCaptureCallback(mNativeProxy, callback);
856     }
857 
858     /** called by native */
invokePictureCapturedCallback(long picturePtr, PictureCapturedCallback callback)859     static void invokePictureCapturedCallback(long picturePtr, PictureCapturedCallback callback) {
860         Picture picture = new Picture(picturePtr);
861         callback.onPictureCaptured(picture);
862     }
863 
864    /**
865      * Interface used to receive callbacks when Webview requests a surface control.
866      *
867      * @hide
868      */
869     public interface PrepareSurfaceControlForWebviewCallback {
870         /**
871          * Invoked when Webview calls to get a surface control.
872          *
873          */
prepare()874         void prepare();
875     }
876 
877     /**
878      * Interface used to receive callbacks when a transaction needs to be merged.
879      *
880      * @hide
881      */
882     public interface ASurfaceTransactionCallback {
883         /**
884          * Invoked during a frame drawing.
885          *
886          * @param aSurfaceTranactionNativeObj the ASurfaceTransaction native object handle
887          * @param aSurfaceControlNativeObj ASurfaceControl native object handle
888          * @param frame The id of the frame being drawn.
889          */
onMergeTransaction(long aSurfaceTranactionNativeObj, long aSurfaceControlNativeObj, long frame)890         boolean onMergeTransaction(long aSurfaceTranactionNativeObj,
891                                 long aSurfaceControlNativeObj, long frame);
892     }
893 
894     /**
895      * Interface used to receive callbacks when a frame is being drawn.
896      *
897      * @hide
898      */
899     public interface FrameDrawingCallback {
900         /**
901          * Invoked during a frame drawing.
902          *
903          * @param frame The id of the frame being drawn.
904          */
onFrameDraw(long frame)905         void onFrameDraw(long frame);
906     }
907 
908     /**
909      * Interface used to be notified when a frame has finished rendering
910      *
911      * @hide
912      */
913     public interface FrameCommitCallback {
914         /**
915          * Invoked after a new frame was drawn
916          *
917          * @param didProduceBuffer The draw successfully produced a new buffer.
918          */
onFrameCommit(boolean didProduceBuffer)919         void onFrameCommit(boolean didProduceBuffer);
920     }
921 
922     /**
923      * Interface used to be notified when RenderThread has finished an attempt to draw. This doesn't
924      * mean a new frame has drawn, specifically if there's nothing new to draw, but only that
925      * RenderThread had a chance to draw a frame.
926      *
927      * @hide
928      */
929     public interface FrameCompleteCallback {
930         /**
931          * Invoked after a frame draw was attempted.
932          */
onFrameComplete()933         void onFrameComplete();
934     }
935 
936     /**
937      * Interface for listening to picture captures
938      * @hide
939      */
940     public interface PictureCapturedCallback {
941         /** @hide */
onPictureCaptured(Picture picture)942         void onPictureCaptured(Picture picture);
943     }
944 
validateAlpha(float alpha, String argumentName)945     private static void validateAlpha(float alpha, String argumentName) {
946         if (!(alpha >= 0.0f && alpha <= 1.0f)) {
947             throw new IllegalArgumentException(argumentName + " must be a valid alpha, "
948                     + alpha + " is not in the range of 0.0f to 1.0f");
949         }
950     }
951 
validatePositive(float f, String argumentName)952     private static void validatePositive(float f, String argumentName) {
953         if (!(Float.isFinite(f) && f >= 0.0f)) {
954             throw new IllegalArgumentException(argumentName
955                     + " must be a finite positive, given=" + f);
956         }
957     }
958 
validateFinite(float f, String argumentName)959     private static void validateFinite(float f, String argumentName) {
960         if (!Float.isFinite(f)) {
961             throw new IllegalArgumentException(argumentName + " must be finite, given=" + f);
962         }
963     }
964 
965     /**
966      * b/68769804: For low FPS experiments.
967      *
968      * @hide
969      */
setFPSDivisor(int divisor)970     public static void setFPSDivisor(int divisor) {
971         nHackySetRTAnimationsEnabled(divisor <= 1);
972     }
973 
974     /**
975      * Changes the OpenGL context priority if IMG_context_priority extension is available. Must be
976      * called before any OpenGL context is created.
977      *
978      * @param priority The priority to use. Must be one of EGL_CONTEXT_PRIORITY_* values.
979      * @hide
980      */
setContextPriority(int priority)981     public static void setContextPriority(int priority) {
982         nSetContextPriority(priority);
983     }
984 
985     /**
986      * Sets whether or not high contrast text rendering is enabled. The setting is global
987      * but only affects content rendered after the change is made.
988      *
989      * @hide
990      */
setHighContrastText(boolean highContrastText)991     public static void setHighContrastText(boolean highContrastText) {
992         nSetHighContrastText(highContrastText);
993     }
994 
995     /**
996      * If set RenderThread will avoid doing any IPC using instead a fake vsync & DisplayInfo source
997      *
998      * @hide
999      */
setIsolatedProcess(boolean isIsolated)1000     public static void setIsolatedProcess(boolean isIsolated) {
1001         nSetIsolatedProcess(isIsolated);
1002         ProcessInitializer.sInstance.setIsolated(isIsolated);
1003     }
1004 
1005     /**
1006      * Sends device configuration changes to the render thread, for rendering profiling views.
1007      *
1008      * @hide
1009      */
sendDeviceConfigurationForDebugging(Configuration config)1010     public static void sendDeviceConfigurationForDebugging(Configuration config) {
1011         if (config.densityDpi != Configuration.DENSITY_DPI_UNDEFINED
1012                 && config.densityDpi != sDensityDpi) {
1013             sDensityDpi = config.densityDpi;
1014             nSetDisplayDensityDpi(config.densityDpi);
1015         }
1016     }
1017 
1018     /**
1019      * If set extra graphics debugging abilities will be enabled such as dumping skp
1020      *
1021      * @hide
1022      */
setDebuggingEnabled(boolean enable)1023     public static void setDebuggingEnabled(boolean enable) {
1024         nSetDebuggingEnabled(enable);
1025     }
1026 
1027     /** @hide */
copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap)1028     public static int copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap) {
1029         if (srcRect == null) {
1030             // Empty rect means entire surface
1031             return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap.getNativeInstance());
1032         } else {
1033             return nCopySurfaceInto(surface, srcRect.left, srcRect.top,
1034                     srcRect.right, srcRect.bottom, bitmap.getNativeInstance());
1035         }
1036     }
1037 
1038     /**
1039      * Creates a {@link android.graphics.Bitmap.Config#HARDWARE} bitmap from the given
1040      * RenderNode. Note that the RenderNode should be created as a root node (so x/y of 0,0), and
1041      * not the RenderNode from a View.
1042      *
1043      * @hide
1044      **/
createHardwareBitmap(RenderNode node, int width, int height)1045     public static Bitmap createHardwareBitmap(RenderNode node, int width, int height) {
1046         return nCreateHardwareBitmap(node.mNativeRenderNode, width, height);
1047     }
1048 
1049     /**
1050      * Invoke this method when the system is running out of memory. This
1051      * method will attempt to recover as much memory as possible, based on
1052      * the specified hint.
1053      *
1054      * @param level Hint about the amount of memory that should be trimmed,
1055      *              see {@link android.content.ComponentCallbacks}
1056      * @hide
1057      */
trimMemory(int level)1058     public static void trimMemory(int level) {
1059         nTrimMemory(level);
1060     }
1061 
1062     /** @hide */
overrideProperty(@onNull String name, @NonNull String value)1063     public static void overrideProperty(@NonNull String name, @NonNull String value) {
1064         if (name == null || value == null) {
1065             throw new IllegalArgumentException("name and value must be non-null");
1066         }
1067         nOverrideProperty(name, value);
1068     }
1069 
1070     /**
1071      * Sets the directory to use as a persistent storage for threaded rendering
1072      * resources.
1073      *
1074      * @param cacheDir A directory the current process can write to
1075      * @hide
1076      */
setupDiskCache(File cacheDir)1077     public static void setupDiskCache(File cacheDir) {
1078         setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath(),
1079                 new File(cacheDir, CACHE_PATH_SKIASHADERS).getAbsolutePath());
1080     }
1081 
1082     /** @hide */
setPackageName(String packageName)1083     public static void setPackageName(String packageName) {
1084         ProcessInitializer.sInstance.setPackageName(packageName);
1085     }
1086 
1087     /**
1088      * Gets a context for process initialization
1089      *
1090      * TODO: Remove this once there is a static method for retrieving an application's context.
1091      *
1092      * @hide
1093      */
setContextForInit(Context context)1094     public static void setContextForInit(Context context) {
1095         ProcessInitializer.sInstance.setContext(context);
1096     }
1097 
1098     private static final class DestroyContextRunnable implements Runnable {
1099         private final long mNativeInstance;
1100 
DestroyContextRunnable(long nativeInstance)1101         DestroyContextRunnable(long nativeInstance) {
1102             mNativeInstance = nativeInstance;
1103         }
1104 
1105         @Override
run()1106         public void run() {
1107             nDeleteProxy(mNativeInstance);
1108         }
1109     }
1110 
1111     private static class ProcessInitializer {
1112         static ProcessInitializer sInstance = new ProcessInitializer();
1113 
1114         // Magic values from android/data_space.h
1115         private static final int INTERNAL_DATASPACE_SRGB = 142671872;
1116         private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696;
1117         private static final int INTERNAL_DATASPACE_SCRGB = 411107328;
1118 
1119         private enum Dataspace {
1120             DISPLAY_P3(ColorSpace.Named.DISPLAY_P3, INTERNAL_DATASPACE_DISPLAY_P3),
1121             SCRGB(ColorSpace.Named.EXTENDED_SRGB, INTERNAL_DATASPACE_SCRGB),
1122             SRGB(ColorSpace.Named.SRGB, INTERNAL_DATASPACE_SRGB);
1123 
1124             private final ColorSpace.Named mColorSpace;
1125             private final int mNativeDataspace;
Dataspace(ColorSpace.Named colorSpace, int nativeDataspace)1126             Dataspace(ColorSpace.Named colorSpace, int nativeDataspace) {
1127                 this.mColorSpace = colorSpace;
1128                 this.mNativeDataspace = nativeDataspace;
1129             }
1130 
find(ColorSpace colorSpace)1131             static Optional<Dataspace> find(ColorSpace colorSpace) {
1132                 return Stream.of(Dataspace.values())
1133                         .filter(d -> ColorSpace.get(d.mColorSpace).equals(colorSpace))
1134                         .findFirst();
1135             }
1136         }
1137 
1138         private boolean mInitialized = false;
1139         private boolean mDisplayInitialized = false;
1140 
1141         private boolean mIsolated = false;
1142         private Context mContext;
1143         private String mPackageName;
1144         private IGraphicsStats mGraphicsStatsService;
1145         private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() {
1146             @Override
1147             public void onRotateGraphicsStatsBuffer() throws RemoteException {
1148                 rotateBuffer();
1149             }
1150         };
1151 
ProcessInitializer()1152         private ProcessInitializer() {
1153         }
1154 
setPackageName(String name)1155         synchronized void setPackageName(String name) {
1156             if (mInitialized) return;
1157             mPackageName = name;
1158         }
1159 
setIsolated(boolean isolated)1160         synchronized void setIsolated(boolean isolated) {
1161             if (mInitialized) return;
1162             mIsolated = isolated;
1163         }
1164 
setContext(Context context)1165         synchronized void setContext(Context context) {
1166             if (mInitialized) return;
1167             mContext = context;
1168         }
1169 
init(long renderProxy)1170         synchronized void init(long renderProxy) {
1171             if (mInitialized) return;
1172             mInitialized = true;
1173 
1174             initSched(renderProxy);
1175             initGraphicsStats();
1176         }
1177 
initSched(long renderProxy)1178         private void initSched(long renderProxy) {
1179             try {
1180                 int tid = nGetRenderThreadTid(renderProxy);
1181                 ActivityManager.getService().setRenderThread(tid);
1182             } catch (Throwable t) {
1183                 Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
1184             }
1185         }
1186 
initGraphicsStats()1187         private void initGraphicsStats() {
1188             if (mPackageName == null) return;
1189 
1190             try {
1191                 IBinder binder = ServiceManager.getService("graphicsstats");
1192                 if (binder == null) return;
1193                 mGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
1194                 requestBuffer();
1195             } catch (Throwable t) {
1196                 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
1197             }
1198         }
1199 
initUsingContext()1200         synchronized void initUsingContext() {
1201             if (mContext == null) return;
1202 
1203             initDisplayInfo();
1204 
1205             nSetIsHighEndGfx(ActivityManager.isHighEndGfx());
1206             // Defensively clear out the context in case we were passed a context that can leak
1207             // if we live longer than it, e.g. an activity context.
1208             mContext = null;
1209         }
1210 
initDisplayInfo()1211         private void initDisplayInfo() {
1212             if (mDisplayInitialized) return;
1213             if (mIsolated) {
1214                 mDisplayInitialized = true;
1215                 return;
1216             }
1217 
1218             DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
1219             if (dm == null) {
1220                 Log.d(LOG_TAG, "Failed to find DisplayManager for display-based configuration");
1221                 return;
1222             }
1223 
1224             Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
1225             if (display == null) {
1226                 Log.d(LOG_TAG, "Failed to find default display for display-based configuration");
1227                 return;
1228             }
1229 
1230             Dataspace wideColorDataspace =
1231                     Optional.ofNullable(display.getPreferredWideGamutColorSpace())
1232                             .flatMap(Dataspace::find)
1233                             // Default to SRGB if the display doesn't support wide color
1234                             .orElse(Dataspace.SRGB);
1235 
1236             // Grab the physical screen dimensions from the active display mode
1237             // Strictly speaking the screen resolution may not always be constant - it is for
1238             // sizing the font cache for the underlying rendering thread. Since it's a
1239             // heuristic we don't need to be always 100% correct.
1240             Mode activeMode = display.getMode();
1241             nInitDisplayInfo(activeMode.getPhysicalWidth(), activeMode.getPhysicalHeight(),
1242                     display.getRefreshRate(), wideColorDataspace.mNativeDataspace,
1243                     display.getAppVsyncOffsetNanos(), display.getPresentationDeadlineNanos());
1244 
1245             mDisplayInitialized = true;
1246         }
1247 
rotateBuffer()1248         private void rotateBuffer() {
1249             nRotateProcessStatsBuffer();
1250             requestBuffer();
1251         }
1252 
requestBuffer()1253         private void requestBuffer() {
1254             try {
1255                 ParcelFileDescriptor pfd = mGraphicsStatsService
1256                         .requestBufferForProcess(mPackageName, mGraphicsStatsCallback);
1257                 nSetProcessStatsBuffer(pfd.getFd());
1258                 pfd.close();
1259             } catch (Throwable t) {
1260                 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
1261             }
1262         }
1263     }
1264 
1265     /**
1266      * @hide
1267      */
disableVsync()1268     public static native void disableVsync();
1269 
1270     /**
1271      * Start render thread and initialize EGL or Vulkan.
1272      *
1273      * Initializing EGL involves loading and initializing the graphics driver. Some drivers take
1274      * several 10s of milliseconds to do this, so doing it on-demand when an app tries to render
1275      * its first frame adds directly to user-visible app launch latency.
1276      *
1277      * Should only be called after GraphicsEnvironment.chooseDriver().
1278      * @hide
1279      */
preload()1280     public static native void preload();
1281 
1282     /**
1283      * @hide
1284      */
isWebViewOverlaysEnabled()1285     public static native boolean isWebViewOverlaysEnabled();
1286 
1287     /** @hide */
setupShadersDiskCache(String cacheFile, String skiaCacheFile)1288     protected static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile);
1289 
nRotateProcessStatsBuffer()1290     private static native void nRotateProcessStatsBuffer();
1291 
nSetProcessStatsBuffer(int fd)1292     private static native void nSetProcessStatsBuffer(int fd);
1293 
nGetRenderThreadTid(long nativeProxy)1294     private static native int nGetRenderThreadTid(long nativeProxy);
1295 
nCreateRootRenderNode()1296     private static native long nCreateRootRenderNode();
1297 
nCreateProxy(boolean translucent, long rootRenderNode)1298     private static native long nCreateProxy(boolean translucent, long rootRenderNode);
1299 
nDeleteProxy(long nativeProxy)1300     private static native void nDeleteProxy(long nativeProxy);
1301 
nLoadSystemProperties(long nativeProxy)1302     private static native boolean nLoadSystemProperties(long nativeProxy);
1303 
nSetName(long nativeProxy, String name)1304     private static native void nSetName(long nativeProxy, String name);
1305 
nSetSurface(long nativeProxy, Surface window, boolean discardBuffer)1306     private static native void nSetSurface(long nativeProxy, Surface window, boolean discardBuffer);
1307 
nSetSurfaceControl(long nativeProxy, long nativeSurfaceControl)1308     private static native void nSetSurfaceControl(long nativeProxy, long nativeSurfaceControl);
1309 
nPause(long nativeProxy)1310     private static native boolean nPause(long nativeProxy);
1311 
nSetStopped(long nativeProxy, boolean stopped)1312     private static native void nSetStopped(long nativeProxy, boolean stopped);
1313 
nSetLightGeometry(long nativeProxy, float lightX, float lightY, float lightZ, float lightRadius)1314     private static native void nSetLightGeometry(long nativeProxy,
1315             float lightX, float lightY, float lightZ, float lightRadius);
1316 
nSetLightAlpha(long nativeProxy, float ambientShadowAlpha, float spotShadowAlpha)1317     private static native void nSetLightAlpha(long nativeProxy, float ambientShadowAlpha,
1318             float spotShadowAlpha);
1319 
nSetOpaque(long nativeProxy, boolean opaque)1320     private static native void nSetOpaque(long nativeProxy, boolean opaque);
1321 
nSetColorMode(long nativeProxy, int colorMode)1322     private static native void nSetColorMode(long nativeProxy, int colorMode);
1323 
nSetSdrWhitePoint(long nativeProxy, float whitePoint)1324     private static native void nSetSdrWhitePoint(long nativeProxy, float whitePoint);
1325 
nSetIsHighEndGfx(boolean isHighEndGfx)1326     private static native void nSetIsHighEndGfx(boolean isHighEndGfx);
1327 
nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size)1328     private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
1329 
nDestroy(long nativeProxy, long rootRenderNode)1330     private static native void nDestroy(long nativeProxy, long rootRenderNode);
1331 
nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode)1332     private static native void nRegisterAnimatingRenderNode(long rootRenderNode,
1333             long animatingNode);
1334 
nRegisterVectorDrawableAnimator(long rootRenderNode, long animator)1335     private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
1336 
nCreateTextureLayer(long nativeProxy)1337     private static native long nCreateTextureLayer(long nativeProxy);
1338 
nBuildLayer(long nativeProxy, long node)1339     private static native void nBuildLayer(long nativeProxy, long node);
1340 
nCopyLayerInto(long nativeProxy, long layer, long bitmapHandle)1341     private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmapHandle);
1342 
nPushLayerUpdate(long nativeProxy, long layer)1343     private static native void nPushLayerUpdate(long nativeProxy, long layer);
1344 
nCancelLayerUpdate(long nativeProxy, long layer)1345     private static native void nCancelLayerUpdate(long nativeProxy, long layer);
1346 
nDetachSurfaceTexture(long nativeProxy, long layer)1347     private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
1348 
nDestroyHardwareResources(long nativeProxy)1349     private static native void nDestroyHardwareResources(long nativeProxy);
1350 
nTrimMemory(int level)1351     private static native void nTrimMemory(int level);
1352 
nOverrideProperty(String name, String value)1353     private static native void nOverrideProperty(String name, String value);
1354 
nFence(long nativeProxy)1355     private static native void nFence(long nativeProxy);
1356 
nStopDrawing(long nativeProxy)1357     private static native void nStopDrawing(long nativeProxy);
1358 
nNotifyFramePending(long nativeProxy)1359     private static native void nNotifyFramePending(long nativeProxy);
1360 
nDumpProfileInfo(long nativeProxy, FileDescriptor fd, @DumpFlags int dumpFlags)1361     private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
1362             @DumpFlags int dumpFlags);
1363 
nAddRenderNode(long nativeProxy, long rootRenderNode, boolean placeFront)1364     private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
1365             boolean placeFront);
1366 
nRemoveRenderNode(long nativeProxy, long rootRenderNode)1367     private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
1368 
nDrawRenderNode(long nativeProxy, long rootRenderNode)1369     private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
1370 
nSetContentDrawBounds(long nativeProxy, int left, int top, int right, int bottom)1371     private static native void nSetContentDrawBounds(long nativeProxy, int left,
1372             int top, int right, int bottom);
1373 
nSetPictureCaptureCallback(long nativeProxy, PictureCapturedCallback callback)1374     private static native void nSetPictureCaptureCallback(long nativeProxy,
1375             PictureCapturedCallback callback);
1376 
nSetASurfaceTransactionCallback(long nativeProxy, ASurfaceTransactionCallback callback)1377     private static native void nSetASurfaceTransactionCallback(long nativeProxy,
1378             ASurfaceTransactionCallback callback);
1379 
nSetPrepareSurfaceControlForWebviewCallback(long nativeProxy, PrepareSurfaceControlForWebviewCallback callback)1380     private static native void nSetPrepareSurfaceControlForWebviewCallback(long nativeProxy,
1381             PrepareSurfaceControlForWebviewCallback callback);
1382 
nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback)1383     private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);
1384 
nSetFrameCommitCallback(long nativeProxy, FrameCommitCallback callback)1385     private static native void nSetFrameCommitCallback(long nativeProxy,
1386             FrameCommitCallback callback);
1387 
nSetFrameCompleteCallback(long nativeProxy, FrameCompleteCallback callback)1388     private static native void nSetFrameCompleteCallback(long nativeProxy,
1389             FrameCompleteCallback callback);
1390 
nAddObserver(long nativeProxy, long nativeObserver)1391     private static native void nAddObserver(long nativeProxy, long nativeObserver);
1392 
nRemoveObserver(long nativeProxy, long nativeObserver)1393     private static native void nRemoveObserver(long nativeProxy, long nativeObserver);
1394 
nCopySurfaceInto(Surface surface, int srcLeft, int srcTop, int srcRight, int srcBottom, long bitmapHandle)1395     private static native int nCopySurfaceInto(Surface surface,
1396             int srcLeft, int srcTop, int srcRight, int srcBottom, long bitmapHandle);
1397 
nCreateHardwareBitmap(long renderNode, int width, int height)1398     private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
1399 
nSetHighContrastText(boolean enabled)1400     private static native void nSetHighContrastText(boolean enabled);
1401 
1402     // For temporary experimentation b/66945974
nHackySetRTAnimationsEnabled(boolean enabled)1403     private static native void nHackySetRTAnimationsEnabled(boolean enabled);
1404 
nSetDebuggingEnabled(boolean enabled)1405     private static native void nSetDebuggingEnabled(boolean enabled);
1406 
nSetIsolatedProcess(boolean enabled)1407     private static native void nSetIsolatedProcess(boolean enabled);
1408 
nSetContextPriority(int priority)1409     private static native void nSetContextPriority(int priority);
1410 
nAllocateBuffers(long nativeProxy)1411     private static native void nAllocateBuffers(long nativeProxy);
1412 
nSetForceDark(long nativeProxy, boolean enabled)1413     private static native void nSetForceDark(long nativeProxy, boolean enabled);
1414 
nSetDisplayDensityDpi(int densityDpi)1415     private static native void nSetDisplayDensityDpi(int densityDpi);
1416 
nInitDisplayInfo(int width, int height, float refreshRate, int wideColorDataspace, long appVsyncOffsetNanos, long presentationDeadlineNanos)1417     private static native void nInitDisplayInfo(int width, int height, float refreshRate,
1418             int wideColorDataspace, long appVsyncOffsetNanos, long presentationDeadlineNanos);
1419 }
1420