ios 图像显示原理及掉帧卡顿、离屏渲染的原因分析与优化
发布网友
发布时间:2022-09-05 02:20
我来回答
共1个回答
热心网友
时间:2024-07-11 12:14
1.CPU和GPU通过总线连接起来,工作流程如上图示:
在CPU中的工作完成会生成一个位图(bitmap),位图再经由总线在合适的时机上传给GPU处理,GPU拿到位图之后会进行相应位图的图层渲染(顶点变换、纹理混合等操作),之后会把结果放到帧缓冲区(Frame Buffer)中,由视屏控制器根据Vsync信号,在指定时间前提取对应帧缓冲区中的屏幕显示内容,最终显示到手机屏幕上。
2.UI视图显示到屏幕上的大概流程如上图示:创建一个UIView,它的显示部分是由CALayer负责的,CALayer有一个contents属性(即最终要绘制到屏幕上的位图),比如说创建的是一个显示“Hello world”的UILable,那么contents中放置的结果就是一个关于"Hello world"的文字位图。另外系统会在合适的时机回调一个drawRect:方法,在此基础上我们就可以绘制一些想要自定义的内容,绘制好的位图,会经由CoreAnimation框架,提交给GPU部分的OpenGL渲染管线进行位图的渲染,最终显示到屏幕上。
3.CPU工作:负责UI布局、文本计算,绘制,图片解码,绘制纹理交给GPU
4.GPU工作:纹理混合,顶点变换,渲染到帧缓冲区
1.通常来说页面滑动的流畅性是60fps(指每一秒会有60帧画面更新),人眼看到的是流畅的效果。也因此每隔 s(即16.7ms)就要产生一帧画面,也就是说在这16.7ms时间内GUP和CPU要协同完成产生一帧的数据,比如CPU花了一定的时间做UI布局、文本计算、视图的绘制和图片解码,并把产生的位图提交给GPU,GPU又要花一定的时间进行纹理混合渲染,然后在下一帧的VSync垂直信号到来之前显示这一帧画面。
在上图中,如果CPU和GPU协同工作的时间在16.7ms内,那么图像的显示是流畅的;如果CPU花费了大量时间来做frame的布局、视图绘制和图片解码,那么留给GPU的时间就不多了,GPU要想把图层合成、纹理渲染全部完成就要超过16.7ms,那么在下一帧的垂直信号VSync到来之前,还没有准备好当前的一帧画面,这就产生了掉帧,体现在滑动上的就是上下滑动卡顿的效果。
总而言之,在规定的16.7ms内,CPU和GPU并没有在下一帧的Vsync信号到来之前把当前的一帧画面生产完成,由此产生了掉帧卡顿。
2.滑动优化方案
CPU资源消耗分析
GPU资源消耗分析
基于上述的分析保持界面流畅,优化的时候就要从CPU和GPU两方面考虑。
优化参考 iOS如何优化项目
参考文章 Texture的异步渲染和布局引擎
1.有关概念:
CPU渲染及非GPU缓冲区的渲染统称为离屏渲染
2.离屏渲染消耗性能的原因
3.何时会触发?
4.检测离屏渲染
5.光栅化
光栅化简介:隐式创建一个位图,各种阴影遮罩等效果也会保存到位图中缓存起来,从而减少渲染的频度,把GPU的操作转到CPU上,生成位图缓存,直接读取调用。(注:对于经常变动的内容,不要开启光栅化,防止性能浪费,如Cell的复用)
任何时候优先考虑避免触发离屏渲染,无法避免时优化方案有两种:
•Rasterization:适用于静态内容的视图,也就是内部结构和内容不发生变化的视图,对上面的所有效果而言,在实现成本以及性能上最均衡的。即使是动态变化的视图,开启 Rasterization 后能够有效降低 GPU 的负荷,不过在动态视图里是否启用还是看 Instruments 的数据。
•规避离屏渲染,用其他手法来模拟效果,混合图层是个性能最好、耗能最少的通用优化方案,尤其对于 rounded corer 和 mask
关于离屏渲染触发及优化可以看下面的文章:
离屏渲染优化详解:实例示范+性能测试
图像撕裂原因:当视频控制器还未读取完成时,GPU将新的一帧内容提交到帧缓冲区并把两个帧缓冲区进行更新后,视频控制器就会把新的一帧数据的下半段显示到屏幕上,造成画面撕裂的现象。
•解决方案:垂直同步机制
•弊端:GPU会等待显示的V-Sync信号发出后,才进行新的一帧渲染和缓存区更新。能解决画面撕裂现象,也增加了画面流畅度,但需要消耗更多的计算资源,由此可能导致卡顿。
参考文章 ios图像显示原理
Texture相关参考资料
官方文档: http://texturegroup.org/docs/getting-started.html
官方文档部分译文一: https://juejin.im/post/5a16acf56fb9a04509092ce5
官方文档部分译文二(布局系统): https://juejin.im/post/5a1be41351882561a20a32e9#heading-17
即刻技术团队关于ASDK:
一、 https://zhuanlan.hu.com/p/25371361
二、 https://zhuanlan.hu.com/p/26283742
三、 https://zhuanlan.hu.com/p/29537687
iOS 保持界面流畅的技巧: https://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/
ASDK源码剖析: http://beelearning.cn/2017/11/ASDK/
从 Auto Layout 的布局算法谈性能 : https://draveness.me/layout-performance
ios 图像显示原理及掉帧卡顿、离屏渲染的原因分析与优化
图像撕裂原因:当视频控制器还未读取完成时,GPU将新的一帧内容提交到帧缓冲区并把两个帧缓冲区进行更新后,视频控制器就会把新的一帧数据的下半段显示到屏幕上,造成画面撕裂的现象。•解决方案:垂直同步机制 •弊端:GPU会等待显示的V-Sync信号发出后,才进行新的一帧渲染和缓存区更新。
UI卡顿和掉帧原因,及相关优化方案
原因知道了,就可以提出相应的优化方案了。可以从CPU和GPU做以下优化:CPU:1)对象创建、调整、销毁。2)预排版(布局计算、文本计算)。3)预渲染(文本等乙部绘制、图片解码等)。将以上3点操作放到子线程里做。GPU:1.纹理渲染 1)避免离屏渲染。2)依托于CPU的异步绘制机制来减轻GPU的压力。2....
UI渲染及显示原理
1、离屏渲染(Off-Screen Rendering):就是GPU在当前屏幕以外开辟一个另外的缓冲区进行渲染操作。2、当前屏幕渲染(On-Screen Rendering):指的是GPU是在当前显示的屏幕缓冲区进行的渲染操作。3、CPU的离屏渲染:即非GPU渲染,如果重写了drawReact,并且使用Core Graphics技术进行了绘制操作,就涉及到了这...
3、离屏渲染原理
1.按钮设置背景图片 开启clipsToBounds或者layer.masksToBounds 会触发离屏渲染 2.按钮不设置背景图片开启clipsToBounds或者layer.masksToBounds不会触发离屏渲染 4.UIImageView 只设置了图片,无背景色开启clipsToBounds或者layer.masksToBounds 不会触发离屏渲染 这里不得不提一下CALayer,它是由backgroundColor、conten...
2. 图像显示原理
GPU资源消耗分析 1、纹理混合:尽量减少短时间内大量图片的显示,尽可能将多张图片合成一张进行显示。2、视图混合:尽量减少视图层次和数量,并在不透明的视图里标明opaque属性以避免无用的Alpha通道合成。3、图形生成:尽量避免离屏渲染,尽量采用异步绘制,尽量避免使用圆角、阴影、遮罩等属性。必要时用静态...
Instrument调试界面卡顿
1. 界面卡顿的原因。主要从两个角度考虑,cpu限制—》对象的创建,释放,属性调整,CALayer的属性调整的时候是会创建隐士动画,是比较损耗性能的;视图和文本的布局计算,AutoLayout的布局计算都是在主线程上的,所以占用CPU时间也很多;文本渲染如UILable和UITextView都是在主线程渲染的;图片的解码,通常...
图像渲染原理
渲染缓冲对象的一大优点是,它以 OpenGL 原生渲染格式储存它的数据,因此在离屏渲染到帧缓冲的时候,这些数据就相当于被优化过的了。渲染缓冲对象(RBO) 将所有渲染数据直接储存到它们的缓冲里,而不会进行针对特定纹理格式的任何转换,这样它们就成了一种快速可写的存储介质了。然而,渲染缓冲对象通常是只...
图形渲染原理
但是双缓冲区仍然会产生掉帧的问题。具体掉帧的原因可以参考我写的另一篇文章 【UIView的绘制原理及优化】 。在使用了双缓冲区和垂直同步信号后,由于总要等待缓冲区交换之后再进行下一帧的渲染,使得帧率无法完全得到硬件的最高水平。所以引进了 三缓冲区 。即在等待垂直同步信号到来之前,来回交替两个...
如何编写稳定流畅的ios移动端应用
GPU 资源消耗原因和解决方案 相对于 CPU 来说,GPU 能干的事情比较单一:接收提交的纹理(Texture)和顶点描述(三角形),应用变换(transform)、混合并渲染,然后输出到屏幕上。通常你所能看到的内容,主要也就是纹理(图片)和形状(三角模拟的矢量图形)两类。纹理的渲染 所有的 Bitmap,包括图片、...
如何编写稳定流畅的iOS移动端应用
GPU 资源消耗原因和解决方案 相对于 CPU 来说,GPU 能干的事情比较单一:接收提交的纹理(Texture)和顶点描述(三角形),应用变换(transform)、混合并渲染,然后输出到屏幕上。通常你所能看到的内容,主要也就是纹理(图片)和形状(三角模拟的矢量图形)两类。纹理的渲染 所有的 Bitmap,包括图片、...