第二十一篇:离屏渲染

手机软件开发 2024-9-15 19:18:18 97 0 来自 中国
我们经常用的UIKit框架就是继承与CoreAnimation,CoreGraphics框架。这两个框架又依赖于OpenGL ES。CoreImage是处置惩罚图像之前的一些使用。

2.jpeg 下面这张图是焦点:
通过视频控制器去frameBuffer也就是帧缓存里读取,就是通过下面的电子枪帧扫描读取。当扫描一圈后,也就是回到初始位置的时间,就会形成一个Vsync垂直信号。

3.jpeg 离屏渲染的界说:

如果要在体现屏上体现内容,我们至少必要一块与屏幕像素数据量一样大
的frame buffer(帧缓冲区),作为像素数据存储地区,然后由体现控制器把帧缓存区的数据体现到屏幕上。如果偶尔由于面临一些限制,一些缘故原由,比如说阴影,遮罩mask等,GPU无法把渲染效果直接写入frame buffer,而是先暂把中央的一个临时状态存在别的的内存地区,之后再写入frame buffer,那么这个过程被称之为离屏渲染。
UIview是基于CALayer的,CALayer其有三个部分,分别是backgroundColor,contents,borderWidthborderColor。此中clip to bounds属性就是设置修改contents的。
6.png 下面就是离屏渲染的过程,当要体现最后面一幅画时间,GPU在绘制时间数据时间,会先绘制个山,然后会绘制个草地,然后再绘制个树,然后会开辟了单独空间举行合成,这个空间也就是framebuffer。离屏渲染就是由于硬件的瓶颈限制导致的。

7.jpeg 触发离屏渲染使用

光栅化肯定会触发离屏渲染:

光栅化是一个缓存机制,开启的话就会以bitmap位图的情势保存起来,下次再使用的话就会从缓存中拿取举行渲染,可以镌汰CPU盘算,其只能缓存100ms,以是很少用,其会触发离屏渲染。

  • (void)ShouldRasterize {
    self.lgImageView.layer.shouldRasterize = NO;
    }
遮罩mask肯定会触发离屏渲染:

当添加遮罩,这个遮罩会放到CALayer的上层,这个就肯定会导致离屏渲染。

  • (void)Mask {
    //添加到layer的上层
    CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(30, 30, self.lgImageView.bounds.size.width, self.lgImageView.bounds.size.height);
    layer.backgroundColor = [UIColor redColor].CGColor;
    self.lgImageView.layer.mask = layer;
    }
阴影肯定会触发离屏渲染:

阴影是添加到layer的下层,层级就会比力复杂,就会触发离屏渲染。

  • (void)Shadows {
    //添加到layer的下层
    self.lgImageView.layer.shadowColor = [UIColor redColor].CGColor;
    self.lgImageView.layer.shadowOffset = CGSizeMake(20, 20);
    self.lgImageView.layer.shadowOpacity = 0.2;
    self.lgImageView.layer.shadowRadius = 5;
    self.lgImageView.layer.masksToBounds = NO;
    }
上面的阴影是可以优化的,我们可以提前指定阴影的路径,通过UIBezierPath曲线途径如许就不会触发离屏渲染了。
//阴影优化

  • (void)Shadows2 {
    self.lgImageView.layer.shadowColor = [UIColor redColor].CGColor;
    self.lgImageView.layer.shadowOpacity = 0.2;
    self.lgImageView.layer.shadowRadius = 5;
    self.lgImageView.layer.masksToBounds = NO;
    //提前指定阴影的路径
    [self.lgImageView.layer setShadowPath:[UIBezierPath bezierPathWithRect:CGRectMake(0, 0, self.lgImageView.bounds.size.width + 20, self.lgImageView.bounds.size.height + 20)].CGPath];
    }
抗锯齿在满意肯定条件会触发离屏渲染。如果在设置属性时间,如果选择的模式为fit就会触发离屏渲染。选择的是fill就不会触发离屏渲染,是由于如许就不会有抗锯齿了,也就不会触发离屏渲染。

抗锯齿盘算量也很大,对性能有要求

  • (void) EdgeAnntialiasing {
    CGFloat angle = M_PI / 60.0;
    [self.lgImageView.layer setTransform:CATransform3DRotate(self.lgImageView.layer.transform, angle, 0.0, 0.0, 1.0)];
    self.lgImageView.layer.allowsEdgeAntialiasing = YES;
    }
不透明不肯定会触发离屏渲染(必要看起是否有子视图)。

allowsGroupOpacity 这个是设置了视图的子视图在透明度上是否和俯视图同等,可以看标注1,如果没有标注1这块是不会触发离屏渲染的。

  • (void)lgAllowsGroupOpacity {
    //标注1
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
    view.backgroundColor = [UIColor greenColor];
    view.alpha = 0.8;
    [self.lgImageView addSubview:view];
    //标注1
    self.lgImageView.alpha = 1;
    //allowsGroupOpacity 设置视图的子视图在透明度上是否和俯视图同等
    self.lgImageView.layer.allowsGroupOpacity = YES;
    }
当view上另有别的subview时
view 上子视图的 alpha 在 0 ~ 1 之间
view.layer.allowsGroupOpcity = Yes
具体缘故原由在于重叠部分的图像必要两个view的图像合成来盘算,因此只有满意上述三个条件时,才会触发。
圆角不肯定会触发离屏渲染(label就不会触发离屏渲染,其他控件就会触发)。这个是由于lable我们在设置backgroundColor 颜色时间,着实是设置contents的颜色。


  • (void)lgRadius {
    //uilabel 设置圆角
    self.lgImageView.backgroundColor = [UIColor redColor];
    [self lgBezier];
    //    self.lgImageView.layer.backgroundColor = [UIColor greenColor].CGColor;
    //contents + backgroundColor\border
    //    self.lgImageView.layer.cornerRadius = 40;
    //
    ////    self.lgLabel.backgroundColor = [UIColor redColor];
    //    self.lgLabel.layer.backgroundColor = [UIColor greenColor].CGColor;
    //    self.lgLabel.layer.cornerRadius = 10;
    }
在开辟中只管制止离屏渲染,由于会导致丢帧(卡顿),和斲丧内存(由于其必要单独分配一个空间出来存framebuffer)。
drawRect方法解说(一种特殊的离屏渲染):

使用drawRect方法会再开辟一块画布, 是在开辟的画布上画,在开辟中只管少重写drawRect方法。这个会增大内存斲丧,这个被称为一种特殊的离屏渲染。使用drawRect后天生一个backing store,这个是村bitmap的,同时 会使用CoreGraphics框架,在CoreGraphics框架上使用这个是直接在CPU处置惩罚的。
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-18 22:31, Processed in 0.152986 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表