Renderer.GlesRenderer

Added in 1.0.0
Deprecated in 1.1.0

public abstract class Renderer.GlesRenderer extends Renderer

Known direct subclasses
ListenableGlesRenderer

This class is deprecated. Use ListenableGlesRenderer2 instead

Renderer.GlesRenderer2

Watch faces that require GLES20 rendering and are able to take advantage of SharedAssets to save memory (there can be more than once instance when editing), should extend their Renderer from this class.

Known indirect subclasses
ListenableGlesRenderer2

ListenableFuture-based compatibility wrapper around Renderer.GlesRenderer's suspending methods.


Watch faces that require GLES20 rendering should extend their Renderer from this class or GlesRenderer2 if they can take advantage of SharedAssets to save memory when editing (there can be more than once WatchFace instance when editing).

A GlesRenderer is expected to be constructed on the background thread associated with WatchFaceService.getBackgroundThreadHandler inside a call to WatchFaceService.createWatchFace. All rendering is be done on the UiThread. There is a memory barrier between construction and rendering so no special threading primitives are required.

Two linked EGLContexts are created eglBackgroundThreadContext and eglUiThreadContext which are associated with background and UiThread respectively and are shared by all instances of the renderer. OpenGL objects created on (e.g. shaders and textures) can be used on the other.

If you need to make any OpenGl calls outside of render, onBackgroundThreadGlContextCreated or onUiThreadGlSurfaceCreated then you must use either runUiThreadGlCommands or runBackgroundThreadGlCommands to execute a Runnable inside of the corresponding context. Access to the GL contexts this way is necessary because GL contexts are not shared between renderers and there can be multiple watch face instances existing concurrently (e.g. headless and interactive, potentially from different watch faces if an APK contains more than one WatchFaceService). In addition most drivers do not support concurrent access.

In Java it may be easier to extend androidx.wear.watchface.ListenableGlesRenderer instead.

Summary

Nested types

Exception thrown if a GL call fails

Public constructors

@WorkerThread
GlesRenderer(
    @NonNull SurfaceHolder surfaceHolder,
    @NonNull CurrentUserStyleRepository currentUserStyleRepository,
    @NonNull WatchState watchState,
    @IntRange(from = 0, to = 60000) long interactiveDrawModeUpdateDelayMillis,
    @NonNull int[] eglConfigAttribList,
    @NonNull int[] eglSurfaceAttribList,
    @NonNull int[] eglContextAttribList
)

Constructs a GlesRenderer, it is recommended that new code uses GlesRenderer2 instead.

Public methods

final @NonNull EGLContext

The GlesRenderer's background Thread EGLContext.

final @NonNull EGLConfig

The GlesRenderer's EGLConfig.

final @NonNull EGLDisplay

The GlesRenderer's EGLDisplay.

final @NonNull EGLContext

The GlesRenderer's UiThread EGLContext.

void

Called once a background thread when a new GL context is created on the background thread, before any subsequent calls to render.

void

Called when the Renderer is destroyed.

void

Called when adb shell dumpsys is invoked for the WatchFaceService, allowing the renderer to optionally record state for debugging purposes.

void
@UiThread
onUiThreadGlSurfaceCreated(@Px int width, @Px int height)

Called when a new GL surface is created on the UiThread, before any subsequent calls to render or in response to SurfaceHolder.Callback.surfaceChanged.

abstract void

Sub-classes should override this to implement their watch face rendering logic which should respect the current renderParameters.

abstract void

Sub-classes should override this to implement their watch face highlight layer rendering logic for the RenderParameters.highlightLayer aspect of renderParameters.

final void

Inside of a Mutex this function sets the GL context associated with the WatchFaceService.getBackgroundThreadHandler's looper thread as the current one, executes commands and finally unsets the GL context.

final void
runUiThreadGlCommands(@NonNull SuspendFunction0<Unit> commands)

Inside of a Mutex this function sets the UiThread GL context as the current one, executes commands and finally unsets the GL context.

final void

This method is deprecated. It's not intended for eglConfig to be set

final void

This method is deprecated. It's not intended for eglDisplay to be set

Inherited methods

From androidx.wear.watchface.Renderer
final @NonNull Collection<@NonNull Pair<@NonNull Integer, @NonNull ContentDescriptionLabel>>

Accessibility ContentDescriptionLabel for any rendered watch face elements other than the time and ComplicationSlots which are generated automatically.

final float

The center x coordinate of the SurfaceHolder this Renderer renders into.

final float

The center y coordinate of the SurfaceHolder this Renderer renders into.

final long

The interval in milliseconds between frames in interactive DrawModes.

@NonNull Rect

This method is used for accessibility support to describe the portion of the screen containing the main clock element.

final @NonNull RenderParameters

The current RenderParameters.

final @NonNull Rect

The bounds of the SurfaceHolder this Renderer renders into.

final @NonNull SurfaceHolder

