Multiple CAMetalLayer Slow Down

Creating multiple CAMetalLayers from a single device on iOS slows down the rendering cycle as the pool of available textures runs out. Any ways of getting around this limitation?
Answered by Graphics and Games Engineer in 616624022
I'm assuming that you are using on of the -[MTLCommandBuffer presentDrawable:] methods to present the drawable for each of the layers instead of using one of the -[MTLDrawable present] methods.

There is a limit to the rate of drawables command buffers from a single command queue can present when using any of the -[MTLCommandBuffer presentDrawable:] methods.  So, if you're using one of these present functions you're likely getting throttled by this limitation.  There 2 ways to get around it:

A) Use a separate command queue to issue commands to each of the layers.  This removes the limit at which your app can present drawables. However, it also means that each drawable will have a completely parallel stream of commands.  So if you have commands that are dependent on one another, you will need to synchronize those dependencies with a MTLEvent or MTLFence object.

B) Present each drawable using -[MTLDrawable present] after Metal has scheduled each frame's final command buffer. The tricky part here is making sure the command buffer is scheduled by Metal first.  The preferred solution is to make calls to -[MTLDrawable present] on each drawable within a schedule hander added to the final command buffer.  Alternatively you can call -[MTLCommandBuffer waitUntilScheduled] and then make calls to each drawable's -[MTLDrawable present] method, but this has the drawback of stalling your thread while Metal schedules the command buffer. 
Accepted Answer
I'm assuming that you are using on of the -[MTLCommandBuffer presentDrawable:] methods to present the drawable for each of the layers instead of using one of the -[MTLDrawable present] methods.

There is a limit to the rate of drawables command buffers from a single command queue can present when using any of the -[MTLCommandBuffer presentDrawable:] methods.  So, if you're using one of these present functions you're likely getting throttled by this limitation.  There 2 ways to get around it:

A) Use a separate command queue to issue commands to each of the layers.  This removes the limit at which your app can present drawables. However, it also means that each drawable will have a completely parallel stream of commands.  So if you have commands that are dependent on one another, you will need to synchronize those dependencies with a MTLEvent or MTLFence object.

B) Present each drawable using -[MTLDrawable present] after Metal has scheduled each frame's final command buffer. The tricky part here is making sure the command buffer is scheduled by Metal first.  The preferred solution is to make calls to -[MTLDrawable present] on each drawable within a schedule hander added to the final command buffer.  Alternatively you can call -[MTLCommandBuffer waitUntilScheduled] and then make calls to each drawable's -[MTLDrawable present] method, but this has the drawback of stalling your thread while Metal schedules the command buffer. 
Multiple CAMetalLayer Slow Down
 
 
Q