iOS离屏渲染

2020-07-08  本文已影响0人  wu890608

1.iOS界面渲染过程

WWDC14 419

1.在Application这一层中主要是CPU在操作,而到了Render Server这一层,CoreAnimation会将具体操作转换成发送给GPU的draw calls(以前是call OpenGL ES,现在慢慢转到了Metal),显然CPU和GPU双方同处于一个流水线中,协作完成整个渲染工作。
2.Runloop有一个60fps的回调,即每16.7ms绘制一次屏幕,所以view的绘制必须在这个时间内完成,view内容的绘制是cpu的工作,然后把绘制的内容交给GPU渲染,包括多个view的拼接,纹理的渲染等,最后显示在屏幕上。

屏幕渲染有如下三种:
CPU计算好显示内容提交到GPU,GPU渲染完成后将渲染结果放到帧缓存区,随后视频控制器会按照VSync信号逐行读取帧缓存区的数据。
1、GPU中的当前屏幕渲染 (On-Screen Renderin
指的是GPU的渲染操作是在当前用于显示的帧缓冲区中进行
2、GPU中的离屏渲染 (Off-Screen Rendering
指的是GPU在当前帧缓冲区以外新开辟一个离屏缓冲区进行渲染操作
3、CPU中的渲染(特殊离屏渲染,即不在GPU中的渲染
如果我们重写了drawRect方法,并且使用任何Core Graphics的技术进行了绘制操作,系统也会为这个view申请一块内存区域,等待CoreGraphics可能的绘画操作,对于类似这种“新开一块CGContext来画图“的操作,有很多文章和视频也称之为“离屏渲染”。

注:通过CPU渲染就是俗称的“软件渲染”,而真正的离屏渲染发生在GPU,打开Xcode调试的“Color offscreen rendered yellow”开关,你会发现这片区域不会被标记为黄色,说明Xcode并不认为这属于离屏渲染。

2.什么情况会出现离屏渲染

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

官方
1.UIView继承UIResponder,可以处理系统传递过来的事件;遵守CALayerDelegate。每个UIView内部都有一个CALayer提供内容的绘制和显示
2.CALayer继承NSObject类,负责UIView提供内容的contents。CALayer有三个视图元素:背景色,内容,边框。其中内容的本质就是一个CGImage
3.设置layer.cornerRadius只会设置backgroundColor和border的圆角,不会设置content的圆角,除非同时设置了layer。masksToBounds为true(对应view中的clipsToBounds属性)

3.常⻅见触发离屏渲染的⼏几种情况:

光栅化使用建议
1.如果layer没有被复用,则没有必要开启光栅化
2.如果layer不是静态的,需要被频繁修改,比如处于动画之中,那么开启离屏缓存反而影响效率了
3.离屏换粗内容有时间限制,缓存内容100ms内如果没有被使用,那么他就会丢弃,无法复用了

  1. 离屏缓存空间有限,超过2.5倍屏幕像素大小的话,也会失效,且无法进行复用

3.离屏渲染对性能的影响

GPU的操作是高度流水线化的。本来所有计算工作都在有条不紊地正在向frame buffer输出,此时突然收到指令,需要输出到另一块内存,那么流水线中正在进行的一切都不得不被丢弃,切换到只能服务于我们当前的“切圆角”操作。等到完成以后再次清空,再回到向frame buffer输出的正常流程。

4.性能检测和离屏渲染分析

当然Debug还有其它的选项,来分析不同的性能问题,如有需求,请参考其它资料。

5.离屏渲染的优化方案

上一篇 下一篇

猜你喜欢

热点阅读