JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
14.85k stars 1.08k forks source link

org.jetbrains.skiko.RenderException: Cannot init graphic context / Insufficient Memory #4761

Open sunny-chung opened 1 week ago

sunny-chung commented 1 week ago

Describe the bug On running the gradle task run, an empty window is displayed, and some error messages are logged.

Affected platforms

Versions

To Reproduce Steps and/or the code snippet to reproduce the behavior:

  1. In IntelliJ IDEA, run the gradle task run. Optionally, add the java VM option -Xmx4096m to the run configuration.
  2. Wait and observe the output.

Expected behavior A window with application UI should be displayed.

Screenshots

Screenshot 2024-05-03 at 12 21 54 PM Screenshot 2024-05-06 at 12 40 01 PM

Additional context

Log:

[SKIKO] warn: Failed to create Skia Metal context!
java.lang.RuntimeException: Can't wrap nullptr
[SKIKO] warn: Exception in draw scope
org.jetbrains.skiko.RenderException: Cannot init graphic context
2024-05-06 12:47:52.292 java[40676:28196535] WARNING: Secure coding is not enabled for restorable state! Enable secure coding by implementing NSApplicationDelegate.applicationSupportsSecureRestorableState: and returning YES.
2024-05-06 12:47:52.558 java[40676:28196546] GLDRendererMetal command buffer completion error: Error Domain=MTLCommandBufferErrorDomain Code=8 "Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory)" UserInfo={NSLocalizedDescription=Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory), NSUnderlyingError=0x600003410960 {Error Domain=IOGPUCommandQueueErrorDomain Code=8 "(null)"}}
2024-05-06 12:47:52.591 java[40676:28196615] GLDRendererMetal command buffer completion error: Error Domain=MTLCommandBufferErrorDomain Code=8 "Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory)" UserInfo={NSLocalizedDescription=Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory), NSUnderlyingError=0x60000340f360 {Error Domain=IOGPUCommandQueueErrorDomain Code=8 "(null)"}}
2024-05-06 12:47:52.660 java[40676:28196546] GLDRendererMetal command buffer completion error: Error Domain=MTLCommandBufferErrorDomain Code=8 "Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory)" UserInfo={NSLocalizedDescription=Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory), NSUnderlyingError=0x60000340fc90 {Error Domain=IOGPUCommandQueueErrorDomain Code=8 "(null)"}}
2024-05-06 12:47:52.661 java[40676:28196546] GLDRendererMetal command buffer completion error: Error Domain=MTLCommandBufferErrorDomain Code=8 "Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory)" UserInfo={NSLocalizedDescription=Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory), NSUnderlyingError=0x60000340f480 {Error Domain=IOGPUCommandQueueErrorDomain Code=8 "(null)"}}
2024-05-06 12:47:52.662 java[40676:28196546] GLDRendererMetal command buffer completion error: Error Domain=MTLCommandBufferErrorDomain Code=8 "Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory)" UserInfo={NSLocalizedDescription=Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory), NSUnderlyingError=0x600003421650 {Error Domain=IOGPUCommandQueueErrorDomain Code=8 "(null)"}}
2024-05-06 12:47:52.663 java[40676:28196546] GLDRendererMetal command buffer completion error: Error Domain=MTLCommandBufferErrorDomain Code=8 "Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory)" UserInfo={NSLocalizedDescription=Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory), NSUnderlyingError=0x60000342e0a0 {Error Domain=IOGPUCommandQueueErrorDomain Code=8 "(null)"}}
2024-05-06 12:47:57.515 java[40676:28196546] GLDRendererMetal command buffer completion error: Error Domain=MTLCommandBufferErrorDomain Code=8 "Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory)" UserInfo={NSLocalizedDescription=Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory), NSUnderlyingError=0x600003418690 {Error Domain=IOGPUCommandQueueErrorDomain Code=8 "(null)"}}
2024-05-06 12:47:57.547 java[40676:28196615] GLDRendererMetal command buffer completion error: Error Domain=MTLCommandBufferErrorDomain Code=8 "Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory)" UserInfo={NSLocalizedDescription=Insufficient Memory (00000008:kIOGPUCommandBufferCallbackErrorOutOfMemory), NSUnderlyingError=0x600003418600 {Error Domain=IOGPUCommandQueueErrorDomain Code=8 "(null)"}}

