Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
skiko
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
liuqiang
skiko
Commits
0f45ab4e
Unverified
Commit
0f45ab4e
authored
Nov 08, 2021
by
Igor Demin
Committed by
GitHub
Nov 08, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Create ContextHandler inside Redrawer (#300)
parent
e7c30e9e
Changes
32
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
201 additions
and
261 deletions
+201
-261
App.kt
...le/src/jsMain/kotlin/org/jetbrains/skiko/sample/js/App.kt
+1
-1
RenderException.kt
.../commonMain/kotlin/org/jetbrains/skiko/RenderException.kt
+6
-0
RenderFactory.kt
...rc/commonMain/kotlin/org/jetbrains/skiko/RenderFactory.kt
+0
-2
ContextHandler.kt
...Main/kotlin/org/jetbrains/skiko/context/ContextHandler.kt
+31
-30
Redrawer.kt
...ommonMain/kotlin/org/jetbrains/skiko/redrawer/Redrawer.kt
+1
-0
SkiaLayer.ios.kt
...o/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt
+5
-12
MetalContextHandler.kt
...kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt
+1
-1
MetalRedrawer.ios.kt
.../kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt
+19
-6
RenderFactory.js.kt
...src/jsMain/kotlin/org/jetbrains/skiko/RenderFactory.js.kt
+0
-5
SkiaLayer.js.kt
skiko/src/jsMain/kotlin/org/jetbrains/skiko/SkiaLayer.js.kt
+1
-5
RenderExceptionsHandler.kt
...ain/kotlin/org/jetbrains/skiko/RenderExceptionsHandler.kt
+0
-6
RenderFactory.jvm.kt
...c/jvmMain/kotlin/org/jetbrains/skiko/RenderFactory.jvm.kt
+0
-15
SkiaLayer.jvm.kt
...o/src/jvmMain/kotlin/org/jetbrains/skiko/SkiaLayer.jvm.kt
+29
-54
AngleContextHandler.kt
...kotlin/org/jetbrains/skiko/context/AngleContextHandler.kt
+1
-1
Direct3DContextHandler.kt
...lin/org/jetbrains/skiko/context/Direct3DContextHandler.kt
+1
-5
DirectSoftwareContextHandler.kt
...g/jetbrains/skiko/context/DirectSoftwareContextHandler.kt
+1
-2
JvmContextHandler.kt
...n/kotlin/org/jetbrains/skiko/context/JvmContextHandler.kt
+5
-0
MetalContextHandler.kt
...kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt
+1
-1
OpenGLContextHandler.kt
...otlin/org/jetbrains/skiko/context/OpenGLContextHandler.kt
+1
-10
SoftwareContextHandler.kt
...lin/org/jetbrains/skiko/context/SoftwareContextHandler.kt
+2
-8
AbstractDirectSoftwareRedrawer.kt
...etbrains/skiko/redrawer/AbstractDirectSoftwareRedrawer.kt
+8
-3
AngleRedrawer.kt
...Main/kotlin/org/jetbrains/skiko/redrawer/AngleRedrawer.kt
+6
-1
Direct3DRedrawer.kt
...n/kotlin/org/jetbrains/skiko/redrawer/Direct3DRedrawer.kt
+7
-2
LinuxOpenGLRedrawer.kt
...otlin/org/jetbrains/skiko/redrawer/LinuxOpenGLRedrawer.kt
+6
-3
MetalRedrawer.kt
...Main/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.kt
+7
-1
SoftwareRedrawer.kt
...n/kotlin/org/jetbrains/skiko/redrawer/SoftwareRedrawer.kt
+8
-2
WindowsOpenGLRedrawer.kt
...lin/org/jetbrains/skiko/redrawer/WindowsOpenGLRedrawer.kt
+6
-3
SkiaWindowTest.kt
.../src/jvmTest/kotlin/org/jetbrains/skiko/SkiaWindowTest.kt
+15
-41
SkiaLayer.macos.kt
...c/macosMain/kotlin/org/jetbrains/skiko/SkiaLayer.macos.kt
+4
-24
OpenGLContextHandler.macos.kt
...org/jetbrains/skiko/context/OpenGLContextHandler.macos.kt
+15
-9
OpenGLRedrawer.macos.kt
...tlin/org/jetbrains/skiko/redrawer/OpenGLRedrawer.macos.kt
+13
-4
RenderFactory.native.kt
...veMain/kotlin/org/jetbrains/skiko/RenderFactory.native.kt
+0
-4
No files found.
samples/SkiaJsSample/src/jsMain/kotlin/org/jetbrains/skiko/sample/js/App.kt
View file @
0f45ab4e
...
...
@@ -35,7 +35,7 @@ fun main() {
}
skiaLayer
.
renderer
=
GenericSkikoApp
(
skiaLayer
,
app
)
skiaLayer
.
setCanvas
(
canvas
)
skiaLayer
.
draw
()
skiaLayer
.
needRe
draw
()
}
}
}
skiko/src/commonMain/kotlin/org/jetbrains/skiko/RenderException.kt
0 → 100644
View file @
0f45ab4e
package
org.jetbrains.skiko
internal
class
RenderException
(
message
:
String
?
=
null
,
cause
:
Throwable
?
=
null
)
:
RuntimeException
(
message
,
cause
)
skiko/src/commonMain/kotlin/org/jetbrains/skiko/RenderFactory.kt
View file @
0f45ab4e
package
org.jetbrains.skiko
import
org.jetbrains.skiko.context.*
import
org.jetbrains.skiko.redrawer.*
internal
interface
RenderFactory
{
fun
createContextHandler
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
):
ContextHandler
fun
createRedrawer
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
,
properties
:
SkiaLayerProperties
):
Redrawer
companion
object
{
...
...
skiko/src/commonMain/kotlin/org/jetbrains/skiko/context/ContextHandler.kt
View file @
0f45ab4e
...
...
@@ -5,41 +5,33 @@ import org.jetbrains.skia.Canvas
import
org.jetbrains.skia.DirectContext
import
org.jetbrains.skia.Picture
import
org.jetbrains.skia.Surface
import
org.jetbrains.skiko.GraphicsApi
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.hostArch
import
org.jetbrains.skiko.hostOs
import
org.jetbrains.skiko.OS
internal
abstract
class
ContextHandler
(
val
layer
:
SkiaLayer
)
{
open
val
clearColor
=
if
(
layer
.
transparency
||
hostOs
==
OS
.
MacOS
)
0
else
-
1
var
context
:
DirectContext
?
=
null
var
renderTarget
:
BackendRenderTarget
?
=
null
var
surface
:
Surface
?
=
null
var
canvas
:
Canvas
?
=
null
abstract
fun
initContext
():
Boolean
abstract
fun
initCanvas
()
fun
clearCanvas
()
{
val
color
=
if
(
layer
.
fullscreen
&&
hostOs
!=
OS
.
MacOS
)
-
1
else
clearColor
canvas
?.
clear
(
color
)
}
open
fun
drawOnCanvas
(
picture
:
Picture
)
{
canvas
?.
drawPicture
(
picture
)
}
open
fun
flush
()
{
import
org.jetbrains.skiko.*
import
org.jetbrains.skiko.RenderException
internal
abstract
class
ContextHandler
(
protected
val
layer
:
SkiaLayer
,
private
val
drawContent
:
Canvas
.()
->
Unit
)
{
// TODO can we simplify clearColor logic? is there a reason why SoftwareContextHandler has opposite logic?
protected
open
val
clearColor
=
if
(
layer
.
transparency
||
hostOs
==
OS
.
MacOS
)
0
else
-
1
protected
var
context
:
DirectContext
?
=
null
protected
var
renderTarget
:
BackendRenderTarget
?
=
null
protected
var
surface
:
Surface
?
=
null
protected
var
canvas
:
Canvas
?
=
null
protected
abstract
fun
initContext
():
Boolean
protected
abstract
fun
initCanvas
()
protected
open
fun
flush
()
{
context
?.
flush
()
}
open
fun
dispose
()
{
disposeCanvas
()
destroyContext
()
context
?.
close
()
}
open
fun
disposeCanvas
()
{
protected
open
fun
disposeCanvas
()
{
surface
?.
close
()
renderTarget
?.
close
()
}
...
...
@@ -49,7 +41,16 @@ internal abstract class ContextHandler(val layer: SkiaLayer) {
"OS: ${hostOs.id} ${hostArch.id}\n"
}
protected
open
fun
destroyContext
()
{
context
?.
close
()
// throws RenderException if initialization of graphic context was not successful
fun
draw
()
{
if
(!
initContext
())
{
throw
RenderException
(
"Cannot init graphic context"
)
}
initCanvas
()
canvas
?.
apply
{
clear
(
if
(
layer
.
fullscreen
&&
hostOs
!=
OS
.
MacOS
)
-
1
else
clearColor
)
drawContent
()
}
flush
()
}
}
skiko/src/commonMain/kotlin/org/jetbrains/skiko/redrawer/Redrawer.kt
View file @
0f45ab4e
...
...
@@ -5,4 +5,5 @@ internal interface Redrawer {
fun
needRedraw
()
fun
redrawImmediately
()
fun
syncSize
()
=
Unit
val
renderInfo
:
String
}
\ No newline at end of file
skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt
View file @
0f45ab4e
...
...
@@ -2,6 +2,7 @@ package org.jetbrains.skiko
import
kotlinx.cinterop.ObjCAction
import
kotlinx.cinterop.useContents
import
org.jetbrains.skia.Canvas
import
org.jetbrains.skia.PictureRecorder
import
org.jetbrains.skia.Rect
import
org.jetbrains.skiko.context.MetalContextHandler
...
...
@@ -121,18 +122,10 @@ actual open class SkiaLayer(
this
.
picture
=
PictureHolder
(
picture
,
pictureWidth
.
toInt
(),
pictureHeight
.
toInt
())
}
fun
draw
()
{
contextHandler
?.
apply
{
if
(!
initContext
())
{
error
(
"initContext() failure"
)
}
initCanvas
()
clearCanvas
()
val
picture
=
picture
if
(
picture
!=
null
)
{
drawOnCanvas
(
picture
.
instance
)
}
flush
()
internal
fun
draw
(
canvas
:
Canvas
)
{
check
(!
isDisposed
)
{
"SkiaLayer is disposed"
}
picture
?.
also
{
canvas
.
drawPicture
(
it
.
instance
)
}
}
}
...
...
skiko/src/iosMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt
View file @
0f45ab4e
...
...
@@ -8,7 +8,7 @@ import org.jetbrains.skia.SurfaceOrigin
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.redrawer.MetalRedrawer
internal
class
MetalContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
)
{
internal
class
MetalContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
,
layer
::
draw
)
{
val
metalRedrawer
:
MetalRedrawer
get
()
=
layer
.
redrawer
!!
...
...
skiko/src/iosMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt
View file @
0f45ab4e
...
...
@@ -8,6 +8,8 @@ import kotlinx.cinterop.useContents
import
org.jetbrains.skia.BackendRenderTarget
import
org.jetbrains.skia.DirectContext
import
org.jetbrains.skiko.*
import
org.jetbrains.skiko.context.ContextHandler
import
org.jetbrains.skiko.context.MetalContextHandler
import
platform.CoreGraphics.CGColorCreate
import
platform.CoreGraphics.CGColorSpaceCreateDeviceRGB
import
platform.CoreGraphics.CGContextRef
...
...
@@ -24,6 +26,9 @@ internal class MetalRedrawer(
private
val
layer
:
SkiaLayer
,
private
val
properties
:
SkiaLayerProperties
)
:
Redrawer
{
private
val
contextHandler
=
MetalContextHandler
(
layer
)
override
val
renderInfo
:
String
get
()
=
contextHandler
.
rendererInfo
()
private
var
isDisposed
=
false
internal
val
device
=
MTLCreateSystemDefaultDevice
()
!!
private
val
queue
=
device
.
newCommandQueue
()
!!
...
...
@@ -31,7 +36,7 @@ internal class MetalRedrawer(
private
val
metalLayer
=
MetalLayer
()
init
{
metalLayer
.
init
(
this
.
layer
,
device
)
metalLayer
.
init
(
this
.
layer
,
contextHandler
,
device
)
}
private
val
frameDispatcher
=
FrameDispatcher
(
SkikoDispatchers
.
Main
)
{
...
...
@@ -51,6 +56,7 @@ internal class MetalRedrawer(
override
fun
dispose
()
{
if
(!
isDisposed
)
{
frameDispatcher
.
cancel
()
contextHandler
.
dispose
()
metalLayer
.
dispose
()
isDisposed
=
true
}
...
...
@@ -63,7 +69,7 @@ internal class MetalRedrawer(
size
.
width
to
size
.
height
}
metalLayer
.
frame
=
osView
.
frame
metalLayer
.
init
(
layer
,
device
)
metalLayer
.
init
(
layer
,
contextHandler
,
device
)
metalLayer
.
drawableSize
=
CGSizeMake
(
w
*
metalLayer
.
contentsScale
,
h
*
metalLayer
.
contentsScale
)
}
...
...
@@ -82,7 +88,7 @@ internal class MetalRedrawer(
// TODO: maybe make flush async as in JVM version.
autoreleasepool
{
if
(!
isDisposed
)
{
lay
er
.
draw
()
contextHandl
er
.
draw
()
}
}
}
...
...
@@ -100,15 +106,22 @@ internal class MetalRedrawer(
}
}
class
MetalLayer
:
CAMetalLayer
{
internal
class
MetalLayer
:
CAMetalLayer
{
private
lateinit
var
skiaLayer
:
SkiaLayer
private
lateinit
var
contextHandler
:
ContextHandler
@OverrideInit
constructor
():
super
()
@OverrideInit
constructor
(
layer
:
Any
):
super
(
layer
)
fun
init
(
skiaLayer
:
SkiaLayer
,
theDevice
:
MTLDeviceProtocol
)
{
fun
init
(
skiaLayer
:
SkiaLayer
,
contextHandler
:
ContextHandler
,
theDevice
:
MTLDeviceProtocol
)
{
this
.
skiaLayer
=
skiaLayer
this
.
contextHandler
=
contextHandler
this
.
setNeedsDisplayOnBoundsChange
(
true
)
this
.
removeAllAnimations
()
// TODO: looks like a bug in K/N interop.
...
...
@@ -133,7 +146,7 @@ class MetalLayer : CAMetalLayer {
override
fun
drawInContext
(
ctx
:
CGContextRef
?)
{
skiaLayer
.
update
(
getTimeNanos
())
skiaLay
er
.
draw
()
contextHandl
er
.
draw
()
super
.
drawInContext
(
ctx
)
}
}
skiko/src/jsMain/kotlin/org/jetbrains/skiko/RenderFactory.js.kt
View file @
0f45ab4e
package
org.jetbrains.skiko
import
org.jetbrains.skiko.context.*
import
org.jetbrains.skiko.redrawer.*
internal
actual
fun
makeDefaultRenderFactory
():
RenderFactory
{
return
object
:
RenderFactory
{
override
fun
createContextHandler
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
):
ContextHandler
{
TODO
()
}
override
fun
createRedrawer
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
,
...
...
skiko/src/jsMain/kotlin/org/jetbrains/skiko/SkiaLayer.js.kt
View file @
0f45ab4e
...
...
@@ -25,7 +25,7 @@ actual open class SkiaLayer(properties: SkiaLayerProperties = makeDefaultSkiaLay
}
actual
fun
needRedraw
()
{
draw
()
state
?.
draw
()
}
actual
var
skikoView
:
SkikoView
?
=
null
...
...
@@ -99,10 +99,6 @@ actual open class SkiaLayer(properties: SkiaLayerProperties = makeDefaultSkiaLay
))
})
}
fun
draw
()
{
state
?.
draw
()
}
}
actual
typealias
SkikoPlatformInputEvent
=
InputEvent
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/RenderExceptionsHandler.kt
View file @
0f45ab4e
package
org.jetbrains.skiko
import
java.io.File
import
java.lang.RuntimeException
import
java.text.SimpleDateFormat
import
java.util.Date
import
kotlin.jvm.JvmStatic
internal
class
RenderException
(
message
:
String
?
=
null
,
cause
:
Exception
?
=
null
)
:
RuntimeException
(
message
,
cause
)
internal
class
RenderExceptionsHandler
{
companion
object
{
private
var
output
:
File
?
=
null
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/RenderFactory.jvm.kt
View file @
0f45ab4e
package
org.jetbrains.skiko
import
org.jetbrains.skiko.context.*
import
org.jetbrains.skiko.redrawer.*
internal
actual
fun
makeDefaultRenderFactory
():
RenderFactory
{
return
object
:
RenderFactory
{
override
fun
createContextHandler
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
):
ContextHandler
{
return
when
(
renderApi
)
{
GraphicsApi
.
DIRECT_SOFTWARE
->
return
when
(
hostOs
)
{
OS
.
Windows
,
OS
.
Linux
->
DirectSoftwareContextHandler
(
layer
)
else
->
SoftwareContextHandler
(
layer
)
}
GraphicsApi
.
SOFTWARE
->
SoftwareContextHandler
(
layer
)
GraphicsApi
.
OPENGL
->
OpenGLContextHandler
(
layer
)
GraphicsApi
.
DIRECT3D
->
Direct3DContextHandler
(
layer
)
GraphicsApi
.
METAL
->
MetalContextHandler
(
layer
)
else
->
TODO
(
"Unsupported yet."
)
}
}
override
fun
createRedrawer
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
,
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/SkiaLayer.jvm.kt
View file @
0f45ab4e
package
org.jetbrains.skiko
import
org.jetbrains.skia.Canvas
import
org.jetbrains.skia.Bitmap
import
org.jetbrains.skia.ColorAlphaType
import
org.jetbrains.skia.ColorInfo
import
org.jetbrains.skia.ColorType
import
org.jetbrains.skia.ColorSpace
import
org.jetbrains.skia.ClipMode
import
org.jetbrains.skia.ImageInfo
import
org.jetbrains.skia.PictureRecorder
import
org.jetbrains.skia.Rect
import
org.jetbrains.skia.*
import
org.jetbrains.skiko.context.ContextHandler
import
org.jetbrains.skiko.redrawer.Redrawer
import
java.awt.Color
...
...
@@ -209,7 +200,6 @@ actual open class SkiaLayer internal constructor(
@Volatile
private
var
isDisposed
=
false
internal
var
redrawer
:
Redrawer
?
=
null
internal
var
contextHandler
:
ContextHandler
?
=
null
private
val
fallbackRenderApiQueue
=
SkikoProperties
.
fallbackRenderApiQueue
.
toMutableList
()
private
var
renderApi_
=
fallbackRenderApiQueue
[
0
]
actual
var
renderApi
:
GraphicsApi
...
...
@@ -219,10 +209,10 @@ actual open class SkiaLayer internal constructor(
notifyChange
(
PropertyKind
.
Renderer
)
}
val
renderInfo
:
String
get
()
=
if
(
contextHandler
?.
context
==
null
)
"
ContextHandler hasn't been initialized yet.
"
get
()
=
if
(
redrawer
==
null
)
"
SkiaLayer isn't initialized yet
"
else
contextHandler
!!
.
rendererInfo
()
redrawer
!!
.
renderInfo
@Volatile
private
var
picture
:
PictureHolder
?
=
null
...
...
@@ -235,9 +225,7 @@ actual open class SkiaLayer internal constructor(
thrown
=
false
try
{
renderApi
=
fallbackRenderApiQueue
.
removeAt
(
0
)
contextHandler
?.
dispose
()
redrawer
?.
dispose
()
contextHandler
=
renderFactory
.
createContextHandler
(
this
,
renderApi
)
redrawer
=
renderFactory
.
createRedrawer
(
this
,
renderApi
,
properties
)
redrawer
?.
syncSize
()
}
catch
(
e
:
RenderException
)
{
...
...
@@ -251,7 +239,7 @@ actual open class SkiaLayer internal constructor(
}
}
pr
otected
open
fun
init
(
recreation
:
Boolean
=
false
)
{
pr
ivate
fun
init
(
recreation
:
Boolean
=
false
)
{
isDisposed
=
false
backedLayer
.
init
()
pictureRecorder
=
PictureRecorder
()
...
...
@@ -281,8 +269,6 @@ actual open class SkiaLayer internal constructor(
// we should dispose redrawer first (to cancel `draw` in rendering thread)
redrawer
?.
dispose
()
redrawer
=
null
contextHandler
?.
dispose
()
contextHandler
=
null
picture
?.
instance
?.
close
()
picture
=
null
pictureRecorder
?.
close
()
...
...
@@ -413,6 +399,7 @@ actual open class SkiaLayer internal constructor(
check
(
isEventDispatchThread
())
{
"Method should be called from AWT event dispatch thread"
}
check
(!
isDisposed
)
{
"SkiaLayer is disposed"
}
FrameWatcher
.
nextFrame
()
fpsCounter
?.
tick
()
val
pictureWidth
=
(
width
*
contentScale
).
toInt
().
coerceAtLeast
(
0
)
...
...
@@ -459,49 +446,37 @@ actual open class SkiaLayer internal constructor(
}
}
// can be called from non-swing thread
// throws exception if initialization of graphic context was not successful
internal
fun
draw
()
{
contextHandler
?.
apply
{
if
(!
initContext
())
{
throw
RenderException
(
"Cannot init graphic context"
)
}
initCanvas
()
internal
fun
draw
(
canvas
:
Canvas
)
{
check
(!
isDisposed
)
{
"SkiaLayer is disposed"
}
lockPicture
{
canvas
.
drawPicture
(
it
.
instance
)
}
}
check
(!
isDisposed
)
{
"SkiaLayer is disposed"
}
contextHandler
?.
apply
{
clearCanvas
()
synchronized
(
pictureLock
)
{
val
picture
=
picture
if
(
picture
!=
null
)
{
drawOnCanvas
(
picture
.
instance
)
}
private
fun
<
T
:
Any
>
lockPicture
(
action
:
(
PictureHolder
)
->
T
):
T
?
{
return
synchronized
(
pictureLock
)
{
val
picture
=
picture
if
(
picture
!=
null
)
{
action
(
picture
)
}
else
{
null
}
flush
()
}
FrameWatcher
.
nextFrame
()
}
// Captures current layer as bitmap.
fun
screenshot
():
Bitmap
?
{
return
contextHandler
?.
let
{
synchronized
(
pictureLock
)
{
val
picture
=
picture
if
(
picture
!=
null
)
{
val
store
=
Bitmap
()
val
ci
=
ColorInfo
(
ColorType
.
BGRA_8888
,
ColorAlphaType
.
OPAQUE
,
ColorSpace
.
sRGB
)
store
.
setImageInfo
(
ImageInfo
(
ci
,
picture
.
width
,
picture
.
height
))
store
.
allocN32Pixels
(
picture
.
width
,
picture
.
height
)
val
canvas
=
Canvas
(
store
)
canvas
.
drawPicture
(
picture
.
instance
)
store
.
setImmutable
()
store
}
else
{
null
}
}
check
(!
isDisposed
)
{
"SkiaLayer is disposed"
}
return
lockPicture
{
picture
->
val
store
=
Bitmap
()
val
ci
=
ColorInfo
(
ColorType
.
BGRA_8888
,
ColorAlphaType
.
OPAQUE
,
ColorSpace
.
sRGB
)
store
.
setImageInfo
(
ImageInfo
(
ci
,
picture
.
width
,
picture
.
height
))
store
.
allocN32Pixels
(
picture
.
width
,
picture
.
height
)
val
canvas
=
Canvas
(
store
)
canvas
.
drawPicture
(
picture
.
instance
)
store
.
setImmutable
()
store
}
}
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/AngleContextHandler.kt
View file @
0f45ab4e
...
...
@@ -8,7 +8,7 @@ import org.jetbrains.skiko.RenderException
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.redrawer.AngleRedrawer
internal
class
AngleContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
)
{
internal
class
AngleContextHandler
(
layer
:
SkiaLayer
)
:
Jvm
ContextHandler
(
layer
)
{
val
angleRedrawer
:
AngleRedrawer
get
()
=
layer
.
redrawer
!!
as
AngleRedrawer
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/Direct3DContextHandler.kt
View file @
0f45ab4e
...
...
@@ -7,7 +7,7 @@ import org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.redrawer.Direct3DRedrawer
import
java.lang.ref.Reference
internal
class
Direct3DContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
)
{
internal
class
Direct3DContextHandler
(
layer
:
SkiaLayer
)
:
Jvm
ContextHandler
(
layer
)
{
private
val
bufferCount
=
2
private
var
surfaces
:
Array
<
Surface
?>
=
arrayOfNulls
(
bufferCount
)
...
...
@@ -85,10 +85,6 @@ internal class Direct3DContextHandler(layer: SkiaLayer) : ContextHandler(layer)
}
}
override
fun
destroyContext
()
{
context
?.
close
()
}
override
fun
disposeCanvas
()
{
for
(
bufferIndex
in
0
until
bufferCount
)
{
surfaces
[
bufferIndex
]
?.
close
()
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/DirectSoftwareContextHandler.kt
View file @
0f45ab4e
...
...
@@ -5,9 +5,8 @@ import org.jetbrains.skia.impl.Native
import
org.jetbrains.skia.impl.getPtr
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.redrawer.AbstractDirectSoftwareRedrawer
import
java.lang.ref.Reference
internal
class
DirectSoftwareContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
)
{
internal
class
DirectSoftwareContextHandler
(
layer
:
SkiaLayer
)
:
Jvm
ContextHandler
(
layer
)
{
var
isInited
=
false
val
softwareRedrawer
:
AbstractDirectSoftwareRedrawer
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/JvmContextHandler.kt
0 → 100644
View file @
0f45ab4e
package
org.jetbrains.skiko.context
import
org.jetbrains.skiko.SkiaLayer
internal
abstract
class
JvmContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
,
layer
::
draw
)
\ No newline at end of file
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt
View file @
0f45ab4e
...
...
@@ -7,7 +7,7 @@ import org.jetbrains.skia.SurfaceOrigin
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.redrawer.MetalRedrawer
internal
class
MetalContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
)
{
internal
class
MetalContextHandler
(
layer
:
SkiaLayer
)
:
Jvm
ContextHandler
(
layer
)
{
val
metalRedrawer
:
MetalRedrawer
get
()
=
layer
.
redrawer
!!
as
MetalRedrawer
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.kt
View file @
0f45ab4e
...
...
@@ -10,7 +10,7 @@ import org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.makeGLContext
import
org.jetbrains.skiko.makeGLRenderTarget
internal
class
OpenGLContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
)
{
internal
class
OpenGLContextHandler
(
layer
:
SkiaLayer
)
:
Jvm
ContextHandler
(
layer
)
{
override
fun
initContext
():
Boolean
{
try
{
if
(
context
==
null
)
{
...
...
@@ -73,13 +73,4 @@ internal class OpenGLContextHandler(layer: SkiaLayer) : ContextHandler(layer) {
"Model: ${gl.glGetString(gl.GL_RENDERER)}\n"
+
"Total VRAM: ${gl.glGetIntegerv(gl.GL_TOTAL_MEMORY) / 1024} MB\n"
}
fun
disposeInOpenGLContext
()
{
super
.
dispose
()
}
// dispose should be called only in the OpenGL context.
// TODO remove in https://github.com/JetBrains/skiko/pull/300
override
open
fun
dispose
()
{
}
}
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/context/SoftwareContextHandler.kt
View file @
0f45ab4e
...
...
@@ -18,7 +18,7 @@ import java.awt.image.DataBufferByte
import
java.awt.image.Raster
import
java.awt.image.WritableRaster
internal
class
SoftwareContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
)
{
internal
class
SoftwareContextHandler
(
layer
:
SkiaLayer
)
:
Jvm
ContextHandler
(
layer
)
{
override
val
clearColor
=
if
(
layer
.
transparency
&&
hostOs
==
OS
.
MacOS
)
0
else
-
1
val
colorModel
=
ComponentColorModel
(
...
...
@@ -59,9 +59,7 @@ internal class SoftwareContextHandler(layer: SkiaLayer) : ContextHandler(layer)
canvas
=
Canvas
(
storage
)
}
override
fun
drawOnCanvas
(
picture
:
Picture
)
{
super
.
drawOnCanvas
(
picture
)
override
fun
flush
()
{
val
scale
=
layer
.
contentScale
val
w
=
(
layer
.
width
*
scale
).
toInt
().
coerceAtLeast
(
0
)
val
h
=
(
layer
.
height
*
scale
).
toInt
().
coerceAtLeast
(
0
)
...
...
@@ -87,8 +85,4 @@ internal class SoftwareContextHandler(layer: SkiaLayer) : ContextHandler(layer)
graphics
?.
drawImage
(
image
!!
,
0
,
0
,
layer
.
width
,
layer
.
height
,
null
)
}
}
override
fun
flush
()
{
// Raster does not need to flush canvas
}
}
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/AbstractDirectSoftwareRedrawer.kt
View file @
0f45ab4e
...
...
@@ -8,11 +8,15 @@ import org.jetbrains.skiko.FrameLimiter
import
org.jetbrains.skiko.RenderException
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.SkiaLayerProperties
import
org.jetbrains.skiko.context.DirectSoftwareContextHandler
internal
abstract
class
AbstractDirectSoftwareRedrawer
(
private
val
layer
:
SkiaLayer
,
private
val
properties
:
SkiaLayerProperties
)
:
Redrawer
{
private
val
contextHandler
=
DirectSoftwareContextHandler
(
layer
)
override
val
renderInfo
:
String
get
()
=
contextHandler
.
rendererInfo
()
private
val
frameJob
=
Job
()
private
val
frameLimiter
=
FrameLimiter
(
CoroutineScope
(
Dispatchers
.
IO
+
frameJob
),
layer
.
backedLayer
)
private
val
frameDispatcher
=
FrameDispatcher
(
Dispatchers
.
Swing
)
{
...
...
@@ -22,7 +26,7 @@ internal abstract class AbstractDirectSoftwareRedrawer(
if
(
layer
.
isShowing
)
{
layer
.
update
(
System
.
nanoTime
())
layer
.
inDrawScope
(
lay
er
::
draw
)
layer
.
inDrawScope
(
contextHandl
er
::
draw
)
}
}
...
...
@@ -34,7 +38,7 @@ internal abstract class AbstractDirectSoftwareRedrawer(
override
fun
redrawImmediately
()
{
layer
.
update
(
System
.
nanoTime
())
layer
.
inDrawScope
(
lay
er
::
draw
)
layer
.
inDrawScope
(
contextHandl
er
::
draw
)
}
open
fun
resize
(
width
:
Int
,
height
:
Int
)
=
resize
(
device
,
width
,
height
)
...
...
@@ -47,8 +51,9 @@ internal abstract class AbstractDirectSoftwareRedrawer(
}
open
fun
finishFrame
()
=
finishFrame
(
device
)
override
fun
dispose
()
{
disposeDevice
(
device
)
frameDispatcher
.
cancel
()
contextHandler
.
dispose
()
disposeDevice
(
device
)
runBlocking
{
frameJob
.
cancelAndJoin
()
}
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/AngleRedrawer.kt
View file @
0f45ab4e
...
...
@@ -7,11 +7,15 @@ import org.jetbrains.skia.DirectContext
import
org.jetbrains.skiko.FrameDispatcher
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.SkiaLayerProperties
import
org.jetbrains.skiko.context.AngleContextHandler
import
org.jetbrains.skiko.context.DirectSoftwareContextHandler
internal
class
AngleRedrawer
(
private
val
layer
:
SkiaLayer
,
private
val
properties
:
SkiaLayerProperties
)
:
Redrawer
{
private
val
contextHandler
=
AngleContextHandler
(
layer
)
override
val
renderInfo
:
String
get
()
=
contextHandler
.
rendererInfo
()
private
var
isDisposed
=
false
private
var
device
:
Long
=
0
...
...
@@ -25,6 +29,7 @@ internal class AngleRedrawer(
override
fun
dispose
()
{
frameDispatcher
.
cancel
()
contextHandler
.
dispose
()
disposeDevice
(
device
)
isDisposed
=
true
}
...
...
@@ -45,7 +50,7 @@ internal class AngleRedrawer(
}
private
fun
draw
()
{
lay
er
.
draw
()
contextHandl
er
.
draw
()
}
fun
createDevice
():
Long
{
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/Direct3DRedrawer.kt
View file @
0f45ab4e
...
...
@@ -6,11 +6,15 @@ import kotlinx.coroutines.withContext
import
org.jetbrains.skia.DirectContext
import
org.jetbrains.skia.Surface
import
org.jetbrains.skiko.*
import
org.jetbrains.skiko.context.AngleContextHandler
import
org.jetbrains.skiko.context.Direct3DContextHandler
internal
class
Direct3DRedrawer
(
private
val
layer
:
SkiaLayer
,
private
val
properties
:
SkiaLayerProperties
)
:
Redrawer
{
private
val
contextHandler
=
Direct3DContextHandler
(
layer
)
override
val
renderInfo
:
String
get
()
=
contextHandler
.
rendererInfo
()
private
var
isDisposed
=
false
private
var
drawLock
=
Any
()
...
...
@@ -29,8 +33,9 @@ internal class Direct3DRedrawer(
}
override
fun
dispose
()
=
synchronized
(
drawLock
)
{
disposeDevice
(
device
)
frameDispatcher
.
cancel
()
contextHandler
.
dispose
()
disposeDevice
(
device
)
isDisposed
=
true
}
...
...
@@ -61,7 +66,7 @@ internal class Direct3DRedrawer(
private
fun
drawAndSwap
(
withVsync
:
Boolean
)
=
synchronized
(
drawLock
)
{
if
(!
isDisposed
)
{
lay
er
.
draw
()
contextHandl
er
.
draw
()
swap
(
device
,
withVsync
)
}
}
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/LinuxOpenGLRedrawer.kt
View file @
0f45ab4e
...
...
@@ -3,12 +3,16 @@ package org.jetbrains.skiko.redrawer
import
kotlinx.coroutines.*
import
kotlinx.coroutines.swing.Swing
import
org.jetbrains.skiko.*
import
org.jetbrains.skiko.context.Direct3DContextHandler
import
org.jetbrains.skiko.context.OpenGLContextHandler
internal
class
LinuxOpenGLRedrawer
(
private
val
layer
:
SkiaLayer
,
private
val
properties
:
SkiaLayerProperties
)
:
Redrawer
{
private
val
contextHandler
=
OpenGLContextHandler
(
layer
)
override
val
renderInfo
:
String
get
()
=
contextHandler
.
rendererInfo
()
private
var
isDisposed
=
false
private
var
context
=
0L
private
val
swapInterval
=
if
(
properties
.
isVsyncEnabled
)
1
else
0
...
...
@@ -52,8 +56,7 @@ internal class LinuxOpenGLRedrawer(
// makeCurrent is mandatory to destroy context, otherwise, OpenGL will destroy wrong context (from another window).
// see the official example: https://www.khronos.org/opengl/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)
it
.
makeCurrent
(
context
)
// TODO remove in https://github.com/JetBrains/skiko/pull/300
(
layer
.
contextHandler
as
OpenGLContextHandler
).
disposeInOpenGLContext
()
contextHandler
.
dispose
()
it
.
destroyContext
(
context
)
}
runBlocking
{
...
...
@@ -84,7 +87,7 @@ internal class LinuxOpenGLRedrawer(
}
private
fun
draw
()
{
layer
.
inDrawScope
(
lay
er
::
draw
)
layer
.
inDrawScope
(
contextHandl
er
::
draw
)
}
companion
object
{
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.kt
View file @
0f45ab4e
...
...
@@ -8,12 +8,17 @@ import kotlinx.coroutines.withContext
import
org.jetbrains.skia.BackendRenderTarget
import
org.jetbrains.skia.DirectContext
import
org.jetbrains.skiko.*
import
org.jetbrains.skiko.context.MetalContextHandler
import
org.jetbrains.skiko.context.OpenGLContextHandler
import
javax.swing.SwingUtilities.*
internal
class
MetalRedrawer
(
private
val
layer
:
SkiaLayer
,
private
val
properties
:
SkiaLayerProperties
)
:
Redrawer
{
private
val
contextHandler
=
MetalContextHandler
(
layer
)
override
val
renderInfo
:
String
get
()
=
contextHandler
.
rendererInfo
()
companion
object
{
init
{
Library
.
load
()
...
...
@@ -39,6 +44,7 @@ internal class MetalRedrawer(
override
fun
dispose
()
=
synchronized
(
drawLock
)
{
frameDispatcher
.
cancel
()
contextHandler
.
dispose
()
disposeDevice
(
device
)
isDisposed
=
true
}
...
...
@@ -90,7 +96,7 @@ internal class MetalRedrawer(
if
(!
isDisposed
)
{
val
handle
=
startRendering
()
try
{
lay
er
.
draw
()
contextHandl
er
.
draw
()
}
finally
{
endRendering
(
handle
)
}
...
...
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/SoftwareRedrawer.kt
View file @
0f45ab4e
...
...
@@ -6,11 +6,16 @@ import org.jetbrains.skiko.FrameDispatcher
import
org.jetbrains.skiko.FrameLimiter
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.SkiaLayerProperties
import
org.jetbrains.skiko.context.MetalContextHandler
import
org.jetbrains.skiko.context.SoftwareContextHandler
internal
class
SoftwareRedrawer
(
private
val
layer
:
SkiaLayer
,
private
val
properties
:
SkiaLayerProperties
)
:
Redrawer
{
private
val
contextHandler
=
SoftwareContextHandler
(
layer
)
override
val
renderInfo
:
String
get
()
=
contextHandler
.
rendererInfo
()
private
val
frameJob
=
Job
()
private
val
frameLimiter
=
FrameLimiter
(
CoroutineScope
(
Dispatchers
.
IO
+
frameJob
),
layer
.
backedLayer
)
...
...
@@ -21,12 +26,13 @@ internal class SoftwareRedrawer(
if
(
layer
.
isShowing
)
{
layer
.
update
(
System
.
nanoTime
())
layer
.
inDrawScope
(
lay
er
::
draw
)
layer
.
inDrawScope
(
contextHandl
er
::
draw
)
}
}
override
fun
dispose
()
{
frameDispatcher
.
cancel
()
contextHandler
.
dispose
()
runBlocking
{
frameJob
.
cancelAndJoin
()
}
...
...
@@ -38,6 +44,6 @@ internal class SoftwareRedrawer(
override
fun
redrawImmediately
()
{
layer
.
update
(
System
.
nanoTime
())
layer
.
inDrawScope
(
lay
er
::
draw
)
layer
.
inDrawScope
(
contextHandl
er
::
draw
)
}
}
\ No newline at end of file
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/WindowsOpenGLRedrawer.kt
View file @
0f45ab4e
...
...
@@ -6,11 +6,15 @@ import kotlinx.coroutines.swing.Swing
import
kotlinx.coroutines.withContext
import
org.jetbrains.skiko.*
import
org.jetbrains.skiko.context.OpenGLContextHandler
import
org.jetbrains.skiko.context.SoftwareContextHandler
internal
class
WindowsOpenGLRedrawer
(
private
val
layer
:
SkiaLayer
,
private
val
properties
:
SkiaLayerProperties
)
:
Redrawer
{
private
val
contextHandler
=
OpenGLContextHandler
(
layer
)
override
val
renderInfo
:
String
get
()
=
contextHandler
.
rendererInfo
()
private
val
device
=
layer
.
backedLayer
.
useDrawingSurfacePlatformInfo
(
::
getDevice
)
private
val
context
=
createContext
(
device
,
layer
.
contentHandle
,
layer
.
transparency
).
also
{
if
(
it
==
0L
)
{
...
...
@@ -35,8 +39,7 @@ internal class WindowsOpenGLRedrawer(
override
fun
dispose
()
{
check
(!
isDisposed
)
{
"WindowsOpenGLRedrawer is disposed"
}
makeCurrent
()
// TODO remove in https://github.com/JetBrains/skiko/pull/300
(
layer
.
contextHandler
as
OpenGLContextHandler
).
disposeInOpenGLContext
()
contextHandler
.
dispose
()
deleteContext
(
context
)
isDisposed
=
true
}
...
...
@@ -61,7 +64,7 @@ internal class WindowsOpenGLRedrawer(
}
private
fun
draw
()
{
layer
.
inDrawScope
(
lay
er
::
draw
)
layer
.
inDrawScope
(
contextHandl
er
::
draw
)
}
private
fun
makeCurrent
()
=
makeCurrent
(
device
,
context
)
...
...
skiko/src/jvmTest/kotlin/org/jetbrains/skiko/SkiaWindowTest.kt
View file @
0f45ab4e
...
...
@@ -11,11 +11,10 @@ import org.jetbrains.skia.paragraph.FontCollection
import
org.jetbrains.skia.paragraph.ParagraphBuilder
import
org.jetbrains.skia.paragraph.ParagraphStyle
import
org.jetbrains.skia.paragraph.TextStyle
import
org.jetbrains.skiko.context.ContextHandler
import
org.jetbrains.skiko.context.
Jvm
ContextHandler
import
org.jetbrains.skiko.redrawer.Redrawer
import
org.jetbrains.skiko.util.ScreenshotTestRule
import
org.jetbrains.skiko.util.swingTest
import
org.junit.Assert
import
org.junit.Assert.assertEquals
import
org.junit.Assume.assumeTrue
import
org.junit.Rule
...
...
@@ -174,7 +173,7 @@ class SkiaWindowTest {
@Test
fun
`
render
three
windows
`
()
=
swingTest
{
fun
window
(
color
:
Color
)
=
SkiaWindow
().
apply
{
setLocation
(
200
,
200
)
setLocation
(
200
,
200
)
setSize
(
400
,
200
)
defaultCloseOperation
=
WindowConstants
.
DISPOSE_ON_CLOSE
layer
.
skikoView
=
RectRenderer
(
layer
,
200
,
100
,
color
)
...
...
@@ -244,7 +243,7 @@ class SkiaWindowTest {
@Test
(
timeout
=
60000
)
fun
`
stress
test
-
open
multiple
windows
`
()
=
swingTest
{
fun
window
(
isAnimated
:
Boolean
)
=
SkiaWindow
().
apply
{
setLocation
(
200
,
200
)
setLocation
(
200
,
200
)
setSize
(
40
,
20
)
defaultCloseOperation
=
WindowConstants
.
DISPOSE_ON_CLOSE
layer
.
skikoView
=
if
(
isAnimated
)
{
...
...
@@ -288,7 +287,7 @@ class SkiaWindowTest {
fun
openWindow
()
=
SkiaWindow
(
properties
=
SkiaLayerProperties
(
isVsyncEnabled
=
false
,
isVsyncFramelimitFallbackEnabled
=
true
)
).
apply
{
setLocation
(
200
,
200
)
setLocation
(
200
,
200
)
setSize
(
400
,
200
)
defaultCloseOperation
=
WindowConstants
.
DISPOSE_ON_CLOSE
layer
.
skikoView
=
AnimatedBoxRenderer
(
layer
,
pixelsPerSecond
=
20.0
,
size
=
20.0
)
...
...
@@ -311,7 +310,7 @@ class SkiaWindowTest {
fun
openWindow
()
=
SkiaWindow
(
properties
=
SkiaLayerProperties
(
isVsyncEnabled
=
false
,
isVsyncFramelimitFallbackEnabled
=
true
)
).
apply
{
setLocation
(
200
,
200
)
setLocation
(
200
,
200
)
setSize
(
400
,
200
)
preferredSize
=
Dimension
(
400
,
200
)
defaultCloseOperation
=
WindowConstants
.
DISPOSE_ON_CLOSE
...
...
@@ -336,22 +335,20 @@ class SkiaWindowTest {
fun
`
fallback
to
software
renderer
,
fail
on
init
context
`
()
=
swingTest
{
testFallbackToSoftware
(
object
:
RenderFactory
{
override
fun
createContextHandler
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
)
=
object
:
ContextHandler
(
layer
)
{
override
fun
initContext
()
=
false
override
fun
initCanvas
()
=
Unit
}
override
fun
createRedrawer
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
,
properties
:
SkiaLayerProperties
):
Redrawer
=
object
:
Redrawer
{
)
=
object
:
Redrawer
{
private
val
contextHandler
=
object
:
JvmContextHandler
(
layer
)
{
override
fun
initContext
()
=
false
override
fun
initCanvas
()
=
Unit
}
override
fun
dispose
()
=
Unit
override
fun
needRedraw
()
=
Unit
override
fun
redrawImmediately
()
=
layer
.
inDrawScope
{
layer
.
draw
()
}
override
fun
redrawImmediately
()
=
layer
.
inDrawScope
(
contextHandler
::
draw
)
override
val
renderInfo
=
""
}
}
)
...
...
@@ -361,19 +358,11 @@ class SkiaWindowTest {
fun
`
fallback
to
software
renderer
,
fail
on
create
redrawer
`
()
=
swingTest
{
testFallbackToSoftware
(
object
:
RenderFactory
{
override
fun
createContextHandler
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
)
=
object
:
ContextHandler
(
layer
)
{
override
fun
initContext
()
=
true
override
fun
initCanvas
()
=
Unit
}
override
fun
createRedrawer
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
,
properties
:
SkiaLayerProperties
)
=
throw
RenderException
()
)
=
throw
RenderException
()
}
)
}
...
...
@@ -382,14 +371,6 @@ class SkiaWindowTest {
fun
`
fallback
to
software
renderer
,
fail
on
draw
`
()
=
swingTest
{
testFallbackToSoftware
(
object
:
RenderFactory
{
override
fun
createContextHandler
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
)
=
object
:
ContextHandler
(
layer
)
{
override
fun
initContext
()
=
true
override
fun
initCanvas
()
=
Unit
}
override
fun
createRedrawer
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
,
...
...
@@ -400,6 +381,7 @@ class SkiaWindowTest {
override
fun
redrawImmediately
()
=
layer
.
inDrawScope
{
throw
RenderException
()
}
override
val
renderInfo
=
""
}
}
)
...
...
@@ -439,14 +421,6 @@ class SkiaWindowTest {
private
class
OverrideNonSoftwareRenderFactory
(
private
val
nonSoftwareRenderFactory
:
RenderFactory
)
:
RenderFactory
{
override
fun
createContextHandler
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
):
ContextHandler
{
return
if
(
renderApi
==
GraphicsApi
.
SOFTWARE
)
{
RenderFactory
.
Default
.
createContextHandler
(
layer
,
renderApi
)
}
else
{
nonSoftwareRenderFactory
.
createContextHandler
(
layer
,
renderApi
)
}
}
override
fun
createRedrawer
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
,
...
...
skiko/src/macosMain/kotlin/org/jetbrains/skiko/SkiaLayer.macos.kt
View file @
0f45ab4e
...
...
@@ -37,8 +37,6 @@ actual open class SkiaLayer(
actual
var
skikoView
:
SkikoView
?
=
null
private
var
contextHandler
=
MacOSOpenGLContextHandler
(
this
)
private
var
redrawer
:
Redrawer
?
=
null
private
var
picture
:
PictureHolder
?
=
null
...
...
@@ -131,13 +129,11 @@ actual open class SkiaLayer(
}
nsView
.
frame
=
CGRectMake
(
0.0
,
0.0
,
w
,
h
)
redrawer
?.
syncSize
()
initedCanvas
=
false
redrawer
?.
redrawImmediately
()
}
override
fun
windowDidChangeBackingProperties
(
notification
:
NSNotification
)
{
redrawer
?.
syncSize
()
initedCanvas
=
false
redrawer
?.
redrawImmediately
()
}
}
...
...
@@ -151,14 +147,13 @@ actual open class SkiaLayer(
actual
fun
detach
()
{
redrawer
?.
dispose
()
redrawer
=
null
initedCanvas
=
false
}
actual
fun
needRedraw
()
{
redrawer
?.
needRedraw
()
}
fun
update
(
nanoTime
:
Long
)
{
internal
fun
update
(
nanoTime
:
Long
)
{
val
width
=
nsView
.
frame
.
useContents
{
size
.
width
}
val
height
=
nsView
.
frame
.
useContents
{
size
.
height
}
...
...
@@ -173,24 +168,9 @@ actual open class SkiaLayer(
this
.
picture
=
PictureHolder
(
picture
,
pictureWidth
.
toInt
(),
pictureHeight
.
toInt
())
}
private
var
initedCanvas
=
false
fun
draw
()
{
contextHandler
.
apply
{
if
(!
initedCanvas
)
{
if
(!
initContext
())
{
error
(
"initContext() failure"
)
return
}
initCanvas
()
initedCanvas
=
true
}
clearCanvas
()
val
picture
=
picture
if
(
picture
!=
null
)
{
drawOnCanvas
(
picture
.
instance
)
}
flush
()
internal
fun
draw
(
canvas
:
Canvas
)
{
picture
?.
also
{
canvas
.
drawPicture
(
it
.
instance
)
}
}
}
...
...
skiko/src/macosMain/kotlin/org/jetbrains/skiko/context/OpenGLContextHandler.macos.kt
View file @
0f45ab4e
...
...
@@ -7,7 +7,7 @@ import platform.OpenGL.GL_DRAW_FRAMEBUFFER_BINDING
import
platform.OpenGL.glGetIntegerv
import
platform.OpenGLCommon.GLenum
internal
class
MacOSOpenGLContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
)
{
internal
class
MacOSOpenGLContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
,
layer
::
draw
)
{
override
fun
initContext
():
Boolean
{
try
{
if
(
context
==
null
)
{
...
...
@@ -31,13 +31,16 @@ internal class MacOSOpenGLContextHandler(layer: SkiaLayer) : ContextHandler(laye
return
result
}
var
initedCanvas
=
false
override
fun
initCanvas
()
{
val
scale
=
layer
.
contentScale
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
(!
initedCanvas
)
{
val
scale
=
layer
.
contentScale
val
w
=
(
layer
.
nsView
.
frame
.
useContents
{
size
.
width
}
*
scale
).
toInt
().
coerceAtLeast
(
0
)
val
h
=
(
layer
.
nsView
.
frame
.
useContents
{
size
.
height
}
*
scale
).
toInt
().
coerceAtLeast
(
0
)
val
fbId
=
openglGetIntegerv
(
GL_DRAW_FRAMEBUFFER_BINDING
.
toUInt
())
renderTarget
=
BackendRenderTarget
.
makeGL
(
val
fbId
=
openglGetIntegerv
(
GL_DRAW_FRAMEBUFFER_BINDING
.
toUInt
())
renderTarget
=
BackendRenderTarget
.
makeGL
(
w
,
h
,
0
,
...
...
@@ -45,7 +48,7 @@ internal class MacOSOpenGLContextHandler(layer: SkiaLayer) : ContextHandler(laye
fbId
.
toInt
(),
FramebufferFormat
.
GR_GL_RGBA8
)
surface
=
Surface
.
makeFromBackendRenderTarget
(
surface
=
Surface
.
makeFromBackendRenderTarget
(
context
!!
,
renderTarget
!!
,
SurfaceOrigin
.
BOTTOM_LEFT
,
...
...
@@ -53,7 +56,10 @@ internal class MacOSOpenGLContextHandler(layer: SkiaLayer) : ContextHandler(laye
ColorSpace
.
sRGB
)
canvas
=
surface
?.
canvas
?:
error
(
"Could not obtain Canvas from Surface"
)
canvas
=
surface
?.
canvas
?:
error
(
"Could not obtain Canvas from Surface"
)
initedCanvas
=
true
}
}
}
skiko/src/macosMain/kotlin/org/jetbrains/skiko/redrawer/OpenGLRedrawer.macos.kt
View file @
0f45ab4e
...
...
@@ -6,6 +6,8 @@ import org.jetbrains.skiko.FrameDispatcher
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.SkiaLayerProperties
import
org.jetbrains.skiko.SkikoDispatchers
import
org.jetbrains.skiko.context.ContextHandler
import
org.jetbrains.skiko.context.MacOSOpenGLContextHandler
import
platform.CoreFoundation.CFTimeInterval
import
platform.CoreGraphics.CGRectMake
import
platform.CoreVideo.CVTimeStamp
...
...
@@ -20,17 +22,21 @@ internal class MacOsOpenGLRedrawer(
private
val
skiaLayer
:
SkiaLayer
,
private
val
properties
:
SkiaLayerProperties
)
:
Redrawer
{
private
val
contextHandler
=
MacOSOpenGLContextHandler
(
skiaLayer
)
override
val
renderInfo
:
String
get
()
=
contextHandler
.
rendererInfo
()
private
val
glLayer
=
MacosGLLayer
()
init
{
glLayer
.
init
(
skiaLayer
)
glLayer
.
init
(
skiaLayer
,
contextHandler
)
}
private
val
frameDispatcher
=
FrameDispatcher
(
SkikoDispatchers
.
Main
)
{
redrawImmediately
()
}
override
fun
dispose
()
{
override
fun
dispose
()
{
contextHandler
.
dispose
()
glLayer
.
dispose
()
}
...
...
@@ -44,6 +50,7 @@ internal class MacOsOpenGLRedrawer(
size
.
height
.
toInt
().
coerceAtLeast
(
0
)
)
}
contextHandler
.
initedCanvas
=
false
}
private
fun
syncContentScale
()
{
...
...
@@ -66,13 +73,15 @@ internal class MacOsOpenGLRedrawer(
internal
class
MacosGLLayer
:
CAOpenGLLayer
{
private
lateinit
var
layer
:
SkiaLayer
private
lateinit
var
contextHandler
:
ContextHandler
@OverrideInit
constructor
():
super
()
@OverrideInit
constructor
(
layer
:
Any
):
super
(
layer
)
fun
init
(
layer
:
SkiaLayer
)
{
fun
init
(
layer
:
SkiaLayer
,
contextHandler
:
ContextHandler
)
{
this
.
layer
=
layer
this
.
contextHandler
=
contextHandler
this
.
setNeedsDisplayOnBoundsChange
(
true
)
this
.
removeAllAnimations
()
this
.
setAutoresizingMask
(
kCALayerWidthSizable
or
kCALayerHeightSizable
)
...
...
@@ -112,7 +121,7 @@ internal class MacosGLLayer : CAOpenGLLayer {
CGLSetCurrentContext
(
ctx
);
try
{
layer
.
update
(
getTimeNanos
())
lay
er
.
draw
()
contextHandl
er
.
draw
()
}
catch
(
e
:
Throwable
)
{
e
.
printStackTrace
()
throw
e
...
...
skiko/src/nativeMain/kotlin/org/jetbrains/skiko/RenderFactory.native.kt
View file @
0f45ab4e
...
...
@@ -13,10 +13,6 @@ internal expect fun createNativeRedrawer(
internal
actual
fun
makeDefaultRenderFactory
():
RenderFactory
{
return
object
:
RenderFactory
{
override
fun
createContextHandler
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
):
ContextHandler
{
return
createNativeContextHandler
(
layer
,
renderApi
)
}
override
fun
createRedrawer
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment