Eliminate background flash on first window show - #1237
Eliminate background flash on first window show#1237Alexander Maryanovsky (m-sasha) merged 13 commits into
Conversation
| * Only called when [supportsRenderingBeforeShown] is `true`. Implementations must present the frame in a | ||
| * way that the window's first on-screen composite reflects it rather than the background. | ||
| */ | ||
| protected open fun renderBeforeShown() { |
There was a problem hiding this comment.
We also perform a force render inside Compose. How is it coordinated with this change? Do you plan to remove it, call conditionally, or just keep the double call?
There was a problem hiding this comment.
I plan to remove the workaround from Compose.
There was a problem hiding this comment.
But it should be removed when we implement all the renderers, right?
There was a problem hiding this comment.
I'm not sure how Metal-specific this PR is, really. It's possible that supportsRenderingBeforeShown is not needed and we can, as a default, call renderImmediately (which is what we do from Compose anyway). If this turns out to be true, then we're just moving the current workaround from Compose into Skiko while allowing some renderers to do it even better, by writing their own renderer-specific code.
I will know better when I implement it for Direct3D.
There was a problem hiding this comment.
Please, before merging this, create a PR in Compose to remove the render in Compose, to be sure that you can implement it.
There was a problem hiding this comment.
Not a PR because skiko needs to be published first, but here's the branch:
https://github.com/JetBrains/compose-multiplatform-core/tree/m-sasha/integrate-skiko-fixes
9fec510 to
ef6e227
Compare
220e01d to
8aa1822
Compare
There was a problem hiding this comment.
Pull request overview
This PR addresses a macOS Metal-specific visual artifact where the window background briefly flashes on the very first window show in a fresh process, by ensuring a first frame is rendered/presented while the window is displayable but not yet visible.
Changes:
- Add an AWT redrawer hook to render/present a frame before the component is shown, and implement it for Metal.
- Split Metal present paths into async vs sync JNI entrypoints to support “render-before-shown” and live-resize transactional presentation.
- Add an AWT test that spawns a fresh JVM harness and samples screen pixels to detect first-show flashes.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| skiko/src/awtTest/kotlin/org/jetbrains/skiko/SkiaLayerTest.kt | Adds a regression test that spawns a fresh JVM and samples pixels to detect first-show flashes; adds a window-open await helper. |
| skiko/src/awtTest/kotlin/org/jetbrains/skiko/FirstWindowShowFlashHelper.kt | Adds a standalone child-process harness that renders an expensive first frame for flash detection. |
| skiko/src/awtMain/objectiveC/macos/MetalContextHandler.mm | Renames/splits JNI entrypoints into async vs sync frame finishing and expands sync present rationale. |
| skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt | Minor import/formatting adjustments (not behavior-changing). |
| skiko/src/awtMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.kt | Implements “render before shown” for Metal and routes presentation through async/sync finish methods. |
| skiko/src/awtMain/kotlin/org/jetbrains/skiko/redrawer/AWTRedrawer.kt | Renders eagerly on resize when displayable-but-not-showing for redrawers that support it. |
| skiko/src/awtMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt | Renames/splits finishFrame API into async vs sync to match native entrypoints. |
Comments suppressed due to low confidence (1)
skiko/src/awtTest/kotlin/org/jetbrains/skiko/SkiaLayerTest.kt:56
- Unused import:
Duration.Companion.nanosecondsis imported but not referenced in this file.
import kotlin.time.Duration.Companion.nanoseconds
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
… flash without it too)
d92e682 to
46cec4c
Compare
ff66954 to
310b526
Compare
There was a problem hiding this comment.
Please coordinate with Ivan Matkov (@MatkovIvan) what should be merged first and what should be adapted:
#1234
0d3816a to
257f270
Compare
Fix by presenting the first frame when the window is displayable but not yet visible.
Fixes https://youtrack.jetbrains.com/issue/CMP-10484/Metal-Eliminate-window-background-flash-on-first-show
Fixes https://youtrack.jetbrains.com/issue/CMP-10485/Direct3D-Eliminate-window-background-flash-on-first-show