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