基于 systrace GFX 统计每帧绘制的帧率和掉帧统计
目标需求:实时统计 android 帧率,无论正在操作任何 app
设计原理:
数据来源 systrace GFX 的信息
- 1、获取方式:
adb shell cat /sys/kernel/debug/tracing/trace_pipe
- 2、开始抓取:
atrace gfx -b 1024 -c --async_start
- 3、停止获取:
atrace gfx --async_stop 1>/dev/null
- 4、解析规则:
(1)只处理类别为 C 和 postFramebuffer(postFramebuffer 函数就是告诉 HWC 开始做最后的合成了,postComposition:合成后处理,将图像传递到物理屏幕。由于 postComposition 并不是都有用 postFramebuffer)
(2)postComposition 前完成的 surface 信息作为窗口名
(3)TX - *
格式的信息为 app 启动、退出。部分 Surface 更新,按是否存在记录 0/1
(4)postComposition 之后最近一个 Vsync 记录绘制时间
(5)帧率统计中,大于 500ms 的帧间隔不参与,记为静置等待,存储等待总时长和次数
(6)用户体验掉帧区间评估:
A:[100ms,500ms),人眼判断卡顿的认知是:人眼有 100ms 的缓存,大于 100ms 才感知为卡顿,
B:[50ms,100ms),20 帧是游戏最低可玩的底线,再低就完全无法忍了;常见 UI 的 gif 动画也是 20 帧刷新。
C:[42ms,50ms),视频体验是 24 帧录制播放
(7)vsync 间隔超过系统的间隔值记录 D
脚本设计思路:
- 设备端离线后台 shell 脚本监控
- 用 busybox 的 awk 做数据提取存为 csv
- 结果获取到 PC 端用 python 脚本生成 html 报告
依赖文件:
- 设备端需存在/data/local/tmp/busybox
(busybox可到官网对应cpu架构下载)
,命令:
adb push busybox /data/local/tmp
adb shell chmod 755 /data/local/tmp/busybox
脚本文件:
- 监控脚本 gfx.sh
注:1、有不支持 awk 中调用外部命令执行情况,增加:gfx_no_system.sh
adb shell
sh /data/local/tmp/gfx.sh
- GFX() 参数说明:
$1 = 目标帧率,默认 60
$2 = 评估体验卡顿的把控线,默认 100ms
$3 = 输出类型:
0) ~ 默认只输出帧率
1)~ 增加 APP 内容两帧间隔 >42ms 的单帧信息
2)~ 增加绘制间隔 >vsync 间隔的单帧信息
3)~ 只输出 APP 内容两帧间隔 >42ms 的单帧信息
4)~ 只输出绘制间隔 >vsync 间隔的单帧信息
$4 = 检查输出结果的间隔,默认间隔 1 秒
$5 = 检查输出时,满足?帧以上输出条件的才输出
预期监控时长结束后,停止监控:
kill cat /sys/kernel/debug/tracing/trace_pipe 的进程
获取结果
adb pull /data/local/tmp/fps
- 监控脚本 systrace.py
生成报告:(需安装python环境和pandas库)
python systrace.py fps.csv
说明:
- GFX_HTML 是报告的模板文件,数据采用的是生成 js 动态加载的形式,脚本会将其复制到传参目录下
- 处理 csv 数据存为
data/?.js
(?对应包名的数组 index),list.js 为选择框信息的数组
- 查看报告数据需要浏览器有本地读写权限:
chrome: start chrome.exe --allow-file-access-from-files
firefox: about:config 中 privacy.file_unique_origin属性false
- 报告数据刷新会在选择后更新