Added in API level 29

HardwareRenderer

open class HardwareRenderer
kotlin.Any
   ↳ android.graphics.HardwareRenderer

Creates an instance of a hardware-accelerated renderer. This is used to render a scene built from RenderNode's to an output android.view.Surface. There can be as many HardwareRenderer instances as desired.

Resources & lifecycle

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 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.

NOTE: Due to the shared, cooperative nature of the render thread it is critical that any Surface used must have a prompt, reliable consuming side. System-provided consumers such as android.view.SurfaceView, android.view.Window#takeSurface(SurfaceHolder.Callback2), or android.view.TextureView all fit this requirement. However if custom consumers are used such as when using SurfaceTexture or 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.

Summary

Nested classes

Sets the parameters that can be used to control a render request for a HardwareRenderer.

Constants
static Int

The hardware renderer has been set to a "stopped" state.

static Int

The content was synced but the renderer has declined to produce a frame in this vsync interval.

static Int

The hardware renderer no longer has a valid android.view.Surface to render to.

static Int

Nothing interesting to report.

static Int

The renderer is requesting a redraw.

Public constructors

Creates a new instance of a HardwareRenderer.

Public methods
open Unit

Destroys all the display lists associated with the current rendering content.

open HardwareRenderer.FrameRenderRequest

Returns a FrameRenderRequest that can be used to render a new frame.

open Unit

Destroys the rendering context of this HardwareRenderer.

open static Boolean

Returns true if HardwareRender will produce output.

open Boolean

Whether or not the renderer is set to be opaque.

open Unit

Notifies the hardware renderer that a call to FrameRenderRequest#syncAndDraw() will be coming soon.

open Unit

Sets the content root to render.

open static Unit
setDrawingEnabled(drawingEnabled: Boolean)

Toggles whether or not HardwareRenderer will produce drawing output globally in the current process.

open Unit
setLightSourceAlpha(ambientShadowAlpha: Float, spotShadowAlpha: Float)

Configures the ambient & spot shadow alphas.

open Unit
setLightSourceGeometry(lightX: Float, lightY: Float, lightZ: Float, lightRadius: Float)

Sets the center of the light source.

open Unit
setName(name: String)

Sets a name for this renderer.

open Unit
setOpaque(opaque: Boolean)

Change the HardwareRenderer's opacity.

open Unit
setSurface(surface: Surface?)

The surface to render into.

open Unit

Resumes rendering into the surface.

open Unit

Hard stops rendering into the surface.

Constants

SYNC_CONTEXT_IS_STOPPED

Added in API level 29
static val SYNC_CONTEXT_IS_STOPPED: Int

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.

Value: 4

SYNC_FRAME_DROPPED

Added in API level 29
static val SYNC_FRAME_DROPPED: Int

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.

Value: 8

SYNC_LOST_SURFACE_REWARD_IF_FOUND

Added in API level 29
static val SYNC_LOST_SURFACE_REWARD_IF_FOUND: Int

The hardware renderer no longer has a valid android.view.Surface to render to. This can happen if Surface#release() was called. The user should no longer attempt to call syncAndDraw until a new surface has been provided by calling setSurface.

Spoiler: the reward is GPU-accelerated drawing, better find that Surface!

Value: 2

SYNC_OK

Added in API level 29
static val SYNC_OK: Int

Nothing interesting to report. Sync & draw kicked off

Value: 0

SYNC_REDRAW_REQUESTED

Added in API level 29
static val SYNC_REDRAW_REQUESTED: Int

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.

If this is returned from syncAndDraw the expectation is that syncAndDraw will be called again on the next vsync signal.

Value: 1

Public constructors

HardwareRenderer

Added in API level 29
HardwareRenderer()

Creates a new instance of a HardwareRenderer. The HardwareRenderer will default to opaque with no light source configured.

Public methods

clearContent

Added in API level 29
open fun clearContent(): Unit

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 setContentRoot(android.graphics.RenderNode) in order to resume rendering after calling this, along with re-recording the display lists for the RenderNode tree.

It is recommended, but not necessary, to use this in combination with lifecycle events such as Activity#onStop() and Activity#onStart() or in response to android.content.ComponentCallbacks2#onTrimMemory(int) signals such as android.content.ComponentCallbacks2#TRIM_MEMORY_UI_HIDDEN See also stop().

createRenderRequest

Added in API level 29
open fun createRenderRequest(): HardwareRenderer.FrameRenderRequest

Returns a FrameRenderRequest that can be used to render a new frame. This is used to synchronize the RenderNode content provided by setContentRoot(android.graphics.RenderNode) with the RenderThread and then renders a single frame to the Surface set with setSurface(android.view.Surface).

Return
HardwareRenderer.FrameRenderRequest An instance of FrameRenderRequest. The instance may be reused for every frame, so the caller should not hold onto it for longer than a single render request. This value cannot be null.

destroy

Added in API level 29
open fun destroy(): Unit

Destroys the rendering context of this HardwareRenderer. This destroys the resources associated with this renderer and releases the currently set Surface. This must be called when this HardwareRenderer is no longer needed.

The renderer may be restored from this state by setting a new Surface, setting new rendering content with setContentRoot(android.graphics.RenderNode), and resuming rendering by issuing a new FrameRenderRequest.

