iOS 底层探究:屏幕卡顿解析

528 阅读4分钟

这是我参与8月更文挑战的第30天,活动详情查看:8月更文挑战

1.屏幕卡顿

屏幕卡顿是指图形图像的在显示时出现了撕裂(即图片错位显示)、掉帧(重复显示同一帧数据)等问题,导致用户能直观的从屏幕上看到的一种异常现象。为什么会出现这种情况呢?下面就来详细解说下屏幕卡顿

1.1 屏幕卡顿的原因

主要有以下三种原因

  • CPU和GPU在渲染的流水线中耗时过长,导致从缓存区获取位图显示时,下一帧的数据还没有准备好,获取的仍是上一帧的数据,产生掉帧现象,掉帧就会导致屏幕卡顿
  • 苹果官方针对屏幕撕裂问题,目前一直使用的方案是垂直同步+双缓存区,可以从根本上防止和解决屏幕撕裂,但是同时也导致了新的问题掉帧。虽然我们采用了双缓存区,但是我们并不能解决CPU和GPU处理图形图像的速度问题,导致屏幕在接收到垂直信号时,数据尚未准备好,缓存区仍是上一帧的数据,因此导致掉帧
  • 在垂直同步+双缓存区的方案上,再次进行优化,将双缓存区,改为三缓存区,这样其实也并不能从根本上解决掉帧的问题,只是比双缓存区掉帧的概率小了很多,仍有掉帧的可能性,对于用户而言,可能是无感知的。

接下来,详细解析下屏幕撕裂及掉帧问题

1.2 屏幕撕裂

如图所示,屏幕撕裂就类似于这样的情形

image.png 在讲屏幕撕裂之前,首先说说屏幕是如何成像的,主要的流程是什么

屏幕成像过程

请看下面这张图,详细说明了屏幕成像的一个流程

WeChate0fdfd6e34f9f5fcb41be5df8db271f6.png

  • 将需要显示的图像,经由GPU渲染
  • 将渲染后的结果,存储到帧缓存区,帧缓存区中存储的格式是位图
  • 由视屏控制器从帧缓存区中读取位图,交由显示器,从左上角逐行扫描进行显示

屏幕撕裂的原因

  • 在屏幕显示图形图像的过程中,是不断从帧缓存区获取一帧一帧数据进行显示的,
  • 然后在渲染的过程中,帧缓存区中仍是旧的数据,屏幕拿到旧的数据去进行显示,
  • 在旧的数据没有读取完时 ,新的一帧数据处理好了,放入了缓存区,这时就会导致屏幕另一部分的显示是获取的新数据,从而导致屏幕上呈现图片不匹配,人物、景象等错位显示的情况。
    图示如下:

2711630285604_.pic_hd.jpg 苹果官方的解决方案
苹果官方针对屏幕撕裂现象,目前一直采用的是 垂直同步+双缓存,该方案是强制要求同步,且是以掉帧为代价的。

以下是垂直同步+双缓存的一个图解过程,如有描述错误的地方,欢迎留言指出

2251862-cee7ea0bf1035944.png

  • 垂直同步:是指给帧缓冲加锁,当电子光束扫描的过程中,只有扫描完成了才会读取下一帧的数据,而不是只读取一部分

  • 双缓冲区:采用两个帧缓冲区用途GPU处理结果的存储,当屏幕显示其中一个缓存区内容时,另一个缓冲区继续等待下一个缓冲结果,两个缓冲区依次进行交替

1.3 掉帧

采用苹果的双缓冲区方案后,又会出现新的问题,掉帧。
什么是掉帧?简单来说就是 屏幕重复显示同一帧数据的情况就是掉帧

如图所示:当前屏幕显示的是A,在收到垂直信号后,CPU和GPU处理的B还没有准备好,此时,屏幕显示的仍然是A

image.png

  • 针对掉帧情况,我们可以在苹果方案的基础上进行优化,即采用三缓存区,意味着,在屏幕显示时,后面还准备了3个数据用于显示。