Skip to content

Commit

Permalink
Disable encoding on separate thread for iOS (#907)
Browse files Browse the repository at this point in the history
## Proposed Changes

Using Skia context in multiple threads simultaneously leads to
occasional unreproducable crashes on users' side.
Roll back experimental #896. Disable the path for encoding rendering
commands on a separate thread until the scenario is resolved and
underlying issue is fixed.

## Testing

Test: N/A

## Issues Fixed

Fixes: JetBrains/compose-multiplatform#3862
  • Loading branch information
elijah-semyonov committed Nov 17, 2023
1 parent f01d58e commit 33000e0
Showing 1 changed file with 7 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,6 @@ internal class MetalRedrawer(
private var lastRenderTimestamp: NSTimeInterval = CACurrentMediaTime()
private val pictureRecorder = PictureRecorder()

/**
* Lock used to avoid skia context being disposed in the middle of rendering encoding on a separate thread.
*/
private val disposeLock = NSLock()

// Semaphore for preventing command buffers count more than swapchain size to be scheduled/executed at the same time
private val inflightSemaphore =
dispatch_semaphore_create(metalLayer.maximumDrawableCount.toLong())
Expand Down Expand Up @@ -289,7 +284,7 @@ internal class MetalRedrawer(
caDisplayLink.addToRunLoop(NSRunLoop.mainRunLoop, NSRunLoop.mainRunLoop.currentMode)
}

fun dispose() = disposeLock.doLocked {
fun dispose() {
check(caDisplayLink != null) { "MetalRedrawer.dispose() was called more than once" }

applicationStateListener.dispose()
Expand Down Expand Up @@ -386,7 +381,11 @@ internal class MetalRedrawer(
isForcedToPresentWithTransactionEveryFrame || interopTransaction.isNotEmpty()
metalLayer.presentsWithTransaction = presentsWithTransaction

val mustEncodeAndPresentOnMainThread = presentsWithTransaction || waitUntilCompletion
// TODO: encoding on separate thread requires investigation for reported crashes
// https://github.com/JetBrains/compose-multiplatform/issues/3862
// https://youtrack.jetbrains.com/issue/COMPOSE-608/iOS-reproduce-and-investigate-parallel-rendering-encoding-crash
// val mustEncodeAndPresentOnMainThread = presentsWithTransaction || waitUntilCompletion
val mustEncodeAndPresentOnMainThread = true

val encodeAndPresentBlock = {
surface.canvas.drawPicture(picture)
Expand Down Expand Up @@ -437,16 +436,7 @@ internal class MetalRedrawer(
} else {
dispatch_async(renderingDispatchQueue) {
autoreleasepool {
disposeLock.doLocked {
if (caDisplayLink == null) {
// Was disposed before render encoding started
picture.close()
surface.close()
renderTarget.close()
} else {
encodeAndPresentBlock()
}
}
encodeAndPresentBlock()
}
}
}
Expand Down

0 comments on commit 33000e0

Please sign in to comment.