UI渲染流程+优化方案

一、CPU与GPU

为什么会分化出GPU这个专门用来处理图像的计算处理单元?

CPU需要很强的通用性来处理各种各样不同的数据类型,同时又要进行纷杂的数据运算的逻辑运算,以及各种的时序、中断处理,这些都让CPU的内部结构异常复杂。在CPU的内部有大量的空间被Cache占用,还有很大一部分被控制逻辑占用,剩下的逻辑计算单元还要处理很多其他的工作,比如内存管理等,所以需要将越来越复杂,但是类型高度统一、相互之间没有依赖的大规模数据和不需要处理中断的纯净图形计算独立出去交给GPU计算。

CPU和GPU在图形显示和渲染方面都做哪些工作?

CPU负责Measure、Layout、Record以及Execute等计算工作,把计算好的数据交给GPU。(负责把UI组件计算成Plygons、Texture纹理,然后交给GPU进行栅格化处理)

GPU负责对图形进行渲染,Rasterization(栅格化)操作后并进行驱动转化。

最后显示器负责把Buffer中的数据呈现到屏幕上。

什么是Rasterization(栅格化)?

Raterization是绘制Button、Shape、Path、BitMap等组件的最基础的操作。它把这些组件拆分到不同的像素上进行显示。这是一个非常耗时的操作。
img

二、Android系统的绘图机制

人眼看动态的东西至少要每秒达到10-12帧才会觉得是连续的,而要认为是流畅的必须至少达到每秒24帧以上。而与手机进行交互低于60帧每秒就会感觉到卡顿,所以一般的屏幕刷新率为60Hz,每秒刷新60次。1s=1000ms,1000ms/60=16.666ms/帧,所以Android定在了每16ms刷新一次。

如果对于UI的逻辑操作超过了16ms,那么用户将在16ms x 2的时间内看到同一幅画面,这就是卡顿。
在这里插入图片描述
对于Android中的UI组件,首先系统会调用LayoutInflater来将其加载到内存中,LayoutInflater的获取过程和其解析xml文件的过程如下图所示:
在这里插入图片描述
加载到内存中之后,交由CPU进行运算处理形成多维矢量图形,然后交给GPU让其进行栅格化以进行像素的填充。在这个填充渲染过程中会判断前面的渲染任务是否在16ms内能够完成,如果不能,就会垂直同步等待前面的渲染任务完成,而这时在屏幕上显示的是上一帧的内容不会更新,这样在感官上就形成了卡顿。

显示屏上的内容是从FrameBuffer中读取的,大致的过程为从Buffer起始地址开始,从上往下,从左往右扫描buffer,将里面的内容映射到显示屏上显示。而因为显示屏上的内容需要不断更新,所以除了提供一个Buffer给显示屏读取之外,还有一个Buffer用来在后台写入数据,当前一个Buffer读取完毕的时候,这个写好的Buffer就可以直接使用,这就是***双缓存机制***。

但是两个缓存的速度搭配只有在理想情况下才会同步完美,通常的情况是:

  • 读取的Buffer已经读取完毕,但是写入的Buffer还没有准备好,所以无法显示新的帧——卡顿
  • 读取的Buffer还没有读取完毕,但是写入的Buffer已经写入完成,直接开始显示——屏幕撕裂

所以不能够把屏幕的显示交给Buffer的读写速度——需要做好同步。因为屏幕的刷新率是一个固定的数值,所以我们可以使用屏幕的刷新频率来控制Buffer的读写:

垂直同步(VSync):当屏幕从缓冲区中扫描读取完一帧之后,开始扫描下一帧之前(对于60Hz刷新率的手机而言是16.66ms)发出一个同步信号,用来切换前后缓冲区。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值