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
befd7f0b
Unverified
Commit
befd7f0b
authored
Mar 06, 2023
by
dima.avdeev
Committed by
GitHub
Mar 06, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
UIKit interop (#668)
parent
9de54574
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
33 additions
and
20 deletions
+33
-20
MetalRedrawer.ios.kt
.../kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt
+33
-20
No files found.
skiko/src/iosMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt
View file @
befd7f0b
package
org.jetbrains.skiko.redrawer
package
org.jetbrains.skiko.redrawer
import
kotlinx.cinterop.addressOf
import
kotlinx.cinterop.*
import
kotlinx.cinterop.autoreleasepool
import
kotlinx.cinterop.objcPtr
import
kotlinx.cinterop.usePinned
import
kotlinx.cinterop.useContents
import
org.jetbrains.skia.BackendRenderTarget
import
org.jetbrains.skia.BackendRenderTarget
import
org.jetbrains.skia.DirectContext
import
org.jetbrains.skia.DirectContext
import
org.jetbrains.skiko.
*
import
org.jetbrains.skiko.
SkiaLayer
import
org.jetbrains.skiko.context.ContextHandler
import
org.jetbrains.skiko.context.ContextHandler
import
org.jetbrains.skiko.context.MetalContextHandler
import
org.jetbrains.skiko.context.MetalContextHandler
import
platform.CoreGraphics.CGColorCreate
import
platform.CoreGraphics.CGColorCreate
import
platform.CoreGraphics.CGColorSpaceCreateDeviceRGB
import
platform.CoreGraphics.CGColorSpaceCreateDeviceRGB
import
platform.CoreGraphics.CGContextRef
import
platform.CoreGraphics.CGContextRef
import
platform.CoreGraphics.CGSizeMake
import
platform.Foundation.NSRunLoop
import
platform.Foundation.NSSelectorFromString
import
platform.Metal.MTLCreateSystemDefaultDevice
import
platform.Metal.MTLCreateSystemDefaultDevice
import
platform.Metal.MTLDeviceProtocol
import
platform.Metal.MTLDeviceProtocol
import
platform.Metal.MTLPixelFormatBGRA8Unorm
import
platform.Metal.MTLPixelFormatBGRA8Unorm
import
platform.QuartzCore.CADisplayLink
import
platform.QuartzCore.CAMetalDrawableProtocol
import
platform.QuartzCore.CAMetalDrawableProtocol
import
platform.QuartzCore.CAMetalLayer
import
platform.QuartzCore.CAMetalLayer
import
platform.QuartzCore.kCAGravityTopLeft
import
platform.QuartzCore.kCAGravityTopLeft
import
kotlin.system.getTimeNanos
import
platform.darwin.NSObject
import
platform.CoreGraphics.CGSizeMake
internal
class
MetalRedrawer
(
internal
class
MetalRedrawer
(
private
val
layer
:
SkiaLayer
private
val
layer
:
SkiaLayer
...
@@ -33,16 +32,22 @@ internal class MetalRedrawer(
...
@@ -33,16 +32,22 @@ internal class MetalRedrawer(
private
val
queue
=
device
.
newCommandQueue
()
!!
private
val
queue
=
device
.
newCommandQueue
()
!!
private
var
currentDrawable
:
CAMetalDrawableProtocol
?
=
null
private
var
currentDrawable
:
CAMetalDrawableProtocol
?
=
null
private
val
metalLayer
=
MetalLayer
()
private
val
metalLayer
=
MetalLayer
()
private
val
frameListener
:
NSObject
=
FrameTickListener
{
init
{
caDisplayLink
.
setPaused
(
true
)
metalLayer
.
init
(
this
.
layer
,
contextHandler
,
device
)
}
private
val
frameDispatcher
=
FrameDispatcher
(
SkikoDispatchers
.
Main
)
{
if
(
layer
.
isShowing
())
{
if
(
layer
.
isShowing
())
{
draw
()
draw
()
}
}
}
}
private
val
caDisplayLink
=
CADisplayLink
.
displayLinkWithTarget
(
target
=
frameListener
,
selector
=
NSSelectorFromString
(
FrameTickListener
::
onDisplayLinkTick
.
name
)
)
init
{
metalLayer
.
init
(
this
.
layer
,
contextHandler
,
device
)
caDisplayLink
.
setPaused
(
true
)
caDisplayLink
.
addToRunLoop
(
NSRunLoop
.
mainRunLoop
,
NSRunLoop
.
mainRunLoop
.
currentMode
)
}
fun
makeContext
()
=
DirectContext
.
makeMetal
(
device
.
objcPtr
(),
queue
.
objcPtr
())
fun
makeContext
()
=
DirectContext
.
makeMetal
(
device
.
objcPtr
(),
queue
.
objcPtr
())
...
@@ -53,7 +58,7 @@ internal class MetalRedrawer(
...
@@ -53,7 +58,7 @@ internal class MetalRedrawer(
override
fun
dispose
()
{
override
fun
dispose
()
{
if
(!
isDisposed
)
{
if
(!
isDisposed
)
{
frameDispatcher
.
cancel
()
caDisplayLink
.
invalidate
()
contextHandler
.
dispose
()
contextHandler
.
dispose
()
metalLayer
.
dispose
()
metalLayer
.
dispose
()
isDisposed
=
true
isDisposed
=
true
...
@@ -73,7 +78,7 @@ internal class MetalRedrawer(
...
@@ -73,7 +78,7 @@ internal class MetalRedrawer(
override
fun
needRedraw
()
{
override
fun
needRedraw
()
{
check
(!
isDisposed
)
{
"MetalRedrawer is disposed"
}
check
(!
isDisposed
)
{
"MetalRedrawer is disposed"
}
frameDispatcher
.
scheduleFrame
(
)
caDisplayLink
.
setPaused
(
false
)
}
}
override
fun
redrawImmediately
()
{
override
fun
redrawImmediately
()
{
...
@@ -83,7 +88,7 @@ internal class MetalRedrawer(
...
@@ -83,7 +88,7 @@ internal class MetalRedrawer(
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
{
//todo measure performance without autoreleasepool
if
(!
isDisposed
)
{
if
(!
isDisposed
)
{
contextHandler
.
draw
()
contextHandler
.
draw
()
}
}
...
@@ -108,9 +113,10 @@ internal class MetalLayer : CAMetalLayer {
...
@@ -108,9 +113,10 @@ internal class MetalLayer : CAMetalLayer {
private
lateinit
var
contextHandler
:
ContextHandler
private
lateinit
var
contextHandler
:
ContextHandler
@OverrideInit
@OverrideInit
constructor
():
super
()
constructor
()
:
super
()
@OverrideInit
@OverrideInit
constructor
(
layer
:
Any
):
super
(
layer
)
constructor
(
layer
:
Any
)
:
super
(
layer
)
fun
init
(
fun
init
(
skiaLayer
:
SkiaLayer
,
skiaLayer
:
SkiaLayer
,
...
@@ -129,7 +135,7 @@ internal class MetalLayer : CAMetalLayer {
...
@@ -129,7 +135,7 @@ internal class MetalLayer : CAMetalLayer {
this
.
backgroundColor
=
this
.
backgroundColor
=
CGColorCreate
(
CGColorSpaceCreateDeviceRGB
(),
it
.
addressOf
(
0
))
CGColorCreate
(
CGColorSpaceCreateDeviceRGB
(),
it
.
addressOf
(
0
))
}
}
this
.
opaque
=
true
this
.
opaque
=
false
// For UIKit interop through a "Hole"
skiaLayer
.
view
?.
let
{
skiaLayer
.
view
?.
let
{
this
.
frame
=
it
.
frame
this
.
frame
=
it
.
frame
it
.
layer
.
addSublayer
(
this
)
it
.
layer
.
addSublayer
(
this
)
...
@@ -146,3 +152,10 @@ internal class MetalLayer : CAMetalLayer {
...
@@ -146,3 +152,10 @@ internal class MetalLayer : CAMetalLayer {
super
.
drawInContext
(
ctx
)
super
.
drawInContext
(
ctx
)
}
}
}
}
private
class
FrameTickListener
(
val
onFrameTick
:
()
->
Unit
)
:
NSObject
()
{
@ObjCAction
fun
onDisplayLinkTick
()
{
onFrameTick
()
}
}
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