Unverified Commit 8d61a57a authored by Igor Demin's avatar Igor Demin Committed by GitHub

Fix rendering of an empty layer on metal (#504)

* Fix rendering of an empty layer on metal

* Fix Windows
parent 47985faa
......@@ -38,17 +38,25 @@ internal class DirectSoftwareContextHandler(layer: SkiaLayer) : JvmContextHandle
val h = (layer.height * scale).toInt().coerceAtLeast(0)
if (isSizeChanged(w, h) || surface == null) {
disposeCanvas()
if (w > 0 && h > 0) {
softwareRedrawer.resize(w, h)
surface = softwareRedrawer.acquireSurface()
canvas = surface!!.canvas
} else {
surface = null
canvas = null
}
}
}
override fun flush() {
val surface = surface
if (surface != null) {
try {
softwareRedrawer.finishFrame(getPtr(surface!!))
softwareRedrawer.finishFrame(getPtr(surface))
} finally {
Reference.reachabilityFence(surface!!)
Reference.reachabilityFence(surface)
}
}
}
}
\ No newline at end of file
......@@ -34,6 +34,7 @@ internal class MetalContextHandler(layer: SkiaLayer) : JvmContextHandler(layer)
val w = (layer.width * scale).toInt().coerceAtLeast(0)
val h = (layer.height * scale).toInt().coerceAtLeast(0)
if (w > 0 && h > 0) {
renderTarget = metalRedrawer.makeRenderTarget(w, h)
surface = Surface.makeFromBackendRenderTarget(
......@@ -45,11 +46,16 @@ internal class MetalContextHandler(layer: SkiaLayer) : JvmContextHandler(layer)
) ?: throw RenderException("Cannot create surface")
canvas = surface!!.canvas
} else {
renderTarget = null
surface = null
canvas = null
}
}
override fun flush() {
super.flush()
surface!!.flushAndSubmit()
surface?.flushAndSubmit()
metalRedrawer.finishFrame()
}
......
......@@ -47,6 +47,7 @@ internal class MetalContextHandler(layer: SkiaLayer) : ContextHandler(layer, lay
metalRedrawer.syncSize()
}
if (w > 0 && h > 0) {
renderTarget = metalRedrawer.makeRenderTarget(w, h)
surface = Surface.makeFromBackendRenderTarget(
......@@ -58,12 +59,17 @@ internal class MetalContextHandler(layer: SkiaLayer) : ContextHandler(layer, lay
) ?: throw RenderException("Cannot create surface")
canvas = surface!!.canvas
} else {
renderTarget = null
surface = null
canvas = null
}
}
override fun flush() {
// TODO: maybe make flush async as in JVM version.
super.flush()
surface!!.flushAndSubmit()
surface?.flushAndSubmit()
metalRedrawer.finishFrame()
}
......
......@@ -25,6 +25,7 @@ import java.awt.Color
import java.awt.Dimension
import java.awt.event.WindowEvent
import javax.swing.JFrame
import javax.swing.JLayeredPane
import javax.swing.WindowConstants
import kotlin.random.Random
import kotlin.test.assertTrue
......@@ -135,6 +136,55 @@ class SkiaLayerTest {
}
}
@Test
fun `render empty layer`() = uiTest {
val window = JFrame()
val layer = SkiaLayer(
properties = SkiaLayerProperties(renderApi = renderApi)
)
var renderedWidth = -1
layer.skikoView = object : SkikoView {
override fun onRender(canvas: Canvas, width: Int, height: Int, nanoTime: Long) {
renderedWidth = width
}
}
layer.size = Dimension(0, 0)
val density = window.graphicsConfiguration.defaultTransform.scaleX
try {
val panel = JLayeredPane()
panel.add(layer)
window.contentPane.add(panel)
window.setLocation(200, 200)
window.size = Dimension(200, 200)
window.defaultCloseOperation = WindowConstants.DISPOSE_ON_CLOSE
window.isUndecorated = true
window.isVisible = true
layer.needRedraw()
delay(1000)
assertEquals(0, renderedWidth)
renderedWidth = -1
layer.needRedraw()
delay(1000)
assertEquals(0, renderedWidth)
renderedWidth = -1
layer.size = Dimension(30, 40)
layer.needRedraw()
delay(1000)
assertEquals((30 * density).toInt(), renderedWidth)
renderedWidth = -1
layer.size = Dimension(0, 0)
layer.needRedraw()
delay(1000)
assertEquals(0, renderedWidth)
} finally {
layer.dispose()
window.close()
}
}
@Test
fun `resize window`() = uiTest {
val window = UiTestWindow()
......
......@@ -35,6 +35,7 @@ internal class MacOsMetalContextHandler(layer: SkiaLayer) : ContextHandler(layer
val w = (layer.nsView.frame.useContents { size.width } * scale).toInt().coerceAtLeast(0)
val h = (layer.nsView.frame.useContents { size.height } * scale).toInt().coerceAtLeast(0)
if (w > 0 && h > 0) {
renderTarget = metalRedrawer.makeRenderTarget(w, h)
surface = Surface.makeFromBackendRenderTarget(
......@@ -46,12 +47,17 @@ internal class MacOsMetalContextHandler(layer: SkiaLayer) : ContextHandler(layer
) ?: throw RenderException("Cannot create surface")
canvas = surface!!.canvas
} else {
renderTarget = null
surface = null
canvas = null
}
}
override fun flush() {
// TODO: maybe make flush async as in JVM version.
super.flush()
surface!!.flushAndSubmit()
surface?.flushAndSubmit()
metalRedrawer.finishFrame()
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment