runloop与Vsync 信号

在多数博客中提到的runloop 在即将休眠前的屏幕绘制接收到VSync 信号后的屏幕绘制,它们之间是什么关系呢?

这个问题困扰了我很长时间,现在做一个简单总结。

runloop 在即将休眠前的屏幕绘制:如果 CoreAnimation 有未提交内容,则提交到 GPU 中去工作。也就是说,runloop 与屏幕绘制之间没有直接的关系,只是从 CPU 提交到 GPU。

接收到 VSync 信号后的屏幕绘制:VSync 信号由硬件时钟生成,每秒钟发出 60 次。当 runloop 进入到 mach_msg_trap(睡眠)的状态时,可以通过 mach_port 接收传过来的时钟信号通知(source1 事件),被唤醒。如果 CoreAnimation 有未提交内容,则执行提交操作、如果有 CADisplayLink 等用户自定义回调,则触发回调。

FPS中的刷新屏幕:当两次 Vsync 信号到达之间,如果帧缓冲区中的数据发生了改变,就会刷新这一帧。卡顿是由于 CPU 和 GPU 的过载导致帧缓冲区的数据没有刷新。

关于YY大神提到的

App 的 Runloop 在启动后会注册对应的 CFRunLoopSource 通过 mach_port 接收传过来的时钟信号通知,随后 Source 的回调会驱动整个 App 的动画与显示。

我不能赞同。因为我在 demo 中测试发现,当屏幕静止不动时,runloop 处于一个每一分钟唤醒一次的状态,并没有被 Vsync 信号唤醒。只有当在 runloop 中加入了 CADisplayLink 之后,才会在一秒钟被唤醒 60 次,CADisplayLink 应该是 source1 的 mach_msg 触发(补充 source1: 当 硬件事件发生的时候,mach_port 转发给App进程,source1 接收后触发 source0 再触发到 UIApplication 的事件队列中的)。

参考链接:
深入理解RunLoop
iOS 保持界面流畅的技巧
iOS 事件处理机制与图像渲染过程

你可能感兴趣的:(runloop与Vsync 信号)