FrameBufferRenderer


@RequiresApi(value = 26)
class FrameBufferRenderer : GLRenderer.RenderCallback


GLRenderer.RenderCallback implementation that renders content into a frame buffer object backed by a HardwareBuffer object

Summary

Nested types

Callbacks invoked to render content leveraging a FrameBufferRenderer

Public constructors

FrameBufferRenderer(
    frameBufferRendererCallbacks: FrameBufferRenderer.RenderCallback,
    syncStrategy: SyncStrategy
)

Public functions

Unit
open Unit
onDrawFrame(eglManager: EGLManager)

Callback used to issue OpenGL drawing commands into the EGLSurface created in onSurfaceCreated.

open EGLSurface?
onSurfaceCreated(
    spec: EGLSpec,
    config: EGLConfig,
    surface: Surface,
    width: Int,
    height: Int
)

Used to create a corresponding EGLSurface from the provided android.view.Surface instance.

Public constructors

FrameBufferRenderer

Added in 1.0.2
FrameBufferRenderer(
    frameBufferRendererCallbacks: FrameBufferRenderer.RenderCallback,
    syncStrategy: SyncStrategy = SyncStrategy.ALWAYS
)
Parameters
frameBufferRendererCallbacks: FrameBufferRenderer.RenderCallback

Callbacks to provide a FrameBuffer instance to render into, draw method to render into the FrameBuffer as well as a subsequent callback to consume the contents of the FrameBuffer

syncStrategy: SyncStrategy = SyncStrategy.ALWAYS

SyncStrategy used to determine when a fence is to be created to gate on consumption of the FrameBuffer instance. This determines if a SyncFenceCompat instance is provided in the RenderCallback.onDrawComplete depending on the use case. For example for front buffered rendering scenarios, it is possible that no SyncFenceCompat is provided in order to reduce latency within the rendering pipeline.

This API can be used to render content into a HardwareBuffer directly and convert that to a bitmap with the following code snippet:

val glRenderer = GLRenderer().apply { start() }
val callbacks = object : FrameBufferRenderer.RenderCallback {

override fun obtainFrameBuffer(egl: EGLSpec): FrameBuffer =
FrameBuffer(
egl,
HardwareBuffer.create(
width,
height,
HardwareBuffer.RGBA_8888,
1,
HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE
)
)

override fun onDraw(eglManager: EGLManager) {
// GL code
}

override fun onDrawComplete(frameBuffer: FrameBuffer, syncFenceCompat: SyncFenceCompat?) {
syncFenceCompat?.awaitForever()
val bitmap = Bitmap.wrapHardwareBuffer(frameBuffer.hardwareBuffer,
ColorSpace.get(ColorSpace.Named.LINEAR_SRGB))
// bitmap operations
}
}

glRenderer.createRenderTarget(width,height, FrameBufferRenderer(callbacks)).requestRender()

Public functions

clear

Added in 1.0.2
fun clear(): Unit

onDrawFrame

Added in 1.0.2
open fun onDrawFrame(eglManager: EGLManager): Unit

Callback used to issue OpenGL drawing commands into the EGLSurface created in onSurfaceCreated. This EGLSurface is guaranteed to be current before this callback is invoked and EGLManager.swapAndFlushBuffers will be invoked afterwards. If additional scratch EGLSurfaces are used here it is up to the implementation of this method to ensure that the proper surfaces are made current and the appropriate swap buffers call is made

This method is invoked on the backing thread

Parameters
eglManager: EGLManager

Handle to EGL dependencies

onSurfaceCreated

open fun onSurfaceCreated(
    spec: EGLSpec,
    config: EGLConfig,
    surface: Surface,
    width: Int,
    height: Int
): EGLSurface?

Used to create a corresponding EGLSurface from the provided android.view.Surface instance. This enables consumers to configure the corresponding EGLSurface they wish to render into. The EGLSurface created here is guaranteed to be the current surface before onDrawFrame is called. That is, implementations of onDrawFrame do not need to call eglMakeCurrent on this EGLSurface.

This method is invoked on the GL thread.

The default implementation will create a window surface with EGL_WIDTH and EGL_HEIGHT set to width and height respectively. Implementations can override this method to provide additional EGLConfigAttributes for this surface (ex. EGL14.EGL_SINGLE_BUFFER.

Implementations can return null to indicate the default surface should be used. This is helpful in situations where content is to be rendered within a frame buffer object instead of to an EGLSurface

Parameters
spec: EGLSpec

EGLSpec used to create the corresponding EGLSurface

config: EGLConfig

EGLConfig used to create the corresponding EGLSurface

surface: Surface

android.view.Surface used to create an EGLSurface from

width: Int

Desired width of the surface to create

height: Int

Desired height of the surface to create