GLFrameBufferRenderer.Callback


interface GLFrameBufferRenderer.Callback


GLFrameBufferRenderer callbacks that are invoked to render OpenGL content within the underlying buffers. This includes an optional callback to be used to configure the underlying SurfaceControlCompat.Transaction used to present content to the display

Summary

Public functions

open Unit
@WorkerThread
onBufferReleased(frameBuffer: FrameBuffer, releaseFence: SyncFenceCompat?)

Optional callback invoked the thread backed by the GLRenderer when the provided framebuffer is released.

open Unit
@WorkerThread
onDrawComplete(
    targetSurfaceControl: SurfaceControlCompat,
    transaction: SurfaceControlCompat.Transaction,
    frameBuffer: FrameBuffer,
    syncFence: SyncFenceCompat?
)

Optional callback invoked the thread backed by the GLRenderer when rendering to a buffer is complete but before the buffer is submitted to the hardware compositor.

Unit
@WorkerThread
onDrawFrame(
    eglManager: EGLManager,
    width: Int,
    height: Int,
    bufferInfo: BufferInfo,
    transform: FloatArray
)

Callback invoked on the thread backed by the GLRenderer to render content into a buffer with the specified parameters.

Public functions

onBufferReleased

Added in 1.0.2
@WorkerThread
open fun onBufferReleased(frameBuffer: FrameBuffer, releaseFence: SyncFenceCompat?): Unit

Optional callback invoked the thread backed by the GLRenderer when the provided framebuffer is released. That is the given FrameBuffer instance is no longer being presented and is not visible.

Parameters
frameBuffer: FrameBuffer

The buffer that is no longer being presented and has returned to the buffer allocation pool

releaseFence: SyncFenceCompat?

Optional fence that must be waited upon before the FrameBuffer can be reused. The framework will invoke this callback early to improve performance and signal the fence when it is ready to be re-used.

onDrawComplete

Added in 1.0.2
@WorkerThread
open fun onDrawComplete(
    targetSurfaceControl: SurfaceControlCompat,
    transaction: SurfaceControlCompat.Transaction,
    frameBuffer: FrameBuffer,
    syncFence: SyncFenceCompat?
): Unit

Optional callback invoked the thread backed by the GLRenderer when rendering to a buffer is complete but before the buffer is submitted to the hardware compositor. This provides consumers a mechanism for synchronizing the transaction with other SurfaceControlCompat objects that maybe rendered within the scene.

Parameters
targetSurfaceControl: SurfaceControlCompat

Handle to the SurfaceControlCompat where the buffer is presented. This can be used to configure various properties of the SurfaceControlCompat like z-ordering or visibility with the corresponding SurfaceControlCompat.Transaction.

transaction: SurfaceControlCompat.Transaction

Current SurfaceControlCompat.Transaction to apply updated buffered content to the front buffered layer.

frameBuffer: FrameBuffer

The buffer that has been rendered into and is ready to be displayed. The HardwareBuffer backing this FrameBuffer is already configured to be presented for the targetSurfaceControl. That is SurfaceControlCompat.Transaction.setBuffer is already invoked with the given HardwareBuffer and optional SyncFenceCompat instance before this method is invoked.

syncFence: SyncFenceCompat?

Optional SyncFenceCompat is used to determine when rendering is done and reflected within the given frameBuffer.

onDrawFrame

Added in 1.0.2
@WorkerThread
fun onDrawFrame(
    eglManager: EGLManager,
    width: Int,
    height: Int,
    bufferInfo: BufferInfo,
    transform: FloatArray
): Unit

Callback invoked on the thread backed by the GLRenderer to render content into a buffer with the specified parameters.

import androidx.graphics.lowlatency.BufferInfo
import androidx.graphics.opengl.GLFrameBufferRenderer
import androidx.graphics.opengl.egl.EGLManager

val surfaceView = SurfaceView(context)
val renderer = GLFrameBufferRenderer.Builder(surfaceView,
    object : GLFrameBufferRenderer.Callback {

        val myMatrix = FloatArray(16)
        val result = FloatArray(16)

        override fun onDrawFrame(
            eglManager: EGLManager,
            width: Int,
            height: Int,
            bufferInfo: BufferInfo,
            transform: FloatArray
        ) {
            Matrix.orthoM(
                myMatrix, // matrix
                0, // offset starting index into myMatrix
                0f, // left
                bufferInfo.width.toFloat(), // right
                0f, // bottom
                bufferInfo.width.toFloat(), // top
                -1f, // near
                1f // far
            )

            Matrix.multiplyMM(result, 0, myMatrix, 0, transform, 0)

            // pass result matrix as uniform to shader logic
        }
    }).build()
renderer.render()
Parameters
eglManager: EGLManager

EGLManager useful in configuring EGL objects to be used when issuing OpenGL commands to render into the front buffered layer

width: Int

Logical width of the content to render. This dimension matches what is provided from SurfaceHolder.Callback.surfaceChanged

height: Int

Logical height of the content to render. This dimension matches what is provided from SurfaceHolder.Callback.surfaceChanged

bufferInfo: BufferInfo

BufferInfo about the buffer that is being rendered into. This includes the width and height of the buffer which can be different than the corresponding dimensions of the SurfaceView provided to the GLFrameBufferRenderer as pre-rotation can occasionally swap width and height parameters in order to avoid GPU composition to rotate content. This should be used as input to GLES20.glViewport. Additionally this also contains a frame buffer identifier that can be used to retarget rendering operations to the original destination after rendering into intermediate scratch buffers.

transform: FloatArray

Matrix that should be applied to the rendering in this callback. This should be consumed as input to any vertex shader implementations. Buffers are pre-rotated in advance in order to avoid unnecessary overhead of GPU composition to rotate content in the same install orientation of the display. This is a 4 x 4 matrix is represented as a flattened array of 16 floating point values. Consumers are expected to leverage Matrix.multiplyMM with this parameter alongside any additional transformations that are to be applied. For example:

val myMatrix = FloatArray(16)
Matrix.orthoM(
myMatrix, // matrix
0, // offset starting index into myMatrix
0f, // left
bufferInfo.width.toFloat(), // right
0f, // bottom
bufferInfo.height.toFloat(), // top
-1f, // near
1f, // far
)
val result = FloatArray(16)
Matrix.multiplyMM(result, 0, myMatrix, 0, transform, 0)