为了避免同时从gpu和cpu写入常量缓冲区,Apple建议在信号量的帮助下使用三缓冲系统来防止cpu远远超过gpu(这很好)现阶段至少包含三个金属视频)。
但是,当常量资源是MTLTexture并且AVCaptureVideoDataOutput委托与渲染循环(CADisplaylink)分开运行时,类似的三重缓冲系统(如Apple的示例代码MetalVideoCapture中所使用的)如何保证同步?如果您使用MetalVideoCapture代码并简单地渲染全屏四边形并将预设更改为AVCaptureSessionPresetHigh(此时撕裂被旋转四边形和低质量预设遮挡),则可以观察到屏幕撕裂(纹理撕裂)。
我意识到渲染循环和captureOutput委托方法(在这种情况下)都在主线程上,并且信号量(在渲染循环中)保持_constantDataBufferIndex整数被检查(其中索引到MTLTexture用于创建和编码),但仍然可以观察到屏幕撕裂,这对我来说很困惑(如果纹理的gpu写入不是编码后的下一帧但是后面有2或3帧,那将是有意义的,但我不相信这个是这样的)。此外,只是一个小问题:渲染循环和captureOutput对于缓冲纹理系统不应具有相同的帧速率,因此旧帧不会与最近的帧交错。
对此事的任何想法或澄清将不胜感激;还有另一个来自McZonk的例子,它不使用三重缓冲系统,但我也观察到用这种方法撕裂(但不那么)。显然,如果我使用waitUntilCompleted(相当于Open GL的glfinish),没有观察到撕裂,但这就像是用一只手臂绑在背后的手风琴一样!