本篇文章绘制相关的三个 trace 工具:
- Skia Debugger:查看应用 N 帧绘制的 Skia 指令,但看不了具体耗时,一般用于排查 绘制效果相关问题
- Perfetto:总览 N 秒内系统内的进程的绘制堆栈,但无法得知具体的绘制指令
- AGI(Android GPU Inspector):具备系统 trace 和更具体的渲染指令查看,支持 vulkan 和 opengl,但使用体验不太好,成功率很低。
如需运行 skia debugger 需要编译
libhwui.so
参考 AOSP 编译与调试运行指南 下载环境下一期介绍 【以阴影为例分析 skia 指令】 和 【
libhwui.so
的两种 debug 方法】
Skia Debugger
作用:查看应用 N 帧绘制的 Skia 指令,但看不了具体耗时
效果:
- 逐帧查看 app 的绘制情况:
- 查看某一帧对应的绘制过程和指令,可用于优化不必要的绘制操作:
绘制指令的解析敬请期待下一期【以阴影为例分析 skia 指令】
用法:
编译一个开启 skia debug 的 libhwui.so
在源码的 frameworks/base/libs/hwui/Properties.cpp
文件中,将 Properties::debuggingEnabled
属性改为 true
编译 libhwui.so
,在源码根目录下:
bash
source build/envsetup.sh
lunch sdk_phone_x86_64
make libhwui -j16
产物在 out/target/product/emulator64_x86_64/system/lib64/libhwui.so
下生成
将开启 debug 的 libhwui.so 推到 /system/lib64 下
bash
adb push out/target/product/emulator64_x86_64/system/lib64/libhwui.so /system/lib64/
// 然后重启
adb reboot
需要注意,这里 push 的路径是 /system/lib64,需要匹配对应的系统架构。如果 push 到 /system/lib 会导致机器不能启动, 因为编译的产物是 64 位,而 /system/lib 存放的 32 位。解决办法也很简单,将 out/target/product/emulator64_x86_64/system/lib
下的 libhwui.so push 到 /system/lib 下即可启机。
同时这一步需要 Root 和挂载 /system
目录,否则文件会 push 失败
vbnet
adb: error: failed to copy 'out/target/product/emulator64_x86_64/system/lib64/libhwui.so' to '/system/lib64/libhwui.so': remote couldn't create file: Read-only file system
我一般按照下面过程执行:
arduino
adb disable-verity && adb root && adb shell mount -o rw,remount /system
// 之后重启
adb reboot
// 机器启动之后再一次
adb disable-verity && adb root && adb shell mount -o rw,remount /system
然后按照上面的步骤重新 push libhwui.so
启动脚本,指定要抓取的程序包名和帧数
注意,执行脚本之前务必确认已 root ,否则可能出现脚本一直卡住,可执行两次命令:
adb disable-verity && adb root && adb shell mount -o rw,remount /system
脚本如下:
android.googlesource.com/platform/fr...
例如:我要抓取飞书 com.ss.android.lark
的 5 帧,指令如下
bash
./skp-capture.sh com.ss.android.lark 5
第一次执行可能会提示需要重启进程,杀掉进程重启即可:
vbnet
./skp-capture.sh com.ss.android.lark 5
./skp-capture.sh: 33: 10: not found
debug.hwui.capture_skp_enabled was found to be disabled, enabling it now.
restart the process you want to capture on the device, then retry this script.
脚本成功如图,等待 app 触发帧刷新
这个时候随便交互一下,触发 app 的画面更新,等到 5 帧更新之后。
如果 app 帧刷新了但是这里还是没有变化,检查一下是否 root
在脚本的执行文件夹下就会生成对应的 trace 文件,后缀是 skp
或者 mskp
,之后通过 debugger.skia.org/ 查看即可:
例如,下面这一帧就经过了 425 个绘制指令完成
点击可查看某个绘制指令具体的参数和绘制效果
如图,我们在开发过程中使用的 ImageView,最终是通过下面的 DrawImageRect
指令完成绘制
建议打开右边的两个选项,方便查看当前绘制指令的作用范围和 clip 区域
具体的绘制指令可参数可以参考 Doc :
Perfetto
作用:总览 N 秒内系统内的进程的绘制情况,但无法查看具体的绘制指令
效果:
- 查看 App 多个线程的堆栈,常用于性能分析:
用法:
可以直接通过 GUI 的方式帧,打开 ui.perfetto.dev/,进入 new trace,配置需要 trace 的信息,点击 start recording 即可。
不过这种方式我经常提示 adb 连接错误,所以一般复制下面的命令直接执行:
抓取成功会提示文件位置:
csharp
[731.953] perfetto_cmd.cc:999 Connected to the Perfetto traced service, TTL: 5s
[737.127] perfetto_cmd.cc:1127 Wrote 36690892 bytes into / data /misc/perfetto -traces /trace
把文件 pull 出来之后通过上面的网站打开即可
bash
(base) ➜ trace adb pull /data/misc/perfetto-traces/trace ./
AGI(Android GPU Inspector)
作用:具备系统 trace 和绘制指令查看,并且同时支持 vulkan 和 opengl,但使用体验不太好,成功率很低。
效果:
- 系统 trace 查看
- 帧绘制指令抓取(成功率很低,而且不直观)
用法:
软件下载,支持 Mac/Windows/Linux
两个入口,左边的对应 Perfetto,右边的类似 Skia debugger
System trace
注意选择 trace 的时间,和输出文件的地址,然后点击 start
基本和 Perfetto 一样,不过感觉 Perfetto 的使用体验比这个好
帧绘制指令抓取
首先选择抓取的类型 Vulkan 或者 OpenGL,如果是 GL 模式还需要在手机上安装一个应用 :
agi-angle.storage.googleapis.com/index.html
具体流程参考官方文档,不过这个工具使用成功率很低,不是很推荐
developer.android.com/agi/start#f...
vulkan:
developer.android.com/ndk/guides/...
成功的一次指令如下,可以抓到具体的 gl 指令: