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