The SurfaceHolder that renderInternal will draw into.

final WatchFaceColors

Representative WatchFaceColors which are made available to system clients via androidx.wear.watchface.client.InteractiveWatchFaceClient.OnWatchFaceColorsListener.

final void

Schedules a call to either CanvasRenderer.render or GlesRenderer.render to draw the next frame.

void

Called when the RenderParameters has been updated.

final void

Posts a message to schedule a call to either CanvasRenderer.render or GlesRenderer.render to draw the next frame.

final void

Sends a request to the system asking it to update the preview image.

final void

Accessibility ContentDescriptionLabel for any rendered watch face elements other than the time and ComplicationSlots which are generated automatically.

final void
setInteractiveDrawModeUpdateDelayMillis(
    long interactiveDrawModeUpdateDelayMillis
)
final void

The SurfaceHolder that renderInternal will draw into.

final void

Representative WatchFaceColors which are made available to system clients via androidx.wear.watchface.client.InteractiveWatchFaceClient.OnWatchFaceColorsListener.

boolean

The system periodically (at least once per minute) calls onTimeTick() to trigger a display update.

Public constructors

GlesRenderer

Added in 1.2.0
Deprecated in 1.2.0
@WorkerThread
public GlesRenderer(
    @NonNull SurfaceHolder surfaceHolder,
    @NonNull CurrentUserStyleRepository currentUserStyleRepository,
    @NonNull WatchState watchState,
    @IntRange(from = 0, to = 60000) long interactiveDrawModeUpdateDelayMillis,
    @NonNull int[] eglConfigAttribList,
    @NonNull int[] eglSurfaceAttribList,
    @NonNull int[] eglContextAttribList
)

Constructs a GlesRenderer, it is recommended that new code uses GlesRenderer2 instead.

Parameters
@NonNull SurfaceHolder surfaceHolder

The SurfaceHolder whose android.view.Surface will draw into.

@NonNull CurrentUserStyleRepository currentUserStyleRepository

The associated CurrentUserStyleRepository.

@NonNull WatchState watchState

The associated WatchState.

@IntRange(from = 0, to = 60000) long interactiveDrawModeUpdateDelayMillis

The interval in milliseconds between frames in interactive DrawModes. To render at 60hz set to 16. Note when battery is low, the frame rate will be clamped to 10fps. Watch faces are recommended to use lower frame rates if possible for better battery life. Variable frame rates can also help preserve battery life, e.g. if a watch face has a short animation once per second it can adjust the frame rate inorder to sleep when not animating.

@NonNull int[] eglConfigAttribList

Attributes for EGL14.eglChooseConfig. By default this selects an RGBA8888 back buffer.

@NonNull int[] eglSurfaceAttribList

The attributes to be passed to EGL14.eglCreateWindowSurface. By default this is empty.

@NonNull int[] eglContextAttribList

The attributes to be passed to EGL14.eglCreateContext. By default this selects EGL14.EGL_CONTEXT_CLIENT_VERSION 2.

Throws
androidx.wear.watchface.Renderer.GlesRenderer.GlesException

If any GL calls fail during initialization.

Public methods

getEglBackgroundThreadContext

Added in 1.0.0
Deprecated in 1.1.0
public final @NonNull EGLContext getEglBackgroundThreadContext()

The GlesRenderer's background Thread EGLContext.

getEglConfig

Added in 1.0.0
Deprecated in 1.1.0
public final @NonNull EGLConfig getEglConfig()

The GlesRenderer's EGLConfig.

Throws
kotlin.UnsupportedOperationException

setEglConfig is unsupported.

getEglDisplay

Added in 1.0.0
Deprecated in 1.1.0
public final @NonNull EGLDisplay getEglDisplay()

The GlesRenderer's EGLDisplay.

Throws
kotlin.UnsupportedOperationException

setEglDisplay is unsupported.

getEglUiThreadContext

Added in 1.0.0
Deprecated in 1.1.0
public final @NonNull EGLContext getEglUiThreadContext()

The GlesRenderer's UiThread EGLContext. Note this not available until after WatchFaceService.createWatchFace has completed.

onBackgroundThreadGlContextCreated

Added in 1.0.0
Deprecated in 1.1.0
@WorkerThread
public void onBackgroundThreadGlContextCreated()

Called once a background thread when a new GL context is created on the background thread, before any subsequent calls to render. Note this function is called inside a lambda passed to runBackgroundThreadGlCommands which has synchronized access to the GL context.

If you need to override this method in java, consider using androidx.wear.watchface.ListenableGlesRenderer instead.

onDestroy

@CallSuper
public void onDestroy()

Called when the Renderer is destroyed.

onDump

Added in 1.3.0-alpha01
Deprecated in 1.3.0-alpha01
public void onDump(@NonNull PrintWriter writer)

