美文网首页
UI图像显示、掉帧原理

UI图像显示、掉帧原理

作者: 暴躁的小豆子 | 来源:发表于2019-12-16 18:17 被阅读0次

CUP 跟 GPU是通过总线连接起来的,CPU输出的结果往往是一个位图,经过总线在合适的时机交给GPU,GPU拿到位图会做图层的渲染,包括纹理的合成,然后把结果放到帧缓冲区,由视频控制器根据Vsync信号在指定时间之前去提取对应帧缓冲区中的屏幕显示内容,最终显示到屏幕上

CPU&GPU分工


当我们创建一个view的时候,显示部分是由CALayer负责的,CALayer中contents属性就是我们最终要绘制到屏幕上的一个位图,比如说我们创建一个hello world的label,那么contents里面放置的就是一个文字位图,然后系统在合适的时机回调给我们一个drawRect方法,我们可以在此基础之上绘制自己想绘制的内容,绘制好的位图会经由CoreAnimation框架提交给OPenGL渲染管线,进行位图的渲染包括纹理的合成,最终显示到屏幕上

CPU的渲染管线其实就是OpenGL的渲染管线,图上五个步骤绝大多数场景是接触不到的,有OpenGL开发经验的同学对这个可能稍有了解,这五个步骤做完之后会把像素点提交到帧缓冲区当中,视频控制器在Vsync信号到来之前从帧缓冲区提取内容,显示到屏幕

UI卡顿&掉帧原理

我们一般说页面滑动的流畅是60fps,也就是说每一秒钟有60帧的画面更新,看到的效果是流畅效果,基于此相当于每隔16.7ms(1/60)就要产生一帧画面。这16.7ms内需要CPU和GPU协同完成这一帧的数据,比如CPU花费一定的时间进行文本计算,UI布局,视图的绘制,以及图片的解码,然后把产生的bitmap提交给GPU,再由GPU进行图层的合成,纹理的渲染,等待Vsync垂直信号的到来,如果下一个Vsync到来前,CPU+GPU的时长大于16.7ms(下一帧的画面没有准备好,掉帧),就会看到页面滑动时卡顿的效果

基于掉帧造成的页面卡顿可以做的列表优化

CPU
对象的创建、调整、销毁可以放到子线程去
预排版(布局计算,文本计算)放到子线程去做
预渲染(文本等异步绘制、图片的编解码等)

GPU
纹理的渲染(尽量避免离屏渲染)
视图混合(一定程度上减轻视图复杂度)

UI绘制原理&异步绘制

由上图可知,当我们调用view的setNeedsDisplay的时候,调用了它随对应layer的同名方法,相当于在当前layer上打了一个脏标记,会到当前runloop将要结束的时候调用[CALayer display]这个函数,然后进入当前视图的绘制流程当中

系统绘制流程

异步绘制

[layer.delegate dispayLayer]

只要我们实现dispayLayer方法,就进入了异步绘制

代理负责生成对应的bitmap

设置该bitmap为layer.contents属性值

流程图

离屏渲染

on_screen rendering
意为当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行

off_screen rendering
意为离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作

何时触发

当我们指定了ui视图的某些属性标记为它在未预合成之前不能用于当前屏幕上直接显示的时候,就会产生离屏渲染

圆角(和maksToBounds一起使用时)
图层蒙版
阴影
光栅化

为何避免

离屏渲染使GPU层面触发了OpenGL多通道渲染管线(就需要上下文切换),产生额外开销(增加了新的渲染缓冲区),进而增添了GPU的工作量,很有可能GPU+CPU的操作时长超出1/60s,导致掉帧,页面滑动卡顿

相关文章

网友评论

      本文标题:UI图像显示、掉帧原理

      本文链接:https://www.haomeiwen.com/subject/crgrnctx.html