移动端渲染原理详解卷一(基础知识)

2022-09-05  本文已影响0人  搬砖的作家

本文首发地址:开源实践网:移动端渲染原理详解卷一(基础知识)

一、客户端图形渲染相关基础知识

1、渲染和客户端渲染

广义渲染 → 将三维场景中的模型,按照设定好的环境、灯光、材质及渲染参数。二维投影成数字图像的过程(Rendering)而这个渲染定义,来源于数字建模类软件工作流的一个特定步骤。
移动端渲染 → 对于我们移动端来讲,渲染更贴切的定义是将手机上的图像数据经过cpu和gpu的协同处理,最终显示在手机屏幕上的整个过程。

2、什么是纹理

纹理相当于着色物体的"皮肤",负责提供基础颜色,例如黄种人和黑种人同时光照的情况下是有较大区别的。计算机在处理纹理映射时通常是使用二维数组储存三维物体的纹理信息,具体原理就像下图所示。


纹理

二、渲染相关的硬件介绍

1、什么是GPU、CPU

CPU(Central Processing Unit):中央处理器,现代计算机的三大核心部分之一,作为整个系统的运算和控制单元。CPU 内部的流水线结构使其拥有一定程度的并行计算能力。

GPU(Graphics Processing Unit):图形处理器,一种可进行绘图运算工作的专用微处理器。GPU 能够生成 2D/3D 的图形图像和视频,从而能够支持基于窗口的操作系统、图形用户界面、视频游戏、可视化图像应用和视频播放。GPU 具有非常强的并行计算能力。简单来说屏幕上面的物理元件是像素,我们在屏幕上面看到的图片,文字,视频,就是由屏幕上的所有像素,通过控制色值变化而呈现出来的。那么像素的色值数据,就是由GPU计算得出的,然后将这些数据提交给视频控制器,由它负责显示到屏幕上。

CPU 和 GPU 其设计目标就是不同的,它们分别针对了两种不同的应用场景。CPU 是运算核心与控制核心,需要有很强的运算通用性,兼容各种数据类型,同时也需要能处理大量不同的跳转、中断等指令,因此 CPU 的内部结构更为复杂。而 GPU 则面对的是类型统一、更加单纯的运算,也不需要处理复杂的指令,但也肩负着更大的运算任务。


cpu与gpu区别

因此,CPU 与 GPU 的架构也不同。因为 CPU 面临的情况更加复杂,因此从上图中也可以看出,CPU 拥有更多的缓存空间 Cache 以及复杂的控制单元,计算能力并不是 CPU 的主要诉求。CPU 是设计目标是低时延,更多的高速缓存也意味着可以更快地访问数据;同时复杂的控制单元也能更快速地处理逻辑分支,更适合串行计算。
而 GPU 拥有更多的计算单元 Arithmetic Logic Unit,具有更强的计算能力,同时也具有更多的控制单元。GPU 基于大吞吐量而设计,每一部分缓存都连接着一个流处理器(stream processor),更加适合大规模的并行计算。

2、图像渲染流水线

图像渲染流程粗粒度的大概分为下面这些步骤:


上述图像渲染流水线中,除了第一部分 Application 阶段,后续主要都由 GPU 负责,为了方便后文讲解,先将 GPU 的渲染流程图展示出来:

上图就是一个三角形被渲染的过程中,GPU 所负责的渲染流水线。可以看到简单的三角形绘制就需要大量的计算,如果再有更多更复杂的顶点、颜色、纹理信息(包括 3D 纹理),那么计算量是难以想象的。这也是为什么 GPU 更适合于渲染流程。

接下来,具体讲解渲染流水线中各个部分的具体任务:

Application 应用处理阶段:得到图元
这个阶段具体指的就是图像在应用中被处理的阶段,此时还处于 CPU 负责的时期。在这个阶段应用可能会对图像进行一系列的操作或者改变,最终将新的图像信息传给下一阶段。这部分信息被叫做图元(primitives),通常是三角形、线段、顶点等。

Geometry 几何处理阶段:处理图元
进入这个阶段之后,以及之后的阶段,就都主要由 GPU 负责了。此时 GPU 可以拿到上一个阶段传递下来的图元信息,GPU 会对这部分图元进行处理,之后输出新的图元。这一系列阶段包括:

这些点可以进行不同的排列和染色以构成图样。当放大位图时,可以看见赖以构成整个图像的无数单个方块。只要有足够多的不同色彩的像素,就可以制作出色彩丰富的图象,逼真地表现自然界的景象。缩放和旋转容易失真,同时文件容量较大。

3、屏幕图像显示的原理

介绍屏幕图像显示的原理,需要先从 CRT 显示器原理说起,如下图所示。CRT 的电子枪从上到下逐行扫描,扫描完成后显示器就呈现一帧画面。然后电子枪回到初始位置进行下一次扫描。为了同步显示器的显示过程和系统的视频控制器,显示器会用硬件时钟产生一系列的定时信号。当电子枪换行进行扫描时,显示器会发出一个水平同步信号(horizonal synchronization),简称 HSync;而当一帧画面绘制完成后,电子枪回复到原位,准备画下一帧前,显示器会发出一个垂直同步信号(vertical synchronization),简称 VSync。显示器通常以固定频率进行刷新,这个刷新率就是 VSync 信号产生的频率,也叫屏幕刷新频率。

