Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reuse cached MTLCommandQueue across multiple MetalRedrawer's #1127

Merged
merged 2 commits into from
Feb 21, 2024

Conversation

elijah-semyonov
Copy link

@elijah-semyonov elijah-semyonov commented Feb 21, 2024

Proposed Changes

MTLCommandQueue is not a transient object and internal pools of them can be starved. It leads to Metal being unable to allocate a new one when GC hasn't collected the previously created queues.
Cache it for reuse purposes.

Testing

Test: N/A

Issues Fixed

Fixes: COMPOSE-1022

@elijah-semyonov elijah-semyonov self-assigned this Feb 21, 2024
@elijah-semyonov elijah-semyonov changed the title Reuse cached MTLCommandQueue. Reuse cached MTLCommandQueue across multiple MetalRedrawer's Feb 21, 2024

private class CachedCommandQueue(
val queue: MTLCommandQueueProtocol,
var refCount: Int = 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

atomic?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assumed to be used from the main thread.

@@ -461,6 +464,46 @@ internal class MetalRedrawer(
companion object {
private val renderingDispatchQueue =
dispatch_queue_create("RenderingDispatchQueue", null)

private class CachedCommandQueue(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd move it out from companion object and expose methods instead of public properties

* Get an existing command queue associated with the device or create a new one and cache it.
* Assumed to be run on the main thread.
*/
fun getCachedCommandQueue(device: MTLDeviceProtocol): MTLCommandQueueProtocol {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be private in current impl

@elijah-semyonov elijah-semyonov merged commit de0d28d into jb-main Feb 21, 2024
6 checks passed
@elijah-semyonov elijah-semyonov deleted the es/ios-fix-mtlcq-crash branch February 21, 2024 13:27
igordmn pushed a commit that referenced this pull request Feb 21, 2024
## Proposed Changes

`MTLCommandQueue` is not a transient object and internal pools of them
can be starved. It leads to Metal being unable to allocate a new one
when GC hasn't collected the previously created queues.
Cache it for reuse purposes.

## Testing

Test: N/A

## Issues Fixed

Fixes:
[COMPOSE-1022](https://youtrack.jetbrains.com/issue/COMPOSE-1022/)
@igordmn igordmn added changelog: prerelease fix Fixes the bug introduced in alpha/beta/rc ios labels Feb 22, 2024
elijah-semyonov added a commit to JetBrains/skiko that referenced this pull request May 27, 2024
Speculative fix for [a
case](JetBrains/compose-multiplatform#4761),
where a lot of windows are created and dismissed.

Caches command queue per device [similar to
iOS](JetBrains/compose-multiplatform-core#1127)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog: prerelease fix Fixes the bug introduced in alpha/beta/rc ios
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants