Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -645,13 +645,22 @@ actual open class SkiaLayer internal constructor(
@Suppress("LeakingThis")
private val fpsCounter = defaultFPSCounter(this)

internal inline fun inDrawScope(body: () -> Unit) {
private fun createDrawScope() = LayerDrawScope(
pixelGeometry = pixelGeometry,
layerWidth = width,
layerHeight = height,
scale = contentScale
)

internal inline fun inDrawScope(body: LayerDrawScope.() -> Unit) {
check(isEventDispatchThread()) { "Method should be called from AWT event dispatch thread" }
check(!isDisposed) { "SkiaLayer is disposed" }
try {
fpsCounter?.tick()
body()
} catch (e: CancellationException) {
with(createDrawScope()) {
body()
}
} catch (_: CancellationException) {
// ignore
} catch (e: RenderException) {
if (!isDisposed) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.jetbrains.skiko.context

import org.jetbrains.skia.*
import org.jetbrains.skiko.AngleApi
import org.jetbrains.skiko.LayerDrawScope
import org.jetbrains.skiko.RenderException
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.redrawer.AngleRedrawer
Expand All @@ -23,12 +24,11 @@ internal class AngleContextHandler(layer: SkiaLayer) : ContextBasedContextHandle
return false
}

override fun initCanvas() {
override fun LayerDrawScope.initCanvas() {
val context = context ?: return
val scale = layer.contentScale

val w = (layer.width * scale).toInt().coerceAtLeast(0)
val h = (layer.height * scale).toInt().coerceAtLeast(0)
val w = scaledLayerWidth
val h = scaledLayerHeight

if (isSizeChanged(w, h) || surface == null) {
disposeCanvas()
Expand All @@ -41,7 +41,7 @@ internal class AngleContextHandler(layer: SkiaLayer) : ContextBasedContextHandle
SurfaceOrigin.BOTTOM_LEFT,
SurfaceColorFormat.RGBA_8888,
ColorSpace.sRGB,
SurfaceProps(pixelGeometry = layer.pixelGeometry)
SurfaceProps(pixelGeometry = pixelGeometry)
) ?: throw RenderException("Cannot create surface")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import org.jetbrains.skiko.SkiaLayer

internal abstract class ContextBasedContextHandler(layer: SkiaLayer, val name: String) : JvmContextHandler(layer) {

abstract protected fun makeContext(): DirectContext
protected abstract fun makeContext(): DirectContext

override fun initContext(): Boolean {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package org.jetbrains.skiko.context
import org.jetbrains.skiko.SkiaLayer

internal abstract class ContextFreeContextHandler(layer: SkiaLayer) : JvmContextHandler(layer) {
private var isInited = false
private var isInitialized = false

override fun initContext(): Boolean {
if (!isInited) {
isInited = true
if (!isInitialized) {
isInitialized = true
onContextInitialized()
}
return isInited
return isInitialized
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import org.jetbrains.skia.DirectContext
import org.jetbrains.skia.Surface
import org.jetbrains.skia.SurfaceProps
import org.jetbrains.skia.impl.getPtr
import org.jetbrains.skiko.Logger
import org.jetbrains.skiko.LayerDrawScope
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.redrawer.Direct3DRedrawer
import java.lang.ref.Reference
Expand All @@ -30,23 +30,22 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : ContextBasedContextHan
return false
}

override fun initCanvas() {
override fun LayerDrawScope.initCanvas() {
val context = context ?: return
val scale = layer.contentScale

// 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)
val width = scaledLayerWidth.coerceAtLeast(1)
val height = scaledLayerHeight.coerceAtLeast(1)

if (isSizeChanged(width, height) || isSurfacesNull()) {
disposeCanvas()
context.flush()

val justInitialized = directXRedrawer.changeSize(width, height)
try {
val surfaceProps = SurfaceProps(pixelGeometry = layer.pixelGeometry)
val surfaceProps = SurfaceProps(pixelGeometry = pixelGeometry)
for (bufferIndex in 0 until bufferCount) {
surfaces[bufferIndex] = directXRedrawer.makeSurface(
context = getPtr(context),
Expand All @@ -68,7 +67,7 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : ContextBasedContextHan
canvas = surface!!.canvas
}

override fun flush() {
override fun flush(scope: LayerDrawScope) {
val context = context ?: return
val surface = surface ?: return
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jetbrains.skiko.context

import org.jetbrains.skia.impl.getPtr
import org.jetbrains.skiko.LayerDrawScope
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.redrawer.AbstractDirectSoftwareRedrawer
import java.lang.ref.Reference
Expand All @@ -20,10 +21,9 @@ internal class DirectSoftwareContextHandler(layer: SkiaLayer) : ContextFreeConte
return false
}

override fun initCanvas() {
val scale = layer.contentScale
val w = (layer.width * scale).toInt().coerceAtLeast(0)
val h = (layer.height * scale).toInt().coerceAtLeast(0)
override fun LayerDrawScope.initCanvas() {
val w = scaledLayerWidth
val h = scaledLayerHeight
if (isSizeChanged(w, h) || surface == null) {
disposeCanvas()
if (w > 0 && h > 0) {
Expand All @@ -37,7 +37,7 @@ internal class DirectSoftwareContextHandler(layer: SkiaLayer) : ContextFreeConte
}
}

override fun flush() {
override fun flush(scope: LayerDrawScope) {
val surface = surface
if (surface != null) {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jetbrains.skiko.context

import org.jetbrains.skia.*
import org.jetbrains.skiko.LayerDrawScope
import org.jetbrains.skiko.Logger
import org.jetbrains.skiko.MetalAdapter
import org.jetbrains.skiko.RenderException
Expand All @@ -20,12 +21,11 @@ internal class MetalContextHandler(
private val device: MetalDevice,
private val adapter: MetalAdapter
) : ContextBasedContextHandler(layer, "Metal") {
override fun initCanvas() {
override fun LayerDrawScope.initCanvas() {
disposeCanvas()

val scale = layer.contentScale
val width = (layer.backedLayer.width * scale).toInt().coerceAtLeast(0)
val height = (layer.backedLayer.height * scale).toInt().coerceAtLeast(0)
val width = scaledLayerWidth
val height = scaledLayerHeight

if (width > 0 && height > 0) {
renderTarget = makeRenderTarget(width, height)
Expand All @@ -36,7 +36,7 @@ internal class MetalContextHandler(
SurfaceOrigin.TOP_LEFT,
SurfaceColorFormat.BGRA_8888,
ColorSpace.sRGB,
SurfaceProps(pixelGeometry = layer.pixelGeometry)
SurfaceProps(pixelGeometry = pixelGeometry)
) ?: throw RenderException("Cannot create surface")

canvas = surface!!.canvas
Expand All @@ -47,8 +47,8 @@ internal class MetalContextHandler(
}
}

override fun flush() {
super.flush()
override fun flush(scope: LayerDrawScope) {
super.flush(scope)
surface?.flushAndSubmit()
finishFrame()
Logger.debug { "MetalContextHandler finished drawing frame" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ internal class OpenGLContextHandler(layer: SkiaLayer) : ContextBasedContextHandl
return false
}

override fun initCanvas() {
val scale = layer.contentScale
val w = (layer.width * scale).toInt().coerceAtLeast(0)
val h = (layer.height * scale).toInt().coerceAtLeast(0)
override fun LayerDrawScope.initCanvas() {
val w = scaledLayerWidth
val h = scaledLayerHeight

if (isSizeChanged(w, h) || surface == null) {
disposeCanvas()
Expand All @@ -41,7 +40,7 @@ internal class OpenGLContextHandler(layer: SkiaLayer) : ContextBasedContextHandl
SurfaceOrigin.BOTTOM_LEFT,
SurfaceColorFormat.RGBA_8888,
ColorSpace.sRGB,
SurfaceProps(pixelGeometry = layer.pixelGeometry)
SurfaceProps(pixelGeometry = pixelGeometry)
) ?: throw RenderException("Cannot create surface")
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jetbrains.skiko.context

import org.jetbrains.skia.*
import org.jetbrains.skiko.LayerDrawScope
import org.jetbrains.skiko.OS
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.hostOs
Expand All @@ -22,25 +23,22 @@ internal class SoftwareContextHandler(layer: SkiaLayer) : ContextFreeContextHand
var imageData: ByteArray? = null
var raster: WritableRaster? = null

override fun initCanvas() {
override fun LayerDrawScope.initCanvas() {
disposeCanvas()

val scale = layer.contentScale
val w = (layer.width * scale).toInt().coerceAtLeast(0)
val h = (layer.height * scale).toInt().coerceAtLeast(0)
val w = scaledLayerWidth
val h = scaledLayerHeight

if (storage.width != w || storage.height != h) {
storage.allocPixelsFlags(ImageInfo.makeS32(w, h, ColorAlphaType.PREMUL), false)
}

canvas = Canvas(storage, SurfaceProps(pixelGeometry = layer.pixelGeometry))
canvas = Canvas(storage, SurfaceProps(pixelGeometry = pixelGeometry))
}

override fun flush() {
val scale = layer.contentScale
val w = (layer.width * scale).toInt().coerceAtLeast(0)
val h = (layer.height * scale).toInt().coerceAtLeast(0)

override fun flush(scope: LayerDrawScope) {
val w = scope.scaledLayerWidth
val h = scope.scaledLayerHeight

val bytes = storage.readPixels(storage.imageInfo, (w * 4), 0, 0)
if (bytes != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ internal abstract class AWTRedrawer(
layer.update(nanoTime)
}

protected inline fun inDrawScope(body: () -> Unit) {
protected inline fun inDrawScope(body: LayerDrawScope.() -> Unit) {
requireNotNull(deviceAnalytics) { "deviceAnalytics is not null. Call onDeviceChosen after choosing the drawing device" }
if (!isDisposed) {
val isFirstFrame = !isFirstFrameRendered
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal abstract class AbstractDirectSoftwareRedrawer(
frameDispatcher.scheduleFrame()
}

protected open fun draw() = inDrawScope(contextHandler::draw)
protected open fun draw() = inDrawScope { contextHandler.draw() }

override fun renderImmediately() {
update()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ internal class AngleRedrawer(
return
}
makeCurrent(device)
contextHandler.draw()
layer.inDrawScope {
contextHandler.draw()
}
swapBuffers(device, withVsync)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ internal class Direct3DRedrawer(
}
}

private fun drawAndSwap(withVsync: Boolean) = synchronized(drawLock) {
private fun LayerDrawScope.drawAndSwap(withVsync: Boolean) = synchronized(drawLock) {
if (isDisposed) {
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ internal class LinuxOpenGLRedrawer(
}

private fun draw() {
inDrawScope(contextHandler::draw)
inDrawScope { contextHandler.draw() }
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ internal class MetalRedrawer(
windowOcclusionStateChannel.trySend(isOccluded)
}

private fun performDraw() = synchronized(drawLock) {
private fun LayerDrawScope.performDraw() = synchronized(drawLock) {
if (!isDisposed) {
autoreleasepool {
contextHandler.draw()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal class SoftwareRedrawer(

if (layer.isShowing) {
update()
inDrawScope(contextHandler::draw)
inDrawScope { contextHandler.draw() }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ internal class WindowsOpenGLRedrawer(
}

private fun draw() {
inDrawScope(contextHandler::draw)
inDrawScope { contextHandler.draw() }
}

private fun makeCurrent() = makeCurrent(device, context)
Expand Down
4 changes: 2 additions & 2 deletions skiko/src/awtTest/kotlin/org/jetbrains/skiko/SkiaLayerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -578,9 +578,9 @@ class SkiaLayerTest {
object : BaseTestRedrawer(layer) {
private val contextHandler = object : JvmContextHandler(layer) {
override fun initContext() = false
override fun initCanvas() = Unit
override fun LayerDrawScope.initCanvas() = Unit
}
override fun renderImmediately() = layer.inDrawScope(contextHandler::draw)
override fun renderImmediately() = layer.inDrawScope { contextHandler.draw() }
}
}
}
Expand Down
Loading
Loading