GLFrameBufferRenderer.Callback


public 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 methods

default void
@WorkerThread
onBufferReleased(
    @NonNull FrameBuffer frameBuffer,
    SyncFenceCompat releaseFence
)

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

default void
@WorkerThread
onDrawComplete(
    @NonNull SurfaceControlCompat targetSurfaceControl,
    @NonNull SurfaceControlCompat.Transaction transaction,
    @NonNull FrameBuffer frameBuffer,
    SyncFenceCompat syncFence
)

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.

abstract void
@WorkerThread
onDrawFrame(
    @NonNull EGLManager eglManager,
    int width,
    int height,
    @NonNull BufferInfo bufferInfo,
    @NonNull float[] transform
)

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

Public methods

onBufferReleased

Added in 1.0.0-rc01
@WorkerThread
default void onBufferReleased(
    @NonNull FrameBuffer frameBuffer,
    SyncFenceCompat releaseFence
)

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
@NonNull FrameBuffer frameBuffer

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

SyncFenceCompat releaseFence

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.0-rc01
@WorkerThread
default void onDrawComplete(
    @NonNull SurfaceControlCompat targetSurfaceControl,
    @NonNull SurfaceControlCompat.Transaction transaction,
    @NonNull FrameBuffer frameBuffer,
    SyncFenceCompat syncFence
)

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
@NonNull SurfaceControlCompat targetSurfaceControl

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.

@NonNull SurfaceControlCompat.Transaction transaction

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

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

SyncFenceCompat syncFence

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

onDrawFrame

Added in 1.0.0-rc01
@WorkerThread
abstract void onDrawFrame(
    @NonNull EGLManager eglManager,
    int width,
    int height,
    @NonNull BufferInfo bufferInfo,
    @NonNull float[] transform
)

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
@NonNull EGLManager eglManager

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

int width

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

int height

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

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

@NonNull float[] transform

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)