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