离屏渲染这词常听,然而今天才有对它比较有深刻的认识,接下来说说我的理解,不足的地方望指正。
我们先了解一下APP渲染显示在屏幕上的大致流程,如下图
如有侵权,联系我删除APP通过CPU和GPU通力合作将每一帧存储在帧缓存区(FrameBuffer)中,之后循环的从帧缓存区(Frame Buffer)中获取每一帧数据显示在屏幕上。
那离屏渲染是什么呢?请看下图
如有侵权,联系我删除APP通过CPU和GPU通力合作将多次渲染的图层结果,暂存在一个新开辟的离屏渲染缓存区(offscreen Buffer)中组合,再转存到帧缓存区(FrameBuffer)中,之后循环的从帧缓存区(Frame Buffer)中获取每一帧数据显示在屏幕上,这就是离屏渲染原理。
到这没有理解离屏渲染的原理,不要着急,接下来我举个例子说明。
如有侵权,联系我删除图3是最终的结果图。首先APP将数据提交给Core Animation,之后来到渲染服务(Render Server),到Command Buffer中,到顶点着色器(Vertex Shader)确定好顶点数据,到片段(Tiling)描绘出范围内的每个像素点位置,到片元着色器(Pixel Shader)处理好每个像素点,之后获得了遮罩(Mask Texture)也就是图1,此时屏幕上不会直接显示图1,会将其存入离屏渲染缓存区(offscreen Buffer)中。
图2(Layer Texture)也是从Command Buffer到片元着色器(Pixel Shader)绘制出来,将其存入离屏渲染缓存区(offscreen Buffer)中。再来从离屏渲染缓存区(offscreen Buffer)中将图1和图2组合,转存到帧缓存区(FrameBuffer)中,最后形成图3显示在屏幕上。现在是否更理解离屏渲染的原理了呢?哈哈。
接下来讲讲使用离屏渲染可能带来的性能问题:
1、需要额外开辟存储空间,大量图层渲染,可能带来内存压力;
2、从离屏渲染缓存区(offscreen Buffer)中,转存帧缓存区(FrameBuffer)的过程需要时间;
3、离屏渲染缓存区(offscreen Buffer)有存储限制的,不超过屏幕像素点2.5倍。
从上面3点来看,很多人就问了,那为啥要使用离屏渲染呢?
个人的理解,为啥要使用离屏渲染:一是在特殊效果中,不能一次性的渲染完成所需的效果,需要离屏渲染缓存区(offscreen Buffer)来储存中间结果,这时才使用离屏渲染。如圆角、阴影等情况。二是在图层需要多次显示在屏幕上时,提前在离屏渲染缓存区(offscreen Buffer)中缓存起来,从而达到复用,提高效率。
普通渲染和离屏渲染有什么区别?
普通渲染:当图层显示在屏幕上时,该图层就从帧缓存区(FrameBuffer)中删除,节省空间。
离屏渲染:将多次图层绘制结果存储到离屏渲染缓存区(offscreen Buffer)中组合,将结果转存至帧缓存区(FrameBuffer)中,最后显示在屏幕上。
接下来说一下我们开发中经常碰到的离屏渲染的几种情况:
1、使用了Mask的layer;
2、需要进行裁剪的layer (layer.masksToBounds、layer.clipsToBounds);
3、设置组透明度为YES,并且组透明度不为1的layer(layer.allowsGrupOpacity、layer.opacity);
4、设置了阴影layer;
5、采用了光栅化的layer(layer.shouldRasterize);
6、绘制了文字的layer(UILaler、CATextLayer、Core Text);
上面的第三点解释一下:
如有侵权,联系我删除如上图,三个UIView分别为透明度为0.12、0.13、0.15叠在一起,这三个分别存储在离屏渲染缓存区(offscreen Buffer)中,转存到帧缓存区(FrameBuffer)中,最后显示在屏幕上,红色区域颜色值是通过混合计算的,此时发生了离屏渲染。
到目前为止离屏渲染个人理解就到这了。上述的内容如有误的,望指正哈。
网友评论