SurfaceCoroutineScope


SurfaceCoroutineScope is a scoped environment provided by AndroidExternalSurface and AndroidEmbeddedExternalSurface when a new Surface is created. This environment is a coroutine scope that also provides access to a SurfaceScope environment which can itself be used to handle other Surface lifecycle events.

import androidx.compose.foundation.AndroidExternalSurface
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.withFrameNanos
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.unit.dp

AndroidExternalSurface(modifier = Modifier.fillMaxWidth().height(400.dp)) {
    // Resources can be initialized/cached here

    // A surface is available, we can start rendering
    onSurface { surface, width, height ->
        var w = width
        var h = height

        // Initial draw to avoid a black frame
        surface.lockCanvas(Rect(0, 0, w, h)).apply {
            drawColor(Color.Blue.toArgb())
            surface.unlockCanvasAndPost(this)
        }

        // React to surface dimension changes
        surface.onChanged { newWidth, newHeight ->
            w = newWidth
            h = newHeight
        }

        // Cleanup if needed
        surface.onDestroyed {}

        // Render loop, automatically cancelled on surface destruction
        while (true) {
            withFrameNanos { time ->
                surface.lockCanvas(Rect(0, 0, w, h)).apply {
                    val timeMs = time / 1_000_000L
                    val t = 0.5f + 0.5f * sin(timeMs / 1_000.0f)
                    drawColor(lerp(Color.Blue, Color.Green, t).toArgb())
                    surface.unlockCanvasAndPost(this)
                }
            }
        }
    }
}

Summary

Inherited functions

From androidx.compose.foundation.SurfaceScope
Unit
Surface.onChanged(onChanged: Surface.(width: Int, height: Int) -> Unit)

Invokes onChanged when the surface's geometry (width and height) changes.

android
Unit
Surface.onDestroyed(onDestroyed: Surface.() -> Unit)

Invokes onDestroyed when the surface is destroyed.

android