iOS 离屏渲染研究

转载 2016年05月30日 16:55:49

GPU渲染机制:

CPU 计算好显示内容提交到 GPU,GPU 渲染完成后将渲染结果放入帧缓冲区,随后视频控制器会按照 VSync 信号逐行读取帧缓冲区的数据,经过可能的数模转换传递给显示器显示。


GPU屏幕渲染有以下两种方式:

  • On-Screen Rendering
    意为当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行。

  • Off-Screen Rendering
    意为离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。

    特殊的离屏渲染:
    如果将不在GPU的当前屏幕缓冲区中进行的渲染都称为离屏渲染,那么就还有另一种特殊的“离屏渲染”方式: CPU渲染。
    如果我们重写了drawRect方法,并且使用任何Core Graphics的技术进行了绘制操作,就涉及到了CPU渲染。整个渲染过程由CPU在App内 同步地
    完成,渲染得到的bitmap最后再交由GPU用于显示。
    备注:CoreGraphic通常是线程安全的,所以可以进行异步绘制,显示的时候再放回主线程,一个简单的异步绘制过程大致如下

    - (void)display {
       dispatch_async(backgroundQueue, ^{
           CGContextRef ctx = CGBitmapContextCreate(...);
           // draw in context...
           CGImageRef img = CGBitmapContextCreateImage(ctx);
           CFRelease(ctx);
           dispatch_async(mainQueue, ^{
               layer.contents = img;
           });
       });
    }

离屏渲染的触发方式

设置了以下属性时,都会触发离屏绘制:

  • shouldRasterize(光栅化)
  • masks(遮罩)
  • shadows(阴影)
  • edge antialiasing(抗锯齿)
  • group opacity(不透明)
  • 复杂形状设置圆角等
  • 渐变

其中shouldRasterize(光栅化)是比较特别的一种:
光栅化概念:将图转化为一个个栅格组成的图象。
光栅化特点:每个元素对应帧缓冲区中的一像素。

shouldRasterize = YES在其他属性触发离屏渲染的同时,会将光栅化后的内容缓存起来,如果对应的layer及其sublayers没有发生改变,在下一帧的时候可以直接复用。shouldRasterize = YES,这将隐式的创建一个位图,各种阴影遮罩等效果也会保存到位图中并缓存起来,从而减少渲染的频度(不是矢量图)。

相当于光栅化是把GPU的操作转到CPU上了,生成位图缓存,直接读取复用。

当你使用光栅化时,你可以开启“Color Hits Green and Misses Red”来检查该场景下光栅化操作是否是一个好的选择。绿色表示缓存被复用,红色表示缓存在被重复创建。

如果光栅化的层变红得太频繁那么光栅化对优化可能没有多少用处。位图缓存从内存中删除又重新创建得太过频繁,红色表明缓存重建得太迟。可以针对性的选择某个较小而较深的层结构进行光栅化,来尝试减少渲染时间。

注意:
对于经常变动的内容,这个时候不要开启,否则会造成性能的浪费

例如我们日程经常打交道的TableViewCell,因为TableViewCell的重绘是很频繁的(因为Cell的复用),如果Cell的内容不断变化,则Cell需要不断重绘,如果此时设置了cell.layer可光栅化。则会造成大量的离屏渲染,降低图形性能。


为什么会使用离屏渲染

当使用圆角,阴影,遮罩的时候,图层属性的混合体被指定为在未预合成之前不能直接在屏幕中绘制,所以就需要屏幕外渲染被唤起。

屏幕外渲染并不意味着软件绘制,但是它意味着图层必须在被显示之前在一个屏幕外上下文中被渲染(不论CPU还是GPU)。

所以当使用离屏渲染的时候会很容易造成性能消耗,因为在OPENGL里离屏渲染会单独在内存中创建一个屏幕外缓冲区并进行渲染,而屏幕外缓冲区跟当前屏幕缓冲区上下文切换是很耗性能的。


Instruments监测离屏渲染

