---------------------

做IOS开发,特别是做界面部分的同学,不得不掌握图形的渲染原理。这里包括不限于图形渲染机制、离屏渲染、png图片渲染等重要问题。

下面以一个系列文章分享下。

屏幕图像显示原理

讲到渲染,就要从计算机的屏幕图像显示开始。在计算机的发展过程中,屏幕图像显示的发展又分了两个阶段:随机扫描,光栅扫描。

随机扫描

电子束是随机的移动,即电子束可以按照显示命令任意方向上自由移动。例如要在计算机上显示一个三角形,那么电子束就按照三角形的边的位置,直接移动,从而绘制出需要的图形。这种扫描方式只能绘制直线、三角形等简单图形,要绘制人物、风景等复杂图形就实现不了。只能通过光栅扫描来实现了。

光栅扫描

电子束依照固定的扫描线和规定的扫描顺序进行扫描。电子束先从荧光屏左上角开始,向右扫一条水平线,然后迅速地回扫到左边偏下一点的位置,再扫第二条水平线,照此固定的路径及顺序扫下去,直到最后一条水平线,从而完成了整个屏幕的扫描。这也是我们常说的逐行扫描。通过这种方式就能绘制人物、风景等复杂图形了。

总结成一句话:随机扫描、光栅扫描都是将二进制数据转换成可见的视图。

渲染的部件

这里我们还需要搞清楚一点:我们计算机渲染是由哪个部件来完成的, CPU还是GPU?答案是GPU。若从普通用户的角度来说,那就是我们的显卡(包括独立显卡和集成显卡)来完成的。

那为什么是GPU呢?一个原因是GPU擅长于简单的大规模并发计算和协同处理,二是CPU偏向于复杂的控制运算。就好比GPU是小学生,处理一些简单的加减运算,CPU就像大学教授,懂微积分运算。像图形渲染属于简单的运算,只要找来十几个小学生计算就可以了, 没有必要去找大学教授用微积分来计算。

但这里特别说明下:IOS平台的png格式的图片解码是由CPU来完成的,而非GPU。这点先记下。后面会讲到。

GPU渲染流水线:

经过前面的讲述,图形经过GPU就会变成我们需要显示的图片。那它内部是怎么个过程呢?

GPU 图形渲染具体分以下六个阶段:

Step1.顶点着色器(Vertex Shader)

Step2.形状装配(Shape Assembly)

Step3.几何着色器(Geometry Shader)

Step4.光栅化(Rasterization)

Step5.片段着色器(Fragment Shader)

Step6.测试与混合(Tests and Blending)

这个过程很复杂,就不详细的讲述。反正通过以上六个步骤,就能得到我们需要显示的图片。

帧缓冲区

经过前面六步处理,数据都会进入帧缓冲区,再从帧缓冲区到显示控制器,最后在屏幕上显示。

帧缓冲区是一个很重要的概念,所有要显示的图片都要经过它,它本身是一块内存缓冲区,其中包含完整视频帧中所有像素的数据。其大小由图形的分辨率、色深或调色板大小来决定。

上面讲了各个具体的概念,再统一起来讲下图形渲染机制。

渲染机制

以IOS开发中UIButton设置一张背景图片为例,先调用了UIButton的SetImage函数,该函数会调用Core Animation 框架,该框架又调用OpenGL ES/Metal底层库,然后进入GPU模块,再经过GPU的渲染流水线,形成图形并放入帧缓冲区中,最终由显示控制器处理并显示在屏幕上。以下是图示

ios渲染流程 ios屏幕渲染过程_图形渲染

小结:

1.现在的图形/图像都是光栅扫描完成.

2.图形/图像的渲染是由GPU完成的。

3.图像/图形的渲染流程是:图片经过OpenGL ES/Metal底层库进入GPU模块,再经过GPU的渲染流水线,形成的位图图形并放入帧缓冲区中,最后由显示控制器负责显示。

图片撕裂

具体图片撕裂样式见下图。 

ios渲染流程 ios屏幕渲染过程_ios渲染流程_02

出现此问题的原因:在显示控制器还在光栅视频帧A时,GPU已经完成了B帧的处理,然后会把B帧的数据放入帧缓冲区。这样显示控制器在光栅屏幕的时候,拿到的是B帧数据。从而导致了屏幕的上部分是A帧(旧数据),下部分是B帧(新数据).

那针对这个问题,怎么解决呢?其实也简单,就是在刷A帧的时候,帧缓冲区的数据不更新,直到屏幕中A帧最后一条刷新了。这就是垂直扫描的同步信号。简单来说,是对帧缓冲区加了一把锁,在起始扫描A帧的时候,加上锁(不允许更新帧缓冲区),当扫描到A帧的最后一行时,发送一个垂直同步信号,释放锁。

视频卡顿

当一屏幕扫描完,垂直扫描信号发出,但是CPU/GPU还没有完成新一帧的渲染工作,那么显示控制器还是继续显示上一帧的数据,这个现象就是卡顿,也叫掉帧。解决这个问题的方法是多缓冲区,其中iOS设备采用的时候双缓冲区(Double Buffering),安卓设备是采用三缓冲区.比较单缓冲区,多缓冲区能减少卡顿次数.

ios渲染流程 ios屏幕渲染过程_图形渲染_03

其实呢,视频卡顿本质来说是:CPU/GPU处理速度太慢,光栅一屏数据,还没有完成新图片的渲染。这个时候,我们就要想想我们业务做了些什么业务?让CPU/GPU这么耗时。

在实际情况下,iOS设备采用了垂直同步信号+双缓冲区 两个方案来解决图形的撕裂和卡顿问题。

-----好的,篇幅太长,先分享到这里。

参考资料:

深度好文:关于图形渲染以及离屏渲染