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
a662a791
Unverified
Commit
a662a791
authored
Jul 26, 2023
by
Elijah Semyonov
Committed by
GitHub
Jul 26, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove synchronous draw reentry logic inside needRedraw completely (#773)
parent
68677fd5
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
10 additions
and
66 deletions
+10
-66
SkikoUIView.kt
skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkikoUIView.kt
+0
-2
MetalRedrawer.ios.kt
.../kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt
+10
-64
No files found.
skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkikoUIView.kt
View file @
a662a791
...
@@ -259,8 +259,6 @@ class SkikoUIView : UIView, UIKeyInputProtocol, UITextInputProtocol {
...
@@ -259,8 +259,6 @@ class SkikoUIView : UIView, UIKeyInputProtocol, UITextInputProtocol {
platform
=
event
platform
=
event
)
)
)
)
// If invalidation doesn't happen while onPointerEvent is processed, it's too late to schedule any work for this frame.
skiaLayer
?.
redrawer
?.
preventDrawDispatchDuringCurrentFrame
()
}
}
private
val
UITouch
.
isPressed
get
()
=
private
val
UITouch
.
isPressed
get
()
=
...
...
skiko/src/iosMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt
View file @
a662a791
...
@@ -16,15 +16,8 @@ import platform.Metal.MTLCreateSystemDefaultDevice
...
@@ -16,15 +16,8 @@ import platform.Metal.MTLCreateSystemDefaultDevice
import
platform.Metal.MTLDeviceProtocol
import
platform.Metal.MTLDeviceProtocol
import
platform.Metal.MTLPixelFormatBGRA8Unorm
import
platform.Metal.MTLPixelFormatBGRA8Unorm
import
platform.QuartzCore.*
import
platform.QuartzCore.*
import
platform.UIKit.window
import
platform.darwin.*
import
platform.darwin.*
private
enum
class
DrawSchedulingState
{
AVAILABLE_ON_NEXT_FRAME
,
AVAILABLE_ON_CURRENT_FRAME
,
SCHEDULED_ON_NEXT_FRAME
}
internal
class
MetalRedrawer
(
internal
class
MetalRedrawer
(
private
val
layer
:
SkiaLayer
private
val
layer
:
SkiaLayer
)
:
Redrawer
{
)
:
Redrawer
{
...
@@ -41,24 +34,9 @@ internal class MetalRedrawer(
...
@@ -41,24 +34,9 @@ internal class MetalRedrawer(
private
val
inflightSemaphore
=
dispatch_semaphore_create
(
metalLayer
.
maximumDrawableCount
.
toLong
())
private
val
inflightSemaphore
=
dispatch_semaphore_create
(
metalLayer
.
maximumDrawableCount
.
toLong
())
/*
/*
* Initial value is [DrawSchedulingState.AVAILABLE_ON_NEXT_FRAME] because voluntarily dispatching a frame
* Indicates that scene is invalidated and next display link callback will draw
* disregarding CADisplayLink timing (which is not accessible while it's paused) can cause frame drifting in worst
* cases adding one frame latency due to presentation mechanism, if followed by steady draw dispatch
* (which is often the case).
* TODO: look closer to what happens after blank frames leave it in AVAILABLE_ON_CURRENT_FRAME. Touch driven events sequence negate that problem.
*/
*/
private
var
drawSchedulingState
=
DrawSchedulingState
.
AVAILABLE_ON_NEXT_FRAME
private
var
hasScheduledDrawOnNextVSync
=
false
/**
* UITouch events are dispatched right before next CADisplayLink callback by iOS.
* It's too late to encode any work for this frame after this happens.
* Any work dispatched before the next CADisplayLink callback should be scheduled after that callback.
*/
fun
preventDrawDispatchDuringCurrentFrame
()
{
if
(
drawSchedulingState
==
DrawSchedulingState
.
AVAILABLE_ON_CURRENT_FRAME
)
{
drawSchedulingState
=
DrawSchedulingState
.
AVAILABLE_ON_NEXT_FRAME
}
}
/**
/**
* Needs scheduling displayLink for forcing UITouch events to come at the fastest possible cadence.
* Needs scheduling displayLink for forcing UITouch events to come at the fastest possible cadence.
...
@@ -74,20 +52,10 @@ internal class MetalRedrawer(
...
@@ -74,20 +52,10 @@ internal class MetalRedrawer(
}
}
private
val
frameListener
:
NSObject
=
FrameTickListener
{
private
val
frameListener
:
NSObject
=
FrameTickListener
{
when
(
drawSchedulingState
)
{
if
(
hasScheduledDrawOnNextVSync
)
{
DrawSchedulingState
.
AVAILABLE_ON_NEXT_FRAME
->
{
hasScheduledDrawOnNextVSync
=
false
drawSchedulingState
=
DrawSchedulingState
.
AVAILABLE_ON_CURRENT_FRAME
}
DrawSchedulingState
.
SCHEDULED_ON_NEXT_FRAME
->
{
drawSchedulingState
=
DrawSchedulingState
.
AVAILABLE_ON_NEXT_FRAME
drawIfLayerIsShowing
()
}
DrawSchedulingState
.
AVAILABLE_ON_CURRENT_FRAME
->
{
drawIfLayerIsShowing
()
// still available, do nothing
}
}
}
if
(!
needsProactiveDisplayLink
)
{
if
(!
needsProactiveDisplayLink
)
{
...
@@ -142,37 +110,15 @@ internal class MetalRedrawer(
...
@@ -142,37 +110,15 @@ internal class MetalRedrawer(
override
fun
needRedraw
()
{
override
fun
needRedraw
()
{
check
(!
isDisposed
)
{
"MetalRedrawer is disposed"
}
check
(!
isDisposed
)
{
"MetalRedrawer is disposed"
}
drawImmediatelyIfPossible
()
hasScheduledDrawOnNextVSync
=
true
if
(
drawSchedulingState
==
DrawSchedulingState
.
SCHEDULED_ON_NEXT_FRAME
)
{
// If caDisplayLink is proactive (touches tracking), this does nothing (already unpaused)
caDisplayLink
.
setPaused
(
false
)
caDisplayLink
.
setPaused
(
false
)
}
}
}
override
fun
redrawImmediately
()
{
override
fun
redrawImmediately
()
{
check
(!
isDisposed
)
{
"MetalRedrawer is disposed"
}
// TODO: separate iOS MetalRedrawer from Redrawer, it's a false abstraction, iOS only uses MetalRedrawer explicitly
draw
()
throw
UnsupportedOperationException
(
"This should never be called on iOS"
)
}
/*
* Dispatch redraw immediately during current frame if possible and updates [drawSchedulingState] to relevant value
*/
private
fun
drawImmediatelyIfPossible
()
{
when
(
drawSchedulingState
)
{
DrawSchedulingState
.
AVAILABLE_ON_NEXT_FRAME
->
{
drawSchedulingState
=
DrawSchedulingState
.
SCHEDULED_ON_NEXT_FRAME
}
DrawSchedulingState
.
AVAILABLE_ON_CURRENT_FRAME
->
{
drawSchedulingState
=
DrawSchedulingState
.
AVAILABLE_ON_NEXT_FRAME
drawIfLayerIsShowing
()
}
DrawSchedulingState
.
SCHEDULED_ON_NEXT_FRAME
->
{
// already scheduled, do nothing
}
}
}
}
private
fun
drawIfLayerIsShowing
()
{
private
fun
drawIfLayerIsShowing
()
{
...
...
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