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