关于layer.cornerRadius的离屏渲染问题

案例解读

在咱们平常开发过程当中 ,常常使用layer.cornerRadius的方式来设置圆角。那到底会不会带来离屏渲染呢 。今天咱们来研究一下。 下面是几个不一样形式的layer.cornerRadius圆角案例缓存

//1.按钮存在背景图片
    UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
    btn1.frame = CGRectMake(100, 30, 100, 100);
    btn1.layer.cornerRadius = 50;
    [self.view addSubview:btn1];
    btn1.backgroundColor = [UIColor blueColor];
    [btn1 setImage:[UIImage imageNamed:@"btn.png"] forState:UIControlStateNormal];
    btn1.clipsToBounds = YES;
    
    //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;
    
    //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"];
    
    //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"];
复制代码

运行的效果如图所示bash

首先开启模拟器的离屏渲染检测app

结果显示 性能

由上图能够看出,并非使用了 layer.cornerRadius就必定会产生离屏渲染。 其产生的缘由有以下几个 :

  • 当图片大小比UIImageView的大小要大,而且clipsToBounds设置的属性为true,这时候,会产生 图片的裁剪。就会产生离屏渲染。
  • 有背景颜色和背景图片一块儿渲染。我的理解为,有背景颜色 和和背景图片 都包含 ,会产生不一样的层次。于是会产生离屏渲染。

离屏渲染原理 app 为了提升渲染效率 ,开辟了 offscreen BufferFrameBuffer 两个缓冲区,目的是为了以空间换取时间。提早进行渲染(offscreenBuffer)能够提升复用目的 还有在特殊效果时 ,屏幕须要使用额外的offscreen Buffer 来保存中间状态,不得不使用离屏渲染,如圆角、阴影。 , 可是离屏渲染渲染也会带来性能问题--容易掉帧. 离屏渲染产生的缘由主要有两方面:优化

1.在VSync(垂直脉冲)信号做用下,视频控制器每隔16.67ms就会去帧缓冲区(当前屏幕缓冲区)读取渲染后的数据;可是有些效果被认为不能直接呈现于屏幕前,而须要在别的地方作额外的处理,进行预合成。ui

好比图层属性的混合体再没有预合成以前不能直接在屏幕中绘制,因此就须要屏幕外渲染。屏幕外渲染并不意味着软件绘制,可是它意味着图层必须在被显示以前必须在一个屏幕外上下文中被渲染(不论CPU仍是GPU)。spa

2.有些视图渲染后的纹理须要被屡次复用,但屏幕内的渲染缓冲区是实时更新的,因此须要经过开辟屏幕外的渲染缓冲区,将视图的内容渲染成纹理并缓存,而后再须要的时候在调入屏幕缓冲区,能够避免屡次渲染的开销。code

典型的例子就是光栅化。光栅化就是经过把视图的内容渲染成纹理并缓存,等到下次调用的时候直接去缓存的取出纹理,可是更新内容时候,会启用离屏渲染,因此更新的代价比较大,只能用于静态内容;并且若是光栅化的元素100ms没有被使用,也将被移除,故而不经常使用元素的光栅化并不会优化显示。orm

注意:光栅化的元素,总大小限制为2.5倍的屏幕。cdn

相关文章
相关标签/搜索