From c3a900847e861ebb847e13fb2a4b8ce6c454cdbd Mon Sep 17 00:00:00 2001 From: Igor Demin Date: Wed, 6 Mar 2024 13:40:53 +0100 Subject: [PATCH] Windows. Fix a crash when we resize to zero and then to non-zero (#883) Fixes https://github.com/JetBrains/compose-multiplatform/issues/4425 It is a regression after https://github.com/JetBrains/skiko/pull/858 The crash was because `d3dDevice->swapChain->GetBuffer` didn't return the buffer to draw on if we reused the buffer from the previous frame (we didn't change `surface` in case of zero size). I am not completely sure why, but I exhausted my the investigation limit and this fix is needed by other reasons (we need to wait for vsync). ## Testing An additional check in the existed test (fails before the fix) --- .../jetbrains/skiko/context/Direct3DContextHandler.kt | 10 +++++----- .../kotlin/org/jetbrains/skiko/SkiaLayerTest.kt | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt index 85ef216ef..d493a7278 100644 --- a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt +++ b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt @@ -45,12 +45,12 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : JvmContextHandler(laye override fun initCanvas() { val context = context ?: return val scale = layer.contentScale - val width = (layer.width * scale).toInt() - val height = (layer.height * scale).toInt() - if (width <= 0 || height <= 0) { - return - } + // Direct3D can't work with zero size. + // Don't rewrite code to skipping, as we need the whole pipeline in zero case too + // (drawing -> flushing -> swapping -> waiting for vsync) + val width = (layer.width * scale).toInt().coerceAtLeast(1) + val height = (layer.height * scale).toInt().coerceAtLeast(1) if (isSizeChanged(width, height) || isSurfacesNull()) { disposeCanvas() diff --git a/skiko/src/awtTest/kotlin/org/jetbrains/skiko/SkiaLayerTest.kt b/skiko/src/awtTest/kotlin/org/jetbrains/skiko/SkiaLayerTest.kt index f0b9eaf42..1ba961e40 100644 --- a/skiko/src/awtTest/kotlin/org/jetbrains/skiko/SkiaLayerTest.kt +++ b/skiko/src/awtTest/kotlin/org/jetbrains/skiko/SkiaLayerTest.kt @@ -249,6 +249,12 @@ class SkiaLayerTest { layer.needRedraw() delay(1000) assertEquals(0, renderedWidth) + + renderedWidth = -1 + layer.size = Dimension(40, 40) + layer.needRedraw() + delay(1000) + assertEquals((40 * density).toInt(), renderedWidth) } finally { layer.dispose() window.close()