Instruments的Core Animation工具中有几个和离屏渲染相关的检查选项:

  • Color Offscreen-Rendered Yellow
    开启后会把那些需要离屏渲染的图层高亮成黄色,这就意味着黄色图层可能存在性能问题。

  • Color Hits Green and Misses Red
    如果shouldRasterize被设置成YES,对应的渲染结果会被缓存,如果图层是绿色,就表示这些缓存被复用;如果是红色就表示缓存会被重复创建,这就表示该处存在性能问题了。


iOS版本上的优化

iOS 9.0 之前UIimageView跟UIButton设置圆角都会触发离屏渲染

iOS 9.0 之后UIButton设置圆角会触发离屏渲染,而UIImageView里png图片设置圆角不会触发离屏渲染了,如果设置其他阴影效果之类的还是会触发离屏渲染的。

这可能是苹果也意识到离屏渲染会产生性能问题,所以能不产生离屏渲染的地方苹果也就不用离屏渲染了。



文/齐滇大圣(简书作者)
原文链接:http://www.jianshu.com/p/6d24a4c29e18
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

ios安全研究方向

Module 1: Introduction to iOS Security iOS Platform Basics iOS Application Development and Tes...
  • u011069813
  • u011069813
  • 2013年09月14日 15:48
  • 1740

对iOS锁的一些研究

最近因为程序中频繁使用到了锁,不知道各种锁对性能的影响,今天稍作测试。顺便研究下里面的机制。 测试代码 测试原理:在一个线程中,对空代码段执行指定次数的加解锁。算出时间差。 ...
  • meegomeego
  • meegomeego
  • 2014年09月25日 10:12
  • 9285

Live555研究之一 源代码编译

Live555学习之一 源码编译       Live555 是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了对标准流媒体传输协议如RTP/RTCP、RTSP、SIP等的支持。Live55...
  • ithzhang
  • ithzhang
  • 2014年07月20日 09:49
  • 11336

视频VR/点播/直播播放器研究与OpenGL(1)

> VR/点播,Google VR;Unity 3D VR Google VR研究,发现它闭源 可定制的东西比较少,可以舍弃它了 翻墙看google VR 官方文档:https://developer...
  • ShareUs
  • ShareUs
  • 2017年07月25日 15:33
  • 1371

计算机网络研究方向和网络安全问题

1)密码理论:研究高强度的密码理论,高速加解密算法,密码分析与攻击算法等     2)安全协议:研究安全协议的形式化方法,如BAN逻辑,串空间,SPI演算等;研究安全多方计算的基础理论  ...
  • moqingxinai2008
  • moqingxinai2008
  • 2016年12月28日 15:33
  • 605

ios多线程初步研究

对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用。产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用。一、显示调用的类为NSThread。一般构造NSThr...
  • k569462166
  • k569462166
  • 2015年11月12日 14:44
  • 169

前瞻性队列、回顾性队列、病例对照研究

一、前瞻性队列研究 研究对象的确定与分组根据研究开始时的实际情况,研究的结局需随访观察一段时间才能得到,这种研究可信度高、偏倚少,但费时、费人力、物力、财力。 二、回顾性队列研究 回顾性队列研究...
  • u012344939
  • u012344939
  • 2017年02月24日 18:31
  • 1123

iOS越狱原理详解

iOS越狱原理详解 转载文章,链接地址: http://blog.sina.com.cn/s/blog_655dac9e01017wv3.html 如果你看完书中的所有例子,你很可能已经...
  • IDOshi201109
  • IDOshi201109
  • 2016年03月29日 18:43
  • 1831

对iOS锁的一些研究

目录(?)[+] [objc] view plain copy   #import    #import    #import    #import        #de...
  • hyugahinat
  • hyugahinat
  • 2016年03月21日 11:33
  • 1106

iOS SDWebImage源码研究(一)

源码地址:https://github.com/rs/SDWebImage 版本:3.7 SDWebImage是一个开源的第三方库,它提供了UIImageView的一个分类,以支持从远程服务器下载并缓...
  • songchunmin_
  • songchunmin_
  • 2016年04月10日 11:20
  • 661
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS 离屏渲染研究
举报原因:
原因补充:

(最多只允许输入30个字)