离屏渲染(OffScreen Rendering)

whbsspuIP属地: 上海
字数 848阅读 4,794
一、基本概念

GPU屏幕渲染有两种方式

  • On-Screen Rendering 当前屏幕渲染,是指渲染操作是在当前用于显示屏幕缓冲区中进行的。
  • Off-Screen Rendering 离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。
  • 另一种特殊的离屏渲染:CPU渲染
    如果我们重写了drawRect方法,并且使用任何Core Graphics的技术进行了绘制操作,就涉及到了CPU渲染。整个渲染过程由CPU在App内同步地完成,渲染得到的bitmap最后再交由GPU用于显示。

相比于当前屏幕渲染,离屏渲染的代价比较高,主要体现在两个方面:

  • 创建新缓冲区
    想要离屏渲染,就必须创建一个新的缓冲区;
  • 上下文切换
    离屏渲染的整个过程,需要多次切换上下文环境:先是从当前屏幕(On-Screen)切换到离屏(Off-Screen);等到离屏渲染结束以后,将离屏缓冲区的渲染结果显示到屏幕上。而上下文环境的切换是要付出很大代价的。
二、离屏渲染的触发方式

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

  • shouldRasterize(光栅化)
  • masks(遮罩)
  • shadows(阴影)
  • edge antialiasing(抗锯齿)
  • group opacity(不透明)

#######举个例子
设置圆角:

view.layer.cornerRadius = 5

这行代码做了什么?文档中cornerRadius属性的说明:

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.

很明了,只对前景框和背景色起作用,再看 CALayer 的结构,如果contents有内容或者内容的背景不是透明的话,还需要把这部分弄个角出来,不然合成的结果还是没有圆角,所以才要修改masksToBounds为true(在 UIView 上对应的属性是clipsToBounds,在 IB 里对应的设置是「Clip Subiews」选项)。前些日子很热闹的圆角优化文章中的2篇指出是修改masksToBounds为true而非修改cornerRadius才是触发离屏渲染的原因,但如果以「Color Offscreen-Renderd Yellow」的特征为标准的话,这两个属性单独作用时都不是引发离屏渲染的原因,他俩合体(masksToBounds = true, cornerRadius>0)才是。

另外对于设置阴影效果(shadow),可以通过设置路径来减少离屏渲染带来的消耗:
let imageViewLayer = avatorView.layer
imageViewLayer.shadowColor = UIColor.blackColor().CGColor
imageViewLayer.shadowOpacity = 1.0 //此参数默认为0,即阴影不显示
imageViewLayer.shadowRadius = 2.0 //给阴影加上圆角,对性能无明显影响
imageViewLayer.shadowOffset = CGSize(width: 5, height: 5)
//设定路径:与视图的边界相同
let path = UIBezierPath(rect: cell.imageView.bounds)
imageViewLayer.shadowPath = path.CGPath//路径默认为 nil
三、如何选择
  • 任何时候优先考虑避免触发离屏渲染;
  • 离屏渲染 VS CPU渲染;
    由于GPU的浮点运算能力比CPU强,CPU渲染的效率可能不如离屏渲染;但如果仅仅是实现一个简单的效果,直接使用CPU渲染的效率又可能比离屏渲染好,毕竟离屏渲染要涉及到缓冲区创建和上下文切换等耗时操作。
    总之,具体的选择应该由性能测试结果来决定。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
0人点赞
更多精彩内容,就在简书APP
"小礼物走一走,来简书关注我"
还没有人赞赏,支持一下
whbsspu不断地、持续地挑战自己的知识深度!
总资产2共写了1.8W字获得18个赞共11个粉丝

推荐阅读更多精彩内容

  • 本篇文章是基于谷歌有关Graphic的一篇概览文章的翻译:http://source.android.com/de...
    lee_3do阅读 7,177评论 2 21
  • 相比于当前屏幕渲染,离屏渲染的代价是很高的,这也是iOS移动端优化的必要部分。 OpenGL中,GPU屏幕渲染有以...
    一个人在路上走下去阅读 8,909评论 0 74
  • README: 引言: 一款优秀的app,流畅很关键,用户使用60的fps的app,跟使用30的fps的app感受...
    uncleRX阅读 30,667评论 31 236
  • 18号早晨在keep上重新做了一次测试,81分虽不算很低,但相比年前的已经明显下降。 与前一次测试相比,核心力量明...
    向阳花z阅读 141评论 0 0
  • 高级文字未必出自于博学人之笔,博学人笔下未必只产高级文字,博学并不代表高级,而博学有什么含义,《中庸》中谈治学曰:...
    Abby王阅读 412评论 2 4