什么是离屏渲染?
GPU屏幕渲染有两种方式:
OnScreen Rendering当前屏幕渲染
,指的是GPU的渲染操作是读取当前帧缓冲区的数据进行渲染,每次渲染帧缓冲区中的数据到屏幕后,帧缓冲区的数据就会丢弃以节省空间,再次开始对新数据的处理
APP -> Frame Buffer -> Display
OffScreen Rendering离屏渲染
,指的是GPU在当前的帧缓冲区以外,需要新开辟一块缓冲区(Offscreen Buffer),每个图层数据经处理后暂时保存在离屏缓冲区,等所有的数据处理后组合在一起,通过帧缓冲区渲染到屏幕
APP -> Offscreen Buffer -> Frame Buffer -> Display
如何触发离屏渲染?
可能有听说过 cornerRadius圆角+masksToBounds=YES
会触发离屏渲染,那么真实情况是否真的是这样?我们从代码来看.
/**
1.有背景颜色
2.masksToBounds = YES
3.没有content层(图片)
*/
UIImageView *imageV1 = [[UIImageView alloc]initWithFrame:CGRectMake(50, 600, 100, 100)];
imageV1.backgroundColor = [UIColor redColor];
imageV1.layer.cornerRadius = 50;
imageV1.layer.masksToBounds = YES;
[self.view addSubview:imageV1];
/**
1.有背景颜色
2.masksToBounds = YES
3.有content层(图片)
*/
UIImageView *imageV2 = [[UIImageView alloc]initWithFrame:CGRectMake(50, 750, 100, 100)];
imageV2.backgroundColor = [UIColor redColor];
imageV2.layer.cornerRadius = 50;
imageV2.layer.masksToBounds = YES;
imageV2.image = [UIImage imageNamed:@"路飞.jpg"];
[self.view addSubview:imageV2];
模拟器设置Debug中的Color Off-screen Rendered,来看是否触发
模拟器结果:
对比上两段代码的区别,都有设置
cornerRadius圆角+masksToBounds=YES
,但是结果只有imageV2触发了离屏渲染,这个结果就推翻了 cornerRadius圆角+masksToBounds=YES
会触发离屏渲染的说法.
解读:
the corner radius does not apply to the image in the layers contents property;it applies only to the background color and border of the layer. However,setting the
masksToBounds
property to YES causes the content to be clipped to the rounded corners
绘制图层圆角,设置layer.cornerRadius,只会设置backgroundColor和border的圆角,除非同时设置masksToBounds=YES
那么我们再来看下,为什么imageV2会触发离屏渲染呢?
imageV2中,除了有背景颜色的图层,还有content内容(image图片),所以GPU在渲染iamgeV2时,需要对两个图层都要做圆角处理,那么就需要用到Offscreen Buffer离屏缓冲区,来进行每个图层数据处理后的保存,当两者都处理完之后组合进行渲染.
那么我们是不是可以有这样的结论:
当渲染的图层大于1,且需要对图层进行处理、合成后,渲染到屏幕上,那么就会触发离屏渲染.
除此之外,类似可以触发离屏渲染的方式还有很多
毛玻璃效果
经过了
对渲染内容的处理组合后,显示了毛玻璃的效果.
layer光栅化
layer的属性shouldRasterize
如果设置属性为YES,会将layer包括阴影、滤镜效果渲染成位图,将位图组合,等待复用.
限制:
- 离屏缓冲区的大小不能超过屏幕的2.5倍
- 离屏缓冲区有时间限制,超过100ms未被使用就会被释放
使用建议:
- 如果layer不能被复用,没有必要打开
- 如果layer不是静态的,会被频繁修改,比如处于动画中,开启离屏渲染反而影响效率
- 离屏渲染缓存空间有限,超过2.5倍无法进行复用
- 离屏渲染缓存时间有限,超过100ms未使用会被丢弃
组透明度
当对layer设置透明度时, 还是会先等待所有的图层处理到离屏缓冲区后,计算整体的透明颜色,得到新的颜色后进行渲染