查看Apple提供的用于Metal缓冲区和纹理资源的三重缓冲的代码,使用信号量可能会阻塞代码中的主线程,如下所示,这似乎很奇怪。这来自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
}
如何在调用drawInMTKView时调用dispatch_semaphore_wait()不阻塞主线程?
答案 0 :(得分:1)
它绝对可以阻止绘图线程,但在大多数应用程序中,这应该很少发生,如果有的话。当绘图由显示链接驱动时(默认情况下为MTKView
),绘制回调每隔约16ms到达一次。由于计数信号量允许在阻塞之前编码多达三个帧,因此这些帧中的第一个几乎肯定已经在后续帧回调到达之前已经完成执行(即,在50ms内),因此等待呼叫不会需要一个块。如果编码或执行平均花费的时间长于标称帧持续时间,则等待呼叫将阻塞,直到最近的未完成帧完成。