【问题标题】:When exactly is drawInMTKView called?究竟什么时候调用 drawInMTKView?
【发布时间】:2023-02-25 04:38:15
【问题描述】:

MetalKit 调用drawInMTKView 时它希望您的委托人绘制一个新框架,但我想知道它是否等待最后一个可绘制对象在它要求您的委托人绘制新框架之前呈现?

据我阅读 this article 的理解,CoreAnimation 最多可以提供三个“飞行中”可绘制对象,但我无法确定 MetalKit 是否会尽快尝试绘制它们,或者是否等待别的东西即将发生。

这会是什么别的东西?让我有点困惑的是提前绘制最多两帧的想法,因为这意味着 CPU 必须已经知道它想要在未来两帧渲染什么,我觉得情况并非总是如此。例如,如果您的应用程序依赖于用户输入,您无法预先知道从现在到您正在绘制的两个框架将被呈现之间用户将执行的操作,因此它们可能会呈现过时的内容。这个假设对吗?在这种情况下,仅以预期帧速率确定的最大速率调用委托方法可能是有意义的。

与帧速率同步的问题在于,这意味着 CPU 有时可能会在本可以完成一些有用的工作时处于非活动状态。

我也有直觉,这可能不会以这种方式发生,因为在上述文章中,drawInMTKView 似乎在 drawable 可用时被调用,因为他们似乎依赖它被调用来完成使用资源的工作一种避免 CPU 停顿的方法,但是由于有很多点我不清楚,所以我不确定到底发生了什么。

【问题讨论】:

    标签: ios swift core-animation metal metalkit


    【解决方案1】:

    MTKView文档在paused页面中提到

    如果值为NO,则视图会以preferredFramesPerSecond的值设置的帧速率定期重绘内容。

    根据 MTKView 的示例,它可能使用内部计时器和 CVDisplayLink 回调的组合。这意味着它基本上会选择“正确的”间隔在正确的时间调用您的绘图函数,通常是在其他可绘制对象“在玻璃上”显示之后,所以在 V-Sync 间隔点,以便您的帧具有最多的 CPU 时间得到绘制。

    您可以创建自己的视图并使用CVDisplayLinkCADisplayLink 来管理调用抽奖的速率。还有其他方法,例如依赖可绘制队列的背压(基本上只是在循环中调用nextDrawable,因为它会阻塞线程直到可绘制可用)或使用presentAfterMinimumDuration。其中一些在WWDC video 中进行了讨论。

    我认为 Core Animation 三重缓冲了由 Window Server 组成的所有内容,所以基本上它会等待您完成绘制您的帧,然后将它与其他帧一起绘制,然后将其呈现给“玻璃”。

    至于你关于延迟的问题:你是对的,CPU 比 GPU 早两个甚至三个“帧”。我对此不太熟悉,也没有尝试过,但我认为如果您将可绘制对象的呈现延迟到最后一刻,可能会延迟到预定时间,那么实际上可以“跳过”您提前绘制的帧您的命令缓冲区之一上的处理程序。

    【讨论】:

    • 非常感谢您的详细解答!我将花一些时间来更详细地探索所有这些,并让自己更加熟悉 CADisplayLink 和 V-Sync。
    猜你喜欢
    • 2014-09-09
    • 2015-10-12
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 2021-04-15
    • 2017-12-11
    • 1970-01-01
    相关资源
    最近更新 更多