离屏渲染触发的原理
离屏渲染检测案例
先实现下面4个圆角Demo,分别为2个UIButton
和2个UIImageVIew
进行测试,我们可以发现圆角DemoA与圆角DemoC会发现离屏渲染,那是什么原因导致的离屏渲染呢?
-
圆角DemoA
//1.按钮存在背景图片 UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeCustom]; btn1.frame = CGRectMake(100, 30, 100, 100); btn1.layer.cornerRadius = 50; [btn1 setImage:[UIImage imageNamed:@"btn.png"] forState:UIControlStateNormal]; btn1.clipsToBounds = YES; [self.view addSubview:btn1];
-
圆角DemoB
//2.按钮不存在背景图片 UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeCustom]; btn2.frame = CGRectMake(100, 180, 100, 100); btn2.layer.cornerRadius = 50; btn2.backgroundColor = [UIColor blueColor]; [self.view addSubview:btn2]; btn2.clipsToBounds = YES;
-
圆角DemoC
//3.UIImageView 设置了图片+背景色; UIImageView *img1 = [[UIImageView alloc]init]; img1.frame = CGRectMake(100, 320, 100, 100); img1.backgroundColor = [UIColor blueColor]; [self.view addSubview:img1]; img1.layer.cornerRadius = 50; img1.layer.masksToBounds = YES; img1.image = [UIImage imageNamed:@"btn.png"];
-
圆角DemoD
//4.UIImageView 只设置了图片,无背景色; UIImageView *img2 = [[UIImageView alloc]init]; img2.frame = CGRectMake(100, 480, 100, 100); [self.view addSubview:img2]; img2.layer.cornerRadius = 50; img2.layer.masksToBounds = YES; img2.image = [UIImage imageNamed:@"btn.png"];
Offscreen Rendering (离屏渲染)渲染流程
iOS 正常渲染流程
正常渲染流程.jpg离屏渲染流程
离屏渲染流程.jpg离屏渲染造成的性能问题
-
离屏渲染的(离屏缓存区)会造成额外的存储空间(最大是屏幕像素区域的2.5倍)
-
离屏渲染帧缓存区到帧缓存区会造成额外的时间开销
为什么要使用离屏渲染的原因
-
特殊的效果不能一次完成渲染,需要使用额外的offscreen Buffer 保存中间的状态,不得不使用离屏渲染。
-
虽然造成了性能的消耗,但是提高了效率,达到了复用的目的。
几种造成离屏渲染的情况
遮罩渲染
遮罩渲染.png高斯模糊渲染
毛玻璃渲染.png开启光栅化(shouldRasterize)
光栅化.png光栅化使用建议
-
如果layer不能被复用,则没有必要打开光栅化
-
如果layer不是静态的,开启离屏渲染反而没有效率
-
离屏渲染缓存空间有限,2.5倍屏幕像素大小
-
离屏渲染缓存内容有时间限制,100ms
圆角触发的离屏渲染
Layer的圆角.png应用cornerRadius
和masksToBounds
进行圆角+裁剪设置背景颜色和内容会造成离屏渲染,因为需要对多个图层进行圆角设置缓存在offscreenBuffer,进行组合渲染。
关于圆角的处理方案
-
UIImageView
仅设置Image
、cornerRadius
及maskToBounds
-
贝塞尔曲线绘制
-
圆角图片遮罩
-
YYImage圆角处理
常见触发离屏渲染的情况
-
使用了mask的layer,
layer.mask
-
需要裁剪的layer,
layer.masksToBounds
-
设置组透明度,并且透明度不为1,
layer.allowsGroupOpacity / layer.opacity
-
添加了投影的layer,
layer.shadow
-
采用了光栅化的layer,
layer.shouldRasterize
-
绘制了文字的layer
网友评论