It is recommended to call this in response to callbacks such as android.view.SurfaceHolder.Callback#surfaceDestroyed(SurfaceHolder).

Note that if there are any outstanding frame commit callbacks they may never being invoked if the frame was deferred to a later vsync.

isDrawingEnabled

Added in API level 33
open static fun isDrawingEnabled(): Boolean

Returns true if HardwareRender will produce output. This value is global to the process and affects all uses of HardwareRenderer, including those created by the system such as those used by the View tree when using hardware accelerated rendering. Default is true in all production environments, but may be false in testing-focused emulators or if setDrawingEnabled(boolean) is used.

isOpaque

Added in API level 29
open fun isOpaque(): Boolean

Whether or not the renderer is set to be opaque. See setOpaque(boolean)

Return
Boolean true if the renderer is opaque, false otherwise

notifyFramePending

Added in API level 29
open fun notifyFramePending(): Unit

Notifies the hardware renderer that a call to 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.

setContentRoot

Added in API level 29
open fun setContentRoot(content: RenderNode?): Unit

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 FrameRenderRequest is issued via createRenderRequest() and FrameRenderRequest#syncAndDraw().

Parameters
content RenderNode?: The content to set as the root RenderNode. If null the content root is removed and the renderer will draw nothing.

setDrawingEnabled

Added in API level 33
open static fun setDrawingEnabled(drawingEnabled: Boolean): Unit

Toggles whether or not HardwareRenderer will produce drawing output globally in the current process. This applies to all HardwareRenderer instances, including those created by the platform such as those used by the system for hardware accelerated View rendering. The capability to disable drawing output is intended for test environments, primarily headless ones. By setting this to false, tests that launch activities or interact with Views can be quicker with less RAM usage by skipping the final step of View drawing. All View lifecycle events will occur as normal, only the final step of rendering on the GPU to the display will be skipped. This can be toggled on and off at will, so screenshot tests can also run in this same environment by toggling drawing back on and forcing a frame to be drawn such as by calling view#invalidate(). Once drawn and the screenshot captured, this can then be turned back off.

setLightSourceAlpha

Added in API level 29
open fun setLightSourceAlpha(
    ambientShadowAlpha: Float,
    spotShadowAlpha: Float
): Unit

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.

These values are typically provided by the current theme, see android.R.attr#spotShadowAlpha and android.R.attr#ambientShadowAlpha.

This must be set at least once along with setLightSourceGeometry(float,float,float,float) before shadows will work.

Parameters
ambientShadowAlpha Float: The alpha for the ambient shadow. If unsure, a reasonable default is 0.039f. Value is between 0.0f and 1.0f inclusive
spotShadowAlpha Float: The alpha for the spot shadow. If unsure, a reasonable default is 0.19f. Value is between 0.0f and 1.0f inclusive

setLightSourceGeometry

Added in API level 29
open fun setLightSourceGeometry(
    lightX: Float,
    lightY: Float,
    lightZ: Float,
    lightRadius: Float
): Unit

Sets the center of the light source. The light source point controls the directionality and shape of shadows rendered by RenderNode Z & elevation.

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.

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.

This must be set at least once along with setLightSourceAlpha(float,float) before shadows will work.

Parameters
lightX Float: The X position of the light source
lightY Float: The Y position of the light source
lightZ Float: The Z position of the light source. Must be >= 0.
lightRadius Float: The radius of the light source. Smaller radius will have sharper edges, larger radius will have softer shadows.

setName

Added in API level 29
open fun setName(name: String): Unit

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'

Parameters
name String: The debug name to use for this HardwareRenderer instance This value cannot be null.

setOpaque

Added in API level 29
open fun setOpaque(opaque: Boolean): Unit

Change the HardwareRenderer's opacity. Will take effect on the next frame produced.

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.

Parameters
opaque Boolean: true if the content rendered is opaque, false if the renderer should clear to transparent before rendering

setSurface

Added in API level 29
open fun setSurface(surface: Surface?): Unit

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 android.view.Choreographer and that it has a native refresh rate matching that of the display's (typically 60hz).

NOTE: Due to the shared, cooperative nature of the render thread it is critical that any Surface used must have a prompt, reliable consuming side. System-provided consumers such as android.view.SurfaceView, android.view.Window#takeSurface(SurfaceHolder.Callback2), or android.view.TextureView all fit this requirement. However if custom consumers are used such as when using SurfaceTexture or 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.

Parameters
surface Surface?: The surface to render into. If null then rendering will be stopped. If non-null then Surface#isValid() must be true.

start

Added in API level 29
open fun start(): Unit

Resumes rendering into the surface. Any pending rendering requests will produce a new frame at the next vsync signal.

This is useful in combination with lifecycle events such as Activity#onStart(). See stop() for stopping rendering.

stop

Added in API level 29
open fun stop(): Unit

Hard stops rendering into the surface. If the renderer is stopped it will block any attempt to render. Calls to FrameRenderRequest#syncAndDraw() will still sync over the latest rendering content, however they will not render and instead SYNC_CONTEXT_IS_STOPPED will be returned.

This is useful in combination with lifecycle events such as Activity#onStop(). See start() for resuming rendering.