When "Insufficient Memory" appeared, I checked "Activity Monitor" in macOS and observed both IntelliJ IDEA and MainKt (the application) did not exceed the customized JVM memory limit. Their sum did not exceed the customized JVM memory limit set on IntelliJ IDEA as well.

"Insufficient Memory" does not always appear (e.g. the first screenshot).

This issue does not consistently appear all the time. I just want to know how could I workaround this when it appears, except restarting my computer.

elijah-semyonov commented 1 week ago

Hey @sunny-chung What is the device you are running this on? Can you create a minimal reproducible with this problem and share it with us?

I can clearly see this in both cases:

Failed to create Skia Metal context!

I wonder why any metal commands are dispatched in a first place.

sunny-chung commented 1 week ago

Hi @elijah-semyonov

I am running on a M2 MacBook Pro.

I can only provide the project I am working on to you, as I am not sure what is going on. The issue is not frequently reproducible. But once I hit it, I would keep hitting for a while. The file Main.kt may have what you need. Please let me know if I use Compose Desktop in a wrong way.

https://github.com/sunny-chung/hello-http/blob/f2dac5216bf8b96c28b57e43a1d6ac03870b7470/src/jvmMain/kotlin/com/sunnychung/application/multiplatform/hellohttp/Main.kt

elijah-semyonov commented 1 week ago

Thanks, I'll have a look.

elijah-semyonov commented 1 week ago

Are there some specific circumstances, that you could note, that lead to this? Do you have some heavy graphics application running along? I've played with an app for several minutes but didn't manage to reproduce the behavior.

elijah-semyonov commented 1 week ago

My wild guess is that id <MTLCommandQueue> is null if there are windows(popups) opened and closed very quickly for continuous time span.

It was solved by this PR on iOS: https://github.com/JetBrains/compose-multiplatform-core/pull/1127 If it's indeed the case, I'll roll a speculative fix for skiko window management on macOS.

sunny-chung commented 1 week ago

~It apparently only reproducible with IntelliJ IDEA and after I upgraded Compose Multiplatform from 1.6.0-rc02 to 1.6.2.~ It only happens while launching the application.

I did have running lots of browsers along. It seems my Mac runs apparently slower and displays some black pixels if I have Instagram with HDR media opening.

Near the end of Main.kt, there is a dummy Window. It will be dismissed after some background loading and after 500ms, and immediately followed by launching another Window. Perhaps that relates to the issue you mentioned.

sunny-chung commented 1 week ago

I have just reproduced with:

  1. Run the gradle task run with IntelliJ IDEA.
  2. Without closing the application, run a test case in the "ux-and-transport-test" module of the project using the green triangle button in IntelliJ IDEA. The window created in the test case is an empty window.
  3. Stop all the tasks.
  4. Rerun the test case. The window created is normal now.
  5. Repeat step 1 - 4 for several times.
  6. Without running the application, run the gradle task :ux-and-transport-test:check, the window created is an empty window.
  7. Stop it and then run the gradle task run. Now the application also shows an empty window, with the reported error messages output in the console.
  8. Rerun the gradle task run, the issue still exists.
  9. Stop it, run the gradle task clean and then run, the issue still exists.

During the time, I have no other heavy graphic-demanding applications running.

Edit: Run ./gradlew run in an external console yields the same result. Sometimes the issue is gone for a short while after reopening IntelliJ IDEA, sometimes after I rerun the :ux-and-transport-test:check gradle task and let it completes for several times.