diff --git a/src/main/java/dev/silenium/compose/gl/surface/GLSurfaceView.kt b/src/main/java/dev/silenium/compose/gl/surface/GLSurfaceView.kt index 1f92115..cdb9d71 100644 --- a/src/main/java/dev/silenium/compose/gl/surface/GLSurfaceView.kt +++ b/src/main/java/dev/silenium/compose/gl/surface/GLSurfaceView.kt @@ -63,11 +63,13 @@ fun GLSurfaceView( cleanup: suspend () -> Unit = {}, draw: suspend GLDrawScope.() -> Unit, ) { + var invalidations by remember { mutableStateOf(0) } val surfaceView = remember { val currentContext = glContextProvider.fromCurrent() ?: error("No current EGL context") GLSurfaceView( state = state, parentContext = currentContext, + invalidate = { invalidations++ }, paint = paint, presentMode = presentMode, swapChainSize = swapChainSize, @@ -115,9 +117,11 @@ fun GLSurfaceView( } } ) { + invalidations.let { directContext?.let { directContext -> surfaceView.display(drawContext.canvas.nativeCanvas, directContext) } + } } } DisposableEffect(surfaceView) { @@ -137,6 +141,7 @@ class GLSurfaceView internal constructor( private val parentContext: GLContext<*>, private val drawBlock: suspend GLDrawScope.() -> Unit, private val cleanupBlock: suspend () -> Unit = {}, + private val invalidate: () -> Unit = {}, private val paint: Paint = Paint(), private val presentMode: PresentMode = PresentMode.MAILBOX, private val swapChainSize: Int = 10, @@ -181,6 +186,7 @@ class GLSurfaceView internal constructor( internal fun display(canvas: Canvas, displayContext: DirectContext) { val t1 = System.nanoTime() fboPool?.display { displayImpl(canvas, displayContext) } + invalidate() val t2 = System.nanoTime() state.onDisplay(t2, (t2 - t1).nanoseconds) } @@ -242,6 +248,7 @@ class GLSurfaceView internal constructor( break } val waitTime = renderResult.getOrNull() + invalidate() val renderEnd = System.nanoTime() state.onRender(renderEnd, (renderEnd - renderStart).nanoseconds) lastFrame = renderStart diff --git a/src/test/kotlin/Main.kt b/src/test/kotlin/Main.kt index 2b05e60..cd67c0d 100644 --- a/src/test/kotlin/Main.kt +++ b/src/test/kotlin/Main.kt @@ -6,6 +6,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.material.Button import androidx.compose.material.MaterialTheme +import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment @@ -62,7 +63,6 @@ fun ApplicationScope.App() { glClearColor(color.red, color.green, color.blue, color.alpha) glClear(GL_COLOR_BUFFER_BIT) glBegin(GL_QUADS) - // fat rectangle from top left to bottom right glColor3f(1f, 0f, 0f) glVertex2f(-1f, 0f) glColor3f(0f, 1f, 0f) @@ -76,20 +76,22 @@ fun ApplicationScope.App() { val wait = (1000.0 / 60).milliseconds redrawAfter(null) } - Column(modifier = Modifier.align(Alignment.TopStart).padding(4.dp)) { - val display by state.displayStatistics.collectAsState() - Text("Display datapoints: ${display.frameTimes.values.size}") - Text("Display frame time: ${display.frameTimes.median.inWholeMicroseconds / 1000.0} ms") - Text("Display frame time (99th): ${display.frameTimes.percentile(0.99).inWholeMicroseconds / 1000.0} ms") - Text("Display FPS: ${display.fps.median}") - Text("Display FPS (99th): ${display.fps.percentile(0.99, Stats.Percentile.LOWEST)}") + Surface(modifier = Modifier.align(Alignment.TopStart).padding(4.dp)) { + Column(modifier = Modifier.padding(4.dp).width(400.dp)) { + val display by state.displayStatistics.collectAsState() + Text("Display datapoints: ${display.frameTimes.values.size}") + Text("Display frame time: ${display.frameTimes.median.inWholeMicroseconds / 1000.0} ms") + Text("Display frame time (99th): ${display.frameTimes.percentile(0.99).inWholeMicroseconds / 1000.0} ms") + Text("Display FPS: ${display.fps.median}") + Text("Display FPS (99th): ${display.fps.percentile(0.99, Stats.Percentile.LOWEST)}") - val render by state.renderStatistics.collectAsState() - Text("Render datapoints: ${render.frameTimes.values.size}") - Text("Render frame time: ${render.frameTimes.median.inWholeMicroseconds / 1000.0} ms") - Text("Render frame time (99th): ${render.frameTimes.percentile(0.99).inWholeMicroseconds / 1000.0} ms") - Text("Render FPS: ${render.fps.median} ms") - Text("Render FPS (99th): ${render.fps.percentile(0.99, Stats.Percentile.LOWEST)}") + val render by state.renderStatistics.collectAsState() + Text("Render datapoints: ${render.frameTimes.values.size}") + Text("Render frame time: ${render.frameTimes.median.inWholeMicroseconds / 1000.0} ms") + Text("Render frame time (99th): ${render.frameTimes.percentile(0.99).inWholeMicroseconds / 1000.0} ms") + Text("Render FPS: ${render.fps.median} ms") + Text("Render FPS (99th): ${render.fps.percentile(0.99, Stats.Percentile.LOWEST)}") + } } Button( onClick = ::exitApplication,