Skip to content

Commit

Permalink
feat: add GLDrawScope.terminate() method to stop the rendering thread…
Browse files Browse the repository at this point in the history
… from inside the render block
  • Loading branch information
silenium-dev committed Oct 8, 2024
1 parent 9d589c8 commit 0b20238
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 8 deletions.
7 changes: 6 additions & 1 deletion src/main/java/dev/silenium/compose/gl/fbo/FBOPool.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import dev.silenium.compose.gl.surface.GLDisplayScope
import dev.silenium.compose.gl.surface.GLDisplayScopeImpl
import dev.silenium.compose.gl.surface.GLDrawScope
import dev.silenium.compose.gl.surface.GLDrawScopeImpl
import kotlinx.coroutines.CancellationException
import org.lwjgl.opengl.GL30.*
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
Expand Down Expand Up @@ -92,7 +93,11 @@ class FBOPool(
glFlush()
fbo.unbind()

Result.success(drawScope.redrawAfter)
if (drawScope.terminate) {
Result.failure(CancellationException("Rendering terminated"))
} else {
Result.success(drawScope.redrawAfter)
}
}
} ?: Result.failure(NoRenderFBOAvailable())
}
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/dev/silenium/compose/gl/surface/GLDrawScope.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ interface GLDrawScope {
* @param duration The duration to redraw after. If null, a call to [GLSurfaceState.requestUpdate] is required to redraw.
*/
fun redrawAfter(duration: Duration?)

/**
* Terminate the rendering thread.
*/
fun terminate()
}

internal class GLDrawScopeImpl(
Expand All @@ -28,6 +33,12 @@ internal class GLDrawScopeImpl(
) : GLDrawScope {
internal var redrawAfter: Duration? = (1000 / 60).milliseconds
private set
internal var terminate = false
private set

override fun terminate() {
terminate = true
}

override fun redrawAfter(duration: Duration?) {
redrawAfter = duration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,13 @@ class GLSurfaceView internal constructor(
val renderResult = fboPool!!.render(deltaTime.nanoseconds, drawBlock)
val e = renderResult.exceptionOrNull()
if (e is NoRenderFBOAvailable) {
logger.debug("No FBO available, waiting for the next frame")
sleep(1)
try {
sleep(1)
} catch (e: InterruptedException) {
break
}
continue
} else if (e is CancellationException) {
} else if (e is CancellationException || e is InterruptedException) {
break
} else if (e != null) {
logger.error("Failed to render frame", e)
Expand Down
12 changes: 8 additions & 4 deletions src/test/kotlin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.ApplicationScope
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.awaitApplication
import dev.silenium.compose.gl.surface.FBOSizeOverride
import dev.silenium.compose.gl.surface.GLSurfaceView
import dev.silenium.compose.gl.surface.Stats
import dev.silenium.compose.gl.surface.rememberGLSurfaceState
Expand All @@ -32,7 +30,7 @@ import kotlin.time.Duration.Companion.milliseconds
@Preview
fun ApplicationScope.App() {
MaterialTheme {
Box(contentAlignment = Alignment.TopStart, modifier = Modifier.fillMaxSize().background(Color.Black)) {
Box(contentAlignment = Alignment.TopStart, modifier = Modifier.fillMaxSize().background(Color.White)) {
val state = rememberGLSurfaceState()
var targetHue by remember { mutableStateOf(0f) }
val color by animateColorAsState(
Expand All @@ -58,10 +56,16 @@ fun ApplicationScope.App() {
.zoomable(rememberZoomableState(ZoomSpec(6f)))
.align(Alignment.Center),
presentMode = GLSurfaceView.PresentMode.MAILBOX,
fboSizeOverride = FBOSizeOverride(4096, 4096, TransformOrigin.Center),
// fboSizeOverride = FBOSizeOverride(4096, 4096, TransformOrigin.Center),
) {
glClearColor(color.red, color.green, color.blue, color.alpha)
glClear(GL_COLOR_BUFFER_BIT)
try {
Thread.sleep(33, 333)
} catch (e: InterruptedException) {
terminate()
return@GLSurfaceView
}
glBegin(GL_QUADS)
glColor3f(1f, 0f, 0f)
glVertex2f(-1f, 0f)
Expand Down

0 comments on commit 0b20238

Please sign in to comment.