1. 图片显示不完整

原因: 图片被渲染到帧缓冲区后,下一次屏幕刷新的时候, 会讲将缓冲区的内容显示到屏幕上。 如果在屏幕刷新的时候,图片没有完整的绘制完,可能就会出现一半图片的情况。

解决方案:为了解决图片显示不完整的问题,引入了双缓冲区技术(Double Buffering)。 即有两个缓冲区,显示到屏幕上的叫屏幕缓冲区,未显示到屏幕上的叫离屏缓冲区。图片渲染的时候,在离屏缓冲区渲染,渲染完成后,两个缓冲区交换。这样渲染完成的图片就可以显示出一张完整的图片了。
三、画面撕裂及卡顿问题分析 - 图1

2. 屏幕撕裂(Screen Tearing)

原因: 屏幕绘制是从左到右,从上到下逐行绘制的。 如果某一帧在绘制过程中,屏幕缓冲区进行了交换,屏幕就会未绘制完的区域,开始绘制下一帧的同位置的图形。

解决方案:为了解决这个问题,引入了垂直同步技术。即在屏幕绘制完成后,发出一个信号,接到信号后,缓冲区再进行交换。就相当于把屏幕绘制过程加了一把锁,等屏幕刷新完成后,再把锁解开。这个信号叫垂直同步信号(Vsync),这个技术叫垂直同步技术。
三、画面撕裂及卡顿问题分析 - 图2

3. 卡顿的本质是掉帧(重复渲染同一帧数据)

原因: 由于要等待离屏缓冲区渲染完成后, 再进行下一帧的绘制。就会出现这样一个情况:当屏幕刷新时,新的一帧没有渲染完,它就只能重新渲染旧的帧,两次刷新屏幕显示的是同一帧,这个现象叫做掉帧。如下图所示:
三、画面撕裂及卡顿问题分析 - 图3
正常一帧有1000/60 = 16.67毫秒, 显示一帧需要 CPU + GPU 共同合作处理。所以说如果他们处理一帧的总时长超过了16.67,就会出现掉帧的情况。
人眼有视觉停留,每秒16帧就会感觉画面连贯,60 / 16 = 3.75, 向上取整就是 4 帧 ,如果 4 帧时间内一直显示同一帧的画面,人眼就能感觉到卡顿了。

解决方案

  • 为了优化掉帧问题,引入了三级缓存技术,即又增加了一个离屏缓冲区。
  • 在显示屏幕缓冲区 A 的同时,两个离屏缓冲区也在同时的渲染接下来要显示的两个帧 B 和 C。
  • 当显示 B 帧的时候,由于 C 帧是在A帧显示的时候,就开始渲染,所以很可能 C 帧已经渲染好了,这时候两个离屏缓冲区可以开始渲染 D 帧和 E 帧。
  • 这样 CPU / GPU 不停的渲染接下来要显示的两帧,就可以大大缓解掉帧问题, 当然也不是完全的解决了掉帧问题,是合理的使用 CPU / GPU 来减少掉帧次数。

4. 苹果当前采用的双缓冲区 + 垂直同步技术

5. 安卓有用到三级缓存