金属有后缓冲吗?

时间:2015-08-13 17:48:40

标签: ios metal

我目前正在追踪我的Metal应用程序中的一些视觉弹出,并且相信这是因为我直接绘制到帧缓冲区,而不是后台缓冲区

  // this is when I've finished passing commands to the render buffer and issue the draw command.  I believe this sends all the images directly to the framebuffer instead of using a backbuffer
  [renderEncoder endEncoding];
  [mtlCommandBuffer presentDrawable:frameDrawable];
  [mtlCommandBuffer commit];
  [mtlCommandBuffer release];
  //[frameDrawable present];   // This line isn't needed (and I believe is performed by presentDrawable

之后的几个谷歌,我还没有找到金属中的后缓冲器的任何文档。我知道我可以自己滚动,但我不相信金属不支持后缓冲。

以下是我如何设置CAMetalLayer对象的代码片段。

+ (id)layerClass
{
    return [CAMetalLayer class];
}

- (void)initCommon
{
    self.opaque          = YES;
    self.backgroundColor = nil;
    ...
}

-(id <CAMetalDrawable>)getMetalLayer
{
    id <CAMetalDrawable> frameDrawable;
    while (!frameDrawable && !frameDrawable.texture)
    {
        frameDrawable = [self->_metalLayer nextDrawable];
    }
    return frameDrawable;
}

我可以在CAMetalLayer对象上启用后备缓冲区,还是需要自己滚动?

1 个答案:

答案 0 :(得分:7)

我假设 back-buffer ,你的意思是渲染的渲染缓冲区,而正在显示相应的前缓冲区

在Metal中,概念由您从CAMetalLayer提取的drawable提供。 CAMetalLayer实例维护一个小的drawables池(通常为3),每次调用nextDrawable时从池中检索其中一个,并在调用{{1}后将其返回池中并且一旦渲染完成(可能需要一段时间,因为GPU从CPU异步运行)。

实际上,在每个帧循环中,您可以通过调用presentDrawable来获取后台缓冲区,并通过调用使其有资格成为前台缓冲区 nextDrawable并提交presentDrawable:

由于池中只有3个drawable,因此您必须自己管理此生命周期,方法是在调用MTLCommandBuffer时添加适当的CPU资源同步,并在渲染时获得回调。完成(根据nextDrawable回调设置)。

通常,您使用MTLCommandBuffer addCompletedHandler:

dispatch_semaphore_t

然后在调用_resource_semaphore = dispatch_semaphore_create(3); 之前添加以下内容:

nextDrawable

这在你的dispatch_semaphore_wait(_resource_semaphore, DISPATCH_TIME_FOREVER); 回调处理程序中:

addCompletedHandler:

查看Apple的一些简单的Metal示例应用程序,了解这一点。 Apple的文档在这方面没有太多。