看看Apple为金属缓冲区和纹理资源的三重缓冲提供的代码,似乎很奇怪,使用信号量会阻止代码中的主线程,如下所示。这是来自 CPU and GPU Synchronization .
- (void)drawInMTKView:(nonnull MTKView *)view { dispatch_semaphore_t inFlightSemaphore = self.inFlightSemaphore; dispatch_semaphore_wait(inFlightSemaphore, DISPATCH_TIME_FOREVER); id <MTLCommandBuffer> commandBuffer = [mrc.commandQueue commandBuffer]; __block dispatch_semaphore_t block_sema = inFlightSemaphore; [commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) { dispatch_semaphore_signal(block_sema); }]; // Metal render commands }
调用dispatch\u semaphore\u wait()如何才能在调用drawInMTKView时阻止主线程?
它绝对可以阻止绘制线程,但在大多数应用程序中,这种情况应该很少发生,如果有的话。当图形由显示链接驱动时,默认情况下 MTKView ,每16毫秒提取一次回调。由于计数信号量允许在阻塞之前对最多三个帧进行编码,因此几乎可以肯定,在后续帧回调到达之前,这些帧中的第一个帧已经完成执行(即,在50 ms内),因此等待调用不需要阻塞。如果编码或执行所需的平均时间超过标称帧持续时间,则等待调用将阻塞,直到最近一个未完成的帧完成。
MTKView