Skip to content

Commit 8a33964

Browse files
committed
feat: start working on rewrite against new compose-gl
1 parent 0ef8f2a commit 8a33964

File tree

11 files changed

+88
-81
lines changed

11 files changed

+88
-81
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ tasks {
6969
kotlin {
7070
compilerOptions {
7171
freeCompilerArgs.add("-Xcontext-receivers")
72-
jvmTarget = JvmTarget.JVM_11
72+
jvmTarget = JvmTarget.JVM_17
7373
}
7474
}
7575

gradle/libs.versions.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ kotlinx-serialization = "1.9.0"
66
kotlinx-datetime = "0.6.1"
77

88
compose = "1.10.0-alpha02"
9-
compose-gl = "0.8.0"
9+
compose-gl = "0.9.0"
1010
jni-utils = "0.1.6"
1111
jna = "5.16.0"
1212

@@ -32,7 +32,7 @@ kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-
3232
kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinx-datetime" }
3333

3434
compose-gl = { group = "dev.silenium.compose.gl", name = "compose-gl", version.ref = "compose-gl" }
35-
compose-gl-natives = { group = "dev.silenium.compose.gl", name = "compose-gl-natives-linux-x86_64", version.ref = "compose-gl" }
35+
compose-gl-natives = { group = "dev.silenium.compose.gl", name = "compose-gl-natives-all", version.ref = "compose-gl" }
3636
ffmpeg-natives = { group = "dev.silenium.libs", name = "ffmpeg-natives", version = "7.1+0.2.0" }
3737
mpv-natives = { group = "dev.silenium.libs", name = "ffmpeg-natives", version = "0.39.0+0.1.2" }
3838
jni-utils = { group = "dev.silenium.libs.jni", name = "jni-utils", version.ref = "jni-utils" }

native/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
*.iml
33
cmake-build-*/
44
/subprojects/*
5-
!/subprojects/*.wrap
5+
!/subprojects/mpv.wrap
66
!/subprojects/packagefiles
77
!/subprojects/packagefiles/*
88
buildDir/

native/src/mpv/MPV.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ void handle_mpv_events(void *ctx) {
220220
extern "C" {
221221
// Client
222222
JNIEXPORT jobject JNICALL Java_dev_silenium_multimedia_core_mpv_MPVKt_createN(JNIEnv *env, jobject thiz) {
223+
setlocale(LC_NUMERIC, "C");
223224
const auto handle = mpv_create();
224225
if (handle == nullptr) {
225226
return mpvResultFailure(env, "mpv_create", MPV_ERROR_NOMEM);

src/main/kotlin/dev/silenium/multimedia/compose/player/VideoPlayer.kt

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package dev.silenium.multimedia.compose.player
22

33
import androidx.compose.runtime.*
4-
import dev.silenium.compose.gl.surface.GLDrawScope
5-
import dev.silenium.compose.gl.surface.GLSurface
6-
import dev.silenium.compose.gl.surface.GLSurfaceState
4+
import dev.silenium.compose.gl.canvas.GLCanvasState
5+
import dev.silenium.compose.gl.canvas.GLDrawScope
76
import dev.silenium.multimedia.compose.util.deferredFlowStateOf
87
import dev.silenium.multimedia.compose.util.mapState
98
import dev.silenium.multimedia.core.annotation.InternalMultimediaApi
@@ -19,7 +18,6 @@ class VideoPlayer(hwdec: Boolean = false) : AutoCloseable {
1918

2019
val config: Config = Config()
2120

22-
internal var surface: GLSurface? = null
2321
private var initialized = false
2422

2523
@PublishedApi
@@ -68,28 +66,33 @@ class VideoPlayer(hwdec: Boolean = false) : AutoCloseable {
6866
return mpv
6967
}
7068

71-
private fun initialize(state: GLSurfaceState) {
69+
private fun initialize(state: GLCanvasState, onInitialized: () -> Unit) {
7270
if (initialized) return
7371
render = mpv.createRender(advancedControl = true, state::requestUpdate)
7472
initialized = true
73+
onInitialized()
7574
}
7675

77-
fun onRender(scope: GLDrawScope, state: GLSurfaceState) {
78-
initialize(state)
76+
fun onRender(scope: GLDrawScope, state: GLCanvasState, onInitialized: () -> Unit = {}) {
77+
initialize(state, onInitialized)
7978

8079
// TODO: fix render block if screen is disconnected and reconnected
8180

8281
glClearColor(0f, 0f, 0f, 0f)
8382
glClear(GL_COLOR_BUFFER_BIT)
8483
render?.render(scope.fbo)?.getOrThrow()
85-
scope.redrawAfter(null)
8684
}
8785

8886
override fun close() {
8987
render?.close()
9088
mpv.close()
9189
}
9290

91+
fun onCanvasDispose() {
92+
render?.close()
93+
render = null
94+
}
95+
9396
companion object {
9497
private val defaultOptions = mapOf(
9598
"terminal" to "yes",

src/main/kotlin/dev/silenium/multimedia/compose/player/VideoSurface.kt

Lines changed: 55 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,64 +5,68 @@ import androidx.compose.foundation.layout.padding
55
import androidx.compose.foundation.layout.width
66
import androidx.compose.material.MaterialTheme
77
import androidx.compose.material.Surface
8-
import androidx.compose.runtime.*
8+
import androidx.compose.runtime.Composable
9+
import androidx.compose.runtime.remember
910
import androidx.compose.ui.Modifier
1011
import androidx.compose.ui.graphics.Color
1112
import androidx.compose.ui.unit.dp
12-
import dev.silenium.compose.gl.surface.*
13-
import dev.silenium.multimedia.core.annotation.InternalMultimediaApi
13+
import dev.silenium.compose.gl.canvas.GLCanvas
14+
import dev.silenium.compose.gl.canvas.rememberGLCanvasState
1415
import org.jetbrains.skia.Paint
1516

16-
@Composable
17-
private fun createGLSurface(
18-
player: VideoPlayer,
19-
surfaceState: GLSurfaceState = rememberGLSurfaceState(),
20-
onInitialized: () -> Unit = {},
21-
): GLSurface {
22-
var initialized by remember { mutableStateOf(false) }
23-
24-
@OptIn(InternalMultimediaApi::class)
25-
val dwidth by player.property<Long>("dwidth")
26-
27-
@OptIn(InternalMultimediaApi::class)
28-
val dheight by player.property<Long>("dheight")
29-
val fboSizeOverride = remember(player.config.pixelPerfect, dwidth, dheight) {
30-
if (!player.config.pixelPerfect) return@remember null
31-
dwidth?.let { w ->
32-
dheight?.let { h ->
33-
FBOSizeOverride(w.toInt(), h.toInt())
34-
}
35-
}
36-
}
37-
return rememberGLSurface(
38-
surfaceState,
39-
presentMode = GLSurface.PresentMode.MAILBOX,
40-
swapChainSize = 3,
41-
fboSizeOverride = fboSizeOverride,
42-
draw = {
43-
player.onRender(this, surfaceState)
44-
if (!initialized) {
45-
initialized = true
46-
onInitialized()
47-
}
48-
}
49-
)
50-
}
17+
//@Composable
18+
//private fun createGLSurface(
19+
// player: VideoPlayer,
20+
// surfaceState: GLSurfaceState = rememberGLSurfaceState(),
21+
// onInitialized: () -> Unit = {},
22+
//): GLSurface {
23+
// var initialized by remember { mutableStateOf(false) }
24+
//
25+
// @OptIn(InternalMultimediaApi::class)
26+
// val dwidth by player.property<Long>("dwidth")
27+
//
28+
// @OptIn(InternalMultimediaApi::class)
29+
// val dheight by player.property<Long>("dheight")
30+
// val fboSizeOverride = remember(player.config.pixelPerfect, dwidth, dheight) {
31+
// if (!player.config.pixelPerfect) return@remember null
32+
// dwidth?.let { w ->
33+
// dheight?.let { h ->
34+
// FBOSizeOverride(w.toInt(), h.toInt())
35+
// }
36+
// }
37+
// }
38+
// return rememberGLSurface(
39+
// surfaceState,
40+
// presentMode = GLSurface.PresentMode.MAILBOX,
41+
// swapChainSize = 3,
42+
// fboSizeOverride = fboSizeOverride,
43+
// draw = {
44+
// player.onRender(this, surfaceState)
45+
// if (!initialized) {
46+
// initialized = true
47+
// onInitialized()
48+
// }
49+
// }
50+
// )
51+
//}
5152

5253
@Composable
5354
fun VideoSurface(
5455
player: VideoPlayer,
5556
showStats: Boolean = false,
5657
modifier: Modifier = Modifier,
5758
paint: Paint = Paint(),
59+
onInitialized: () -> Unit = {},
5860
) {
59-
val surfaceState = rememberGLSurfaceState()
61+
val surfaceState = rememberGLCanvasState()
6062
BoxWithConstraints(modifier = modifier) {
61-
GLSurfaceView(
62-
surface = player.surface!!,
63+
GLCanvas(
6364
modifier = Modifier.matchParentSize(),
64-
paint = paint,
65-
)
65+
state = surfaceState,
66+
// onDispose = player::onCanvasDispose,
67+
) {
68+
player.onRender(this, surfaceState, onInitialized)
69+
}
6670
if (showStats) {
6771
Surface(
6872
modifier = Modifier.padding(6.dp).width(360.dp),
@@ -77,19 +81,17 @@ fun VideoSurface(
7781

7882
@Composable
7983
fun rememberVideoPlayer(
80-
surfaceState: GLSurfaceState = rememberGLSurfaceState(),
8184
hwdec: Boolean = true,
82-
onInitialized: () -> Unit = {},
8385
): VideoPlayer {
8486
val player = remember { VideoPlayer(hwdec) }
85-
val surface = createGLSurface(player, surfaceState, onInitialized)
87+
// val surface = createGLSurface(player, surfaceState, onInitialized)
8688

87-
DisposableEffect(player, surface) {
88-
player.surface = surface
89-
onDispose {
90-
player.surface = null
91-
player.close()
92-
}
93-
}
89+
// DisposableEffect(player, surface) {
90+
// player.surface = surface
91+
// onDispose {
92+
// player.surface = null
93+
// player.close()
94+
// }
95+
// }
9496
return player
9597
}

src/main/kotlin/dev/silenium/multimedia/compose/player/VideoSurfaceEvents.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import dev.silenium.multimedia.core.annotation.InternalMultimediaApi
1313
import kotlinx.coroutines.Job
1414
import kotlinx.coroutines.delay
1515
import kotlinx.coroutines.launch
16-
import kotlinx.datetime.Clock
17-
import kotlinx.datetime.Instant
16+
import kotlin.time.Clock
1817
import kotlin.time.Duration.Companion.milliseconds
18+
import kotlin.time.ExperimentalTime
19+
import kotlin.time.Instant
1920

20-
@OptIn(ExperimentalComposeUiApi::class, InternalMultimediaApi::class)
21+
@OptIn(ExperimentalComposeUiApi::class, InternalMultimediaApi::class, ExperimentalTime::class)
2122
@Composable
2223
fun Modifier.handleInputs(player: VideoPlayer, focusRequester: FocusRequester? = null): Modifier {
2324
val coroutineScope = rememberCoroutineScope()

src/main/kotlin/dev/silenium/multimedia/compose/player/VideoSurfaceStats.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ import androidx.compose.runtime.getValue
99
import androidx.compose.ui.Modifier
1010
import androidx.compose.ui.graphics.Color
1111
import androidx.compose.ui.unit.dp
12-
import dev.silenium.compose.gl.surface.GLSurfaceState
13-
import dev.silenium.compose.gl.surface.Stats
12+
import dev.silenium.compose.gl.canvas.GLCanvasState
13+
import dev.silenium.compose.gl.canvas.Stats
1414
import dev.silenium.multimedia.compose.format.format
1515
import dev.silenium.multimedia.compose.util.deferredFlowStateOf
1616

1717
@Composable
18-
fun VideoSurfaceStats(player: VideoPlayer, state: GLSurfaceState, textColor: Color = Color.White) {
18+
fun VideoSurfaceStats(player: VideoPlayer, state: GLCanvasState, textColor: Color = Color.White) {
1919
Column(modifier = Modifier.padding(6.dp)) {
2020
val position by deferredFlowStateOf(player::position)
2121
val duration by deferredFlowStateOf(player::duration)

src/main/kotlin/dev/silenium/multimedia/compose/player/VideoSurfaceWithControls.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ fun VideoSurfaceWithControls(
1515
showStats: Boolean = false,
1616
controlFocusRequester: FocusRequester? = null,
1717
paint: Paint = Paint(),
18+
onInitialized: () -> Unit = {},
1819
) {
1920
BoxWithConstraints(modifier) {
2021
VideoSurface(
@@ -26,6 +27,7 @@ fun VideoSurfaceWithControls(
2627
maxHeight = maxHeight,
2728
),
2829
paint = paint,
30+
onInitialized = onInitialized,
2931
)
3032
VideoSurfaceControls(player, Modifier.matchParentSize(), controlFocusRequester)
3133
}

src/test/kotlin/dev/silenium/multimedia/compose/Main.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,7 @@ fun App() {
4040
}
4141
var ready by remember { mutableStateOf(false) }
4242
val coroutineScope = rememberCoroutineScope()
43-
val player = rememberVideoPlayer(
44-
onInitialized = {
45-
ready = true
46-
},
47-
)
43+
val player = rememberVideoPlayer()
4844
DisposableEffect(Unit) {
4945
onDispose {
5046
ready = false
@@ -94,6 +90,9 @@ fun App() {
9490
modifier = Modifier.fillParentMaxSize().animateItem(),
9591
showStats = true,
9692
controlFocusRequester = remember { FocusRequester() },
93+
onInitialized = {
94+
ready = true
95+
},
9796
)
9897
DisposableEffect(Unit) {
9998
coroutineScope.launch {

0 commit comments

Comments
 (0)