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 /** @hide */ setASurfaceTransactionCallback(ASurfaceTransactionCallback callback)762 protected void setASurfaceTransactionCallback(ASurfaceTransactionCallback callback) { 763 nSetASurfaceTransactionCallback(mNativeProxy, callback); 764 } 765 766 /** @hide */ setPrepareSurfaceControlForWebviewCallback( PrepareSurfaceControlForWebviewCallback callback)767 protected void setPrepareSurfaceControlForWebviewCallback( 768 PrepareSurfaceControlForWebviewCallback callback) { 769 nSetPrepareSurfaceControlForWebviewCallback(mNativeProxy, callback); 770 } 771 772 /** @hide */ setFrameCallback(FrameDrawingCallback callback)773 public void setFrameCallback(FrameDrawingCallback callback) { 774 nSetFrameCallback(mNativeProxy, callback); 775 } 776 777 /** 778 * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the 779 * rendernode of the UI thread. 780 * 781 * @param node The node to add. 782 * @param placeFront If true, the render node will be placed in front of the content node, 783 * otherwise behind the content node. 784 * @hide 785 */ addRenderNode(RenderNode node, boolean placeFront)786 public void addRenderNode(RenderNode node, boolean placeFront) { 787 nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront); 788 } 789 790 /** 791 * Only especially added render nodes can be removed. 792 * 793 * @param node The node which was added via addRenderNode which should get removed again. 794 * @hide 795 */ removeRenderNode(RenderNode node)796 public void removeRenderNode(RenderNode node) { 797 nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode); 798 } 799 800 /** 801 * Draws a particular render node. If the node is not the content node, only the additional 802 * nodes will get drawn and the content remains untouched. 803 * 804 * @param node The node to be drawn. 805 * @hide 806 */ drawRenderNode(RenderNode node)807 public void drawRenderNode(RenderNode node) { 808 nDrawRenderNode(mNativeProxy, node.mNativeRenderNode); 809 } 810 811 /** 812 * Loads system properties used by the renderer. This method is invoked 813 * whenever system properties are modified. Implementations can use this 814 * to trigger live updates of the renderer based on properties. 815 * 816 * @return True if a property has changed. 817 * @hide 818 */ loadSystemProperties()819 public boolean loadSystemProperties() { 820 return nLoadSystemProperties(mNativeProxy); 821 } 822 823 /** 824 * @hide 825 */ dumpGlobalProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags)826 public static void dumpGlobalProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags) { 827 nDumpGlobalProfileInfo(fd, dumpFlags); 828 } 829 830 /** 831 * @hide 832 */ dumpProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags)833 public void dumpProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags) { 834 nDumpProfileInfo(mNativeProxy, fd, dumpFlags); 835 } 836 837 /** 838 * To avoid unnecessary overdrawing of the main content all additionally passed render nodes 839 * will be prevented to overdraw this area. It will be synchronized with the draw call. 840 * This should be updated in the content view's draw call. 841 * 842 * @param left The left side of the protected bounds. 843 * @param top The top side of the protected bounds. 844 * @param right The right side of the protected bounds. 845 * @param bottom The bottom side of the protected bounds. 846 * @hide 847 */ setContentDrawBounds(int left, int top, int right, int bottom)848 public void setContentDrawBounds(int left, int top, int right, int bottom) { 849 nSetContentDrawBounds(mNativeProxy, left, top, right, bottom); 850 } 851 852 /** 853 * Force the new frame to draw, ensuring the UI draw request will attempt a draw this vsync. 854 * @hide 855 */ forceDrawNextFrame()856 public void forceDrawNextFrame() { 857 nForceDrawNextFrame(mNativeProxy); 858 } 859 860 /** @hide */ setPictureCaptureCallback(@ullable PictureCapturedCallback callback)861 public void setPictureCaptureCallback(@Nullable PictureCapturedCallback callback) { 862 nSetPictureCaptureCallback(mNativeProxy, callback); 863 } 864 865 /** called by native */ invokePictureCapturedCallback(long picturePtr, PictureCapturedCallback callback)866 static void invokePictureCapturedCallback(long picturePtr, PictureCapturedCallback callback) { 867 Picture picture = new Picture(picturePtr); 868 callback.onPictureCaptured(picture); 869 } 870 871 /** 872 * Interface used to receive callbacks when Webview requests a surface control. 873 * 874 * @hide 875 */ 876 public interface PrepareSurfaceControlForWebviewCallback { 877 /** 878 * Invoked when Webview calls to get a surface control. 879 * 880 */ prepare()881 void prepare(); 882 } 883 884 /** 885 * Interface used to receive callbacks when a transaction needs to be merged. 886 * 887 * @hide 888 */ 889 public interface ASurfaceTransactionCallback { 890 /** 891 * Invoked during a frame drawing. 892 * 893 * @param aSurfaceTranactionNativeObj the ASurfaceTransaction native object handle 894 * @param aSurfaceControlNativeObj ASurfaceControl native object handle 895 * @param frame The id of the frame being drawn. 896 */ onMergeTransaction(long aSurfaceTranactionNativeObj, long aSurfaceControlNativeObj, long frame)897 boolean onMergeTransaction(long aSurfaceTranactionNativeObj, 898 long aSurfaceControlNativeObj, long frame); 899 } 900 901 /** 902 * Interface used to receive callbacks when a frame is being drawn. 903 * 904 * @hide 905 */ 906 public interface FrameDrawingCallback { 907 /** 908 * Invoked during a frame drawing. 909 * 910 * @param frame The id of the frame being drawn. 911 */ onFrameDraw(long frame)912 void onFrameDraw(long frame); 913 914 /** 915 * Invoked during a frame drawing. 916 * 917 * @param syncResult The result of the draw. Should be a value or a combination of values 918 * from {@link SyncAndDrawResult} 919 * @param frame The id of the frame being drawn. 920 * 921 * @return A {@link FrameCommitCallback} that will report back if the current vsync draws. 922 */ onFrameDraw(@yncAndDrawResult int syncResult, long frame)923 default FrameCommitCallback onFrameDraw(@SyncAndDrawResult int syncResult, long frame) { 924 onFrameDraw(frame); 925 return null; 926 } 927 } 928 929 /** 930 * Interface used to be notified when a frame has finished rendering 931 * 932 * @hide 933 */ 934 public interface FrameCommitCallback { 935 /** 936 * Invoked after a new frame was drawn 937 * 938 * @param didProduceBuffer The draw successfully produced a new buffer. 939 */ onFrameCommit(boolean didProduceBuffer)940 void onFrameCommit(boolean didProduceBuffer); 941 } 942 943 /** 944 * Interface used to be notified when RenderThread has finished an attempt to draw. This doesn't 945 * mean a new frame has drawn, specifically if there's nothing new to draw, but only that 946 * RenderThread had a chance to draw a frame. 947 * 948 * @hide 949 */ 950 public interface FrameCompleteCallback { 951 /** 952 * Invoked after a frame draw was attempted. 953 */ onFrameComplete()954 void onFrameComplete(); 955 } 956 957 /** 958 * Interface for listening to picture captures 959 * @hide 960 */ 961 public interface PictureCapturedCallback { 962 /** @hide */ onPictureCaptured(Picture picture)963 void onPictureCaptured(Picture picture); 964 } 965 validateAlpha(float alpha, String argumentName)966 private static void validateAlpha(float alpha, String argumentName) { 967 if (!(alpha >= 0.0f && alpha <= 1.0f)) { 968 throw new IllegalArgumentException(argumentName + " must be a valid alpha, " 969 + alpha + " is not in the range of 0.0f to 1.0f"); 970 } 971 } 972 validatePositive(float f, String argumentName)973 private static void validatePositive(float f, String argumentName) { 974 if (!(Float.isFinite(f) && f >= 0.0f)) { 975 throw new IllegalArgumentException(argumentName 976 + " must be a finite positive, given=" + f); 977 } 978 } 979 validateFinite(float f, String argumentName)980 private static void validateFinite(float f, String argumentName) { 981 if (!Float.isFinite(f)) { 982 throw new IllegalArgumentException(argumentName + " must be finite, given=" + f); 983 } 984 } 985 986 /** 987 * b/68769804, b/66945974: For low FPS experiments. 988 * 989 * @hide 990 */ setFPSDivisor(int divisor)991 public static void setFPSDivisor(int divisor) { 992 nSetRtAnimationsEnabled(divisor <= 1); 993 } 994 995 /** 996 * Changes the OpenGL context priority if IMG_context_priority extension is available. Must be 997 * called before any OpenGL context is created. 998 * 999 * @param priority The priority to use. Must be one of EGL_CONTEXT_PRIORITY_* values. 1000 * @hide 1001 */ setContextPriority(int priority)1002 public static void setContextPriority(int priority) { 1003 nSetContextPriority(priority); 1004 } 1005 1006 /** 1007 * Sets whether or not high contrast text rendering is enabled. The setting is global 1008 * but only affects content rendered after the change is made. 1009 * 1010 * @hide 1011 */ setHighContrastText(boolean highContrastText)1012 public static void setHighContrastText(boolean highContrastText) { 1013 nSetHighContrastText(highContrastText); 1014 } 1015 1016 /** 1017 * If set RenderThread will avoid doing any IPC using instead a fake vsync & DisplayInfo source 1018 * 1019 * @hide 1020 */ setIsolatedProcess(boolean isIsolated)1021 public static void setIsolatedProcess(boolean isIsolated) { 1022 nSetIsolatedProcess(isIsolated); 1023 ProcessInitializer.sInstance.setIsolated(isIsolated); 1024 } 1025 1026 /** 1027 * Sends device configuration changes to the render thread, for rendering profiling views. 1028 * 1029 * @hide 1030 */ sendDeviceConfigurationForDebugging(Configuration config)1031 public static void sendDeviceConfigurationForDebugging(Configuration config) { 1032 if (config.densityDpi != Configuration.DENSITY_DPI_UNDEFINED 1033 && config.densityDpi != sDensityDpi) { 1034 sDensityDpi = config.densityDpi; 1035 nSetDisplayDensityDpi(config.densityDpi); 1036 } 1037 } 1038 1039 /** 1040 * If set extra graphics debugging abilities will be enabled such as dumping skp 1041 * 1042 * @hide 1043 */ setDebuggingEnabled(boolean enable)1044 public static void setDebuggingEnabled(boolean enable) { 1045 nSetDebuggingEnabled(enable); 1046 } 1047 1048 /** @hide */ copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap)1049 public static int copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap) { 1050 if (srcRect == null) { 1051 // Empty rect means entire surface 1052 return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap.getNativeInstance()); 1053 } else { 1054 return nCopySurfaceInto(surface, srcRect.left, srcRect.top, 1055 srcRect.right, srcRect.bottom, bitmap.getNativeInstance()); 1056 } 1057 } 1058 1059 /** 1060 * Creates a {@link android.graphics.Bitmap.Config#HARDWARE} bitmap from the given 1061 * RenderNode. Note that the RenderNode should be created as a root node (so x/y of 0,0), and 1062 * not the RenderNode from a View. 1063 * 1064 * @hide 1065 **/ createHardwareBitmap(RenderNode node, int width, int height)1066 public static Bitmap createHardwareBitmap(RenderNode node, int width, int height) { 1067 return nCreateHardwareBitmap(node.mNativeRenderNode, width, height); 1068 } 1069 1070 /** 1071 * Invoke this method when the system is running out of memory. This 1072 * method will attempt to recover as much memory as possible, based on 1073 * the specified hint. 1074 * 1075 * @param level Hint about the amount of memory that should be trimmed, 1076 * see {@link android.content.ComponentCallbacks} 1077 * @hide 1078 */ trimMemory(int level)1079 public static void trimMemory(int level) { 1080 nTrimMemory(level); 1081 } 1082 1083 /** @hide */ overrideProperty(@onNull String name, @NonNull String value)1084 public static void overrideProperty(@NonNull String name, @NonNull String value) { 1085 if (name == null || value == null) { 1086 throw new IllegalArgumentException("name and value must be non-null"); 1087 } 1088 nOverrideProperty(name, value); 1089 } 1090 1091 /** 1092 * Sets the directory to use as a persistent storage for threaded rendering 1093 * resources. 1094 * 1095 * @param cacheDir A directory the current process can write to 1096 * @hide 1097 */ setupDiskCache(File cacheDir)1098 public static void setupDiskCache(File cacheDir) { 1099 setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath(), 1100 new File(cacheDir, CACHE_PATH_SKIASHADERS).getAbsolutePath()); 1101 } 1102 1103 /** @hide */ setPackageName(String packageName)1104 public static void setPackageName(String packageName) { 1105 ProcessInitializer.sInstance.setPackageName(packageName); 1106 } 1107 1108 /** 1109 * Gets a context for process initialization 1110 * 1111 * TODO: Remove this once there is a static method for retrieving an application's context. 1112 * 1113 * @hide 1114 */ setContextForInit(Context context)1115 public static void setContextForInit(Context context) { 1116 ProcessInitializer.sInstance.setContext(context); 1117 } 1118 1119 /** 1120 * Returns true if HardwareRender will produce output. 1121 * 1122 * This value is global to the process and affects all uses of HardwareRenderer, 1123 * including 1124 * those created by the system such as those used by the View tree when using hardware 1125 * accelerated rendering. 1126 * 1127 * Default is true in all production environments, but may be false in testing-focused 1128 * emulators or if {@link #setDrawingEnabled(boolean)} is used. 1129 */ isDrawingEnabled()1130 public static boolean isDrawingEnabled() { 1131 return nIsDrawingEnabled(); 1132 } 1133 1134 /** 1135 * Toggles whether or not HardwareRenderer will produce drawing output globally in the current 1136 * process. 1137 * 1138 * This applies to all HardwareRenderer instances, including those created by the platform such 1139 * as those used by the system for hardware accelerated View rendering. 1140 * 1141 * The capability to disable drawing output is intended for test environments, primarily 1142 * headless ones. By setting this to false, tests that launch activities or interact with Views 1143 * can be quicker with less RAM usage by skipping the final step of View drawing. All View 1144 * lifecycle events will occur as normal, only the final step of rendering on the GPU to the 1145 * display will be skipped. 1146 * 1147 * This can be toggled on and off at will, so screenshot tests can also run in this same 1148 * environment by toggling drawing back on and forcing a frame to be drawn such as by calling 1149 * view#invalidate(). Once drawn and the screenshot captured, this can then be turned back off. 1150 */ 1151 // TODO(b/194195794): Add link to androidx's Screenshot library for help with this setDrawingEnabled(boolean drawingEnabled)1152 public static void setDrawingEnabled(boolean drawingEnabled) { 1153 nSetDrawingEnabled(drawingEnabled); 1154 } 1155 1156 /** 1157 * Disable RenderThread animations that schedule draws directly from RenderThread. This is used 1158 * when we don't want to de-schedule draw requests that come from the UI thread. 1159 * 1160 * @hide 1161 */ setRtAnimationsEnabled(boolean enabled)1162 public static void setRtAnimationsEnabled(boolean enabled) { 1163 nSetRtAnimationsEnabled(enabled); 1164 } 1165 1166 private static final class DestroyContextRunnable implements Runnable { 1167 private final long mNativeInstance; 1168 DestroyContextRunnable(long nativeInstance)1169 DestroyContextRunnable(long nativeInstance) { 1170 mNativeInstance = nativeInstance; 1171 } 1172 1173 @Override run()1174 public void run() { 1175 nDeleteProxy(mNativeInstance); 1176 } 1177 } 1178 1179 private static class ProcessInitializer { 1180 static ProcessInitializer sInstance = new ProcessInitializer(); 1181 1182 // Magic values from android/data_space.h 1183 private static final int INTERNAL_DATASPACE_SRGB = 142671872; 1184 private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696; 1185 private static final int INTERNAL_DATASPACE_SCRGB = 411107328; 1186 1187 private enum Dataspace { 1188 DISPLAY_P3(ColorSpace.Named.DISPLAY_P3, INTERNAL_DATASPACE_DISPLAY_P3), 1189 SCRGB(ColorSpace.Named.EXTENDED_SRGB, INTERNAL_DATASPACE_SCRGB), 1190 SRGB(ColorSpace.Named.SRGB, INTERNAL_DATASPACE_SRGB); 1191 1192 private final ColorSpace.Named mColorSpace; 1193 private final int mNativeDataspace; Dataspace(ColorSpace.Named colorSpace, int nativeDataspace)1194 Dataspace(ColorSpace.Named colorSpace, int nativeDataspace) { 1195 this.mColorSpace = colorSpace; 1196 this.mNativeDataspace = nativeDataspace; 1197 } 1198 find(ColorSpace colorSpace)1199 static Optional<Dataspace> find(ColorSpace colorSpace) { 1200 return Stream.of(Dataspace.values()) 1201 .filter(d -> ColorSpace.get(d.mColorSpace).equals(colorSpace)) 1202 .findFirst(); 1203 } 1204 } 1205 1206 private boolean mInitialized = false; 1207 private boolean mDisplayInitialized = false; 1208 1209 private boolean mIsolated = false; 1210 private Context mContext; 1211 private String mPackageName; 1212 private IGraphicsStats mGraphicsStatsService; 1213 private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() { 1214 @Override 1215 public void onRotateGraphicsStatsBuffer() throws RemoteException { 1216 rotateBuffer(); 1217 } 1218 }; 1219 ProcessInitializer()1220 private ProcessInitializer() { 1221 } 1222 setPackageName(String name)1223 synchronized void setPackageName(String name) { 1224 if (mInitialized) return; 1225 mPackageName = name; 1226 } 1227 setIsolated(boolean isolated)1228 synchronized void setIsolated(boolean isolated) { 1229 if (mInitialized) return; 1230 mIsolated = isolated; 1231 } 1232 setContext(Context context)1233 synchronized void setContext(Context context) { 1234 if (mInitialized) return; 1235 mContext = context; 1236 } 1237 init(long renderProxy)1238 synchronized void init(long renderProxy) { 1239 if (mInitialized) return; 1240 mInitialized = true; 1241 1242 initSched(renderProxy); 1243 initGraphicsStats(); 1244 } 1245 initSched(long renderProxy)1246 private void initSched(long renderProxy) { 1247 try { 1248 int tid = nGetRenderThreadTid(renderProxy); 1249 ActivityManager.getService().setRenderThread(tid); 1250 } catch (Throwable t) { 1251 Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t); 1252 } 1253 } 1254 initGraphicsStats()1255 private void initGraphicsStats() { 1256 if (mPackageName == null) return; 1257 1258 try { 1259 IBinder binder = ServiceManager.getService("graphicsstats"); 1260 if (binder == null) return; 1261 mGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder); 1262 requestBuffer(); 1263 } catch (Throwable t) { 1264 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t); 1265 } 1266 } 1267 initUsingContext()1268 synchronized void initUsingContext() { 1269 if (mContext == null) return; 1270 1271 initDisplayInfo(); 1272 1273 nSetIsHighEndGfx(ActivityManager.isHighEndGfx()); 1274 // Defensively clear out the context in case we were passed a context that can leak 1275 // if we live longer than it, e.g. an activity context. 1276 mContext = null; 1277 } 1278 initDisplayInfo()1279 private void initDisplayInfo() { 1280 if (mDisplayInitialized) return; 1281 if (mIsolated) { 1282 mDisplayInitialized = true; 1283 return; 1284 } 1285 1286 DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); 1287 if (dm == null) { 1288 Log.d(LOG_TAG, "Failed to find DisplayManager for display-based configuration"); 1289 return; 1290 } 1291 1292 Display display = dm.getDisplay(Display.DEFAULT_DISPLAY); 1293 if (display == null) { 1294 Log.d(LOG_TAG, "Failed to find default display for display-based configuration"); 1295 return; 1296 } 1297 1298 Dataspace wideColorDataspace = 1299 Optional.ofNullable(display.getPreferredWideGamutColorSpace()) 1300 .flatMap(Dataspace::find) 1301 // Default to SRGB if the display doesn't support wide color 1302 .orElse(Dataspace.SRGB); 1303 1304 // Grab the physical screen dimensions from the active display mode 1305 // Strictly speaking the screen resolution may not always be constant - it is for 1306 // sizing the font cache for the underlying rendering thread. Since it's a 1307 // heuristic we don't need to be always 100% correct. 1308 Mode activeMode = display.getMode(); 1309 nInitDisplayInfo(activeMode.getPhysicalWidth(), activeMode.getPhysicalHeight(), 1310 display.getRefreshRate(), wideColorDataspace.mNativeDataspace, 1311 display.getAppVsyncOffsetNanos(), display.getPresentationDeadlineNanos()); 1312 1313 mDisplayInitialized = true; 1314 } 1315 rotateBuffer()1316 private void rotateBuffer() { 1317 nRotateProcessStatsBuffer(); 1318 requestBuffer(); 1319 } 1320 requestBuffer()1321 private void requestBuffer() { 1322 try { 1323 ParcelFileDescriptor pfd = mGraphicsStatsService 1324 .requestBufferForProcess(mPackageName, mGraphicsStatsCallback); 1325 nSetProcessStatsBuffer(pfd.getFd()); 1326 pfd.close(); 1327 } catch (Throwable t) { 1328 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t); 1329 } 1330 } 1331 } 1332 1333 /** 1334 * @hide 1335 */ disableVsync()1336 public static native void disableVsync(); 1337 1338 /** 1339 * Start render thread and initialize EGL or Vulkan. 1340 * 1341 * Initializing EGL involves loading and initializing the graphics driver. Some drivers take 1342 * several 10s of milliseconds to do this, so doing it on-demand when an app tries to render 1343 * its first frame adds directly to user-visible app launch latency. 1344 * 1345 * Should only be called after GraphicsEnvironment.chooseDriver(). 1346 * @hide 1347 */ preload()1348 public static native void preload(); 1349 1350 /** 1351 * @hide 1352 */ isWebViewOverlaysEnabled()1353 protected static native boolean isWebViewOverlaysEnabled(); 1354 1355 /** @hide */ setupShadersDiskCache(String cacheFile, String skiaCacheFile)1356 protected static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile); 1357 nRotateProcessStatsBuffer()1358 private static native void nRotateProcessStatsBuffer(); 1359 nSetProcessStatsBuffer(int fd)1360 private static native void nSetProcessStatsBuffer(int fd); 1361 nGetRenderThreadTid(long nativeProxy)1362 private static native int nGetRenderThreadTid(long nativeProxy); 1363 nCreateRootRenderNode()1364 private static native long nCreateRootRenderNode(); 1365 nCreateProxy(boolean translucent, long rootRenderNode)1366 private static native long nCreateProxy(boolean translucent, long rootRenderNode); 1367 nDeleteProxy(long nativeProxy)1368 private static native void nDeleteProxy(long nativeProxy); 1369 nLoadSystemProperties(long nativeProxy)1370 private static native boolean nLoadSystemProperties(long nativeProxy); 1371 nSetName(long nativeProxy, String name)1372 private static native void nSetName(long nativeProxy, String name); 1373 nSetSurface(long nativeProxy, Surface window, boolean discardBuffer)1374 private static native void nSetSurface(long nativeProxy, Surface window, boolean discardBuffer); 1375 nSetSurfaceControl(long nativeProxy, long nativeSurfaceControl)1376 private static native void nSetSurfaceControl(long nativeProxy, long nativeSurfaceControl); 1377 nPause(long nativeProxy)1378 private static native boolean nPause(long nativeProxy); 1379 nSetStopped(long nativeProxy, boolean stopped)1380 private static native void nSetStopped(long nativeProxy, boolean stopped); 1381 nSetLightGeometry(long nativeProxy, float lightX, float lightY, float lightZ, float lightRadius)1382 private static native void nSetLightGeometry(long nativeProxy, 1383 float lightX, float lightY, float lightZ, float lightRadius); 1384 nSetLightAlpha(long nativeProxy, float ambientShadowAlpha, float spotShadowAlpha)1385 private static native void nSetLightAlpha(long nativeProxy, float ambientShadowAlpha, 1386 float spotShadowAlpha); 1387 nSetOpaque(long nativeProxy, boolean opaque)1388 private static native void nSetOpaque(long nativeProxy, boolean opaque); 1389 nSetColorMode(long nativeProxy, int colorMode)1390 private static native void nSetColorMode(long nativeProxy, int colorMode); 1391 nSetSdrWhitePoint(long nativeProxy, float whitePoint)1392 private static native void nSetSdrWhitePoint(long nativeProxy, float whitePoint); 1393 nSetIsHighEndGfx(boolean isHighEndGfx)1394 private static native void nSetIsHighEndGfx(boolean isHighEndGfx); 1395 nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size)1396 private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size); 1397 nDestroy(long nativeProxy, long rootRenderNode)1398 private static native void nDestroy(long nativeProxy, long rootRenderNode); 1399 nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode)1400 private static native void nRegisterAnimatingRenderNode(long rootRenderNode, 1401 long animatingNode); 1402 nRegisterVectorDrawableAnimator(long rootRenderNode, long animator)1403 private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator); 1404 nCreateTextureLayer(long nativeProxy)1405 private static native long nCreateTextureLayer(long nativeProxy); 1406 nBuildLayer(long nativeProxy, long node)1407 private static native void nBuildLayer(long nativeProxy, long node); 1408 nCopyLayerInto(long nativeProxy, long layer, long bitmapHandle)1409 private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmapHandle); 1410 nPushLayerUpdate(long nativeProxy, long layer)1411 private static native void nPushLayerUpdate(long nativeProxy, long layer); 1412 nCancelLayerUpdate(long nativeProxy, long layer)1413 private static native void nCancelLayerUpdate(long nativeProxy, long layer); 1414 nDetachSurfaceTexture(long nativeProxy, long layer)1415 private static native void nDetachSurfaceTexture(long nativeProxy, long layer); 1416 nDestroyHardwareResources(long nativeProxy)1417 private static native void nDestroyHardwareResources(long nativeProxy); 1418 nTrimMemory(int level)1419 private static native void nTrimMemory(int level); 1420 nOverrideProperty(String name, String value)1421 private static native void nOverrideProperty(String name, String value); 1422 nFence(long nativeProxy)1423 private static native void nFence(long nativeProxy); 1424 nStopDrawing(long nativeProxy)1425 private static native void nStopDrawing(long nativeProxy); 1426 nNotifyFramePending(long nativeProxy)1427 private static native void nNotifyFramePending(long nativeProxy); 1428 nDumpProfileInfo(long nativeProxy, FileDescriptor fd, @DumpFlags int dumpFlags)1429 private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd, 1430 @DumpFlags int dumpFlags); 1431 nDumpGlobalProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags)1432 private static native void nDumpGlobalProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags); 1433 nAddRenderNode(long nativeProxy, long rootRenderNode, boolean placeFront)1434 private static native void nAddRenderNode(long nativeProxy, long rootRenderNode, 1435 boolean placeFront); 1436 nRemoveRenderNode(long nativeProxy, long rootRenderNode)1437 private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode); 1438 nDrawRenderNode(long nativeProxy, long rootRenderNode)1439 private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode); 1440 nSetContentDrawBounds(long nativeProxy, int left, int top, int right, int bottom)1441 private static native void nSetContentDrawBounds(long nativeProxy, int left, 1442 int top, int right, int bottom); 1443 nForceDrawNextFrame(long nativeProxy)1444 private static native void nForceDrawNextFrame(long nativeProxy); 1445 nSetPictureCaptureCallback(long nativeProxy, PictureCapturedCallback callback)1446 private static native void nSetPictureCaptureCallback(long nativeProxy, 1447 PictureCapturedCallback callback); 1448 nSetASurfaceTransactionCallback(long nativeProxy, ASurfaceTransactionCallback callback)1449 private static native void nSetASurfaceTransactionCallback(long nativeProxy, 1450 ASurfaceTransactionCallback callback); 1451 nSetPrepareSurfaceControlForWebviewCallback(long nativeProxy, PrepareSurfaceControlForWebviewCallback callback)1452 private static native void nSetPrepareSurfaceControlForWebviewCallback(long nativeProxy, 1453 PrepareSurfaceControlForWebviewCallback callback); 1454 nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback)1455 private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback); 1456 nSetFrameCommitCallback(long nativeProxy, FrameCommitCallback callback)1457 private static native void nSetFrameCommitCallback(long nativeProxy, 1458 FrameCommitCallback callback); 1459 nSetFrameCompleteCallback(long nativeProxy, FrameCompleteCallback callback)1460 private static native void nSetFrameCompleteCallback(long nativeProxy, 1461 FrameCompleteCallback callback); 1462 nAddObserver(long nativeProxy, long nativeObserver)1463 private static native void nAddObserver(long nativeProxy, long nativeObserver); 1464 nRemoveObserver(long nativeProxy, long nativeObserver)1465 private static native void nRemoveObserver(long nativeProxy, long nativeObserver); 1466 nCopySurfaceInto(Surface surface, int srcLeft, int srcTop, int srcRight, int srcBottom, long bitmapHandle)1467 private static native int nCopySurfaceInto(Surface surface, 1468 int srcLeft, int srcTop, int srcRight, int srcBottom, long bitmapHandle); 1469 nCreateHardwareBitmap(long renderNode, int width, int height)1470 private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height); 1471 nSetHighContrastText(boolean enabled)1472 private static native void nSetHighContrastText(boolean enabled); 1473 nSetDebuggingEnabled(boolean enabled)1474 private static native void nSetDebuggingEnabled(boolean enabled); 1475 nSetIsolatedProcess(boolean enabled)1476 private static native void nSetIsolatedProcess(boolean enabled); 1477 nSetContextPriority(int priority)1478 private static native void nSetContextPriority(int priority); 1479 nAllocateBuffers(long nativeProxy)1480 private static native void nAllocateBuffers(long nativeProxy); 1481 nSetForceDark(long nativeProxy, boolean enabled)1482 private static native void nSetForceDark(long nativeProxy, boolean enabled); 1483 nSetDisplayDensityDpi(int densityDpi)1484 private static native void nSetDisplayDensityDpi(int densityDpi); 1485 nInitDisplayInfo(int width, int height, float refreshRate, int wideColorDataspace, long appVsyncOffsetNanos, long presentationDeadlineNanos)1486 private static native void nInitDisplayInfo(int width, int height, float refreshRate, 1487 int wideColorDataspace, long appVsyncOffsetNanos, long presentationDeadlineNanos); 1488 nSetDrawingEnabled(boolean drawingEnabled)1489 private static native void nSetDrawingEnabled(boolean drawingEnabled); 1490 nIsDrawingEnabled()1491 private static native boolean nIsDrawingEnabled(); 1492 nSetRtAnimationsEnabled(boolean rtAnimationsEnabled)1493 private static native void nSetRtAnimationsEnabled(boolean rtAnimationsEnabled); 1494 } 1495