ios 使用Metal进行屏幕撕裂和摄像头捕获

gijlo24d  于 9个月前  发布在  iOS
关注(0)|答案(1)|浏览(103)

为了避免同时从GPU和CPU写入恒定的缓冲区,Apple建议使用三重缓冲系统,并借助信号量防止CPU远远领先于GPU(这很好,目前至少有三个Metal视频介绍)。
但是,当常量资源是MTLTexture并且AVCaptureVideoDataOutput委托与呈现循环分开运行时,(CADisplaylink),一个类似的三重缓冲系统(如在苹果的示例代码MetalVideoCapture中使用的)保证同步?屏幕撕裂如果您使用MetalVideoCapture代码并简单地渲染全屏四边形并将预设更改为AVCaptureSessionPresetHigh,则可以观察到(纹理撕裂)(此时撕裂被旋转的四边形和低质量预设所掩盖)。
我意识到呈现循环和captureOutput委托方法(在这种情况下)都在主线程上,并且信号量(在呈现循环中)保持_constantDataBufferIndex整数处于检查状态(它索引到MTLTexture中以进行创建和编码),但仍然可以观察到屏幕撕裂,这让我很困惑(如果纹理的gpu写入不是编码后的下一帧而是编码后的2或3帧,这是有意义的,但我不相信是这种情况)。只是一个小问题:渲染循环和captureOutput是否应该有相同的帧速率,以便缓冲纹理系统,使旧帧不会与最近的帧交错渲染。
如果您有任何想法或澄清,我将不胜感激;还有一个来自McZonk的例子,它没有使用三重缓冲系统,但我也观察到了这种方法的撕裂(但不太严重)。显然,如果我使用waitUntilCompleted(相当于Open GL的glfinish),就不会观察到撕裂,但这就像在背后绑着一只胳膊拉 accordion 一样!

nzrxty8p

nzrxty8p1#

根据我的评论,我应该在几年前发布一个答案,但是通过为Y和CbCr的CVMetalTextureRef使用三重缓冲示例变量,撕裂消失了。在Apple发布的第一个示例代码中,只有Y和CbCr MTLTextures是示例变量。

相关问题