Android性能专项FPS测试实践(一)

2016-09-22   出处: Qtest之道  作/译者:刘俊


之前团队的小伙伴@德才写了篇文章《Android的过度渲染介绍及优化》写的很棒,恰好最近手上有个项目,需要进行流畅度的专项测试,目前已经进行了一段时间,因此想总结一些经验和教训跟大家分享。

测试需求

  • 通过技术手段量化程序卡顿程度,过程数据可视化

  • 多平台机型适配,方案不能依赖root

  • 不能有Android的API版本限制(因为需要兼容多个系统版本)

  • 监控流程可自动化执行

  • 过程需要连续可靠

测试准备

理解FPS的概念

FPS即Frames per second>>点击这篇文章(链接1) 解释的非常清楚。当我们准备测试流畅度的时候,必须先理解两个关键指标60帧每秒以及16.67毫秒,这两个值代表什么意思?怎么得来的? 
用过flash的人应该知道动画片其实是由一张张画出来的图片连贯执行产生的效果,当一张张独立的图片切换速度足够快的时候,会欺骗我们的眼睛,以为这是连续的动作。反之类推,当你的图片切换不够快的时候,就会被人眼看穿,反馈给用户的就是所谓的卡顿现象。 
想要让大脑觉得动作是连续的,至少是每秒10-12帧的速度,而想达到流畅的效果,至少需要每秒24帧。这也是为什么电影片源通常都是24帧的原因,好奇的同学点击>>知乎高知(链接2)看看大神的解答。不过60帧每秒的流畅度是最佳的,我们的目标就是让程序的流畅度能接近60帧每秒,当然超过60帧速的话大部分人还是会受不了的。

综上所述,APP需要尽可能的超过24帧/秒,接近60帧/秒的速度,并且在使用的过程中保持这个速率,试想一下你吃着火锅看着电影,突然图像发生了跳跃或者画面撕裂,那种感觉就像米饭里吃到了沙子一样极度不爽,因此这意味着我们的程序需要在16.67ms内处理一幅画面内的所有事,并保持住这个状态。


计算公式:1000ms / 60 frames ≈ 16.67 ms/frames

获取FPS的可行性方案

在查阅了很多的资料,也学习了同行前辈们的各种记录后,我根据自己需要将可行性方案的范围缩小到三种。

  • 方案一 
        通过 [设置]->[开发者选项]->[GPU呈现模式分析] ->[在屏幕上显示为条形图] 进行直观的取样,截图如下:


设置完成后的效果是这样的:

 

屏幕下方的柱形图会持续刷新,最上方会有一根绿色的线,代表的是16ms的阈值,超过这个界限表示当前帧绘制的时间出现了延迟,及卡顿现象,后面会详细介绍原因。横坐标表示时间的持续,每一根柱形图表示当前帧的绘制时间。因此我们在使用的过程中,下面的柱形图会一直的刷新,单位是ms。各位看官是否有注意到每一帧的柱形图颜色不一样呢(注:不同手机的颜色不一样,仅限安卓4.0以上版本参考)?下图是官网提供的比较典型的GPU渲染卡顿的例子:


绘制过程中的不同颜色具有不同的含义,详细解释请移步>>官网(链接3) 查看更多。

那么是不是说我只需要打开界面去数一下超过绿色阈值的柱状图有多少就可以观察我们应用的流畅度了?然而并没有,因为这个方式获取到的渲染时间只是UI主线程上的绘制行为,目前我所接手的项目,采用的方式是捕捉相机的数据然后放到GPU中去进行绘制,有单独的绘制线程,单独的视图,所以这个方案并不适合我手上的项目。

  • 方案二

 

使用这个命令可以得到如下的返回值,节选关键部分:

 

大家可以看到,使用起来非常方便,但是遗憾的是必须是Android M 版本以上才支持,而且需要拖动屏幕产生的数据才比较准确,对于我这种需要适配多种机型和版本的情况就不太符合了,关于这个命令的详细解释,各位可以看一下谷歌官方的>>Document(链接4)。

  • 方案三

 

执行这条命令以后,你会得到这样的信息:

 

第一行是设备的刷新周期refresh-period,单位是纳秒,换算成毫秒就是16666667\1000\1000≈16.67ms;这条命令的含义是获取当前layer(窗口、图层)的最近128帧的信息(仅保存128帧),所以上面我省略的部分实际上总共有128行(刨去第一行刷新率,需要按127帧来换算),这三列数据的解释是(ps:翻译不正确的请指正):

  • 第一列: when the app started     to draw (开始绘制图像的瞬时时间)

  • 第二列: the vsync immediately     preceding SF submitting the frame to the h/w (VSYNC信令将软件SF帧传递给硬件HW之前的垂直同步时间)

  • 第三列:timestamp immediately after SF submitted that frame tothe h/w (SF将帧传递给HW的瞬时时间,及完成绘制的瞬时时间)


【垂直同步】 
Vertical Synchronization,屏幕从图形芯片获取每帧的数据,然后逐行进行绘制。理想状况下,你期望显示屏在绘制完一帧之后,图形芯片整好能提供新帧的数据。图像撕裂的状况就发生在图形芯片在图像绘制到一半的时候,就载入了新一帧的数据,以致你最终得到的数据帧是半个帧的新数据和半个帧的老数据。而垂直同步,顾名思义就是用来同步的。它告知GPU在载入新帧之前,要等待屏幕绘制完成前一帧。

没有垂直同步的示意图

 

有垂直同步的示意图

【掉帧jank 
统计硬件掉帧数的计算方式是:在一个刷新周期内(16.67ms)会记录127行绘制时间,其中包括起始绘制(上面第一列的时间数据)和完成绘制两个纳秒时间(上面第三列的时间数据),每两行的绘制时间间隔应该相等,否则就发生了帧延迟,即掉帧(jank),每个周期内发生掉帧就计数1次,在整个绘制周期内的掉帧数即是渲染掉帧的数量。


文章中链接地址如下:

链接1: http://blog.csdn.net/xiaosongluo/article/details/51212296

链接2: http://www.zhihu.com/question/31513136

链接3: https://developer.android.com/studio/profile/dev-options-rendering.html?hl=zh-cn

链接4: https://developer.android.com/training/testing/performance.html?hl=zh-cn#aggregate


文章未完待续……



声明:本文为本站编辑转载,文章版权归原作者所有。文章内容为作者个人观点,本站只提供转载参考(依行业惯例严格标明出处和作译者),目的在于传递更多专业信息,普惠测试相关从业者,开源分享,推动行业交流和进步。 如涉及作品内容、版权和其它问题,请原作者及时与本站联系(QQ:1017718740),我们将第一时间进行处理。本站拥有对此声明的最终解释权!欢迎大家通过新浪微博(@测试窝)或微信公众号(测试窝)关注我们,与我们的编辑和其他窝友交流。
541° /5419 人阅读/0 条评论 发表评论

登录 后发表评论