如下图,屏幕的刷新过程是每一行从左到右(行刷新,水平刷新,Horizontal Scanning),从上到下(屏幕刷新,垂直刷新,Vertical Scanning)。当整个屏幕刷新完毕,即一个垂直刷新周期完成,会有短暂的空白期,此时发出 VSync 信号。所以,VSync 中的 V 指的是垂直刷新中的垂直/Vertical。 屏幕刷新过程

帧率
即 Frame Rate,单位 fps,是指 gpu 一秒内生成帧的速率,如 33 fps,60fps,120fps越高越好。
屏幕刷新频率
即 Refresh Rate 或 Scanning Frequency,单位赫兹/Hz,是指设备刷新屏幕的频率,该值对于特定的设备来说是个常量,如 60hz,120hz。在最新的
垂直同步信号
VSync: 垂直同步信号,又叫做帧同步信号,表示扫描1帧的开始,一帧也就是LCD显示的一个画面。Vsync信号是由硬件时钟产生的一个脉冲信号,起到开关或触发某种操作的作用。Vsync会以固定的频率产生,不受软件的影响(只要有电就会产生)。这个固定的频率叫做屏幕刷新频率(refresh rate或者Scanning Frequency)。通常情况下,这个频率是60hz。也就是1/60s == 16.666ms就会产生一个垂直同步信号。屏幕刷新频率和帧率没有什么关系。
另外还有水平同步信号HSync,当电子枪换行进行扫描时,显示器会发出一个水平同步信号
如下是工作原理图:

VSync

4、屏幕图像显示整体流程


CPU计算好现实内容提交到GPU,GPU渲染完成后将渲染结果放入帧缓冲区,随后视频控制器就会按照VSync信号逐行读取帧缓冲区的数据,然后在显示器上显示。

即,电脑显示一张画面是分成两个步骤完成的。

第一步: 是CPU和显卡把所要显示的画面数据计算出来。
第二步: 是显示器把这些数据写到屏幕上。

由于上两步工作耗时执行时长远远超过 16.67 ms,因此为了满足对屏幕的 60 FPS 刷新率的支持,需要将这些步骤进行分解,并且这两个过程的硬件是相互独立的(是cpu/显卡 和 视频控制器),所以可以利用流水线的方式并行执行,提升渲染帧的速率。
cpu以及显卡每秒能计算出的画面数量是根据硬件性能决定的。 但是显示器每秒刷新频率是固定的(一般是60hz,所以每隔16.667ms就会刷新一次)。
这种两边速率不统一的问题(先不说谁快谁慢),引入了帧缓冲(FrameBuffer)的概念。

帧缓冲能在一定程度上提升效率,但还是有几个问题:

  1. 画面撕裂
  2. 画面闪烁
  3. 跳帧
  4. 卡顿

我们接下来聊聊显示上会遇到的几个问题以及方案的演进:


画面撕裂效果

如上面说过的,显示器刷新的时候是从最上面的一行像素开始逐行向下刷新,所以从顶端到底部的刷新是有时间差的。如果显卡的性能很强,也就是显卡帧率大于屏幕刷新率的时候,就会出现屏幕上半部分还停留在上一帧的画面,新的一帧的数据已经拷贝上来了,那么屏幕的下半部分渲染出来的就是下一帧的画面-----这种情况被称为画面撕裂(问题-1)。

如果显卡再快一点,那么下一帧的图像还没来得及显示,下下一帧的数据就覆盖上来了,中间这帧就跳过了-----这种情况被称为跳帧(问题-3)。

反过来,如果显卡帧率小于显示器刷新率,那每次在屏幕上看到的可能不是完整的图形,每次看到的图形比上次更完整一些。于是在用户看起来,画面是卡顿掉帧不顺滑(问题-4)。

在单缓冲的场景下,渲染下一帧的时候先清除画布的当前视图,这样就会导致画面看起来闪烁,比如大学时候在win32的GDI+写过小游戏的朋友一定有印象,不使用额外手段的情况下,画面动起来的时候是会一闪一闪的(问题-2)。

解决方案:针对这问题-1问题-3,引入了垂直同步的技术。

垂直同步(V-Sync),开启后GPU会等待显示器的VSync信号发出后再进行新的一帧渲染和缓冲区更新。即,把显卡帧率锁定为显示器的刷新率,

由上述结论我们只能得到,垂直同步可以在显卡帧率比显示器刷新率高的时候解决撕裂和跳帧的问题。但是,显卡帧率小于显示器刷新率的时候,也就是问题-3问题-4,引入了双缓冲技术。

双缓冲技术,GPU会预先渲染好一帧放入一个缓冲区内,让视频控制器读取,当下一帧渲染好后,GPU会直接把视频控制器的指针指向第二个缓冲区。也就是说,在一帧被渲染完以后才会交给屏幕显示,不会看到“半成品画面”。并且有两个缓冲区互换,不需要在显示前台清理画布,所以不会闪烁。

