Skip to content

Commit 0b20238

Browse files
committed
feat: add GLDrawScope.terminate() method to stop the rendering thread from inside the render block
1 parent 9d589c8 commit 0b20238

File tree

4 files changed

+31
-8
lines changed

4 files changed

+31
-8
lines changed

src/main/java/dev/silenium/compose/gl/fbo/FBOPool.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import dev.silenium.compose.gl.surface.GLDisplayScope
88
import dev.silenium.compose.gl.surface.GLDisplayScopeImpl
99
import dev.silenium.compose.gl.surface.GLDrawScope
1010
import dev.silenium.compose.gl.surface.GLDrawScopeImpl
11+
import kotlinx.coroutines.CancellationException
1112
import org.lwjgl.opengl.GL30.*
1213
import kotlin.contracts.ExperimentalContracts
1314
import kotlin.contracts.InvocationKind
@@ -92,7 +93,11 @@ class FBOPool(
9293
glFlush()
9394
fbo.unbind()
9495

95-
Result.success(drawScope.redrawAfter)
96+
if (drawScope.terminate) {
97+
Result.failure(CancellationException("Rendering terminated"))
98+
} else {
99+
Result.success(drawScope.redrawAfter)
100+
}
96101
}
97102
} ?: Result.failure(NoRenderFBOAvailable())
98103
}

src/main/java/dev/silenium/compose/gl/surface/GLDrawScope.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ interface GLDrawScope {
2020
* @param duration The duration to redraw after. If null, a call to [GLSurfaceState.requestUpdate] is required to redraw.
2121
*/
2222
fun redrawAfter(duration: Duration?)
23+
24+
/**
25+
* Terminate the rendering thread.
26+
*/
27+
fun terminate()
2328
}
2429

2530
internal class GLDrawScopeImpl(
@@ -28,6 +33,12 @@ internal class GLDrawScopeImpl(
2833
) : GLDrawScope {
2934
internal var redrawAfter: Duration? = (1000 / 60).milliseconds
3035
private set
36+
internal var terminate = false
37+
private set
38+
39+
override fun terminate() {
40+
terminate = true
41+
}
3142

3243
override fun redrawAfter(duration: Duration?) {
3344
redrawAfter = duration

src/main/java/dev/silenium/compose/gl/surface/GLSurfaceView.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,13 @@ class GLSurfaceView internal constructor(
239239
val renderResult = fboPool!!.render(deltaTime.nanoseconds, drawBlock)
240240
val e = renderResult.exceptionOrNull()
241241
if (e is NoRenderFBOAvailable) {
242-
logger.debug("No FBO available, waiting for the next frame")
243-
sleep(1)
242+
try {
243+
sleep(1)
244+
} catch (e: InterruptedException) {
245+
break
246+
}
244247
continue
245-
} else if (e is CancellationException) {
248+
} else if (e is CancellationException || e is InterruptedException) {
246249
break
247250
} else if (e != null) {
248251
logger.error("Failed to render frame", e)

src/test/kotlin/Main.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,10 @@ import androidx.compose.runtime.*
1212
import androidx.compose.ui.Alignment
1313
import androidx.compose.ui.Modifier
1414
import androidx.compose.ui.graphics.Color
15-
import androidx.compose.ui.graphics.TransformOrigin
1615
import androidx.compose.ui.unit.dp
1716
import androidx.compose.ui.window.ApplicationScope
1817
import androidx.compose.ui.window.Window
1918
import androidx.compose.ui.window.awaitApplication
20-
import dev.silenium.compose.gl.surface.FBOSizeOverride
2119
import dev.silenium.compose.gl.surface.GLSurfaceView
2220
import dev.silenium.compose.gl.surface.Stats
2321
import dev.silenium.compose.gl.surface.rememberGLSurfaceState
@@ -32,7 +30,7 @@ import kotlin.time.Duration.Companion.milliseconds
3230
@Preview
3331
fun ApplicationScope.App() {
3432
MaterialTheme {
35-
Box(contentAlignment = Alignment.TopStart, modifier = Modifier.fillMaxSize().background(Color.Black)) {
33+
Box(contentAlignment = Alignment.TopStart, modifier = Modifier.fillMaxSize().background(Color.White)) {
3634
val state = rememberGLSurfaceState()
3735
var targetHue by remember { mutableStateOf(0f) }
3836
val color by animateColorAsState(
@@ -58,10 +56,16 @@ fun ApplicationScope.App() {
5856
.zoomable(rememberZoomableState(ZoomSpec(6f)))
5957
.align(Alignment.Center),
6058
presentMode = GLSurfaceView.PresentMode.MAILBOX,
61-
fboSizeOverride = FBOSizeOverride(4096, 4096, TransformOrigin.Center),
59+
// fboSizeOverride = FBOSizeOverride(4096, 4096, TransformOrigin.Center),
6260
) {
6361
glClearColor(color.red, color.green, color.blue, color.alpha)
6462
glClear(GL_COLOR_BUFFER_BIT)
63+
try {
64+
Thread.sleep(33, 333)
65+
} catch (e: InterruptedException) {
66+
terminate()
67+
return@GLSurfaceView
68+
}
6569
glBegin(GL_QUADS)
6670
glColor3f(1f, 0f, 0f)
6771
glVertex2f(-1f, 0f)

0 commit comments

Comments
 (0)