美文网首页
iOS 离屏渲染总结

iOS 离屏渲染总结

作者: spades_K | 来源:发表于2020-07-08 15:59 被阅读0次

    什么是离屏渲染

    如果要在显示屏上显示内容,我们至少需要一块与屏幕像素数据量一样大的frame buffer,作为像素数据存储区域,而这也是GPU存储渲染结果的地方。如果有时因为面临一些限制,无法把渲染结果直接写入frame buffer,而是先暂存在另外的内存区域,之后再写入frame buffer,那么这个过程被称之为离屏渲染。

    离屏渲染

    运行实例demo

        //1.按钮存在背景图片
        UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
        btn1.frame = CGRectMake(100, 30, 100, 100);
        btn1.layer.cornerRadius = 50;
        [self.view addSubview:btn1];
        
        [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.layer.borderWidth = 10;
        btn2.layer.borderColor = [[UIColor redColor] colorWithAlphaComponent:0.3].CGColor;
        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"];
    
    
    结果

    Why?

    先来了解下CALayer的结构


    CALayer结构

    图层叠加绘制遵循 油画算法 ,按次序输出到frame buffer,后一层覆盖前一层,就能得到最终的显示结果(渲染完成后丢弃不做保存)。

    油画算法示例图
    如果想对绘制好的结果界面进行圆角操作,是不可能的。要想实现圆角效果,只能把需要处理的Layer依次在 Offscreen Buffer处理,处理完成之后再写入frame buffer进行渲染。

    Demo 解读

    • bt1
      button设置背景图片进行圆角操作。
      我们可以看下层级 UIButton中包含UIImageView层级,做圆角操作是需要离屏渲染的。
      bt1层级
      如果bt1 做下列修改则不会造成离屏渲染 与 img2是一个道理
        btn1.imageView.layer.cornerRadius = 50;
        btn1.imageView.clipsToBounds = YES;
    
    • bt2
      设置了背景色和cornerRadius ,只为layer的backgroundColor和border设置圆角(content层不会被修改),设置clipsToBounds =YES后,会应用到所有图层,但是content层没有内容,所以不会触发离屏渲染。

    • img1
      设置了Layer的backgroundColor层和content层,会触发离屏渲染。

    总结

    条件 (layer.clipsToBounds=YES && layer.cornerRadius>0)
    1.当存在子layer(layer不透明)设置时触发离屏渲染。
    2.单层layer设置 (backgroundColor && border),不设置content层不会触发离屏渲染,但是((backgroundColor || border)&&content )会触发离屏渲染。

    相关文章

      网友评论

          本文标题:iOS 离屏渲染总结

          本文链接:https://www.haomeiwen.com/subject/twkqcktx.html