5、VSYNC,二重缓存机制,三重缓存机制

通常来说,渲染的瓶颈来自于cpu或者gpu,所以帧率超过刷新频率只是一种理想的状况,并且在超过 60fps 的情况下,GPU 所产生的帧数据会因为等待 VSYNC 的刷新信息而被 Hold 住,这样能够保持每次刷新都有实际的新的数据可以显示。我们在开发中遇到更多的情况是帧率小于刷新频率的情况。



在这种情况下,某些帧显示的画面内容就会与上一帧的画面相同。糟糕的事情是,帧率从超过 60fps 突然掉到 60fps 以下,这样就会发生 LAG,JANK,HITCHING 等卡顿掉帧的不顺滑的情况。这也是用户感受不好的原因所在。

接下来,我们以具体示例来看 VSYNC 的作用。

1. 不使用 VSYNC 时

这个图中有三个元素,Display 是显示屏幕,GPU 和 CPU 负责渲染帧数据,每个帧以方框表示,并以数字进行编号,如0、1、2等等。

CPU 正常执行帧1,GPU 正常渲染帧1,所以帧1正常显示。
但,CPU 由于被占用等原因,等到即将显示帧2时,它才开始处理第二帧的内容,这显然完不成了,所以等到第二帧显示的时候,只能使用上一帧的内容显示了,也即是丢帧了。
上面丢帧的原因,我们可以从图中看出,是因为新的一帧开始的时候,CPU 在处理其他任务,并没有马上执行下一帧的任务,那么如何让 CPU 在新的一帧开始的时候立即处理显示内容呢?答案就在 VSYNC 身上!

2. 使用 VSYNC 时
  1. 第0帧显示时,CPU 和 GPU 准备好了第一帧的内容。
  2. 第1帧刚开始显示时,CPU 放下手中的任务,立马处理第2帧显示相关的任务,这样,在第二帧显示之前, CPU 和 GPU 也提前完成了显示任务的处理,第二帧正常显示。
    可以看到,使用 VSYNC 信号机制,提升了渲染任务的优先级,优化了渲染性能,可有效的减少了丢帧、卡顿等问题。

但是上图中仍然存在一个问题:CPU 和 GPU 处理数据的速度似乎都能在 16ms 内完成,而且还有时间空余,也就是说,CPU 和 GPU 的帧率要高于 Display 的帧率。由于 CPU/GPU 只在收到 VSYNC 时才开始数据处理,故它们的帧率被拉低到与 Display 相同。但这种处理并没有什么问题,因为 Android或iOS 设备的 Display FPS 一般是 60,其对应的显示效果非常平滑。

但如果 CPU/GPU 的帧率小于 Display 的帧率,情况又不同了,将会发生如下图的情况:

3. 二重缓存机制
image.png

在第二个 16ms 时间段,Display 本应显示 B 帧,但却因为 GPU 还在处理 B 帧,导致 A 帧被重复显示。
同理,在第二个 16ms 时间段内,CPU 无所事事,因为 A Buffer 被 Display 在使用。B Buffer 被 GPU 在使用。注意,一旦过了 VSYNC 时间点,CPU 就不能被触发以处理绘制工作了。

以上是使用双重缓存机制时产生的问题,那么又如何来解决呢?

为了解决这个问题,引入了 Triple Buffer 机制。

4. 三重缓存机制(Triple Buffer)

一般我们在绘制 UI 的时候,都会采用一种称为“双缓存”的技术(例如,上面几个例子)。双缓存意味着要使用两个缓存区,其中一个称为 Front Buffer,另外一个称为 Back Buffer。UI 总是先在 Back Buffer 中绘制,然后再和 Front Buffer 交换,渲染到显示设备中。理想情况下,这样一个刷新会在 16ms 内完成,下图就是描述的这样一个刷新过程:Display 处理前 Front Buffer,CPU、GPU 处理 Back Buffer。

只有两个 Buffer(Android 4.1之前)时,CPU 在空闲时,如果 Back Buffer 被占用了,它也只能等待 GPU 使用之后再次进行写入。我们可以想想,如果有第三个 Buffer 的存在,CPU 是不是就可以提前工作,而不至于空闲了?所以,Google 在 Android4.1 以后,引入了三重缓存机制:Tripple Buffer。Tripple Buffer 利用 CPU/GPU 的空闲等待时间提前准备好数据,并不一定会使用。

引入 Triple Buffer 效果如下图所示:


上图中,第二个 16ms 时间段,CPU 使用 C Buffer 绘图。虽然还是会多显示 A 帧一次,但后续显示就比较顺畅了。

那么,是不是 Buffer 越多越好呢?回答是否定的。由上图可知,在第二个时间段内,CPU 绘制的第 C 帧数据要到第四个 16ms 才能显示,这比双 Buffer 情况多了 16ms 延迟,并且大量的缓存数据也会导致内存增大,以及显示数据是否失效等问题。所以,Buffer 三个足矣。

上一篇下一篇

猜你喜欢

热点阅读