When the GPU finishes rendering a view we can copy the resulting data back to the CPU. Because the buffer is still in use this requires flushing the RHI and stalling the GPU from doing any additional work while the copy is in progress. To resolve this issue, when the data is returned we schedule a copy to a surface that isn't in use which allows the GPU to resume work. Then when the surface is written to, we can copy it to the CPU without blocking the GPU. This requires ensuring that the surface is available, so this SurfaceReader implements a trigger system to ensure we don't try to access the surface until it has been written to, combined with a round-robin of surfaces to avoid stalls.