Called when adb shell dumpsys is invoked for the WatchFaceService, allowing the renderer to optionally record state for debugging purposes.

onUiThreadGlSurfaceCreated

Added in 1.0.0
Deprecated in 1.1.0
@UiThread
public void onUiThreadGlSurfaceCreated(@Px int width, @Px int height)

Called when a new GL surface is created on the UiThread, before any subsequent calls to render or in response to SurfaceHolder.Callback.surfaceChanged. Note this function is called inside a lambda passed to runUiThreadGlCommands which has synchronized access to the GL context.

If you need to override this method in java, consider using androidx.wear.watchface.ListenableGlesRenderer instead.

Parameters
@Px int width

width of surface in pixels

@Px int height

height of surface in pixels

render

Added in 1.0.0
Deprecated in 1.1.0
@UiThread
public abstract void render(@NonNull ZonedDateTime zonedDateTime)

Sub-classes should override this to implement their watch face rendering logic which should respect the current renderParameters. Please note WatchState.isAmbient may not match the RenderParameters.drawMode and should not be used to decide what to render. E.g. when editing from the companion phone while the watch is ambient, renders may be requested with DrawMode.INTERACTIVE.

Any highlights due to RenderParameters.highlightLayer should be rendered by renderHighlightLayer instead where possible. For correct behavior this function must use the supplied ZonedDateTime in favor of any other ways of getting the time.

Note this function is called inside a lambda passed to runUiThreadGlCommands which has synchronized access to the GL context.

Note also GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ZERO) is called by the library before this method.

Before any calls to this function onBackgroundThreadGlContextCreated and onUiThreadGlSurfaceCreated will have been called once on their respective threads.

Parameters
@NonNull ZonedDateTime zonedDateTime

The zonedDateTime ZonedDateTime to render with

renderHighlightLayer

Added in 1.0.0
Deprecated in 1.1.0
@UiThread
public abstract void renderHighlightLayer(@NonNull ZonedDateTime zonedDateTime)

Sub-classes should override this to implement their watch face highlight layer rendering logic for the RenderParameters.highlightLayer aspect of renderParameters. Typically the implementation will clear the buffer to RenderParameters.HighlightLayer.backgroundTint before rendering a transparent highlight or a solid outline around the RenderParameters.HighlightLayer.highlightedElement. This will be composited as needed on top of the results of render. For correct behavior this function must use the supplied ZonedDateTime in favor of any other ways of getting the time.

Note this function is called inside a lambda passed to runUiThreadGlCommands which has synchronized access to the GL context.

Note also GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ZERO) is called by the library before this method.

Parameters
@NonNull ZonedDateTime zonedDateTime

The zonedDateTime ZonedDateTime to render with

runBackgroundThreadGlCommands

Added in 1.0.0
Deprecated in 1.1.0
@WorkerThread
public final void runBackgroundThreadGlCommands(@NonNull SuspendFunction0<Unit> commands)

Inside of a Mutex this function sets the GL context associated with the WatchFaceService.getBackgroundThreadHandler's looper thread as the current one, executes commands and finally unsets the GL context.

Access to the GL context this way is necessary because GL contexts are not shared between renderers and there can be multiple watch face instances existing concurrently (e.g. headless and interactive, potentially from different watch faces if an APK contains more than one WatchFaceService).

NB this function is called by the library before running runBackgroundThreadGlCommands so there's no need to use this directly in client code unless you need to make GL calls outside of those methods. If you need to call this method from java, consider using androidx.wear.watchface.ListenableGlesRenderer which provides an overload taking a Runnable.

Throws
kotlin.IllegalStateException

if the calls to EGL14.eglMakeCurrent fails

runUiThreadGlCommands

Added in 1.0.0
Deprecated in 1.1.0
public final void runUiThreadGlCommands(@NonNull SuspendFunction0<Unit> commands)

Inside of a Mutex this function sets the UiThread GL context as the current one, executes commands and finally unsets the GL context.

Access to the GL context this way is necessary because GL contexts are not shared between renderers and there can be multiple watch face instances existing concurrently (e.g. headless and interactive, potentially from different watch faces if an APK contains more than one WatchFaceService).

If you need to call this method from java, consider using androidx.wear.watchface.ListenableGlesRenderer which provides an overload taking a Runnable.

Throws
kotlin.IllegalStateException

if the calls to EGL14.eglMakeCurrent fails

setEglConfig

Added in 1.0.0
Deprecated in 1.1.0
public final void setEglConfig(@NonNull EGLConfig eglConfig)

The GlesRenderer's EGLConfig.

Throws
kotlin.UnsupportedOperationException

setEglConfig is unsupported.

setEglDisplay

Added in 1.0.0
Deprecated in 1.1.0
public final void setEglDisplay(@NonNull EGLDisplay eglDisplay)

The GlesRenderer's EGLDisplay.

Throws
kotlin.UnsupportedOperationException

setEglDisplay is unsupported.