屏幕撕裂及掉帧原因与解决方案

目录

      • 1. 什么是屏幕撕裂
      • 2. 光栅扫描显示系统结构
        • 2.1 简单的光栅扫描显示系统
        • 2.2 常用的光栅扫描显示系统
        • 2.3 高级的光栅扫描显示系统
      • 3. 屏幕撕裂原因
      • 4. 双缓存区及垂直同步信号Vsync
      • 5. 掉帧

1. 什么是屏幕撕裂

还记得以前的显示器中常常出现上下两半屏幕显示错位的情况,比如下面的图:
屏幕撕裂及掉帧原因与解决方案_第1张图片
由图中可知,上半部分和下半部分显示的完全是不同的画面,这就是屏幕撕裂
那么为什么会出现这种情况呢?是什么原因造成了屏幕撕裂呢?首先我们先了解一下光栅扫描显示系统结构。

2. 光栅扫描显示系统结构

什么时候光栅扫描呢?它是指我们显示器的电子束从屏幕的左上角开始横向向右一行一行逐行扫描。类似于打印机打印文档。 如下图:
屏幕撕裂及掉帧原因与解决方案_第2张图片
图像是由像素矩阵组成的,显示一个图像的时间和图像的复杂度毫无关系,而是显示整个光栅所需要的时间。
屏幕撕裂及掉帧原因与解决方案_第3张图片

2.1 简单的光栅扫描显示系统

屏幕撕裂及掉帧原因与解决方案_第4张图片
当要显示图片的时候,首先CPU先对图片进行数据处理,然后将处理后的数据存储在内存中,再由显示控制器通过系统总线读取数据进行显示,此时并没有独立的显卡。

2.2 常用的光栅扫描显示系统

此时我们在内存中单独开辟了一个图片数据的存储区域(帧缓存),如下图:
屏幕撕裂及掉帧原因与解决方案_第5张图片
此时虽然有了独立的存储空间,但是没有本质上的改变,显示控制器还是通过系统总线读取图片数据,对系统总线仍有较大的压力。随后更高级一点的显示系统变出来了。

2.3 高级的光栅扫描显示系统

屏幕撕裂及掉帧原因与解决方案_第6张图片
上面这种系统结构是我们现在计算机常用的显示系统结构,此时已经有了独立的显卡,在现实图片的时候,CPU解码处理完后,数据将被显示处理器拷贝到显存中,后期再操作的时候不会占用内存空间,也不依赖系统总线。

3. 屏幕撕裂原因

在显示一张图片的时候,其流程为:GPU进⾏渲染—>帧缓存区⾥ —>显示控制器—>读取帧缓存区信息(位图) —> 数模转化(数字信号处—>模 拟型号) —>(逐⾏扫描)显示。
正常的情况下,显示器完全显示完一帧后,帧缓存区更新一帧,这样便不会有撕裂问题,但事实并非如此。
当显卡输出帧的速度比显示器快,显示器的处理速度跟不上显卡,在显示器处理显卡丢过来的第1帧的时候,第2帧就又到了(帧缓存区已更新),导致同一个画面同时出现1、2两帧,撕裂就产生了。

4. 双缓存区及垂直同步信号Vsync

为了解决撕裂,苹果引入了: 垂直同步Vsync + 双缓存区 DoubleBuffering。
(1)垂直同步Vsync: 当屏幕扫描完成后,便会发出同步信号,显示控制器切换帧缓存区。
(2)双缓存区 DoubleBuffering :就是GPU开辟了两个帧缓存区(暂叫A、B缓存区)。
执行流程:
当CPU/GPU处理完数据后,将图片数据放入A帧缓存区,然后显示控制器读取A帧缓存区,并在屏幕上扫描,当扫描结束后,发出同步信号,显示控制器切换到B帧缓存区并读取数据扫描显示,一次类推,不断的切换取数据显示,此时屏幕撕裂的问题便解决了。

屏幕撕裂及掉帧原因与解决方案_第7张图片

5. 掉帧

当采用垂直同步信号和双缓存区后,仍有一种情况无法避免,那边是掉帧,所谓的掉帧,并不是某一帧丢失了,没有渲染,而是重复渲染同一帧数据。
为什么会出现这种情况呢?
如果按照1秒60帧算的话,每帧渲染的时间为16.7ms(1s/60 ≈16.7ms),当CPU/GPU处理图⽚数据速度大于了16.7ms,那么在同步信号来的时候,便拿不到帧缓存区数据,这个时候显示控制器只能显示同一帧的数据。

为了减少掉帧,便引入了三级缓存区,三级缓存区是为了充分利用CPU/GPU的空余时间,开辟ABC三个帧缓存区,A显示屏幕, B也渲染好,C再从GPU拿取渲染数据,当屏幕缓存区和帧缓存区都弄好了,然后视频控制器再指向帧缓存区的另外一个,再显示,这样交替,达到减少掉帧的情况,这样做就比二级缓存区多了一个确认的操作。

掉帧问题,我们只能是减少掉帧,即使用三级缓存区,也不一定能绝对的避免掉帧。

你可能感兴趣的:(音视频,缓存,OpenGL)