Commit 1aecfc1a authored by Igor Demin's avatar Igor Demin

WindowsRedrawer, LinuxRedrawer. More accurate disposing

parent ef910e66
...@@ -96,6 +96,8 @@ open class SkiaLayer : HardwareLayer() { ...@@ -96,6 +96,8 @@ open class SkiaLayer : HardwareLayer() {
renderer?.onRender(canvas, pictureWidth, pictureHeight, nanoTime) renderer?.onRender(canvas, pictureWidth, pictureHeight, nanoTime)
check(!isDisposed)
synchronized(pictureLock) { synchronized(pictureLock) {
picture?.instance?.close() picture?.instance?.close()
val picture = pictureRecorder.finishRecordingAsPicture() val picture = pictureRecorder.finishRecordingAsPicture()
......
package org.jetbrains.skiko.redrawer package org.jetbrains.skiko.redrawer
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.swing.Swing import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext
import org.jetbrains.skiko.FrameDispatcher import org.jetbrains.skiko.FrameDispatcher
import org.jetbrains.skiko.HardwareLayer import org.jetbrains.skiko.HardwareLayer
import org.jetbrains.skiko.OpenGLApi import org.jetbrains.skiko.OpenGLApi
...@@ -16,6 +19,7 @@ internal class LinuxRedrawer( ...@@ -16,6 +19,7 @@ internal class LinuxRedrawer(
context context
} }
private var isDisposed = false private var isDisposed = false
private val job = Job()
override fun dispose() { override fun dispose() {
check(!isDisposed) check(!isDisposed)
...@@ -23,13 +27,25 @@ internal class LinuxRedrawer( ...@@ -23,13 +27,25 @@ internal class LinuxRedrawer(
it.destroyContext(context) it.destroyContext(context)
} }
isDisposed = true isDisposed = true
job.cancel()
} }
override fun needRedraw() { override fun needRedraw() {
check(!isDisposed)
toRedraw.add(this) toRedraw.add(this)
frameDispatcher.scheduleFrame() frameDispatcher.scheduleFrame()
} }
private suspend fun update(nanoTime: Long) {
withContext(job) {
layer.update(nanoTime)
}
}
private fun draw() {
layer.draw()
}
companion object { companion object {
private val toRedraw = mutableSetOf<LinuxRedrawer>() private val toRedraw = mutableSetOf<LinuxRedrawer>()
private val toRedrawCopy = mutableSetOf<LinuxRedrawer>() private val toRedrawCopy = mutableSetOf<LinuxRedrawer>()
...@@ -43,14 +59,18 @@ internal class LinuxRedrawer( ...@@ -43,14 +59,18 @@ internal class LinuxRedrawer(
val nanoTime = System.nanoTime() val nanoTime = System.nanoTime()
for (redrawer in toRedrawAlive) { for (redrawer in toRedrawAlive) {
redrawer.layer.update(nanoTime) try {
redrawer.update(nanoTime)
} catch (e: CancellationException) {
// continue
}
} }
val drawingSurfaces = toRedrawAlive.map { lockDrawingSurface(it.layer) }.toList() val drawingSurfaces = toRedrawAlive.map { lockDrawingSurface(it.layer) }.toList()
try { try {
toRedrawAlive.forEachIndexed { index, redrawer -> toRedrawAlive.forEachIndexed { index, redrawer ->
drawingSurfaces[index].makeCurrent(redrawer.context) drawingSurfaces[index].makeCurrent(redrawer.context)
redrawer.layer.draw() redrawer.draw()
} }
toRedrawAlive.forEachIndexed { index, _ -> toRedrawAlive.forEachIndexed { index, _ ->
......
...@@ -89,7 +89,6 @@ internal class MacOsRedrawer( ...@@ -89,7 +89,6 @@ internal class MacOsRedrawer(
override fun needRedraw() { override fun needRedraw() {
frameDispatcher.scheduleFrame() frameDispatcher.scheduleFrame()
} }
} }
private open class AWTGLLayer(private val containerPtr: Long) { private open class AWTGLLayer(private val containerPtr: Long) {
......
package org.jetbrains.skiko.redrawer package org.jetbrains.skiko.redrawer
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.swing.Swing import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.jetbrains.skiko.FrameDispatcher import org.jetbrains.skiko.FrameDispatcher
...@@ -13,6 +15,7 @@ internal class WindowsRedrawer( ...@@ -13,6 +15,7 @@ internal class WindowsRedrawer(
private val device = getDevice(layer) private val device = getDevice(layer)
private val context = createContext(device) private val context = createContext(device)
private var isDisposed = false private var isDisposed = false
private val job = Job()
init { init {
makeCurrent() makeCurrent()
...@@ -27,13 +30,25 @@ internal class WindowsRedrawer( ...@@ -27,13 +30,25 @@ internal class WindowsRedrawer(
check(!isDisposed) check(!isDisposed)
deleteContext(context) deleteContext(context)
isDisposed = true isDisposed = true
job.cancel()
} }
override fun needRedraw() { override fun needRedraw() {
check(!isDisposed)
toRedraw.add(this) toRedraw.add(this)
frameDispatcher.scheduleFrame() frameDispatcher.scheduleFrame()
} }
private suspend fun update(nanoTime: Long) {
withContext(job) {
layer.update(nanoTime)
}
}
private fun draw() {
layer.draw()
}
private fun makeCurrent() = makeCurrent(device, context) private fun makeCurrent() = makeCurrent(device, context)
private fun swapBuffers() = swapBuffers(device) private fun swapBuffers() = swapBuffers(device)
...@@ -50,12 +65,16 @@ internal class WindowsRedrawer( ...@@ -50,12 +65,16 @@ internal class WindowsRedrawer(
val nanoTime = System.nanoTime() val nanoTime = System.nanoTime()
for (redrawer in toRedrawAlive) { for (redrawer in toRedrawAlive) {
redrawer.layer.update(nanoTime) try {
redrawer.update(nanoTime)
} catch (e: CancellationException) {
// continue
}
} }
for (redrawer in toRedrawAlive) { for (redrawer in toRedrawAlive) {
redrawer.makeCurrent() redrawer.makeCurrent()
redrawer.layer.draw() redrawer.draw()
} }
for (redrawer in toRedrawAlive) { for (redrawer in toRedrawAlive) {
......
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