离屏渲染

离屏渲染是在iOS开发过程中脱离不了的话题,那么什么是离屏渲染以及哪些情况会导致离屏渲染呢?以及离谱渲染有哪些优势和劣势?

首先看下面一段代码,那种模式会触发离屏渲染呢?

       //按钮存在背景图片,并且设置圆角

        let btn1 =UIButton.init(type: .custom)

        btn1.frame=CGRect.init(x:100, y:100, width:44, height:44)

        btn1.layer.cornerRadius=5.0

        self.view.addSubview(btn1)

        btn1.setImage(UIImage.init(named:"tabbar_discover_hl"), for: .normal)

        btn1.clipsToBounds=true


        //按钮不存在背景图片,并且设置圆角

        let btn2 =UIButton(type: .custom)

        btn2.frame=CGRect.init(x:100, y:180, width:44, height:44)

        btn2.layer.cornerRadius=5.0

        btn2.backgroundColor = .blue

        self.view.addSubview(btn2)

        btn2.clipsToBounds=true


        //图片设置了背景色+背景图片

        let imgv1 =UIImageView(frame:CGRect.init(x:100, y:260, width:44, height:44))

        imgv1.image=UIImage.init(named:"tabbar_friends_hl")

        imgv1.backgroundColor = .blue

        imgv1.layer.cornerRadius=5.0

        imgv1.layer.masksToBounds=true

        self.view.addSubview(imgv1)


        //图片只设置了背景色

        let imgv2 =UIImageView(frame:CGRect.init(x:100, y:340, width:44, height:44))

        imgv2.image=UIImage.init(named:"tabbar_mine_hl")

        imgv2.layer.cornerRadius=5.0

        imgv2.layer.masksToBounds=true

        self.view.addSubview(imgv2)

XCode查看离屏渲染
测试效果

从上图可知,1、3中写法触发了离屏渲染,2、4两种写法未触发离屏渲染;

APP渲染流程

渲染流水线示意图

从图中可以看到(图片来源:WWDC),Application以及RenderServer部分是运行在CPU上的,Application处理好数据后,提交到Render Server,然后Core Animation在会将具体操作转换成GPU的Draw calls(OpenGL/Metal);也就是CPU+GPU共同完成渲染工作

什么是离屏渲染:

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

通过下面两幅图结合上面的概念可以清晰离屏渲染的原理:

渲染结果直接给到FrameBuffer,然后展示到屏幕上
渲染结果线给到offscreenBuffer,在到FrameBuffer,然后展示到屏幕上

那么离屏渲染是如何工作的呢?通过圆角触发离屏渲染来进行分析

设置圆角触发offscreen render

从上图可知,给UIButton设置背景图片并且添加圆角涉及3部分内容

1、backgroundColor

2、contents

3、borderColor/borderWidth

当每一部分layer会独立绘制,然后保存到offscreenBuffer中,当全部layer绘制后,对这3部分整体进行添加圆角,所以需要先存入到offscreenBuffer中,否则绘制完会自动销毁,当设置圆角时无法获取到之前的layer;

绘制原理图示

GPU离屏渲染,“画家画法”

通过渲染流水线示意图中我们可以看到,主要的渲染操作都是由CoreAnimation的Render Server模块,通过调用显卡驱动所提供的OpenGL/Metal接口来执行的。通常对于每一层layer,Render Server会遵循“画家算法”,按次序输出到frame buffer,后一层覆盖前一层,就能得到最终的显示结果(值得一提的是,与一般桌面架构不同,在iOS中,设备主存和GPU的显存共享物理内存,这样可以省去一些数据传输开销)

然而有些场景并没有那么简单。作为“画家”的GPU虽然可以一层一层往画布上进行输出,但是无法在某一层渲染完成之后,再回过头来擦除/改变其中的某个部分——因为在这一层之前的若干层layer像素数据,已经在渲染中被永久覆盖了。这就意味着,对于每一层layer,要么能找到一种通过单次遍历就能完成渲染的算法,要么就不得不另开一块内存,借助这个临时中转区域来完成一些更复杂的、多次的修改/剪裁操作

当sublayer绘制到屏幕上之后,就会将sublayer从帧缓存区移除,从而节省空间


将要混合的内容各自渲染完,暂时存在离屏缓存区
等所有layer全部绘制完成,从offscreenBuffer中获取数据,进行组合

通过上面的理解,可以发现,App需要进行额外的渲染和合并,必须使用Offscreen Buffer,然后进行组合放入到Frame Buffer中,然后现在到屏幕上

离屏渲染性能问题:

1,需要额外的存储空间,

2,将结果从Offscreen buffer转存到Frame Buffer中也是需要时间的

Offscreen Buffer的空间也是有限制的(限制大小是屏幕像素大小的2.5倍)

既然离屏渲染容易带来性能问题,为什么还要用呢?

1.非常多的特殊效果,并不能一次用一个图层就能画出来,所以需要使用额外的offscreen Buffer来保持中间状态(不得不使用),比如:圆角,阴影

2.能带来效率的优势:既然效果会多次出现在屏幕上,可提前渲染好,保存在offscreen Buffer中,从而达到复用的结果  比如:光珊化shouldRasterize

常见离屏渲染:

能引起离屏渲染

所以我们在项目开发的过程中,根据实际情况进行相关的优化,突出其优势避免其劣势

特别说明:关于光珊化并不是所有的光珊化都会带来性能问题,以下是关于光珊化的使用建议

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