Android小知识-了解下Android系统的显示原理

本平台的文章更新会有延迟,大家可以关注微信公众号-顾林海,包括年底前会更新kotlin由浅入深系列教程,目前计划在微信公众号进行首发,如果大家想获取最新教程,请关注微信公众

在Android系统中应用层负责绘制,系统层负责渲染,通过进程间通信把应用层需要绘制的数据传递到系统层,系统层服务通过刷新机制把数据更新到屏幕上,图形显示系统采用的是C/S架构。

Android中View绘制需要三个步骤,通过Measure和Layout来确定当前需要绘制的View所在的大小和位置,接着通过Draw绘制到suface。

Measure用深度优先原则递归得到所有视图的宽和高,获取当前View的正确宽度childWidthMeasureSpec和高度childHeightMeasureSpec之后,可以调用它的成员函数Measure来设置大小。如果当前正在测量的子视图是一个视图容器,那么它又会重复执行操作,直到它的所有子孙视图的大小测量完成为止。Layout也是采用深度优先原则递归得到所有视图的位置,当子View在应用程序窗口左上角的位置确定后,再结合它在前面测量过程中确定的宽度和高度,就可以完全确定它在应用程序窗口中的布局。Draw采用两种绘制方式,分别是软件绘制(CPU)和硬件加速(GPU),硬件加速是在Android 3.0开始采用的。

硬件加速的优点是UI的显示和绘制的效率高于CPU绘制,但它也存在明显的缺点,GPU的功耗比CPU高,造成耗电问题;某些接口和函数不支持硬件加速,造成兼容问题;使用OpenGL的接口至少需要8MB内存,造成内存过大问题。

将数据渲染到屏幕上,是通过系统级进程中的SufaceFlinger服务来实现的,应用层绘制到缓存区,SufaceFlinger把缓存区数据渲染到屏幕,由于是两个不同的进程,所以Android的匿名共享内存SharedClient缓存需要显示的数据来达到目的。

FPS代表每秒传递的帧数,Android系统每隔16ms发出VSYNC(垂直中断)信号,触发对UI进行渲染,如果每次渲染都成功,这样就能达到流畅的画面所需的60FPS。如果未能在16ms内发出信号,触发对UI进行渲染,就会造成丢帧现象,用户会感到卡顿不流畅。

Android 4.1版本推出了Project Butter。Project Butter对Android Display进行了重构,引入三个核心元素:VSYNC、Triple Buffer和Choreographer。

VSYNC是一种定时中断,一旦受到VSYNC中断,CPU就开始处理各帧数据。Choreographer起一个调度的作用,将绘制工作统一到VSYNC某个时间点上,使应用的绘制工作有序。Triple Buffer是第三块绘制的Buffer,减少显示内容的延迟,之前采用的是双缓冲,所谓的双缓冲就是使用两个缓冲区,其中一个称为Front Buffer,另外一个成为Back Buffer,UI在Back Buffer中绘制,然后再和Front Buffer交换,渲染到显示设备中,当两个Buffer不够用时,就会采用三级缓冲来增强。

下图是Android 4.1之前未加入VSYNC的绘制流程图:

Display显示第0帧数据,此时CPU和GPU渲染第1帧画面,而且赶在Display显示下一帧前完成,因为渲染及时,Display在第0帧显示完成后,也就是第1个VSync后,正常显示第1帧。 由于某些原因,比如CPU资源被占用,系统没有及时地开始处理第2帧,直到第2个VSync快来前才开始处理 ,第2个VSync来时,由于第2帧数据还没有准备就绪,显示的还是第1帧。就出现了所谓的“Jank”。 当第2帧数据准备完成后,它并不会马上被显示,而是要等待下一个VSync。

下图是Android 4.1加入VSYNC的绘制流程图:

CPU/GPU根据VSYNC信号同步处理数据,可以让CPU/GPU有完整的16ms时间来处理数据,减少了jank。

双缓冲下当CPU和GPU处理时间过长时流程图如下:

当CPU/GPU的处理时间超过16ms时,在第二个16ms时间段内,Display应该显示B帧,但因为GPU还在处理B帧,导致A帧重复显示。并且在第二个16ms内,CPU什么事情都做不了,这是因为A Buffer由Display在使用,B Buffer由GPU在使用。

三级缓冲绘制图如下:

当第一次VSync发生后,CPU不用再等待了,它会使用第三个buffer C来进行下一帧数据的准备工作。虽然对缓冲区C的处理所需时间同样超过了16ms,但这并不影响显示屏,第2次VSync到来后,它选择buffer B进行显示;而第3次VSync时,它会接着采用C,而不是像double buffering中所看到的情况一样只能再显示一遍B了。这样子就有效地降低了jank。


搜索微信“顾林海”公众号,定期推送优质文章。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值