Prepare your app to move into the background by pausing future GPU use and ensuring previous work is scheduled.
iOS and tvOS restrict a background app's access to the GPU, to guarantee foreground app performance. If a Metal command queue tries to schedule command buffers after the app moves in the background, the system prevents those commands from executing. When UIKit notifies you that your app is being suspended or moved into the background, your app must restrict its use of Metal.
For more information on the UIKit app life cycle, see Preparing Your UI to Run in the Background.
Disable Code that Commits New Command Buffers
When your app is deactivated, stop sending work to Metal. Enable that code only after your app is reactivated.
After the system notifies your app that it is being deactivated, you have some time before the system restricts your app from using Metal. You can schedule additional commands if that work is critical to prepare your app to be in the background state. Similarly, if your app was already in the middle of encoding commands, your app can typically finish the current task before disabling further work. For example, if your app renders frames of animation to the screen, and you receive the notification while you're encoding commands for a new frame, you can finish encoding that frame before disabling your rendering code.
Ensure All Previous Work is Scheduled for Execution
When UIKit calls your app delegate's
application method, make sure Metal has scheduled all command buffers you've already committed before your app returns control to the system. On each command queue, if the last command buffer you queued isn't already scheduled or complete, call
wait to force it to be scheduled.
If you're in the middle of encoding a new command buffer, you can combine these steps. Finish encoding commands to render the frame and commit the command buffer, then call
After your app moves into the background, if Metal sees a new command buffer from your app, it returns an error, rather than scheduling the command buffer. You can test for this error by adding a completion handler (
add). Inside your completion handler, check the