Android 显示系统:Vsync机制

Posted blogs-of-lxl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 显示系统:Vsync机制相关的知识,希望对你有一定的参考价值。

一、Vsync简介:

  屏幕的刷新过程是每一行从左到右(行刷新,水平刷新,Horizontal Scanning),从上到下(屏幕刷新,垂直刷新,Vertical Scanning)。当整个屏幕刷新完毕,即一个垂直刷新周期完成,会有短暂的空白期,此时发出 VSync 信号。所以,VSync 中的 V 指的是垂直刷新中的垂直-Vertical。

  android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,VSync是Vertical Synchronization(垂直同步)的缩写,是一种在PC上很早就广泛使用的技术,可以简单的把它认为是一种定时中断。而在Android 4.1(JB)中已经开始引入VSync机制,用来同步渲染,让AppUI和SurfaceFlinger可以按硬件产生的VSync节奏进行工作。

 

二、黄油计划:三个方法改进显示系统

 1.Vsync同步:

 

  技术图片

 

  可见vsync信号没有提醒CPU/GPU工作的情况下,第二次vsync到来需要显示内容时,CPU和GPU还没有来得及准备好下一帧的数据,所以只能接着显示上一帧的数据,产生Jank!

 

 

 

技术图片

 

  CPU/GPU接收vsync信号提前准备下一帧要显示的内容,所以能够及时准备好每一帧的数据,保证画面的流程。

 

 2.多级缓冲:

  除了Vsync的机制,Android还使用了多级缓冲的手段以优化UI流程度,例如双缓冲(A+B),在显示buffer A的数据时,CPU/GPU就开始在buffer B中准备下一帧数据:

  

  技术图片

 

 

   但是不能保证每一帧CPU、GPU都运行状态良好,可能由于资源抢占等性能问题导致某一帧GPU掉链子,vsync信号到来时buffer B的数据还没准备好,而此时Display又在显示buffer A的数据,导致后面CPU/GPU没有新的buffer着手准备数据,空白时间无事可做,后面Jank频出:

  技术图片

 

   因此用三级缓冲来提高系统对性能波动的容忍度:

  技术图片

 

   虽然GPU在准备buffer B的数据耗时过长,第二帧Jank,但是新增1个buffer可以减少CPU和GPU在vsync同步间的空白间隙,此时CPU/GPU能够利用buffer C继续工作,所以后面就不会再产生Jank了,当然具体使用多少个buffer要根据实际硬件性能情况调整,最终目的就是解决Display的Jank产生。

 

 3.Vsync虚拟化(Vsync App + Vsync SurfaceFlinger):

  虽然vsync使得CPU/GPU/Display同步了,但App UI和SurfaceFlinger的工作显然是一个流水线的模型。即对于一帧内容,先等App UI画完了,SurfaceFlinger再出场对其进行合并渲染后放入framebuffer,最后整到屏幕上。而现有的VSync模型是让大家一起开始干活,这样对于同一帧内容,第一个VSync信号时App UI的数据开始准备,第二个VSync信号时SurfaceFlinger工作,第三个VSync信号时用户看到Display内容,这样就两个VSync period(每个16ms)过去了,影响用户体验。
  解决思路:SurfaceFlinger在App UI准备好数据后及时开工做合成。

  Android 4.4(KitKat)引入了VSync的虚拟化,即把硬件的VSync信号先同步到一个本地VSync模型中,再从中一分为二,引出两条VSync时间与之有固定偏移的线程。示意图如下:

  技术图片

 

  这样,大家工作既保持一定的节拍,又可以相互错开,一前一后保持着流水节奏。

  注意其中两个Phase offset参数(即VSYNC_EVENT_PHASE_OFFSET_NSSF_VSYNC_EVENT_PHASE_OFFSET_NS)是可调的。

  处理流程:

  技术图片

 

   类型DispSync表示了一个基于硬件VSync信号的同步模型,它会根据从HWComposer来的硬件VSync信号的采样来进行同步。其它两个EventThread分别用了两个不同的虚拟VSync信号源(用DispSyncSource表示,其中包含了与真实VSync信号的偏移值),这两个VSync信号源就是被虚拟出来分别用于控制App UI和SurfaceFlinger渲染。在EventThread的线程循环中,如果有需要就会向DispSync注册相应的listener。DispSyncThread就像乐队鼓手一样控制着大家的节奏。它在主循环中会先通过已经向DispSync注册的listener计算下一个要产生的虚拟VSync信号还要多久,等待相应时间后就会调用相应listener的callback函数。这样,对于那些注册了listener的监听者来说,就好像被真实的VSync信号控制着一样。至于EventControlThread是用来向真实的VSync硬件发命令。

 

 

 

三、Vsync框架

 

以上是关于Android 显示系统:Vsync机制的主要内容,如果未能解决你的问题,请参考以下文章

Android 进阶——图形显示系统之底层图像显示原理小结

Android 进阶——图形显示系统之底层图像显示原理小结

Android 进阶——图形显示系统之底层图像显示原理小结

Android 渲染机制 —— (显示原理全过程解析)

史上最全Android渲染机制讲解(长文源码深度剖析)

针对Android的性能优化集中哪些方面