计算机图形显示流程

典型的计算机光栅扫描显示系统

计算机光栅扫描显示系统(Computer raster scan display system)是一种常见的计算机显示技术,它使用一个光栅扫描器将图像分成一系列水平线条,并逐行显示在屏幕上。以下是典型的计算机光栅扫描显示系统的基本组成部分:

显示器:通常由一个大型平面显示器或液晶显示器组成,用于显示图像和文字。

光栅扫描器:通常由一个电子枪和一个移动的扫描线圈组成。电子枪发射电子束,扫描线圈控制电子束在屏幕上移动。扫描器将图像分解为一系列水平线条,并按顺序将每一行显示在屏幕上。

视频控制器:通常是一种硬件设备或软件程序,用于管理和控制计算机系统中的视频显示功能。它可以控制显示器的分辨率、颜色深度、刷新率、显示模式等参数,以及视频输出的信号源、信号类型等方面。

计算机:负责生成图像数据,将图像数据传输到显示控制器,并控制整个显示过程。

帧缓冲区

帧缓冲区(FrameBuffer)是用来存储图像数据的一块连续的内存区域。主要用于在屏幕上显示图像或视频,以及进行图形处理、渲染等。在现代计算机中,帧缓冲区一般放在显卡的内存中。

计算机里面的CPU和GPU

CPU 与 GPU :说到图形显示就不得不老生常谈一下CPU和GPU,CPU擅长完成多重复杂任务,重在逻辑,重在串行程序;GPU的核心擅长完成具有简单的控制逻辑的任务,重在计算,重在并行。

虽然 CPU 能以尽可能快的速度执行一系列操作(称为线程)并且可以并行执行几十个这样的线程,但 GPU 擅长并行执行数千个线程(分摊较慢的单线程性能以实现更大的吞吐量)。因此GPU设计有更多晶体管专用于数据处理,而不是数据缓存和流量控制。如下图显示了 CPU 与 GPU 的芯片资源分布示例。

CPU和GPU的区别

简而言之,在显示系统中CPU负责图像纹理的生成,GPU负责纹理的处理。CPU将计算机动态或静态数据生成对应的纹理,然后将生成的纹理数据传递给GPU,GPU将这些纹理数据处理成一张需要显示的图片数据,放到FrameBuffer里。

显示图像的原理

显示原理

在典型的计算机光栅扫描显示系统中,计算机将图像数据转换为数字信号,然后传输给视频控制器。视频控制器将这些数字信号转换为扫描器可以理解的信号,并将其传输到光栅扫描器中。光栅扫描器使用电子枪和扫描线圈扫描屏幕,并按照显示控制器发送的信号逐行显示图像。电子枪会按照下面的方式(Z字型),从上到下一行行扫描,扫描完成后显示器就呈现一帧画面,随后电子枪回到初始位置继续下一次扫描,整个过程被不断重复,这样显示器就能不断地显示帧缓冲区里面的图像。

在最简单的情况下,帧缓冲区只有一个,这时帧缓冲区的读取和刷新都都会有比较大的效率问题。为了解决效率问题,显示系统通常会引入两个缓冲区,即双缓冲机制(帧缓冲区被分成两个缓冲区,一个前缓冲区和一个后缓冲区)。在这种情况下,GPU 会预先渲染好一帧放入一个缓冲区内(前缓冲区),让视频控制器读取,当下一帧渲染好后(后缓冲区),GPU 会直接把视频控制器的指针指向第二个缓冲器(后缓冲区)。如此一来效率会有很大的提升。

屏幕撕裂

虽然双缓冲虽然能解决效率问题,但仍然会像单缓冲区一样存在一个问题:当视频控制器还未读取完成时,即屏幕内容刚显示一半时,GPU 将新的一帧内容提交到帧缓冲区并把两个缓冲区进行交换后,视频控制器就会把新的一帧数据的下半段显示到屏幕上,造成屏幕撕裂现象,如下图:

16773152983830.jpg

造成屏幕撕裂的原因通常是由于显示器刷新率与帧缓冲区数据更新的帧率不匹配所导致的,未了解决这个问题,就需要把显示器的显示过程和系统的视频控制器进行同步,现代显示器(或者其他硬件)会用硬件时钟产生一系列的定时信号。

  • 当电子枪换到新的一行,准备进行扫描时,显示器会发出一个水平同步信号(horizonal synchronization),简称 HSync;
  • 当一帧画面绘制完成后,电子枪回复到原位,准备画下一帧前,显示器会发出一个垂直同步信号(vertical synchronization),简称 VSync。

垂直同步技术是根据上述的垂直同步信号强制将视频控制器和显示器同步,如果显示器还在显示前缓冲,GPU完成了缓冲,那这时候禁止显卡进行绘图,直到显示器把前缓冲的画面显示完整了,显示器跳后缓冲后,才允许显卡去绘制前缓冲。简单理解就是强制显卡的刷新率和显示器刷新率完美契合。那如果60HZ显示器,开了垂直同步帧缓冲区数据更新的速度就会被锁定60HZ。

掉帧

当采用垂直同步信号和双缓冲区后,仍有一种情况无法避免,那边是掉帧。所谓的掉帧,并不是某一帧丢失了,没有渲染,而是重复渲染同一帧数据,就像画面卡顿了一样,比如页面滚动过程中出现滚动不流畅的、鼠标不跟手现象等。

为什么会出现这种情况呢?

如果按照显卡帧缓冲区60Hz的刷新率来计算的话,每帧渲染的时间为16.7ms(1s/60 ≈16.7ms),当CPU/GPU处理图⽚数据速度大于了16.7ms,那么在同步信号来的时候,便拿不到帧缓冲区数据,这个时候视频控制器只能显示上一帧的数据。

为了减少掉帧,便引入了三级缓冲区,三级缓冲区是为了充分利用CPU/GPU的空余时间,开辟三个帧缓冲区:1个前缓冲区、2个后缓冲区,前缓冲区用来显示当前画面。
当显卡在渲染完第一个后缓冲区的数据后,立即开始处理第二个后缓冲区,这样来回处理两个后缓冲区,每次收到VSync信号时,前缓冲区指针指向就和最近完成写入的那个后缓冲区交换。

当然利用三级缓冲区,能够减少掉帧现象,但并不是能完全避免。

参考:
1、《CUDA C++ Programming Guide》
https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html
2、《iOS 保持界面流畅的技巧》
https://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/
3、《什么是画面撕裂?垂直同步,G-sync,Freesync到底有啥用?》
https://zhuanlan.zhihu.com/p/41848908
4、《Android 进阶——图形显示系统之底层图像显示原理小结》
https://crazymo.blog.csdn.net/article/details/124182206
5、《屏幕撕裂及掉帧原因与解决方案》
https://blog.csdn.net/guoyongming925/article/details/107326361

分类: 音视频开发 标签: OpenGL缓冲区

评论

暂无评论数据

暂无评论数据

目录