究竟什么时候调用 drawInMTKView?
When exactly is drawInMTKView called?
MetalKit 在需要您的代表绘制新框架时调用 drawInMTKView
,但我想知道它是否在要求您的代表绘制新框架之前等待最后一个可绘制对象呈现?
根据我阅读 this article 的理解,CoreAnimation 可以提供最多三个“飞行中”的可绘制对象,但我无法确定 MetalKit 是否尝试尽快绘制它们,或者它是否等待其他事情 发生。
这个其他东西会是什么?让我有点困惑的是提前绘制最多两帧的想法,因为这意味着 CPU 必须已经知道它想要在未来渲染两帧什么,我觉得它并不总是案子。例如,如果您的应用程序依赖于用户输入,您无法预先知道从现在到您正在绘制的两个框架将被呈现之间用户将执行的操作,因此它们可能会呈现过时的内容。这个假设对吗?在这种情况下,仅以预期帧速率确定的最大速率调用委托方法可能是有意义的。
与帧速率同步的问题在于,这意味着 CPU 有时可能会在本可以完成一些有用的工作时处于非活动状态。
我也有直觉,这可能不会以这种方式发生,因为在上述文章中,似乎 drawInMTKView
被调用的次数与可绘制对象的可用次数一样多,因为它们似乎依赖于它被调用以避免 CPU 停滞的方式使用资源来完成工作,但由于有很多我不清楚的地方,我不确定到底发生了什么。
MTKView
文档在 paused
页面中提到
If the value is NO
, the view periodically redraws the contents, at a frame rate set by the value of preferredFramesPerSecond
.
根据 MTKView
的示例,它可能结合使用了内部计时器和 CVDisplayLink
回调。这意味着它基本上会选择“正确的”间隔在正确的时间调用您的绘图函数,通常在其他可绘制对象显示“on-glass”之后,所以在 V-Sync 间隔点,以便您的框架具有最多 CPU 次抽奖。
您可以创建自己的视图并使用 CVDisplayLink
或 CADisplayLink
来管理调用抽奖的速率。还有其他方法,例如依赖可绘制队列的背压(基本上只是在循环中调用 nextDrawable
,因为它会阻塞线程直到可绘制可用)或使用 presentAfterMinimumDuration
。 WWDC video.
中讨论了其中一些内容
我认为 Core Animation 三重缓冲由 Window 服务器组成的所有内容,所以基本上它会等待您完成绘制帧,然后将其与其他帧一起绘制,然后将其呈现给“玻璃".
关于您关于延迟的问题:您是对的,CPU 比 GPU 提前两个甚至三个“帧”。我对此不太熟悉,也没有尝试过,但我认为如果您将可绘制对象的呈现延迟到最后一刻,可能会延迟到预定时间,那么实际上可以“跳过”您提前绘制的帧您的命令缓冲区之一上的处理程序。
MetalKit 在需要您的代表绘制新框架时调用 drawInMTKView
,但我想知道它是否在要求您的代表绘制新框架之前等待最后一个可绘制对象呈现?
根据我阅读 this article 的理解,CoreAnimation 可以提供最多三个“飞行中”的可绘制对象,但我无法确定 MetalKit 是否尝试尽快绘制它们,或者它是否等待其他事情 发生。
这个其他东西会是什么?让我有点困惑的是提前绘制最多两帧的想法,因为这意味着 CPU 必须已经知道它想要在未来渲染两帧什么,我觉得它并不总是案子。例如,如果您的应用程序依赖于用户输入,您无法预先知道从现在到您正在绘制的两个框架将被呈现之间用户将执行的操作,因此它们可能会呈现过时的内容。这个假设对吗?在这种情况下,仅以预期帧速率确定的最大速率调用委托方法可能是有意义的。
与帧速率同步的问题在于,这意味着 CPU 有时可能会在本可以完成一些有用的工作时处于非活动状态。
我也有直觉,这可能不会以这种方式发生,因为在上述文章中,似乎 drawInMTKView
被调用的次数与可绘制对象的可用次数一样多,因为它们似乎依赖于它被调用以避免 CPU 停滞的方式使用资源来完成工作,但由于有很多我不清楚的地方,我不确定到底发生了什么。
MTKView
文档在 paused
页面中提到
If the value is
NO
, the view periodically redraws the contents, at a frame rate set by the value ofpreferredFramesPerSecond
.
根据 MTKView
的示例,它可能结合使用了内部计时器和 CVDisplayLink
回调。这意味着它基本上会选择“正确的”间隔在正确的时间调用您的绘图函数,通常在其他可绘制对象显示“on-glass”之后,所以在 V-Sync 间隔点,以便您的框架具有最多 CPU 次抽奖。
您可以创建自己的视图并使用 CVDisplayLink
或 CADisplayLink
来管理调用抽奖的速率。还有其他方法,例如依赖可绘制队列的背压(基本上只是在循环中调用 nextDrawable
,因为它会阻塞线程直到可绘制可用)或使用 presentAfterMinimumDuration
。 WWDC video.
我认为 Core Animation 三重缓冲由 Window 服务器组成的所有内容,所以基本上它会等待您完成绘制帧,然后将其与其他帧一起绘制,然后将其呈现给“玻璃".
关于您关于延迟的问题:您是对的,CPU 比 GPU 提前两个甚至三个“帧”。我对此不太熟悉,也没有尝试过,但我认为如果您将可绘制对象的呈现延迟到最后一刻,可能会延迟到预定时间,那么实际上可以“跳过”您提前绘制的帧您的命令缓冲区之一上的处理程序。