1. 移动设备显示原理:CPU 计算好要显示的内容提交给 GPU,GPU 渲染完成后将渲染结果放入帧缓存区,随后视频播放器在刷新帧的时候发出 VSync 信号逐行读取帧缓存区的数据,经过数模传输给显示器显示
2. 单缓存机制:在最简单的情况下,帧缓存区只有一个,这样的话帧缓存区的读取的刷新都会有较大的问题。
3. 双缓存机制:为了解决效率问题,显示系统通常会引入两个帧缓存区。在这种情况下,GPU会预先渲染好一帧放入一个缓存区内,让视频控制器读取。当下一帧渲染好后 GPU 会直接把视频控制器的指针指向第二个缓存区,这样效率会有很大提升,但是同时带来一个问题,就是当视频控制器还未读取完成,即屏幕内容刚显示一半时,GPU 可能将新的一帧内容提交到帧缓存区,此时视频控制器就会把新的一帧数据的下半段显示到屏幕上,造成画面撕裂的现象。
4. 双缓存机制+垂直同步机制:为了解决双缓存机制带来的画面撕裂的问题,GPU 通常会有一个垂直同步机制:GPU 会等待显示器的 VSync 信号发出后,,才进行新的一帧和缓存区更新,这样能解决画面撕裂的现象,也增加了画面流畅度,但需要消耗更多的计算资源,也会带来部分的延迟。iOS 设备使用的是双缓存机制+垂直同步机制,安卓在 4.1 版本以后才引入垂直同步机制,使用的是三缓存+垂直同步机制。
5. 造成卡顿的原因:iOS 使用的是双缓存+垂直同步机制,当 VSync 信号到来之后,系统图形服务会通过 CADisplayLink 等机制通知 App ,App 主线程开始在 CPU 中计算显示内容,比如视图的创建、布局计算、图片解码、文本绘制等,随后 CPU 会将计算好的内容提交到 GPU 中,由 GPU 来完成变换、合成、渲染,随后 GPU 将渲染结果提交到帧缓存区,等待下一次 VSync 信号到来的时候显示到屏幕上。由于垂直同步机制,如果在一个 VSync 时间内,CPU 或者 GPU 没有完成内容提交,那么这一帧就会被丢弃,等待下一次 VSync 信号,而这时候显示屏会保持之前的内容不变,这样就造成了内存卡顿。不论是 CPU 还是 GPU 阻挡了显示流程,都会造成掉帧,所以在开发的时候需要分别对 CPU 和 GPU 压力进行评估和优化。