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