标题先写。
之前看了一次SF, 感觉到一知半解, 画了些图, 总感觉没找到重点, 而且有些问题太深入(Fence), 反而影响整体的理解, 网上的文章要么太深入, 要么太浅显, 要么就是太依赖代码, 很少有一个把大致的流程介绍的浅显易懂的。
我觉得代码都是开源的, 哪里都有, 把重点问题列出来, 流程说清楚, 特别是白前因后果。
有了前因后果再去看问题, 就可以事半功倍。
----------------------吐槽分割线--------------------------
VSync 百度百科
V-Sync(垂直同步)这个功能事实上由来已久,早于Voodoo2的时代V-Sync就已引入到DirectX和Windows操作系统当中,其作用主要是让显卡的运算和显示器刷新率一致以稳定输出的画面质量。
VSync 解决的问题
tear.pngVSync 主要解决的就是上面这个问题。
产生的原因:
假设屏幕刷新率为60HZ, 显卡的刷新率是100HZ。
当显示第一帧的时候, 大家都没问题, 当显示第二帧的时候, 屏幕可能刷新到一半的时候, 显示的内容被显卡给更新了, 导致下半部分的内容跟上半部分不一致。 (这里涉及到了屏幕更新, 可以想象成从上到下,从左到右, 屏幕上的内容是一个一个像素的更新的, 只是更新速率够快, 人感觉不到)
解决的方式:
屏幕每次刷新之前就会发送一个信号告诉系统, 我现在准备刷新了, 然后系统再去调用CPU和GPU进行UI更新。
不使用VSync更新UI
no_vsync.png显示器Display
的更新速率是稳定的。
CPU
和GPU
的绘制的时间是不固定的。
这就导致了Jank
的出现。
1: 第一个VSync到来的时候,Display
显示帧1
, CPU
休眠了一段时间再运行。
2: 第二个VSync到来的时候, 由于上一帧的帧2
没有生成, 所以Display
仍然显示帧1
。(这就导致了画面延迟的问题)
3: 第三个VSync到来的时候, 帧2
的内容终于显示完毕, Display
显示帧2
总结: 由于CPU
和GPU
更新的时间点不固定, 导致UI不能及时被显示到屏幕上。
(PS: Display
把UI从内存显示到屏幕上, 这个时间很短暂, 可以忽略不计, 如果没有这个概念, 有些问题会想不明白)
使用VSync更新UI
usb_vsync.png1: 第一个VSync到来的时候,
Display
显示帧1
, CPU
立刻运行,然后GPU
也接着运行,并且生成帧2
.2: 第二个VSync到来的时候, 由于帧
2
已经生成, 所以Display
显示帧2
, CPU
立刻运行,然后GPU
也接着运行,并且生成内容3
.3: 第三个VSync到来的时候, 由于帧
3
已经生成, 所以Display
显示帧3
, CPU
立刻运行,然后GPU
也接着运行,并且生成内容4
.总结: 由于
CPU
和GPU
在每次VSync到来之后立刻执行, 如果能保证CPU
和GPU
运行的时间在一个VSync的周期内, 那么是不会出现Jank
的。
- 1: VSync传递之 HWC -> SF
- 2: VSync传递之 SF
- 3: VSync传递之 App
备注:
图片拷贝了网上的图片。
网友评论