iOS--离屏渲染

2020-09-24  本文已影响0人  mayuee

视图内容的绘制是CPU的工作,GPU负责内容的渲染,包括多个视图的拼接(Compositing)、纹理的渲染(Texture)等,CPU计算好显示内容提交到GPU,GPU渲染完成后将渲染结果放入帧缓冲区,随后视频控制器会按照 VSync信号逐行读取帧缓冲区的数据,经过可能的数模转换传递给显示器显示。

如果满足视觉上流畅,屏幕刷新就需要达到60fps,否则就会感到卡顿、掉帧。60fps,即60帧/秒,折合每帧16.67ms。在16.67ms中,需要CPU和GPU协同合成一帧画面。如果在16.67ms之内,CPU和GPU没有完成当前帧的合成,在下一个VSync信号开始前需要显示的帧画面没有准备好,就会导致页面卡顿、掉帧。

渲染的过程如下:

定义

GPU有两种渲染方式:

  1. On-Screen Rendering (当前屏幕渲染)
    指的是GPU在当前用于显示的屏幕缓冲区进行渲染操作。

  2. Off-Screen Rendering (离屏渲染)
    真正的离屏渲染发生在 GPU,指的是 GPU 在当前屏幕缓冲区外新开辟一个缓冲区进行渲染操作。通俗讲当我们设置某些UIView的图层属性,标记为在没有预合成之前(下一个VSync信号开始前)不能直接在屏幕中绘制的时候就触发了离屏渲染。

还有一种:CPU离屏渲染 的说法,如果我们重写了drawRect方法,并且使用任何Core Graphics的技术进行了绘制操作,就涉及到了CPU离屏渲染。因为这种新开一块CGContext来画图,的操作,像素数据是暂时存入CGContext,而不是直接到了帧缓冲区,只能暂时先放在另一块内存汇总,说起来是”离屏渲染“,CPU渲染并非真正意义上的离屏渲染。”CoreGraphic通常是线程安全的,所以可以进行异步绘制,显示的时候再放回主线程。

GPU离屏渲染:

主要的渲染操作都是由CoreAnimation的Render Server模块,通过调用显卡驱动所提供的OpenGL/Metal接口来执行的。通常对于每一层layer,render server 会遵循“画家算法”,按次序输入到frame buffer,后一层覆盖前一层,最终得到显示结果。但有些场景比较特殊,画家算法虽然可以一层一层往画布上进行输出,但是无法在某一层渲染完成后,再回过头来擦除/改变其中某部分,因为在这一层之前的若干层layer像素数据,已经在渲染中被永久覆盖,意味着对于每一层layer,要么能够找到一种通过单次便利就能完成的渲染算法,要么另开一块内存,借助这个临时中转区域来完成更加复杂的,多次的修改,裁剪操作。

怎样会触发

被动触发

屏幕上的每个像素点的颜色是由当前像素点上的多层layer(如果存在)共同决定的,GPU会对重叠视图的每个像素的RGBA值进行计算得出出最终混合颜色的RGBA值,显示在屏幕上。对于完全不透明的layer,GPU会忽略下面所有的layer,节约计算量。
layer的合成计算是非常消耗GPU性能,多层级大尺寸视图尤为明显。体现在代码层面,CALayer.opaque=YES,GPU就不会进行图层的合成。

opaque 表示当前UIView是否不透明,但是决定不了当前UIView是不是不透明,比如你将opaque设为NO,该UIView照样是可见的(是否可见是由alpha或hidden属性决定的),如果opaque被设置成YES,而对应UIView的alpha属性不为1.0的时候,就会有不可预料的情况发生。

主动触发

为什么要避免?

怎样减少或避免

上一篇 下一篇

猜你喜欢

热点阅读