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
73c0bbc5
Unverified
Commit
73c0bbc5
authored
Oct 14, 2021
by
Nikolay Igotti
Committed by
GitHub
Oct 14, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Basic iOS Metal-based renderer (#260)
parent
920a24cf
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
336 additions
and
81 deletions
+336
-81
build.gradle.kts
samples/SkiaNativeSample/build.gradle.kts
+15
-1
gradle.properties
samples/SkiaNativeSample/gradle.properties
+2
-1
Scene.kt
...src/commonMain/kotlin/org/jetbrains/skiko/sample/Scene.kt
+2
-3
App.ios.kt
.../src/iosMain/kotlin/org/jetbrains/skiko/sample/App.ios.kt
+1
-9
SkikoAppDelegate.kt
...ain/kotlin/org/jetbrains/skiko/sample/SkikoAppDelegate.kt
+1
-2
SkikoViewController.kt
.../kotlin/org/jetbrains/skiko/sample/SkikoViewController.kt
+9
-13
App.macos.kt
.../macosMain/kotlin/org/jetbrains/skiko/sample/App.macos.kt
+1
-1
build.gradle.kts
skiko/build.gradle.kts
+1
-0
FrameDispatcher.kt
.../commonMain/kotlin/org/jetbrains/skiko/FrameDispatcher.kt
+1
-1
Actuals.ios.kt
skiko/src/iosMain/kotlin/org/jetbrains/skiko/Actuals.ios.kt
+2
-2
Dispatchers.kt
skiko/src/iosMain/kotlin/org/jetbrains/skiko/Dispatchers.kt
+102
-0
SkiaLayer.ios.kt
...o/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt
+31
-16
MetalContextHandler.kt
...kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt
+57
-0
MetalRedrawer.ios.kt
.../kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt
+111
-6
OpenGLRedrawer.ios.kt
...kotlin/org/jetbrains/skiko/redrawer/OpenGLRedrawer.ios.kt
+0
-26
No files found.
samples/SkiaNativeSample/build.gradle.kts
View file @
73c0bbc5
...
...
@@ -6,7 +6,7 @@ val coroutinesVersion = "1.5.2"
repositories
{
mavenLocal
()
jcenter
()
mavenCentral
()
maven
(
"https://dl.bintray.com/kotlin/kotlin-eap"
)
maven
(
"https://maven.pkg.jetbrains.space/public/p/compose/dev"
)
}
...
...
@@ -56,6 +56,7 @@ kotlin {
freeCompilerArgs
+=
listOf
(
"-linker-option"
,
"-framework"
,
"-linker-option"
,
"Metal"
,
"-linker-option"
,
"-framework"
,
"-linker-option"
,
"CoreText"
,
"-linker-option"
,
"-framework"
,
"-linker-option"
,
"CoreGraphics"
)
}
}
...
...
@@ -126,6 +127,19 @@ project.tasks.register<Exec>("runIosSim") {
}
}
project
.
tasks
.
register
<
Exec
>(
"run"
)
{
workingDir
=
project
.
buildDir
val
binTask
=
project
.
tasks
.
named
(
"linkDebugExecutable${hostOs.capitalize()}${hostArch.capitalize()}"
)
dependsOn
(
binTask
)
// Hacky approach.
commandLine
=
listOf
(
"bash"
,
"-c"
)
argumentProviders
.
add
{
val
out
=
fileTree
(
binTask
.
get
().
outputs
.
files
.
files
.
single
())
{
include
(
"*.kexe"
)
}
println
(
"Run $out"
)
listOf
(
out
.
single
{
it
.
name
.
endsWith
(
".kexe"
)
}.
absolutePath
)
}
}
// Create Xcode integration tasks.
val
sdkName
:
String
?
=
System
.
getenv
(
"SDK_NAME"
)
...
...
samples/SkiaNativeSample/gradle.properties
View file @
73c0bbc5
kotlin.code.style
=
official
kotlin.native.cacheKind.macosX64
=
none
kotlin.mpp.enableGranularSourceSetsMetadata
=
true
kotlin.native.enableDependencyPropagation
=
false
samples/SkiaNativeSample/src/commonMain/kotlin/org/jetbrains/skiko/sample/Scene.kt
View file @
73c0bbc5
...
...
@@ -3,13 +3,12 @@ package org.jetbrains.skiko.sample
import
org.jetbrains.skia.*
fun
displayScene
(
canvas
:
Canvas
,
nanoTime
:
Long
)
{
val
angleDeg
=
(
nanoTime
/
5
_000_000
)
%
360
val
paint
=
Paint
().
apply
{
color
=
Color
.
GREEN
}
canvas
.
clear
(
Color
.
RED
)
canvas
.
save
();
canvas
.
translate
(
128.0f
,
128.0f
)
canvas
.
rotate
(
nanoTime
.
toFloat
()
/
1
e7f
)
canvas
.
rotate
(
angleDeg
.
toFloat
()
)
val
rect
=
Rect
.
makeXYWH
(-
90.5f
,
-
90.5f
,
181.0f
,
181.0f
)
canvas
.
drawRect
(
rect
,
paint
)
canvas
.
restore
();
...
...
samples/SkiaNativeSample/src/iosMain/kotlin/org/jetbrains/skiko/sample/App.ios.kt
View file @
73c0bbc5
// Use `xcodegen` first, then `open ./SkikoSample.xcodeproj` and then Run button in XCode.
package
org.jetbrains.skiko.sample
import
org.jetbrains.skia.*
import
org.jetbrains.skiko.*
import
kotlinx.cinterop.*
import
platform.UIKit.*
import
platform.Foundation.*
fun
main
()
{
val
paint
=
Paint
().
apply
{
color
=
Color
.
GREEN
}
println
(
"Paint is $paint"
)
runSkikoMain
()
}
fun
runSkikoMain
(
args
:
Array
<
String
>
=
emptyArray
())
{
val
args
=
emptyArray
<
String
>()
memScoped
{
val
argc
=
args
.
size
+
1
val
argv
=
(
arrayOf
(
"skikoApp"
)
+
args
).
map
{
it
.
cstr
.
ptr
}.
toCValues
()
autoreleasepool
{
UIApplicationMain
(
argc
,
argv
,
null
,
NSStringFromClass
(
SkikoAppDelegate
))
}
...
...
samples/SkiaNativeSample/src/iosMain/kotlin/org/jetbrains/skiko/sample/SkikoAppDelegate.kt
View file @
73c0bbc5
package
org.jetbrains.skiko.sample
import
kotlinx.cinterop.*
import
platform.Foundation.*
import
platform.UIKit.*
class
SkikoAppDelegate
:
UIResponder
,
UIApplicationDelegateProtocol
{
companion
object
:
UIResponderMeta
(),
UIApplicationDelegateProtocolMeta
{}
companion
object
:
UIResponderMeta
(),
UIApplicationDelegateProtocolMeta
@ObjCObjectBase
.
OverrideInit
constructor
()
:
super
()
...
...
samples/SkiaNativeSample/src/iosMain/kotlin/org/jetbrains/skiko/sample/SkikoViewController.kt
View file @
73c0bbc5
package
org.jetbrains.skiko.sample
import
kotlinx.cinterop.*
import
kotlinx.coroutines.runBlocking
import
org.jetbrains.skiko.GenericRenderer
import
org.jetbrains.skiko.SkiaLayer
import
platform.CoreGraphics.CGRect
import
platform.CoreGraphics.CGRectMake
import
platform.Foundation.*
import
platform.UIKit.*
import
platform.Foundation.NSCoder
...
...
@@ -15,26 +19,18 @@ class SkikoViewController : UIViewController {
@OverrideInit
constructor
(
coder
:
NSCoder
)
:
super
(
coder
)
override
fun
viewDidLoad
()
{
super
.
viewDidLoad
()
val
(
width
,
height
)
=
UIScreen
.
mainScreen
.
bounds
.
useContents
{
this
.
size
.
width
to
this
.
size
.
height
}
view
.
setFrame
(
CGRectMake
(
0.0
,
0.0
,
width
,
height
))
val
layer
=
SkiaLayer
(
width
.
toInt
(),
height
.
toInt
())
layer
.
initLayer
()
layer
.
view
=
UIView
().
apply
{
backgroundColor
=
UIColor
.
lightGrayColor
view
.
addSubview
(
this
)
translatesAutoresizingMaskIntoConstraints
=
false
leadingAnchor
.
constraintEqualToAnchor
(
view
.
leadingAnchor
).
active
=
true
topAnchor
.
constraintEqualToAnchor
(
view
.
topAnchor
).
active
=
true
widthAnchor
.
constraintEqualToAnchor
(
view
.
widthAnchor
).
active
=
true
heightAnchor
.
constraintEqualToAnchor
(
view
.
heightAnchor
).
active
=
true
val
layer
=
SkiaLayer
(
width
.
toFloat
(),
height
.
toFloat
())
layer
.
renderer
=
GenericRenderer
(
layer
)
{
canvas
,
w
,
h
,
nanoTime
->
displayScene
(
canvas
,
nanoTime
)
}
layer
.
initLayer
(
view
)
}
}
samples/SkiaNativeSample/src/macosMain/kotlin/org/jetbrains/skiko/sample/App.macos.kt
View file @
73c0bbc5
...
...
@@ -12,7 +12,7 @@ fun main() {
NSApp
?.
run
()
}
fun
createWindow
()
{
fun
createWindow
()
{
val
layer
=
SkiaLayer
()
layer
.
renderer
=
GenericRenderer
(
layer
)
{
canvas
,
w
,
h
,
nanoTime
->
displayScene
(
canvas
,
nanoTime
)
...
...
skiko/build.gradle.kts
View file @
73c0bbc5
...
...
@@ -320,6 +320,7 @@ kotlin {
val
commonMain
by
getting
{
dependencies
{
implementation
(
kotlin
(
"stdlib-common"
))
implementation
(
"org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion"
)
}
}
val
commonTest
by
getting
{
...
...
skiko/src/
jvm
Main/kotlin/org/jetbrains/skiko/FrameDispatcher.kt
→
skiko/src/
common
Main/kotlin/org/jetbrains/skiko/FrameDispatcher.kt
View file @
73c0bbc5
...
...
@@ -56,7 +56,7 @@ class FrameDispatcher(
fun
scheduleFrame
()
{
if
(!
frameScheduled
)
{
frameScheduled
=
true
frameChannel
.
offer
(
Unit
)
frameChannel
.
trySend
(
Unit
).
isSuccess
}
}
}
\ No newline at end of file
skiko/src/iosMain/kotlin/org/jetbrains/skiko/Actuals.ios.kt
View file @
73c0bbc5
package
org.jetbrains.skiko
import
org.jetbrains.skiko.context.ContextHandler
import
org.jetbrains.skiko.redrawer.
OpenGL
Redrawer
import
org.jetbrains.skiko.redrawer.
Metal
Redrawer
import
org.jetbrains.skiko.redrawer.Redrawer
internal
actual
fun
createNativeContextHandler
(
layer
:
SkiaLayer
,
renderApi
:
GraphicsApi
):
ContextHandler
{
...
...
@@ -13,5 +13,5 @@ internal actual fun createNativeRedrawer(
renderApi
:
GraphicsApi
,
properties
:
SkiaLayerProperties
):
Redrawer
{
return
OpenGL
Redrawer
(
layer
,
properties
)
return
Metal
Redrawer
(
layer
,
properties
)
}
\ No newline at end of file
skiko/src/iosMain/kotlin/org/jetbrains/skiko/Dispatchers.kt
0 → 100644
View file @
73c0bbc5
package
org.jetbrains.skiko
import
kotlinx.cinterop.interpretCPointer
import
kotlinx.coroutines.*
import
platform.CoreFoundation.*
import
platform.darwin.dispatch_async
import
platform.darwin.dispatch_get_global_queue
import
platform.darwin.dispatch_get_main_queue
import
platform.darwin.dispatch_queue_t
import
platform.posix.QOS_CLASS_BACKGROUND
import
kotlin.coroutines.CoroutineContext
import
kotlin.native.concurrent.AtomicNativePtr
import
kotlin.native.concurrent.freeze
import
kotlin.native.internal.NativePtr
// This is the only dispatcher that shall be used in Skiko on iOS.
// Current (as of 1.5.2) dispatchers in kotlinx.coroutines are not usable
// for needs of Skiko.
object
SkikoDispatchers
{
val
Main
:
CoroutineDispatcher
=
NsQueueDispatcher
(
dispatch_get_main_queue
())
val
IO
:
CoroutineDispatcher
=
NsQueueDispatcher
(
dispatch_get_global_queue
(
QOS_CLASS_BACKGROUND
.
toLong
(),
0
)
)
}
@OptIn
(
InternalCoroutinesApi
::
class
)
internal
class
NsQueueDispatcher
(
private
val
dispatchQueue
:
dispatch_queue_t
)
:
CoroutineDispatcher
(),
Delay
{
override
fun
dispatch
(
context
:
CoroutineContext
,
block
:
Runnable
)
{
dispatch_async
(
dispatchQueue
)
{
block
.
run
()
}
}
@OptIn
(
InternalCoroutinesApi
::
class
)
override
fun
scheduleResumeAfterDelay
(
timeMillis
:
Long
,
continuation
:
CancellableContinuation
<
Unit
>)
{
val
timer
=
Timer
()
val
timerBlock
:
TimerBlock
=
{
timer
.
dispose
()
continuation
.
resume
(
Unit
)
{
t
->
t
.
printStackTrace
()
}
}
timer
.
start
(
timeMillis
,
timerBlock
)
continuation
.
disposeOnCancellation
(
timer
)
}
@OptIn
(
InternalCoroutinesApi
::
class
)
override
fun
invokeOnTimeout
(
timeMillis
:
Long
,
block
:
Runnable
,
context
:
CoroutineContext
):
DisposableHandle
{
val
timer
=
Timer
()
val
timerBlock
:
TimerBlock
=
{
timer
.
dispose
()
block
.
run
()
}
timer
.
start
(
timeMillis
,
timerBlock
)
return
timer
}
}
internal
typealias
TimerBlock
=
(
CFRunLoopTimerRef
?)
->
Unit
@SharedImmutable
private
val
TIMER_NEW
=
NativePtr
.
NULL
@SharedImmutable
private
val
TIMER_DISPOSED
=
NativePtr
.
NULL
.
plus
(
1
)
private
class
Timer
:
DisposableHandle
{
private
val
ref
=
AtomicNativePtr
(
TIMER_NEW
)
init
{
freeze
()
}
fun
start
(
timeMillis
:
Long
,
timerBlock
:
TimerBlock
)
{
val
fireDate
=
CFAbsoluteTimeGetCurrent
()
+
timeMillis
/
1000.0
@Suppress
(
"EXPERIMENTAL_UNSIGNED_LITERALS"
)
val
timer
=
CFRunLoopTimerCreateWithHandler
(
null
,
fireDate
,
0.0
,
0
u
,
0
,
timerBlock
)
!!
CFRunLoopAddTimer
(
CFRunLoopGetMain
(),
timer
,
kCFRunLoopCommonModes
)
if
(!
ref
.
compareAndSet
(
TIMER_NEW
,
timer
.
rawValue
))
{
// dispose was already called concurrently
release
(
timer
)
}
}
override
fun
dispose
()
{
while
(
true
)
{
val
ptr
=
ref
.
value
if
(
ptr
==
TIMER_DISPOSED
)
return
if
(
ref
.
compareAndSet
(
ptr
,
TIMER_DISPOSED
))
{
if
(
ptr
!=
TIMER_NEW
)
release
(
interpretCPointer
(
ptr
))
return
}
}
}
private
fun
release
(
timer
:
CFRunLoopTimerRef
?)
{
CFRunLoopRemoveTimer
(
CFRunLoopGetMain
(),
timer
,
kCFRunLoopCommonModes
)
CFRelease
(
timer
)
}
}
skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt
View file @
73c0bbc5
package
org.jetbrains.skiko
import
kotlinx.cinterop.*
import
org.jetbrains.skia.PictureRecorder
import
org.jetbrains.skia.Rect
import
org.jetbrains.skiko.
redrawer.Redraw
er
import
platform.Foundation.*
import
org.jetbrains.skiko.
context.MetalContextHandl
er
import
org.jetbrains.skiko.redrawer.MetalRedrawer
import
platform.UIKit.*
actual
open
class
SkiaLayer
actual
constructor
(
properties
:
SkiaLayerProperties
val
properties
:
SkiaLayerProperties
)
{
var
width
:
Int
=
0
var
height
:
Int
=
0
var
width
:
Float
=
0f
var
height
:
Float
=
0f
constructor
(
width
:
Int
,
height
:
In
t
)
:
this
(
constructor
(
width
:
Float
,
height
:
Floa
t
)
:
this
(
makeDefaultSkiaLayerProperties
())
{
this
.
width
=
width
this
.
height
=
height
}
fun
isShowing
():
Boolean
{
return
true
}
actual
var
renderApi
:
GraphicsApi
get
()
=
GraphicsApi
.
METAL
set
(
value
)
{
throw
UnsupportedOperationException
()
}
...
...
@@ -40,31 +43,43 @@ actual open class SkiaLayer actual constructor(
lateinit
var
view
:
UIView
fun
initLayer
()
{
fun
initLayer
(
view
:
UIView
)
{
println
(
"SkiaLayer.initLayer"
)
//redrawer = createNativeRedrawer(this, renderApi, properties)
this
.
view
=
view
redrawer
=
MetalRedrawer
(
this
,
properties
)
redrawer
?.
redrawImmediately
()
}
var
renderer
:
SkiaRenderer
?
=
null
private
var
redrawer
:
Redrawer
?
=
null
internal
var
redrawer
:
Metal
Redrawer
?
=
null
private
var
picture
:
PictureHolder
?
=
null
private
val
pictureRecorder
=
PictureRecorder
()
private
val
contextHandler
=
MetalContextHandler
(
this
)
fun
update
(
nanoTime
:
Long
)
{
println
(
"SkiaLayer.update"
)
val
width
=
800f
val
height
=
600f
val
pictureWidth
=
(
width
*
contentScale
).
coerceAtLeast
(
0.0F
)
val
pictureHeight
=
(
height
*
contentScale
).
coerceAtLeast
(
0.0F
)
val
bounds
=
Rect
.
makeWH
(
pictureWidth
,
pictureHeight
)
val
canvas
=
pictureRecorder
.
beginRecording
(
bounds
)
renderer
?.
onRender
(
canvas
,
pictureWidth
.
toInt
(),
pictureHeight
.
toInt
(),
nanoTime
)
val
picture
=
pictureRecorder
.
finishRecordingAsPicture
()
this
.
picture
=
PictureHolder
(
picture
,
pictureWidth
.
toInt
(),
pictureHeight
.
toInt
())
}
fun
draw
()
{
contextHandler
.
apply
{
if
(!
initContext
())
{
error
(
"initContext() failure"
)
return
}
initCanvas
()
clearCanvas
()
val
picture
=
picture
if
(
picture
!=
null
)
{
drawOnCanvas
(
picture
.
instance
)
}
flush
()
}
}
}
skiko/src/iosMain/kotlin/org/jetbrains/skiko/context/MetalContextHandler.kt
0 → 100644
View file @
73c0bbc5
package
org.jetbrains.skiko.context
import
org.jetbrains.skia.ColorSpace
import
org.jetbrains.skia.Surface
import
org.jetbrains.skia.SurfaceColorFormat
import
org.jetbrains.skia.SurfaceOrigin
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.redrawer.MetalRedrawer
internal
class
MetalContextHandler
(
layer
:
SkiaLayer
)
:
ContextHandler
(
layer
)
{
val
metalRedrawer
:
MetalRedrawer
get
()
=
layer
.
redrawer
!!
override
fun
initContext
():
Boolean
{
try
{
if
(
context
==
null
)
{
context
=
metalRedrawer
.
makeContext
()
}
}
catch
(
e
:
Exception
)
{
println
(
"${e.message}\nFailed to create Skia Metal context!"
)
return
false
}
return
true
}
override
fun
initCanvas
()
{
disposeCanvas
()
val
scale
=
layer
.
contentScale
val
w
=
(
layer
.
width
*
scale
).
toInt
().
coerceAtLeast
(
0
)
val
h
=
(
layer
.
height
*
scale
).
toInt
().
coerceAtLeast
(
0
)
renderTarget
=
metalRedrawer
.
makeRenderTarget
(
w
,
h
)
surface
=
Surface
.
makeFromBackendRenderTarget
(
context
!!
,
renderTarget
!!
,
SurfaceOrigin
.
TOP_LEFT
,
SurfaceColorFormat
.
BGRA_8888
,
ColorSpace
.
sRGB
)
canvas
=
surface
!!
.
canvas
}
override
fun
flush
()
{
// TODO: maybe make flush async as in JVM version.
super
.
flush
()
surface
!!
.
flushAndSubmit
()
metalRedrawer
.
finishFrame
()
}
override
fun
rendererInfo
():
String
{
return
"Native Metal: device ${metalRedrawer.device.name}"
}
}
skiko/src/iosMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt
View file @
73c0bbc5
package
org.jetbrains.skiko.redrawer
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.SkiaLayerProperties
import
kotlinx.cinterop.addressOf
import
kotlinx.cinterop.autoreleasepool
import
kotlinx.cinterop.objcPtr
import
kotlinx.cinterop.usePinned
import
org.jetbrains.skia.BackendRenderTarget
import
org.jetbrains.skia.DirectContext
import
org.jetbrains.skiko.*
import
platform.CoreGraphics.CGColorCreate
import
platform.CoreGraphics.CGColorSpaceCreateDeviceRGB
import
platform.CoreGraphics.CGContextRef
import
platform.Metal.MTLCreateSystemDefaultDevice
import
platform.Metal.MTLDeviceProtocol
import
platform.Metal.MTLPixelFormatBGRA8Unorm
import
platform.QuartzCore.CAMetalDrawableProtocol
import
platform.QuartzCore.CAMetalLayer
import
platform.QuartzCore.kCAGravityTopLeft
import
kotlin.system.getTimeNanos
internal
class
MetalRedrawer
(
private
val
layer
:
SkiaLayer
,
private
val
properties
:
SkiaLayerProperties
)
:
Redrawer
{
private
var
isDisposed
=
false
internal
val
device
=
MTLCreateSystemDefaultDevice
()
!!
private
val
queue
=
device
.
newCommandQueue
()
!!
private
var
currentDrawable
:
CAMetalDrawableProtocol
?
=
null
private
val
metalLayer
=
MetalLayer
(
this
.
layer
,
device
)
private
val
frameDispatcher
=
FrameDispatcher
(
SkikoDispatchers
.
Main
)
{
if
(
layer
.
isShowing
())
{
update
(
getTimeNanos
())
draw
()
}
}
fun
makeContext
()
=
DirectContext
.
makeMetal
(
device
.
objcPtr
(),
queue
.
objcPtr
())
fun
makeRenderTarget
(
width
:
Int
,
height
:
Int
):
BackendRenderTarget
{
currentDrawable
=
metalLayer
.
nextDrawable
()
!!
return
BackendRenderTarget
.
makeMetal
(
width
,
height
,
currentDrawable
!!
.
texture
.
objcPtr
())
}
override
fun
dispose
()
{
TODO
()
frameDispatcher
.
cancel
()
isDisposed
=
true
}
override
fun
syncSize
()
{
TODO
(
)
println
(
"TODO: implement syncSize()"
)
}
override
fun
needRedraw
()
{
TODO
()
check
(!
isDisposed
)
{
"MetalRedrawer is disposed"
}
frameDispatcher
.
scheduleFrame
()
}
override
fun
redrawImmediately
()
{
TODO
()
check
(!
isDisposed
)
{
"MetalRedrawer is disposed"
}
update
(
getTimeNanos
())
draw
()
}
private
fun
update
(
nanoTime
:
Long
)
{
layer
.
update
(
nanoTime
)
}
private
fun
draw
()
{
// TODO: maybe make flush async as in JVM version.
autoreleasepool
{
if
(!
isDisposed
)
{
layer
.
draw
()
}
}
}
fun
finishFrame
()
{
autoreleasepool
{
currentDrawable
?.
let
{
val
commandBuffer
=
queue
.
commandBuffer
()
!!
commandBuffer
.
label
=
"Present"
commandBuffer
.
presentDrawable
(
it
)
commandBuffer
.
commit
()
currentDrawable
=
null
}
}
}
}
class
MetalLayer
(
private
val
skiaLayer
:
SkiaLayer
,
theDevice
:
MTLDeviceProtocol
)
:
CAMetalLayer
()
{
init
{
this
.
setNeedsDisplayOnBoundsChange
(
true
)
this
.
removeAllAnimations
()
// TODO: looks like a bug in K/N interop.
this
.
device
=
theDevice
as
objcnames
.
protocols
.
MTLDeviceProtocol
?
this
.
pixelFormat
=
MTLPixelFormatBGRA8Unorm
this
.
contentsGravity
=
kCAGravityTopLeft
doubleArrayOf
(
0.0
,
0.0
,
0.0
,
0.0
).
usePinned
{
this
.
backgroundColor
=
CGColorCreate
(
CGColorSpaceCreateDeviceRGB
(),
it
.
addressOf
(
0
))
}
this
.
opaque
=
true
this
.
frame
=
skiaLayer
.
view
.
frame
skiaLayer
.
view
.
layer
.
addSublayer
(
this
)
}
fun
draw
()
{
skiaLayer
.
update
(
getTimeNanos
())
skiaLayer
.
draw
()
}
fun
dispose
()
{
this
.
removeFromSuperlayer
()
// TODO: anything else to dispose the layer?
}
@Suppress
(
"unused"
)
private
fun
performDraw
()
{
draw
()
}
override
fun
drawInContext
(
ctx
:
CGContextRef
?)
{
draw
()
super
.
drawInContext
(
ctx
)
}
}
skiko/src/iosMain/kotlin/org/jetbrains/skiko/redrawer/OpenGLRedrawer.ios.kt
deleted
100644 → 0
View file @
920a24cf
package
org.jetbrains.skiko.redrawer
import
org.jetbrains.skiko.SkiaLayer
import
org.jetbrains.skiko.SkiaLayerProperties
import
kotlin.system.getTimeNanos
internal
class
OpenGLRedrawer
(
private
val
layer
:
SkiaLayer
,
private
val
properties
:
SkiaLayerProperties
)
:
Redrawer
{
override
fun
dispose
()
{
println
(
"dispose"
)
}
override
fun
syncSize
()
{
println
(
"syncSize"
)
}
override
fun
needRedraw
()
{
println
(
"needRedraw"
)
}
override
fun
redrawImmediately
()
{
layer
.
update
(
getTimeNanos
())
}
}
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