我的 iOS 游戏目前使用 CADisplayLink 来计时 OpenGL 渲染操作。我在第二个线程上运行了一个 GCD 调度队列,该线程向 GPU 发出所有 OpenGL 渲染和状态调用。一切正常,除了时机不完美。即使动画间隔从 1 (60Hz) 更改为 2 (30Hz),我有时也会看到跳帧和故障。
CADisplayLink 从主线程上的 RunLoop 调用您的选择器,这意味着它只能在其他已调度的作业和主线程正在处理的输入事件之间触发。(我已经通过记录这些作业/事件确认了这种情况)。如果这些操作需要几毫秒,那么 CADisplayLink 将永远不会完全准确,因为它无法中断当前在主线程上运行的任何内容。正如我想象的大多数游戏一样,我在主线程上运行游戏模拟、物理和场景剔除。
所以我在想的是,我应该将所有游戏模拟和物理内容移出主线程,以便触摸事件和 CADisplayLink 可以在尽可能接近的时间触发。但我不确定这是否能解决任何问题,而且这不是一项微不足道的工作。
我想知道,由于 presentRenderBuffer 调用实际上是使您的帧与实际硬件显示同步的东西,也许我需要的只是一个非常准确的计时器,它可以在它自己的线程中运行(可能以更高的优先级)并触发渲染那样。然后我可以将所有内容保留在主线程上。似乎 CADisplayLink 提供的所有方法都是在我的代码运行速度超过 60Hz 的情况下等待的一种方式,所以在我看来,类似的延迟可以使用单独的线程轻松编码。我在这里想念什么?