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