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
a2eed5a7
Unverified
Commit
a2eed5a7
authored
Oct 21, 2021
by
Nikolay Igotti
Committed by
GitHub
Oct 21, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
macos dispatcher (#295)
parent
bbd1c31e
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
89 additions
and
82 deletions
+89
-82
BouncingBalls.kt
...onMain/kotlin/org/jetbrains/skiko/sample/BouncingBalls.kt
+5
-1
App.macos.kt
.../macosMain/kotlin/org/jetbrains/skiko/sample/App.macos.kt
+1
-1
build.gradle.kts
skiko/build.gradle.kts
+5
-2
Expects.kt
skiko/src/commonMain/kotlin/org/jetbrains/skiko/Expects.kt
+3
-1
FPSCounter.kt
...o/src/commonMain/kotlin/org/jetbrains/skiko/FPSCounter.kt
+8
-24
Dispatchers.kt
.../src/darwinMain/kotlin/org/jetbrains/skiko/Dispatchers.kt
+0
-0
SkiaLayer.ios.kt
...o/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt
+6
-3
MetalRedrawer.ios.kt
.../kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt
+9
-19
Actuals.js.kt
skiko/src/jsMain/kotlin/org/jetbrains/skiko/Actuals.js.kt
+3
-1
Actuals.jvm.kt
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/Actuals.jvm.kt
+3
-1
SkiaLayer.jvm.kt
...o/src/jvmMain/kotlin/org/jetbrains/skiko/SkiaLayer.jvm.kt
+14
-0
SkiaLayer.macos.kt
...c/macosMain/kotlin/org/jetbrains/skiko/SkiaLayer.macos.kt
+6
-2
OpenGLRedrawer.macos.kt
...tlin/org/jetbrains/skiko/redrawer/OpenGLRedrawer.macos.kt
+23
-26
Actuals.native.kt
...c/nativeMain/kotlin/org/jetbrains/skiko/Actuals.native.kt
+3
-1
No files found.
samples/SkiaMultiplatformSample/src/commonMain/kotlin/org/jetbrains/skiko/sample/BouncingBalls.kt
View file @
a2eed5a7
...
@@ -6,9 +6,11 @@ import kotlin.math.PI
...
@@ -6,9 +6,11 @@ import kotlin.math.PI
import
kotlin.math.cos
import
kotlin.math.cos
import
kotlin.math.sin
import
kotlin.math.sin
class
BouncingBalls
:
SkikoView
{
class
BouncingBalls
(
private
val
withFps
:
Boolean
=
false
)
:
SkikoView
{
private
data class
Circle
(
var
x
:
Float
,
var
y
:
Float
,
var
r
:
Float
)
private
data class
Circle
(
var
x
:
Float
,
var
y
:
Float
,
var
r
:
Float
)
private
val
fpsCounter
=
FPSCounter
(
2.0
,
true
)
companion
object
{
companion
object
{
private
fun
moveCircle
(
c
:
Circle
,
s
:
Float
,
angle
:
Float
,
width
:
Int
,
height
:
Int
,
r
:
Float
)
{
private
fun
moveCircle
(
c
:
Circle
,
s
:
Float
,
angle
:
Float
,
width
:
Int
,
height
:
Int
,
r
:
Float
)
{
c
.
x
=
(
c
.
x
+
s
*
sin
(
angle
)).
coerceAtLeast
(
r
).
coerceAtMost
(
width
.
toFloat
()
-
r
)
c
.
x
=
(
c
.
x
+
s
*
sin
(
angle
)).
coerceAtLeast
(
r
).
coerceAtMost
(
width
.
toFloat
()
-
r
)
...
@@ -85,6 +87,8 @@ class BouncingBalls: SkikoView {
...
@@ -85,6 +87,8 @@ class BouncingBalls: SkikoView {
)).
toMutableList
()
)).
toMutableList
()
override
fun
onRender
(
canvas
:
Canvas
,
width
:
Int
,
height
:
Int
,
nanoTime
:
Long
)
{
override
fun
onRender
(
canvas
:
Canvas
,
width
:
Int
,
height
:
Int
,
nanoTime
:
Long
)
{
if
(
withFps
)
fpsCounter
.
tick
()
canvas
.
clear
(-
1
)
canvas
.
clear
(-
1
)
val
dtime
=
(
nanoTime
-
prevTimestamp
)
val
dtime
=
(
nanoTime
-
prevTimestamp
)
prevTimestamp
=
nanoTime
prevTimestamp
=
nanoTime
...
...
samples/SkiaMultiplatformSample/src/macosMain/kotlin/org/jetbrains/skiko/sample/App.macos.kt
View file @
a2eed5a7
...
@@ -7,7 +7,7 @@ import org.jetbrains.skiko.*
...
@@ -7,7 +7,7 @@ import org.jetbrains.skiko.*
import
kotlinx.cinterop.*
import
kotlinx.cinterop.*
import
platform.Foundation.NSMakeRect
import
platform.Foundation.NSMakeRect
fun
makeApp
()
=
BouncingBalls
()
fun
makeApp
()
=
BouncingBalls
(
true
)
fun
main
()
{
fun
main
()
{
NSApplication
.
sharedApplication
()
NSApplication
.
sharedApplication
()
...
...
skiko/build.gradle.kts
View file @
a2eed5a7
...
@@ -383,14 +383,17 @@ kotlin {
...
@@ -383,14 +383,17 @@ kotlin {
}
}
}
}
if
(
hostOs
==
OS
.
MacOS
)
{
if
(
hostOs
==
OS
.
MacOS
)
{
val
macos
Main
by
creating
{
val
darwin
Main
by
creating
{
dependsOn
(
nativeMain
)
dependsOn
(
nativeMain
)
}
}
val
macosMain
by
creating
{
dependsOn
(
darwinMain
)
}
val
macosTest
by
creating
{
val
macosTest
by
creating
{
dependsOn
(
nativeTest
)
dependsOn
(
nativeTest
)
}
}
val
iosMain
by
creating
{
val
iosMain
by
creating
{
dependsOn
(
native
Main
)
dependsOn
(
darwin
Main
)
}
}
val
iosTest
by
creating
{
val
iosTest
by
creating
{
dependsOn
(
nativeTest
)
dependsOn
(
nativeTest
)
...
...
skiko/src/commonMain/kotlin/org/jetbrains/skiko/Expects.kt
View file @
a2eed5a7
package
org.jetbrains.skiko
package
org.jetbrains.skiko
internal
expect
inline
fun
<
R
>
maybeSynchronized
(
lock
:
Any
,
block
:
()
->
R
):
R
internal
expect
inline
fun
<
R
>
maybeSynchronized
(
lock
:
Any
,
block
:
()
->
R
):
R
internal
expect
fun
makeDefaultSkiaLayerProperties
():
SkiaLayerProperties
internal
expect
fun
makeDefaultSkiaLayerProperties
():
SkiaLayerProperties
\ No newline at end of file
internal
expect
fun
currentNanoTime
():
Long
\ No newline at end of file
skiko/src/
jvm
Main/kotlin/org/jetbrains/skiko/FPSCounter.kt
→
skiko/src/
common
Main/kotlin/org/jetbrains/skiko/FPSCounter.kt
View file @
a2eed5a7
package
org.jetbrains.skiko
package
org.jetbrains.skiko
import
java.awt.Component
import
kotlin.math.roundToInt
import
kotlin.math.roundToInt
internal
class
FPSCounter
(
class
FPSCounter
(
private
val
periodSeconds
:
Double
,
private
val
periodSeconds
:
Double
,
private
val
showLongFrames
:
Boolean
,
private
val
showLongFrames
:
Boolean
,
private
val
getLongFrameMillis
:
()
->
Double
private
val
getLongFrameMillis
:
()
->
Double
=
{
1.5
*
1000
/
60
}
)
{
)
{
private
val
times
=
mutableListOf
<
Long
>()
private
val
times
=
mutableListOf
<
Long
>()
private
var
lastLogTime
=
System
.
n
anoTime
()
private
var
lastLogTime
=
currentN
anoTime
()
private
var
lastTime
=
System
.
n
anoTime
()
private
var
lastTime
=
currentN
anoTime
()
fun
tick
()
{
fun
tick
()
{
val
time
=
System
.
n
anoTime
()
val
time
=
currentN
anoTime
()
val
timestamp
=
time
.
nanosToMillis
().
toLong
()
val
timestamp
=
time
.
nanosToMillis
().
toLong
()
val
frameTime
=
time
-
lastTime
val
frameTime
=
time
-
lastTime
lastTime
=
time
lastTime
=
time
...
@@ -21,7 +22,7 @@ internal class FPSCounter(
...
@@ -21,7 +22,7 @@ internal class FPSCounter(
times
.
add
(
frameTime
)
times
.
add
(
frameTime
)
if
(
showLongFrames
&&
frameTime
>
getLongFrameMillis
().
millisToNanos
())
{
if
(
showLongFrames
&&
frameTime
>
getLongFrameMillis
().
millisToNanos
())
{
println
(
"
[%d] Long frame %.2f ms"
.
format
(
timestamp
,
frameTime
.
nanosToMillis
())
)
println
(
"
$timestamp Long frame ${frameTime.nanosToMillis()} ms"
)
}
}
if
((
time
-
lastLogTime
)
>
periodSeconds
.
secondsToNanos
())
{
if
((
time
-
lastLogTime
)
>
periodSeconds
.
secondsToNanos
())
{
...
@@ -39,21 +40,4 @@ internal class FPSCounter(
...
@@ -39,21 +40,4 @@ internal class FPSCounter(
private
fun
Long
.
nanosToMillis
():
Double
=
this
/
nanosPerMillis
private
fun
Long
.
nanosToMillis
():
Double
=
this
/
nanosPerMillis
private
fun
Double
.
millisToNanos
():
Long
=
(
this
*
nanosPerMillis
).
toLong
()
private
fun
Double
.
millisToNanos
():
Long
=
(
this
*
nanosPerMillis
).
toLong
()
private
fun
Double
.
secondsToNanos
():
Long
=
(
this
*
nanosPerSecond
).
toLong
()
private
fun
Double
.
secondsToNanos
():
Long
=
(
this
*
nanosPerSecond
).
toLong
()
}
internal
fun
defaultFPSCounter
(
component
:
Component
):
FPSCounter
?
=
with
(
SkikoProperties
)
{
if
(!
SkikoProperties
.
fpsEnabled
)
return
@with
null
// it is slow on Linux (100ms), so we cache it. Also refreshRate available only after window is visible
val
refreshRate
by
lazy
{
component
.
graphicsConfiguration
.
device
.
displayMode
.
refreshRate
}
FPSCounter
(
periodSeconds
=
fpsPeriodSeconds
,
showLongFrames
=
fpsLongFramesShow
,
getLongFrameMillis
=
{
fpsLongFramesMillis
?:
1.5
*
1000
/
refreshRate
}
)
}
}
\ No newline at end of file
skiko/src/
ios
Main/kotlin/org/jetbrains/skiko/Dispatchers.kt
→
skiko/src/
darwin
Main/kotlin/org/jetbrains/skiko/Dispatchers.kt
View file @
a2eed5a7
File moved
skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt
View file @
a2eed5a7
...
@@ -23,7 +23,7 @@ actual open class SkiaLayer(
...
@@ -23,7 +23,7 @@ actual open class SkiaLayer(
set
(
value
)
{
throw
UnsupportedOperationException
()
}
set
(
value
)
{
throw
UnsupportedOperationException
()
}
actual
val
contentScale
:
Float
actual
val
contentScale
:
Float
get
()
=
view
!!
.
contentScaleFactor
?
.
toFloat
()
get
()
=
view
!!
.
contentScaleFactor
.
toFloat
()
actual
var
fullscreen
:
Boolean
actual
var
fullscreen
:
Boolean
get
()
=
true
get
()
=
true
...
@@ -50,9 +50,11 @@ actual open class SkiaLayer(
...
@@ -50,9 +50,11 @@ actual open class SkiaLayer(
internal
var
view
:
UIView
?
=
null
internal
var
view
:
UIView
?
=
null
// We need to keep reference to controller as Objective-C will only keep weak reference here.
// We need to keep reference to controller as Objective-C will only keep weak reference here.
lateinit
private
var
controller
:
NSObject
lateinit
private
var
controller
:
NSObject
actual
fun
attachTo
(
container
:
Any
)
{
actual
fun
attachTo
(
container
:
Any
)
{
attachTo
(
container
as
UIView
)
attachTo
(
container
as
UIView
)
}
}
fun
attachTo
(
view
:
UIView
)
{
fun
attachTo
(
view
:
UIView
)
{
this
.
view
=
view
this
.
view
=
view
contextHandler
=
MetalContextHandler
(
this
)
contextHandler
=
MetalContextHandler
(
this
)
...
@@ -79,8 +81,9 @@ actual open class SkiaLayer(
...
@@ -79,8 +81,9 @@ actual open class SkiaLayer(
// We have ':' in selector to take care of function argument.
// We have ':' in selector to take care of function argument.
view
.
addGestureRecognizer
(
UITapGestureRecognizer
(
controller
,
NSSelectorFromString
(
"onTap:"
)))
view
.
addGestureRecognizer
(
UITapGestureRecognizer
(
controller
,
NSSelectorFromString
(
"onTap:"
)))
// TODO: maybe add observer for view.viewDidDisappear() to detach us?
// TODO: maybe add observer for view.viewDidDisappear() to detach us?
redrawer
=
MetalRedrawer
(
this
,
properties
)
redrawer
=
MetalRedrawer
(
this
,
properties
).
apply
{
redrawer
?.
redrawImmediately
()
needRedraw
()
}
}
}
private
var
isDisposed
=
false
private
var
isDisposed
=
false
...
...
skiko/src/iosMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt
View file @
a2eed5a7
...
@@ -36,7 +36,7 @@ internal class MetalRedrawer(
...
@@ -36,7 +36,7 @@ internal class MetalRedrawer(
private
val
frameDispatcher
=
FrameDispatcher
(
SkikoDispatchers
.
Main
)
{
private
val
frameDispatcher
=
FrameDispatcher
(
SkikoDispatchers
.
Main
)
{
if
(
layer
.
isShowing
())
{
if
(
layer
.
isShowing
())
{
update
(
getTimeNanos
())
layer
.
update
(
getTimeNanos
())
draw
()
draw
()
}
}
}
}
...
@@ -49,8 +49,11 @@ internal class MetalRedrawer(
...
@@ -49,8 +49,11 @@ internal class MetalRedrawer(
}
}
override
fun
dispose
()
{
override
fun
dispose
()
{
frameDispatcher
.
cancel
()
if
(!
isDisposed
)
{
isDisposed
=
true
frameDispatcher
.
cancel
()
metalLayer
.
dispose
()
isDisposed
=
true
}
}
}
override
fun
syncSize
()
{
override
fun
syncSize
()
{
...
@@ -71,14 +74,10 @@ internal class MetalRedrawer(
...
@@ -71,14 +74,10 @@ internal class MetalRedrawer(
override
fun
redrawImmediately
()
{
override
fun
redrawImmediately
()
{
check
(!
isDisposed
)
{
"MetalRedrawer is disposed"
}
check
(!
isDisposed
)
{
"MetalRedrawer is disposed"
}
update
(
getTimeNanos
())
layer
.
update
(
getTimeNanos
())
draw
()
draw
()
}
}
private
fun
update
(
nanoTime
:
Long
)
{
layer
.
update
(
nanoTime
)
}
private
fun
draw
()
{
private
fun
draw
()
{
// TODO: maybe make flush async as in JVM version.
// TODO: maybe make flush async as in JVM version.
autoreleasepool
{
autoreleasepool
{
...
@@ -127,23 +126,14 @@ class MetalLayer : CAMetalLayer {
...
@@ -127,23 +126,14 @@ class MetalLayer : CAMetalLayer {
}
}
}
}
fun
draw
()
{
skiaLayer
.
update
(
getTimeNanos
())
skiaLayer
.
draw
()
}
fun
dispose
()
{
fun
dispose
()
{
this
.
removeFromSuperlayer
()
this
.
removeFromSuperlayer
()
// TODO: anything else to dispose the layer?
// TODO: anything else to dispose the layer?
}
}
@Suppress
(
"unused"
)
private
fun
performDraw
()
{
draw
()
}
override
fun
drawInContext
(
ctx
:
CGContextRef
?)
{
override
fun
drawInContext
(
ctx
:
CGContextRef
?)
{
draw
()
skiaLayer
.
update
(
getTimeNanos
())
skiaLayer
.
draw
()
super
.
drawInContext
(
ctx
)
super
.
drawInContext
(
ctx
)
}
}
}
}
skiko/src/jsMain/kotlin/org/jetbrains/skiko/Actuals.js.kt
View file @
a2eed5a7
...
@@ -5,4 +5,6 @@ internal actual fun makeDefaultSkiaLayerProperties(): SkiaLayerProperties {
...
@@ -5,4 +5,6 @@ internal actual fun makeDefaultSkiaLayerProperties(): SkiaLayerProperties {
}
}
internal
actual
inline
fun
<
R
>
maybeSynchronized
(
lock
:
Any
,
block
:
()
->
R
):
R
=
internal
actual
inline
fun
<
R
>
maybeSynchronized
(
lock
:
Any
,
block
:
()
->
R
):
R
=
block
()
block
()
\ No newline at end of file
actual
fun
currentNanoTime
():
Long
=
(
kotlinx
.
browser
.
window
.
performance
.
now
()
*
1
_000_000
).
toLong
()
\ No newline at end of file
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/Actuals.jvm.kt
View file @
a2eed5a7
...
@@ -5,4 +5,6 @@ internal actual fun makeDefaultSkiaLayerProperties(): SkiaLayerProperties {
...
@@ -5,4 +5,6 @@ internal actual fun makeDefaultSkiaLayerProperties(): SkiaLayerProperties {
}
}
internal
actual
inline
fun
<
R
>
maybeSynchronized
(
lock
:
Any
,
block
:
()
->
R
):
R
=
internal
actual
inline
fun
<
R
>
maybeSynchronized
(
lock
:
Any
,
block
:
()
->
R
):
R
=
synchronized
(
lock
,
block
)
synchronized
(
lock
,
block
)
\ No newline at end of file
actual
fun
currentNanoTime
():
Long
=
System
.
nanoTime
()
\ No newline at end of file
skiko/src/jvmMain/kotlin/org/jetbrains/skiko/SkiaLayer.jvm.kt
View file @
a2eed5a7
...
@@ -526,6 +526,20 @@ fun orderEmojiAndSymbolsPopup() {
...
@@ -526,6 +526,20 @@ fun orderEmojiAndSymbolsPopup() {
platformOperations
.
orderEmojiAndSymbolsPopup
()
platformOperations
.
orderEmojiAndSymbolsPopup
()
}
}
internal
fun
defaultFPSCounter
(
component
:
Component
):
FPSCounter
?
=
with
(
SkikoProperties
)
{
if
(!
SkikoProperties
.
fpsEnabled
)
return
@with
null
// it is slow on Linux (100ms), so we cache it. Also refreshRate available only after window is visible
val
refreshRate
by
lazy
{
component
.
graphicsConfiguration
.
device
.
displayMode
.
refreshRate
}
FPSCounter
(
periodSeconds
=
fpsPeriodSeconds
,
showLongFrames
=
fpsLongFramesShow
,
getLongFrameMillis
=
{
fpsLongFramesMillis
?:
1.5
*
1000
/
refreshRate
}
)
}
// InputEvent is abstract, so we wrap to match modality.
// InputEvent is abstract, so we wrap to match modality.
actual
class
SkikoPlatformInputEvent
(
val
wrapped
:
InputEvent
)
actual
class
SkikoPlatformInputEvent
(
val
wrapped
:
InputEvent
)
actual
typealias
SkikoPlatformKeyboardEvent
=
KeyEvent
actual
typealias
SkikoPlatformKeyboardEvent
=
KeyEvent
...
...
skiko/src/macosMain/kotlin/org/jetbrains/skiko/SkiaLayer.macos.kt
View file @
a2eed5a7
...
@@ -74,6 +74,9 @@ actual open class SkiaLayer(
...
@@ -74,6 +74,9 @@ actual open class SkiaLayer(
}
}
nsView
=
object
:
NSView
(
NSMakeRect
(
0.0
,
0.0
,
width
,
height
))
{
nsView
=
object
:
NSView
(
NSMakeRect
(
0.0
,
0.0
,
width
,
height
))
{
private
var
trackingArea
:
NSTrackingArea
?
=
null
private
var
trackingArea
:
NSTrackingArea
?
=
null
override
fun
wantsUpdateLayer
():
Boolean
{
return
true
}
override
fun
acceptsFirstResponder
():
Boolean
{
override
fun
acceptsFirstResponder
():
Boolean
{
return
true
return
true
}
}
...
@@ -121,8 +124,9 @@ actual open class SkiaLayer(
...
@@ -121,8 +124,9 @@ actual open class SkiaLayer(
center
.
addObserver
(
nsView
,
NSSelectorFromString
(
"onWindowClose:"
),
center
.
addObserver
(
nsView
,
NSSelectorFromString
(
"onWindowClose:"
),
NSWindowWillCloseNotification
!!
,
window
)
NSWindowWillCloseNotification
!!
,
window
)
window
.
contentView
!!
.
addSubview
(
nsView
)
window
.
contentView
!!
.
addSubview
(
nsView
)
redrawer
=
createNativeRedrawer
(
this
,
GraphicsApi
.
OPENGL
,
properties
)
redrawer
=
createNativeRedrawer
(
this
,
GraphicsApi
.
OPENGL
,
properties
).
apply
{
redrawer
?.
redrawImmediately
()
needRedraw
()
}
}
}
actual
fun
detach
()
{
actual
fun
detach
()
{
...
...
skiko/src/macosMain/kotlin/org/jetbrains/skiko/redrawer/OpenGLRedrawer.macos.kt
View file @
a2eed5a7
...
@@ -2,8 +2,10 @@ package org.jetbrains.skiko.redrawer
...
@@ -2,8 +2,10 @@ package org.jetbrains.skiko.redrawer
import
kotlinx.cinterop.CPointer
import
kotlinx.cinterop.CPointer
import
kotlinx.cinterop.useContents
import
kotlinx.cinterop.useContents
import
org.jetbrains.skiko.FrameDispatcher
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.SkiaLayerProperties
import
org.jetbrains.skiko.SkiaLayerProperties
import
org.jetbrains.skiko.SkikoDispatchers
import
platform.CoreFoundation.CFTimeInterval
import
platform.CoreFoundation.CFTimeInterval
import
platform.CoreGraphics.CGRectMake
import
platform.CoreGraphics.CGRectMake
import
platform.CoreVideo.CVTimeStamp
import
platform.CoreVideo.CVTimeStamp
...
@@ -15,19 +17,23 @@ import platform.QuartzCore.*
...
@@ -15,19 +17,23 @@ import platform.QuartzCore.*
import
kotlin.system.getTimeNanos
import
kotlin.system.getTimeNanos
internal
class
MacOsOpenGLRedrawer
(
internal
class
MacOsOpenGLRedrawer
(
private
val
l
ayer
:
SkiaLayer
,
private
val
skiaL
ayer
:
SkiaLayer
,
private
val
properties
:
SkiaLayerProperties
private
val
properties
:
SkiaLayerProperties
)
:
Redrawer
{
)
:
Redrawer
{
private
val
drawLayer
=
MacosGLLayer
(
layer
,
setNeedsDisplayOnBoundsChange
=
true
)
private
val
glLayer
=
MacosGLLayer
(
skiaLayer
)
private
val
frameDispatcher
=
FrameDispatcher
(
SkikoDispatchers
.
Main
)
{
redrawImmediately
()
}
override
fun
dispose
()
{
override
fun
dispose
()
{
draw
Layer
.
dispose
()
gl
Layer
.
dispose
()
}
}
override
fun
syncSize
()
{
override
fun
syncSize
()
{
// TODO: What do we really do here?
// TODO: What do we really do here?
l
ayer
.
nsView
.
frame
.
useContents
{
skiaL
ayer
.
nsView
.
frame
.
useContents
{
draw
Layer
.
setFrame
(
gl
Layer
.
setFrame
(
origin
.
x
.
toInt
(),
origin
.
x
.
toInt
(),
origin
.
y
.
toInt
(),
origin
.
y
.
toInt
(),
size
.
width
.
toInt
().
coerceAtLeast
(
0
),
size
.
width
.
toInt
().
coerceAtLeast
(
0
),
...
@@ -37,28 +43,24 @@ internal class MacOsOpenGLRedrawer(
...
@@ -37,28 +43,24 @@ internal class MacOsOpenGLRedrawer(
}
}
override
fun
needRedraw
()
{
override
fun
needRedraw
()
{
frameDispatcher
.
scheduleFrame
()
}
}
override
fun
redrawImmediately
()
{
override
fun
redrawImmediately
()
{
layer
.
update
(
getTimeNanos
())
glLayer
.
setNeedsDisplay
()
skiaLayer
.
nsView
.
setNeedsDisplay
(
true
)
}
}
}
}
class
MacosGLLayer
(
val
layer
:
SkiaLayer
,
setNeedsDisplayOnBoundsChange
:
Boolean
)
:
CAOpenGLLayer
()
{
internal
class
MacosGLLayer
(
val
layer
:
SkiaLayer
)
:
CAOpenGLLayer
()
{
init
{
init
{
this
.
setNeedsDisplayOnBoundsChange
(
setNeedsDisplayOnBoundsChang
e
)
this
.
setNeedsDisplayOnBoundsChange
(
tru
e
)
this
.
removeAllAnimations
()
this
.
removeAllAnimations
()
this
.
setAutoresizingMask
(
kCALayerWidthSizable
or
kCALayerHeightSizable
)
this
.
setAutoresizingMask
(
kCALayerWidthSizable
or
kCALayerHeightSizable
)
this
.
setAsynchronous
(
true
)
layer
.
nsView
.
layer
=
this
layer
.
nsView
.
layer
=
this
layer
.
nsView
.
wantsLayer
=
true
layer
.
nsView
.
wantsLayer
=
true
}
}
fun
draw
()
{
layer
.
update
(
getTimeNanos
())
layer
.
draw
()
}
fun
setFrame
(
x
:
Int
,
y
:
Int
,
width
:
Int
,
height
:
Int
)
{
fun
setFrame
(
x
:
Int
,
y
:
Int
,
width
:
Int
,
height
:
Int
)
{
val
newY
=
layer
.
nsView
.
frame
.
useContents
{
size
.
height
}
-
y
-
height
val
newY
=
layer
.
nsView
.
frame
.
useContents
{
size
.
height
}
-
y
-
height
...
@@ -73,16 +75,6 @@ class MacosGLLayer(val layer: SkiaLayer, setNeedsDisplayOnBoundsChange: Boolean)
...
@@ -73,16 +75,6 @@ class MacosGLLayer(val layer: SkiaLayer, setNeedsDisplayOnBoundsChange: Boolean)
// TODO: anything else to dispose the layer?
// TODO: anything else to dispose the layer?
}
}
@Suppress
(
"unused"
)
private
fun
performDraw
()
{
try
{
draw
()
}
catch
(
e
:
Throwable
)
{
e
.
printStackTrace
()
}
//display.finish()
}
override
fun
canDrawInCGLContext
(
override
fun
canDrawInCGLContext
(
ctx
:
CGLContextObj
?,
ctx
:
CGLContextObj
?,
pixelFormat
:
CGLPixelFormatObj
?,
pixelFormat
:
CGLPixelFormatObj
?,
...
@@ -99,9 +91,14 @@ class MacosGLLayer(val layer: SkiaLayer, setNeedsDisplayOnBoundsChange: Boolean)
...
@@ -99,9 +91,14 @@ class MacosGLLayer(val layer: SkiaLayer, setNeedsDisplayOnBoundsChange: Boolean)
displayTime
:
CPointer
<
CVTimeStamp
>?
displayTime
:
CPointer
<
CVTimeStamp
>?
)
{
)
{
CGLSetCurrentContext
(
ctx
);
CGLSetCurrentContext
(
ctx
);
performDraw
()
try
{
layer
.
update
(
getTimeNanos
())
layer
.
draw
()
}
catch
(
e
:
Throwable
)
{
e
.
printStackTrace
()
throw
e
}
//context.flush() // TODO: I thought the below should call context.flush().
super
.
drawInCGLContext
(
ctx
,
pixelFormat
,
forLayerTime
,
displayTime
)
super
.
drawInCGLContext
(
ctx
,
pixelFormat
,
forLayerTime
,
displayTime
)
}
}
}
}
...
...
skiko/src/nativeMain/kotlin/org/jetbrains/skiko/Actuals.native.kt
View file @
a2eed5a7
...
@@ -5,4 +5,6 @@ internal actual fun makeDefaultSkiaLayerProperties(): SkiaLayerProperties {
...
@@ -5,4 +5,6 @@ internal actual fun makeDefaultSkiaLayerProperties(): SkiaLayerProperties {
}
}
internal
actual
inline
fun
<
R
>
maybeSynchronized
(
lock
:
Any
,
block
:
()
->
R
):
R
=
internal
actual
inline
fun
<
R
>
maybeSynchronized
(
lock
:
Any
,
block
:
()
->
R
):
R
=
block
()
block
()
\ No newline at end of file
actual
fun
currentNanoTime
():
Long
=
kotlin
.
system
.
getTimeNanos
()
\ No newline at end of file
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