Preparing Your Metal App to Run in the Background

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 applicationDidEnterBackground(_:) 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 waitUntilScheduled() 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 waitUntilScheduled().

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 (addCompletedHandler(_:)). Inside your completion handler, check the status and error properties.

See Also

Command Setup

Setting Up a Command Structure

Discover how Metal executes commands on a GPU.

protocol MTLCommandQueue

A queue that organizes command buffers to be executed by a GPU.

protocol MTLCommandBuffer

A container that stores encoded commands for the GPU to execute.

protocol MTLCommandEncoder

An encoder that writes GPU commands into a command buffer.

Counter Sampling

Retrieve information about how the GPU executed your commands.