It is safe to draw on background threads. The docs for -nextDrawable
say:
Calling this method blocks the current CPU thread until a new drawable is available.
(Emphasis added.) If it could only be called on the main thread, that would probably not be so generalized. Also, Apple's general advice is to avoid blocking the main thread, so you'd think they would call out that fact in some way here, such as advising you not to call it unless you're pretty sure it won't block.
For how the drawable is used (rather than obtained), note that a typical use case is to call the command buffer's -presentDrawable:
method. That method is a convenience for adding a scheduled handler block (as via -addScheduledHandler:
) which will then call -present
on the drawable. It is unspecified what thread or queue the handler blocks will be called on, which suggests that there's no promise that the -present
call on the drawable will happen on the main thread.
And even after that, the actual presentation of the drawable to the screen is not synchronous within the call to -present
. The drawable waits until any commands that render or write to its texture are completed and only then presents to the screen. It's not specified how that asynchronicity is achieved, but it further suggests that it doesn't matter what thread -present
is called on.
There's a bit of discussion about multi-threading in the Metal Programming Guide, although it's not quite as direct as one might hope. See especially the section on Multiple Threads, Command Buffers, and Command Encoders. Note that there's a discussion of command buffers being filled by background threads and no specific warning about working with drawables. Again, it's sort of argument by lack of evidence, but I think it's clear. They do call out that only a single thread may act on a given command buffer at a time, so they are considering thread safety questions.