iOS下对离屏渲染的理解
2020-07-07 本文已影响0人
DSMars
离屏渲染定义
离屏渲染的流程如图:
离屏渲染流程.png
GPU把渲染好的的内容存放到离屏渲染缓冲区中,在离屏渲染缓冲区(OffscreenBuffer)中进一步做一些处理后,再提交到帧缓冲区(FrameBuffer)中。
离屏渲染的效率问题( 对性能有什么影响?)
从上面的流程来看,离屏渲染时由于 App 需要提前对部分内容进行额外的渲染并保存到 Offscreen Buffer,以及需要在必要时刻对 Offscreen Buffer 和 Framebuffer 进行内容切换,所以会需要更长的处理时间。
并且 Offscreen Buffer 本身就需要额外的空间,大量的离屏渲染可能早能内存的过大压力。与此同时,Offscreen Buffer 的总大小也有限,不能超过屏幕总像素的 2.5 倍。
使用离屏渲染的原因
情况一:
一般都是系统去触发,例如对layer层相关处理:包括圆角、阴影、mask等等。iOS系统扁平化后出现的高斯模糊也是利用离屏渲染方式。
情况二:
是一种主动行为,是为了提高复用的效率。通常是设置layer的shouldRasterize属性来实现。
shouldRasterize官方文档
shouldRasterize官方文档.png
开启后,会将layer作为位图保存下来,下次直接与其他内容进行混合。这个保存的位置就是OffscreenBuffer中。这样下次需要再次渲染的时候,就可以直接拿来使用了。
shouldRasterize使用建议:
- layer不复用,没必要使用shouldRasterize
- layer不是静态的,也就是说要频繁的进行修改,没必要使用shouldRasterize
- 时间方面:离屏渲染缓存有100ms时间限制,超过该时间的内容会被丢弃,进而不能达到复用的目的
- 空间方面:离屏渲染空间是屏幕像素的2.5倍,如果超过也无法复用。
常见触发离屏渲染的几种情况:
- 使用了 mask 的 layer (layer.mask)
- 需要进行裁剪的 layer (layer.masksToBounds / view.clipsToBounds)
- 设置了组透明度为 YES,并且透明度不为 1 的 layer (layer.allowsGroupOpacity/ layer.opacity)
- 添加了投影的 layer (layer.shadow*)
- 采用了光栅化的 layer (layer.shouldRasterize)
- 绘制了文字的 layer (UILabel, CATextLayer, Core Text 等)