Skip to content

Commit

Permalink
Hide the Metal layer when the SkiaLayer becomes hidden. (#677)
Browse files Browse the repository at this point in the history
  • Loading branch information
m-sasha authored Mar 18, 2023
1 parent befd7f0 commit 20cd028
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 0 deletions.
4 changes: 4 additions & 0 deletions skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,11 @@ actual open class SkiaLayer internal constructor(
private var isRendering = false

private fun checkShowing() {
val wasShowing = isShowingCached
isShowingCached = super.isShowing()
if (wasShowing != isShowing) {
redrawer?.setVisible(isShowing)
}
if (isShowing) {
redrawer?.syncSize()
repaint()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ internal class MetalRedrawer(
)
}

override fun setVisible(isVisible: Boolean) {
setLayerVisible(device, isVisible)
}

fun makeContext() = DirectContext(
makeMetalContext(device)
)
Expand All @@ -153,6 +157,7 @@ internal class MetalRedrawer(
private external fun disposeDevice(device: Long)
private external fun finishFrame(device: Long)
private external fun resizeLayers(device: Long, x: Int, y: Int, width: Int, height: Int)
private external fun setLayerVisible(device: Long, isVisible: Boolean)
private external fun setContentScale(device: Long, contentScale: Float)
private external fun setVSyncEnabled(device: Long, enabled: Boolean)
private external fun isOccluded(window: Long): Boolean
Expand Down
17 changes: 17 additions & 0 deletions skiko/src/awtMain/objectiveC/macos/MetalRedrawer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,23 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_resizeLay
}
}

JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setLayerVisible(
JNIEnv *env, jobject redrawer, jlong devicePtr, jboolean isVisible)
{
@autoreleasepool {
MetalDevice *device = (__bridge MetalDevice *) (void *) devicePtr;
BOOL hidden = !isVisible;
if (!device || !device.layer || device.layer.hidden == hidden) {
return;
}
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
device.layer.hidden = hidden;
[CATransaction commit];
[CATransaction flush];
}
}

JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setContentScale(JNIEnv *env, jobject obj, jlong devicePtr, jfloat contentScale)
{
@autoreleasepool {
Expand Down
29 changes: 29 additions & 0 deletions skiko/src/awtTest/kotlin/org/jetbrains/skiko/SkiaLayerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,35 @@ class SkiaLayerTest {
} finally {
window.dispose()
}
}

@Test
fun `hiding parent stops drawing layer`() = uiTest {
val window = UiTestWindow()
try {
window.setLocation(200, 200)
window.setSize(400, 200)
window.defaultCloseOperation = WindowConstants.DISPOSE_ON_CLOSE
val app = RectRenderer(window.layer, 200, 100, Color.RED)
window.layer.skikoView = app
window.isUndecorated = true
window.isVisible = true

// Force the layered pane to draw itself with a specific color so that the test doesn't depend on the
// default window background, which could be different on different platforms.
window.layeredPane.background = Color.BLUE
window.layeredPane.isOpaque = true

delay(1000)
screenshots.assert(window.bounds, "visible_parent")

window.contentPane.isVisible = false

delay(1000)
screenshots.assert(window.bounds, "hidden_parent")
} finally {
window.close()
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ internal interface Redrawer {
fun needRedraw()
fun redrawImmediately()
fun syncSize() = Unit
fun setVisible(isVisible: Boolean) = Unit
val renderInfo: String
}
6 changes: 6 additions & 0 deletions skiko/src/jvmMain/cpp/common/stubs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_resizeLay
skikoUnimplemented("Java_org_jetbrains_skiko_redrawer_MetalRedrawer_resizeLayers");
}

JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setLayerVisible(
JNIEnv *env, jobject redrawer, jlong devicePtr, jboolean isVisible)
{
skikoUnimplemented("Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setLayerVisible");
}

JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setContentScale(JNIEnv *env, jobject obj, jlong devicePtr, jfloat contentScale)
{
skikoUnimplemented("Java_org_jetbrains_skiko_redrawer_MetalRedrawer_setContentScale");
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 20cd028

Please sign in to comment.