您的位置:首页 > 其它

界面卡顿Jank与FPS获取

2015-11-24 22:08 260 查看
1 VSYNC 的概念

VSYNC(Vertical Synchronization)是一个相当古老的概念,对于游戏玩家,它有一个更加大名鼎鼎的中文名字—-垂直同步。

“垂直同步(vsync)”指的是显卡的输出帧数和屏幕的垂直刷新率相同,这完全是一个CRT显示器上的概念。其实无论是VSYNC还是垂直同步这个名字,因为LCD根本就没有垂直扫描的这种东西,因此这个名字本身已经没有意义。但是基于历史的原因,这个名称在图形图像领域被沿袭下来。

在当下,垂直同步的含义我们可以理解为,使得显卡生成帧的速度和屏幕刷新的速度的保持一致。举例来说,如果屏幕的刷新率为60Hz,那么生成帧的速度就应该被固定在1/60 s。

1.1 Android中的VSYNC

从Android 4.1开始,谷歌致力于解决Android系统中最饱受诟病的一个问题,滑动不如iOS流畅。因谷歌在4.1版本引入了一个重大的改进—Project Butter,也即是黄油计划。

Project Butter对Android Display系统进行了重构,引入了三个核心元素,即VSYNC、Triple Buffer和Choreographer。这里我们重点讲解VSYNC的作用。



这个图中有三个元素,Display是显示屏幕,GPU和CPU负责渲染帧数据,每个帧以方框表示,并以数字进行编号,如0、1、2等等。VSync用于指导双缓冲区的交换。

以时间的顺序来看下将会发生的异常:

Step1. Display显示第0帧数据,此时CPU和GPU渲染第1帧画面,而且赶在Display显示下一帧前完成。

Step2. 因为渲染及时,Display在第0帧显示完成后,也就是第1个VSync后,正常显示第1帧。

Step3. 由于某些原因,比如CPU资源被占用,系统没有及时地开始处理第2帧,直到第2个VSync快来前才开始处理。

Step4. 第2个VSync来时,由于第2帧数据还没有准备就绪,显示的还是第1帧。这种情况被Android开发组命名为“Jank”。

Step5. 当第2帧数据准备完成后,它并不会马上被显示,而是要等待下一个VSync。

所以总的来说,就是屏幕平白无故地多显示了一次第1帧。原因大家应该都看到了,就是CPU没有及时地开始着手处理第2帧的渲染工作,以致“延误军机”。

其实总结上面的这个情况之所以发生,首先的原因就在于第二帧没有及时的绘制。我们将在三重缓冲一节中再讲解这种情况)。那么如何使得第二帧即使被绘制呢?

这就是我们在Graphic系统中引入VSYNC的原因,考虑下面这张图:



如上图所示,一旦VSync出现后,立刻就开始执行下一帧的绘制工作。这样就可以大大降低Jank出现的概率。另外,VSYNC引入后,要求绘制也只能在收到VSYNC消息之后才能进行,因此,也就杜绝了另外一种极端情况的出现—-CPU(GPU)一直不停的进行绘制,帧的生成速度高于屏幕的刷新速度,导致生成的帧不能被显示,只能丢弃,这样就出现了丢帧的情况—-引入VSYNC后,绘制的速度就和屏幕刷新的速度保持一致了。

经过上面的介绍,希望读者对Jank 和VSYNC有所认识。下面将说明怎么来得到FPS和卡顿Jank帧数。

2 Jank 和 FPS

我们只关注present time。



2.1 计算Janky frames



这里的frame duration是有present time两两相减得到的。



由上图可以得到jank 帧,右下角。

2.2 FPS



帧率(FPS)由present time的最后一帧减去第一帧得到时间值,然后除以帧数得到。

3 自动化获取

自动化思路:使用python 结合uiautomator,根据配置信息,启动想评测的app,操作app(滑动,放大等等),打印surfaceflinger数据出来,稍微处理一下即可得到fps和掉帧数。

步骤:

(1)清理历史数据

○ adb shell dumpsys SurfaceFlinger --latency-clear <window name>

(2)使用uiautomator操作某个APP

○ fling, scroll, zoom

(3)根据2操作,打印数据

○ adb shell dumpsys SurfaceFlinger --latency <window name>

(4)处理数据

如读者会使用Python的话,直接按照上面几步即可得到FPS和Jank 数,因为逻辑已经很清晰了。本人写的代码较多,这里不附上说明。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: