界面渲染过程屏幕显示图像原理
首先从过去的 CRT 显示器原理说起。CRT 的电子枪按照上面方式,从上到下一行行扫描,扫描完成后显示器就呈现一帧画面,随后电子枪回到初始位置继续下一次扫描。为了把显示器的显示过程和系统的视频控制器进行同步,显示器(或者其他硬件)会用硬件时钟产生一系列的定时信号。当电子枪换到新的一行,准备进行扫描时,显示器会发出一个水平同步信号(horizonal synchronization),简称 HSync;而当一帧画面绘制完成后,电子枪回复到原位,准备画下一帧前,显示器会发出一个垂直同步信号(vertical synchronization),简称 VSync。显示器通常以固定频率进行刷新,这个刷新率就是 VSync 信号产生的频率。尽管现在的设备大都是液晶显示屏了,但原理仍然没有变。
通常来说,计算机系统中 CPU、GPU、显示器是以上面这种方式协同工作的。CPU 计算好显示内容提交到 GPU,GPU 渲染完成后将渲染结果放入帧缓冲区,随后视频控制器会按照 VSync 信号逐行读取帧缓冲区的数据,经过可能的数模转换传递给显示器显示。
界面渲染过程
RunLoop
有一个60fps
的回调,即每16.7ms
绘制一次屏幕,所以view
的绘制必须在这个时间内完成。
view
内容的绘制是CPU
的工作,如果无法是16.7ms
内完成绘制,就会出现丢帧的问题,一般情况下,如果帧率保证在30fps
以上,界面卡顿效果不明显,那么就需要在33.4ms
内完成View
的绘制,而低于这个帧率,就会产生卡顿的效果,影响体验。
绘制过程:
UIView
的layer
层有一个content
,指向一块缓存,即backing store
UIView
绘制时,会调用drawRect
方法,通过context
将数据写入backing store
- 在
backing store
写完后,通过render server
交给GPU
去渲染,将backing store
中的bitmap
数据显示在屏幕上
屏幕渲染机制
1、On-Screen Rendering
意为当前屏幕渲染,指的是GPU
的渲染操作是在当前用于显示的屏幕缓冲区中进行
2、Off-Screen Rendering
意为离屏渲染,指的是GPU
在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作
3、CPU
中的离屏渲染(特殊离屏渲染,即不在GPU
中的渲染)
如果我们重写了drawRect
方法,并且使用任何Core Graphics
的技术进行了绘制操作,就涉及到了CPU
渲染
离屏渲染
设置了以下属性时,就会触发离屏绘制:
- shouldRasterize(光栅化)
- masks(遮罩)
- shadows(阴影)
- edge antialiasing(抗锯齿)
- group opacity(不透明)
- 复杂形状设置圆角等
- 渐变
Instruments使用
iOS
的性能调试有许多方法,而官方提供的Instruments
是一个强大的性能调试工具,可以分析如下功能:内存、核心动画、自动化、布局、网络等等,本文主要介绍一下利用Core Animation
来分析应用的性能问题。
下面介绍一下Core Animation
中的Debug
属性的部分功能,这些功能在分析离屏渲染等性能问题时十分有用:
Color Blended Layers
这个选项基于渲染程度对屏幕中的混合区域进行绿到红的高亮(也就是多个半透明图层的叠加)。由于重绘的原因,混合对GPU
性能会有影响,同时也是滑动或者动画帧率下降的罪魁祸首之一
Color Hits Green and Misses Red
当设置shouldRasterizep
属性为YES
的时候,耗时的图层绘制会被缓存,然后当做一个简单的扁平图片呈现。当缓存再生的时候这个选项就用红色对栅格化图层进行了高亮。如果缓存频繁再生的话,就意味着栅格化可能会有负面的性能影响了
Color Offscreen-Rendered Yellow
开启后会把那些需要离屏渲染的图层高亮成黄色,这就意味着黄色图层可能存在性能问题
当然Debug
还有其它的选项,来分析不同的性能问题,如有需求,请参考其它资料。