iOS离屏渲染解析

2020-07-07  本文已影响0人  ugpass

iOS渲染层级

image.png

CoreAnimation核心动画是由Layer Kit演变而来,所以它并不是只能做关于动画方面的,它可以理解为一个复合引擎,目的是更快的组合屏幕上不同的显示内容。

离屏渲染的定义

image.png

App通过CPU和GPU的配合,将渲染数据放入帧缓冲区,视频控制器不断的从帧缓冲区取出数据显示到显示屏上。

image.png

和未发生离屏渲染时相比,App并不是直接将数据放入帧缓冲区,而是额外先开辟一个离屏缓冲区(Offscreen Buffer),在离屏缓冲区将渲染内容进行额外渲染和合并之后,再将数据送入帧缓冲区。

Offscreen Buffer存储最大限制为屏幕像素的2.5倍

理解圆角CornerRadius和离屏渲染的关系

问题:btn.layer.cornerRadius = 5; btn.layer.maskToBounds = YES;一定会触发离屏渲染吗?

CornerRadius的官方文档解释:只对layer的background和border起作用,并不会作用于contents。但是设置masksToBounds对应UIView的clipsToBounds则会对内容进行裁剪。

Setting the radius to a value greater than 0.0 causes the layer to begin drawing           
rounded corners on its background. By default, the corner radius does not apply 
to the image in the layer’s 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.

案例1:按钮设置图片 即在按钮上添加一个ImageView,则有两个图层,做圆角需要对两个图层进行裁剪,则会触发离屏渲染。

    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:按钮添加背景色、设置border,仍然只有按钮一个图层做圆角,并不会触发离屏渲染。

    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:ImageView设置图片和背景色,两个图层做圆角,则会触发离屏渲染。

    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:ImageView只设置图片,只有一个图层做圆角则不会触发离屏渲染。

    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 buffer所造成的。我理解的这里的一个图层并不等于一个CALayer,一个CALayer可以包含多个图层。

离屏渲染产生的问题

对应的造成性能问题以及掉帧

需要使用离屏渲染的场景

上一篇 下一篇

猜你喜欢

热点阅读