Metal 三重缓冲示例中使用的信号量是否会阻塞主线程?

Metal 三重缓冲示例中使用的信号量是否会阻塞主线程?,metal,Metal,看看Apple提供的三重缓冲金属缓冲区和纹理资源的代码,使用信号量可能会阻塞如下代码中的主线程,这似乎非常奇怪。这是我的 -(void)drawInMTKView:(非空MTKView*)视图 { dispatch\u semaphore\u t inFlightSemaphore=self.inFlightSemaphore; 调度信号灯等待(inFlightSemaphore,调度时间永远); id commandBuffer=[mrc.commandQueue commandBuffer]

看看Apple提供的三重缓冲金属缓冲区和纹理资源的代码,使用信号量可能会阻塞如下代码中的主线程,这似乎非常奇怪。这是我的

-(void)drawInMTKView:(非空MTKView*)视图
{
dispatch\u semaphore\u t inFlightSemaphore=self.inFlightSemaphore;
调度信号灯等待(inFlightSemaphore,调度时间永远);
id commandBuffer=[mrc.commandQueue commandBuffer];
__块调度信号量\u t块信号量=inFlightSemaphore;
[commandBuffer addCompletedHandler:^(id缓冲区)
{
调度信号量信号(块信号);
}];
//金属渲染命令
}

调用dispatch\u semaphore\u wait()如何才能在调用drawInMTKView时阻止主线程?

它绝对可以阻止绘图线程,但在大多数应用程序中,这种情况应该很少发生,如果有的话。当绘图由显示链接驱动时(默认情况下是使用
MTKView
),绘图回调每隔16毫秒到达一次。由于计数信号量允许在阻塞之前编码最多三个帧,因此几乎可以肯定,在后续帧回调到达之前,这些帧中的第一个帧已经完成执行(即,在50毫秒内),因此等待调用不需要阻塞。如果编码或执行所需的平均时间超过标称帧持续时间,等待调用将阻塞,直到最近一个未完成的帧完成。

好的,在一切都非常快的情况下,它似乎很有用。但是,如果2或3个视图开始落后,会发生什么?这些将一次又一次地阻塞主线程,从而中断事件循环处理,对吗?对于金属性能着色器,是否也建议使用相同的三重缓冲方法?因此,在低优先级队列上执行它们是否更好?@DeepakSharma这可能是一个新问题。广义地说,除非你正在做大量的MPS操作,否则编码它们不太可能占用大量的CPU时间,但这只是等式的一部分。好吧,我将把它作为一个新问题,并提交链接here@warrenm这里是链接-
- (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
}