003-iOS离屏渲染产生的原因

离屏渲染产生的原因

在讨论离屏渲染之前我们先要搞清楚正常的渲染流程是怎样的

非离屏渲染流程:
非离屏渲染

我们可以看到在非离屏渲染的场景下,需要渲染的数据是直接提交到GPU的帧缓冲区,等待屏幕的垂直同步信号来完成页面的显示,但是在离屏渲染的场景下又是怎样的呢?请看下图


离屏渲染

我们可以看到在离屏渲染的场景下,要完成页面的展示,中间多了一个过程,需要渲染的数据首先提交到了离屏缓冲区,然后再提交到帧缓冲区的,为什么要增加一个OffsceenBuffer呢?这个OffsceenBuffer又有什么作用呢?

为什么要增加OffsceenBuffer?

如果触发了离屏渲染,那么在显示这个页面的每一帧都会去做离屏渲染的处理,比如切圆角,显示阴影等,如果每一帧都要重新去处理,那么对于CPU以及GPU都带来很大的负担。所以引入了离屏缓冲区,将处理好的图层直接丢到离屏缓冲区,下次渲染的时候直接拿出来显示到屏幕上

离屏缓存区也是有限制的

  • 时间限制:缓存的内容超过100ms没有被使用,内容将会被丢弃
  • 空间限制:超过屏幕像素大小的2.5倍,将不能再存储新的数据,离屏渲染会失效

这样做虽然解决了多次处理数据的问题,但是还是会带来另外的性能问题,由于离屏缓冲区和帧缓冲区属于两个不同的缓冲区,如果一个页面触发了多个离屏渲染,那么GPU在显示每一帧的时候都要在离屏缓冲区和帧缓冲区之间切换,在快速滚动的场景下就会出现严重的掉帧。那么怎么解决这个问题呢?其实答案就是要减少离屏渲染,那些场景会触发离屏渲染呢?

触发离屏渲染的场景

离屏渲染的检测

在模拟器运行时我们在这里开启离屏渲染的检测:


离屏渲染检测开关

开启后,如果有离屏渲染,则会显示成黄色,如下图:


离屏渲染
1. cornerRadius + masksToBounds

这两个属性我们都不陌生,这是我们经常使用的切圆角的方式,将cornerRadius > 0同时masksToBounds = YES时,就可能会触发离屏渲染,注意,是可能,我们来看下图中的例子


例1

先不要着急,我们再来看另外一个例子:


例2

为什么同样都是设置cornerRadius + masksToBounds,例1和例2的结果却不相同呢?相信细心的同学已经发现了,例2多了一个绿色的view,例2中的图层层级是这样的:


例2图层

所以我们能够得出:

如果只有一个图层,就算同时设置 cornerRadius + masksToBounds 也并不会触发离屏渲染,只有多个图层发生叠加的时候才会触发离屏渲染

为什么多个图层叠加会触发离屏渲染呢 ?

画家算法: 当GPU在渲染图层的时候会根据图层的远近去由远及近完成渲染,这里说的远近就是叠加图层时由内到外,当一帧数据处理好后将被提交到帧缓冲区,但是如果当前图层是多个图层叠加后的结果,那么将不能被直接提交到帧缓冲区(如果提交了,下一个垂直同步信号到来的时候会被直接显示在界面上),需要存储起来,等待这个图层的所有子图层都被处理完通过叠加后,再提交到帧缓冲区用于显示

如果我们只设置cornerRadius,会不会触发离屏渲染呢?

cornerRadius
例3

这个就要从CALayer的结构说起了


CALayer结构

CALayer大致分为三层

  1. backgroundColor : 背景颜色层
  2. content :内容显示层,这一层主要用于显示我们设置的内容
  3. border :当我们设置边框的时候,就是这一层在工作

cornerRadius只会设置backgroundColor和border的圆角,并不会对content设置圆角。除非同时设置了masksToBounds为YES(对应view中的clipsToBounds),所以如果只设置cornerRadius,在图层叠加时并不会触发离屏渲染

2.mask

Mask 效果与混合图层的效果非常相似,只是使用同一个遮罩图像时,mask 与混合图层的效果是相反的。Mask无法取消离屏渲染


例4

3. GroupOpacity

GroupOpacity

GroupOpacity 是指 CALayer 的allowsGroupOpacity属性,UIView 的alpha属性等同于 CALayer opacity属性。开启 GroupOpacity 后,子 layer 在视觉上的透明度的上限是其父 layer 的opacity。

从 iOS 7 以后默认全局开启了这个功能,这样做是为了让子视图与其容器视图保持同样的透明度。

GroupOpacity 开启离屏渲染的条件是:layer.opacity != 1.0并且有子 layer 或者背景图。

例5

4. shadow

阴影直接合成在视图的下面,视图结构里并没有多出一个视图。在没有指定阴影路径时,阴影是沿着视图的非透明部分扩展的,而且 CALayer 的三个视觉元素至少有一个存在时才会有阴影。
使用阴影必须保证 layer 的masksToBounds = false,因此阴影与系统圆角不兼容。但是注意,只是在视觉上看不到,对性能的影响依然。


例6

如果我们在设置阴影时,给阴影指定了路径,就不会触发离屏渲染了
例如,这样设置阴影:

    self.view1.layer.shadowColor = [UIColor greenColor].CGColor;
    self.view1.layer.shadowOffset = CGSizeMake(5, 5);
    self.view1.layer.shadowOpacity = 0.5;
    self.view1.layer.shadowRadius = 3;
    UIBezierPath * path = [UIBezierPath bezierPathWithRect:self.view1.bounds];
    self.view1.layer.shadowPath = path.CGPath;
例7
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355