/**@class android.graphics.HardwareRenderer @extends java.lang.Object <p>Creates an instance of a hardware-accelerated renderer. This is used to render a scene built from {@link android.graphics.RenderNode}'s to an output {@link android.view.Surface}. There can be as many HardwareRenderer instances as desired.</p> <h3>Resources & lifecycle</h3> <p>All HardwareRenderer instances share a common render thread. The render thread contains the GPU context & resources necessary to do GPU-accelerated rendering. As such, the first HardwareRenderer created comes with the cost of also creating the associated GPU contexts, however each incremental HardwareRenderer thereafter is fairly cheap. The expected usage is to have a HardwareRenderer instance for every active {@link Surface}. For example when an Activity shows a Dialog the system internally will use 2 hardware renderers, both of which may be drawing at the same time.</p> <p>NOTE: Due to the shared, cooperative nature of the render thread it is critical that any {@link Surface} used must have a prompt, reliable consuming side. System-provided consumers such as {@link android.view.SurfaceView}, {@link android.view.Window#takeSurface(SurfaceHolder.Callback2)}, or {@link android.view.TextureView} all fit this requirement. However if custom consumers are used such as when using {@link android.graphics.SurfaceTexture} or {@link android.media.ImageReader} it is the app's responsibility to ensure that they consume updates promptly and rapidly. Failure to do so will cause the render thread to stall on that surface, blocking all HardwareRenderer instances.</p> */ var HardwareRenderer = { /** Nothing interesting to report. Sync & draw kicked off */ SYNC_OK : "0", /** The renderer is requesting a redraw. This can occur if there's an animation that's running in the RenderNode tree and the hardware renderer is unable to self-animate. <p>If this is returned from syncAndDraw the expectation is that syncAndDraw will be called again on the next vsync signal. */ SYNC_REDRAW_REQUESTED : "1", /** The hardware renderer no longer has a valid {@link android.view.Surface} to render to. This can happen if {@link Surface#release()} was called. The user should no longer attempt to call syncAndDraw until a new surface has been provided by calling setSurface. <p>Spoiler: the reward is GPU-accelerated drawing, better find that Surface! */ SYNC_LOST_SURFACE_REWARD_IF_FOUND : "2", /** The hardware renderer has been set to a "stopped" state. If this is returned then the rendering content has been synced, however a frame was not produced. */ SYNC_CONTEXT_IS_STOPPED : "4", /** The content was synced but the renderer has declined to produce a frame in this vsync interval. This can happen if a frame was already drawn in this vsync or if the renderer is outrunning the frame consumer. The renderer will internally re-schedule itself to render a frame in the next vsync signal, so the caller does not need to do anything in response to this signal. */ SYNC_FRAME_DROPPED : "8", /**@hide */ FLAG_DUMP_FRAMESTATS : "1", /**@hide */ FLAG_DUMP_RESET : "2", /**@hide */ FLAG_DUMP_ALL : "1", /**Destroys the rendering context of this HardwareRenderer. This destroys the resources associated with this renderer and releases the currently set {@link Surface}. This must be called when this HardwareRenderer is no longer needed. <p>The renderer may be restored from this state by setting a new {@link Surface}, setting new rendering content with {@link #setContentRoot}(RenderNode), and resuming rendering by issuing a new {@link android.graphics.HardwareRenderer.FrameRenderRequest}. <p>It is recommended to call this in response to callbacks such as {@link android.view.SurfaceHolder.Callback#surfaceDestroyed(SurfaceHolder)}. <p>Note that if there are any outstanding frame commit callbacks they may never being invoked if the frame was deferred to a later vsync. */ destroy : function( ) {}, /**Sets a name for this renderer. This is used to identify this renderer instance when reporting debug information such as the per-window frame time metrics reported by 'adb shell dumpsys gfxinfo [package] framestats' @param {String} name The debug name to use for this HardwareRenderer instance */ setName : function( ) {}, /**Sets the center of the light source. The light source point controls the directionality and shape of shadows rendered by RenderNode Z & elevation. <p>The platform's recommendation is to set lightX to 'displayWidth / 2f - windowLeft', set lightY to 0 - windowTop, lightZ set to 600dp, and lightRadius to 800dp. <p>The light source should be setup both as part of initial configuration, and whenever the window moves to ensure the light source stays anchored in display space instead of in window space. <p>This must be set at least once along with {@link #setLightSourceAlpha(float, float)} before shadows will work. @param {Number} lightX The X position of the light source @param {Number} lightY The Y position of the light source @param {Number} lightZ The Z position of the light source. Must be >= 0. @param {Number} lightRadius The radius of the light source. Smaller radius will have sharper edges, larger radius will have softer shadows. */ setLightSourceGeometry : function( ) {}, /**Configures the ambient & spot shadow alphas. This is the alpha used when the shadow has max alpha, and ramps down from the values provided to zero. <p>These values are typically provided by the current theme, see {@link android.R.attr#spotShadowAlpha} and {@link android.R.attr#ambientShadowAlpha}. <p>This must be set at least once along with {@link #setLightSourceGeometry(float, float, float, float)} before shadows will work. @param {Number} ambientShadowAlpha The alpha for the ambient shadow. If unsure, a reasonable default is 0.039f. @param {Number} spotShadowAlpha The alpha for the spot shadow. If unsure, a reasonable default is 0.19f. */ setLightSourceAlpha : function( ) {}, /**Sets the content root to render. It is not necessary to call this whenever the content recording changes. Any mutations to the RenderNode content, or any of the RenderNode's contained within the content node, will be applied whenever a new {@link android.graphics.HardwareRenderer.FrameRenderRequest} is issued via {@link #createRenderRequest}() and {@link android.graphics.HardwareRenderer.FrameRenderRequest#syncAndDraw()}. @param {Object {RenderNode}} content The content to set as the root RenderNode. If null the content root is removed and the renderer will draw nothing. */ setContentRoot : function( ) {}, /**<p>The surface to render into. The surface is assumed to be associated with the display and as such is still driven by vsync signals such as those from {@link android.view.Choreographer} and that it has a native refresh rate matching that of the display's (typically 60hz).</p> <p>NOTE: Due to the shared, cooperative nature of the render thread it is critical that any {@link Surface} used must have a prompt, reliable consuming side. System-provided consumers such as {@link android.view.SurfaceView}, {@link android.view.Window#takeSurface(SurfaceHolder.Callback2)}, or {@link android.view.TextureView} all fit this requirement. However if custom consumers are used such as when using {@link android.graphics.SurfaceTexture} or {@link android.media.ImageReader} it is the app's responsibility to ensure that they consume updates promptly and rapidly. Failure to do so will cause the render thread to stall on that surface, blocking all HardwareRenderer instances.</p> @param {Object {Surface}} surface The surface to render into. If null then rendering will be stopped. If non-null then {@link Surface#isValid()} must be true. */ setSurface : function( ) {}, /**Returns a {@link android.graphics.HardwareRenderer.FrameRenderRequest} that can be used to render a new frame. This is used to synchronize the RenderNode content provided by {@link #setContentRoot}(RenderNode) with the RenderThread and then renders a single frame to the Surface set with {@link #setSurface}(Surface). @return {Object {android.graphics.HardwareRenderer.FrameRenderRequest}} An instance of {@link FrameRenderRequest}. The instance may be reused for every frame, so the caller should not hold onto it for longer than a single render request. */ createRenderRequest : function( ) {}, /**Syncs the RenderNode tree to the render thread and requests a frame to be drawn. @hide */ syncAndDrawFrame : function( ) {}, /**Suspends any current rendering into the surface but do not do any destruction. This is useful to temporarily suspend using the active Surface in order to do any Surface mutations necessary. <p>Any subsequent draws will override the pause, resuming normal operation. @return {Boolean} true if there was an outstanding render request, false otherwise. If this is true the caller should ensure that {@link #createRenderRequest()} and {@link FrameRenderRequest#syncAndDraw()} is called at the soonest possible time to resume normal operation. TODO Should this be exposed? ViewRootImpl needs it because it destroys the old Surface before getting a new one. However things like SurfaceView will ensure that the old surface remains un-destroyed until after a new frame has been produced with the new surface. @hide */ pause : function( ) {}, /**Hard stops rendering into the surface. If the renderer is stopped it will block any attempt to render. Calls to {@link android.graphics.HardwareRenderer.FrameRenderRequest#syncAndDraw()} will still sync over the latest rendering content, however they will not render and instead {@link #SYNC_CONTEXT_IS_STOPPED} will be returned. <p>If false is passed then rendering will resume as normal. Any pending rendering requests will produce a new frame at the next vsync signal. <p>This is useful in combination with lifecycle events such as {@link Activity#onStop()} and {@link Activity#onStart()}. @param {Boolean} stopped true to stop all rendering, false to resume @hide */ setStopped : function( ) {}, /**Hard stops rendering into the surface. If the renderer is stopped it will block any attempt to render. Calls to {@link android.graphics.HardwareRenderer.FrameRenderRequest#syncAndDraw()} will still sync over the latest rendering content, however they will not render and instead {@link #SYNC_CONTEXT_IS_STOPPED} will be returned. <p>This is useful in combination with lifecycle events such as {@link Activity#onStop()}. See {@link #start}() for resuming rendering. */ stop : function( ) {}, /**Resumes rendering into the surface. Any pending rendering requests will produce a new frame at the next vsync signal. <p>This is useful in combination with lifecycle events such as {@link Activity#onStart()}. See {@link #stop}() for stopping rendering. */ start : function( ) {}, /**Destroys all the display lists associated with the current rendering content. This includes releasing a reference to the current content root RenderNode. It will therefore be necessary to call {@link #setContentRoot}(RenderNode) in order to resume rendering after calling this, along with re-recording the display lists for the RenderNode tree. <p>It is recommended, but not necessary, to use this in combination with lifecycle events such as {@link Activity#onStop()} and {@link Activity#onStart()} or in response to {@link android.content.ComponentCallbacks2#onTrimMemory(int)} signals such as {@link android.content.ComponentCallbacks2#TRIM_MEMORY_UI_HIDDEN} See also {@link #stop}(). */ clearContent : function( ) {}, /**Whether or not the force-dark feature should be used for this renderer. @hide */ setForceDark : function( ) {}, /**Allocate buffers ahead of time to avoid allocation delays during rendering. <p>Typically a Surface will allocate buffers lazily. This is usually fine and reduces the memory usage of Surfaces that render rarely or never hit triple buffering. However for UI it can result in a slight bit of jank on first launch. This hint will tell the HardwareRenderer that now is a good time to allocate the 3 buffers necessary for typical rendering. <p>Must be called after a {@link Surface} has been set. TODO: Figure out if we even need/want this. Should HWUI just be doing this in response to setSurface anyway? Vulkan swapchain makes this murky, so delay making it public @hide */ allocateBuffers : function( ) {}, /**Notifies the hardware renderer that a call to {@link android.graphics.HardwareRenderer.FrameRenderRequest#syncAndDraw()} will be coming soon. This is used to help schedule when RenderThread-driven animations will happen as the renderer wants to avoid producing more than one frame per vsync signal. */ notifyFramePending : function( ) {}, /**Change the HardwareRenderer's opacity. Will take effect on the next frame produced. <p>If the renderer is set to opaque it is the app's responsibility to ensure that the content renders to every pixel of the Surface, otherwise corruption may result. Note that this includes ensuring that the first draw of any given pixel does not attempt to blend against the destination. If this is false then the hardware renderer will clear to transparent at the start of every frame. @param {Boolean} opaque true if the content rendered is opaque, false if the renderer should clear to transparent before rendering */ setOpaque : function( ) {}, /**Whether or not the renderer is set to be opaque. See {@link #setOpaque}(boolean) @return {Boolean} true if the renderer is opaque, false otherwise */ isOpaque : function( ) {}, /** @hide */ setFrameCompleteCallback : function( ) {}, /**TODO: Public API this? @hide */ addFrameMetricsObserver : function( ) {}, /**TODO: Public API this? @hide */ removeFrameMetricsObserver : function( ) {}, /**Enable/disable wide gamut rendering on this renderer. Whether or not the actual rendering will be wide gamut depends on the hardware support for such rendering. @param {Boolean} wideGamut true if this renderer should render in wide gamut, false if it should render in sRGB TODO: Figure out color... @hide */ setWideGamut : function( ) {}, /**Blocks until all previously queued work has completed. TODO: Only used for draw finished listeners, but the FrameCompleteCallback does that better @hide */ fence : function( ) {}, /** @hide */ registerAnimatingRenderNode : function( ) {}, /** @hide */ registerVectorDrawableAnimator : function( ) {}, /**Prevents any further drawing until {@link android.graphics.HardwareRenderer.FrameRenderRequest#syncAndDraw()} is called. This is a signal that the contents of the RenderNode tree are no longer safe to play back. In practice this usually means that there are Functor pointers in the display list that are no longer valid. TODO: Can we get webview off of this? @hide */ stopDrawing : function( ) {}, /**Creates a new hardware layer. A hardware layer built by calling this method will be treated as a texture layer, instead of as a render target. @return {Object {android.view.TextureLayer}} A hardware layer @hide */ createTextureLayer : function( ) {}, /**Detaches the layer's surface texture from the GL context and releases the texture id @hide */ detachSurfaceTexture : function( ) {}, /** @hide */ buildLayer : function( ) {}, /** @hide */ copyLayerInto : function( ) {}, /**Indicates that the specified hardware layer needs to be updated as soon as possible. @param {Object {TextureLayer}} layer The hardware layer that needs an update @hide */ pushLayerUpdate : function( ) {}, /**Tells the HardwareRenderer that the layer is destroyed. The renderer should remove the layer from any update queues. @hide */ onLayerDestroyed : function( ) {}, /** @hide */ setFrameCallback : function( ) {}, /**Adds a rendernode to the renderer which can be drawn and changed asynchronously to the rendernode of the UI thread. @param {Object {RenderNode}} node The node to add. @param {Boolean} placeFront If true, the render node will be placed in front of the content node, otherwise behind the content node. @hide */ addRenderNode : function( ) {}, /**Only especially added render nodes can be removed. @param {Object {RenderNode}} node The node which was added via addRenderNode which should get removed again. @hide */ removeRenderNode : function( ) {}, /**Draws a particular render node. If the node is not the content node, only the additional nodes will get drawn and the content remains untouched. @param {Object {RenderNode}} node The node to be drawn. @hide */ drawRenderNode : function( ) {}, /**Loads system properties used by the renderer. This method is invoked whenever system properties are modified. Implementations can use this to trigger live updates of the renderer based on properties. @return {Boolean} True if a property has changed. @hide */ loadSystemProperties : function( ) {}, /** @hide */ dumpProfileInfo : function( ) {}, /**To avoid unnecessary overdrawing of the main content all additionally passed render nodes will be prevented to overdraw this area. It will be synchronized with the draw call. This should be updated in the content view's draw call. @param {Number} left The left side of the protected bounds. @param {Number} top The top side of the protected bounds. @param {Number} right The right side of the protected bounds. @param {Number} bottom The bottom side of the protected bounds. @hide */ setContentDrawBounds : function( ) {}, /** @hide */ setPictureCaptureCallback : function( ) {}, /** @hide */ isWideGamut : function( ) {}, /** @hide */ invokeFunctor : function( ) {}, /**b/68769804: For low FPS experiments. @hide */ setFPSDivisor : function( ) {}, /**Changes the OpenGL context priority if IMG_context_priority extension is available. Must be called before any OpenGL context is created. @param {Number} priority The priority to use. Must be one of EGL_CONTEXT_PRIORITY_* values. @hide */ setContextPriority : function( ) {}, /**Sets whether or not high contrast text rendering is enabled. The setting is global but only affects content rendered after the change is made. @hide */ setHighContrastText : function( ) {}, /**If set RenderThread will avoid doing any IPC using instead a fake vsync & DisplayInfo source @hide */ setIsolatedProcess : function( ) {}, /**If set extra graphics debugging abilities will be enabled such as dumping skp @hide */ setDebuggingEnabled : function( ) {}, /** @hide */ copySurfaceInto : function( ) {}, /**Creates a {@link android.graphics.Bitmap.Config#HARDWARE} bitmap from the given RenderNode. Note that the RenderNode should be created as a root node (so x/y of 0,0), and not the RenderNode from a View. @hide */ createHardwareBitmap : function( ) {}, /**Invoke this method when the system is running out of memory. This method will attempt to recover as much memory as possible, based on the specified hint. @param {Number} level Hint about the amount of memory that should be trimmed, see {@link android.content.ComponentCallbacks} @hide */ trimMemory : function( ) {}, /** @hide */ overrideProperty : function( ) {}, /**Sets the directory to use as a persistent storage for threaded rendering resources. @param {Object {File}} cacheDir A directory the current process can write to @hide */ setupDiskCache : function( ) {}, /** @hide */ setPackageName : function( ) {}, /** @hide */ disableVsync : function( ) {}, /**Start render thread and initialize EGL or Vulkan. Initializing EGL involves loading and initializing the graphics driver. Some drivers take several 10s of milliseconds to do this, so doing it on-demand when an app tries to render its first frame adds directly to user-visible app launch latency. Should only be called after GraphicsEnvironment.chooseDriver(). @hide */ preload : function( ) {}, };