GPU屏幕渲染方式:
1.On-Screen Rending
意为当前屏幕渲染,指的是GPU的渲染操作实在当前用于显示的屏幕缓冲区只能给进行,并没有开辟新的缓冲区。
2.Off-Screen Rending
意为离屏渲染,指的是GPU在渲染操作的时候,在当前屏幕缓冲区以为开辟一个新的缓冲区进行渲染操作。
注意:1.离屏渲染的内容是有时间限制的,缓存内容100ms内没有被使用,它就会被丢弃,无法进行复用。2.离屏渲染的缓存空间是有限的,超过2.5倍屏幕像素大小的话也会失效,且无法进行复用了。
离屏渲染的触发方式
· shouldRasterize(光栅化)
· masks(遮罩)
· shadows(阴影)
· edge antialiasing(抗锯齿)
· group opacity(不透明)
· 复杂形状设置圆角等
· 渐变
离屏渲染检测

用模拟器时候,Debug->Color Off-screen Render 就会检测触发生离屏渲染的部分(黄色阴影)。
Instruments的Core Animation工具中有几个和离屏渲染相关的检查选项:
Color Offscreen-Rendered Yellow
开启后会把那些需要离屏渲染的图层高亮成黄色,这就意味着黄色图层可能存在性能问题。
Color Hits Green and Misses Red
如果shouldRasterize被设置成YES,对应的渲染结果会被缓存,如果图层是绿色,就表示这些缓存被复用;如果是红色就表示缓存会被重复创建,这就表示该处存在性能问题了。
案例分析


由以上案例可知,第1与第3个控件渲染时发生了离屏渲染。在渲染有背景图的button时候,由于设置了圆角,GPU先渲染出背景的数据存放在新开辟的offscreen buffer里面,然后继续渲染背景的layer,继续存放在offscreen buffer里面。然后从offscreen buffer里面copy出来进行圆角的处理放在frame buffter 上。最后显示在屏幕上。如果不设置圆角的话,GPU计算好数据的话直接放在frame buffter然后显示就行了,显示完就丢弃了,正因为这样子,多个图层的话无法对数据进行圆角操作,需要将数据缓存起来。所以并不是所有的圆角设置都会出现离屏渲染的。
然后苹果的官方文档还说到

圆角触发离屏渲染

离屏渲染的逻辑
如果渲染一张有三个layer的图。没有触发离屏渲染如下所示:

当sublayer绘制到屏幕之后,就会讲sublayer从帧缓冲区(frame buffer)中移除,从而达到了节省空间的目的。
如果将这张图加上圆角,就会发生离屏渲染,如图所示:


总结:
其实离屏渲染在iOS系统中也会经常发生,例如下拉时候的毛玻璃效果。众而周知离屏渲染会特别的消耗性能,因为除了要创建一个屏幕外的缓冲区,然后在帧缓冲区跟离屏缓冲区之间的切换完成渲染操作。其中缓冲区的创建以及上下文的切换是非常耗性能的,而绘制并不是性能耗损的主要原因。
难道离屏渲染就没好处了吗?当然不是了!好明显对于数据的复用离屏缓冲区也是能做到的,避免了重复渲染layer。
网友评论