swiftsprite-kit

Execution of the command buffer was aborted due to an error during execution. Insufficient Permission (to submit GPU work from background)


I have a SpriteKit project in which I'm suddenly seeing the following error repeatedly printed to the logs when testing on a real device:

Execution of the command buffer was aborted due to an error during execution. Insufficient Permission (to submit GPU work from background)

This happens when the app is in the background state.

Now, it's pretty obvious what's going on: SpriteKit uses Metal, and the latter is committing new work to the GPU when the app is backgrounded (which is something you can't do).

I've confirmed this theory by not loading my SpriteKit scenes. If I don't load the scenes, the problem does not occur.

What I've tried:

In my SceneDelegate's sceneWillResignActive(_:) function, I tried setting isPaused to true, like this:

func sceneWillResignActive(_ scene: UIScene) {
    GameSceneHelper.scene.isPaused = true
    CloudSceneHelper.scene.isPaused = true
}

...and then resuming the scenes in sceneDidBecomeActive(_:), like this:

func sceneDidBecomeActive(_ scene: UIScene) {
    GameSceneHelper.scene.isPaused = false
    CloudSceneHelper.scene.isPaused = false
}

I'd think that would work, but it doesn't. The error persists.

Question:

What's going on, here? Why am I suddenly getting this new error, and how do I solve the problem?

Thank you!

Edit:

I found a (ugly) workaround: Because my SpriteKit scenes are presented using SwiftUI, I can just set a boolean that indicates whether or not to show the scenes. There's no error when I do it this way.

Unfortunately, this results in undesirable behaviors: 1) when you swipe the app away, you can see the scene suddenly disappear, 2) when you bring the app to the foreground you can see the scene suddenly reappear, and 3) the app snapshot (that iOS takes of your app when you move it to the background) shows an empty screen because the scenes have already been hidden when it takes the snapshot.

I can't understand why this is happening in the first place; my understanding was that SpriteKit scenes are automatically paused when the app is in the background.

So, I'm still looking for a better solution -- and maybe an explanation.

Edit #2:

According to Apple's documentation, SpriteKit is, indeed, paused/resumed automatically when the app goes from/to the background:

When an application moves from an active to an inactive state, isPaused is automatically set to true. When an application returns to an active state, isPaused is automatically set to its previous value.


Solution

  • I heard back from Apple Support after sending them an Xcode project illustrating the problem. They recommended that I file a bug report using Feedback Assistant. So, it appears that this is a legitimate bug.

    Apple says the problem is related to the use of the playSoundFileNamed, which is somehow making my update(_:) function get called while the app is in the background (and while the SpriteKit scene is paused!).

    What's really weird to me is that I don't see other people reporting this problem. If all it takes to trigger this is the use of playSoundFileNamed, I would expect a lot of SpriteKit developers to have the same issue. Maybe SpriteKit isn't used that much? I don't know.