2. Profiling 基础:Perfetto 与 Systrace 工具链搭建,抓取 Camera HAL 层 Trace

在 Camera HAL 稳像调试中,Profiling 是量化性能瓶颈、定位功耗异常的起点。本章将系统讲解如何搭建 Perfetto 与 Systrace 工具链,并精准抓取 HAL 层的 Trace 数据,为后续的稳像算法优化提供数据基础。

2.1 工具链选型对比

Perfetto 与 Systrace 是 Android 平台上最主流的两种 Profiling 工具。下表从多个维度对比两者的适用场景:

对比维度 Systrace Perfetto
底层机制 基于 ftrace + atrace 基于 Perfetto 内核追踪 + 用户态服务
数据精度 毫秒级,适合宏观流程 微秒级,支持细粒度分析
HAL 层支持 需手动添加 ATRACE 标记 原生支持 HAL 层 Trace 点,可扩展
功耗分析 需结合其他工具 内置功耗追踪(BatteryStats、Power Rails)
数据量 适合短时抓取(<30s) 支持长时间录制(分钟级)
UI 交互 Chrome 内置 trace-viewer 独立 UI(ui.perfetto.dev)
选型建议:对于 Camera HAL 稳像调试,推荐以 Perfetto 为主、Systrace 为辅。Perfetto 能提供更精细的 HAL 层调用链和功耗数据,而 Systrace 在快速定位宏观流程问题时仍具优势。

2.2 Perfetto 工具链搭建

Perfetto 工具链由三部分组成:客户端(adb)、服务端(traced / traced_probes) 和 前端 UI。搭建步骤如下:

  1. 确认设备支持:Android 10+ 原生集成 Perfetto,Android 9 及以下需手动推送二进制文件。
  2. 启动 Perfetto 服务:通过 adb shell 执行 setprop persist.traced.enable 1 并重启设备。
  3. 配置 Trace 数据源:编写 .pbtx 配置文件,指定需要追踪的 HAL 层进程和类别。
  4. 执行抓取:使用 perfetto 命令行工具或 adb shell perfetto 启动录制。
  5. 拉取并分析:将生成的 .perfetto-trace 文件导入 ui.perfetto.dev 进行可视化分析。
关键配置示例:以下是一个针对 Camera HAL 的 Perfetto 配置文件片段,用于追踪 cameraserver 进程和内核调度事件。
# camera_hal_trace.pbtx
buffers: {
    size_kb: 65536
    fill_policy: RING_BUFFER
}
data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            ftrace_events: "sched/sched_switch"
            ftrace_events: "power/cpu_frequency"
            ftrace_events: "camera/*"
        }
    }
}
data_sources: {
    config {
        name: "android.process_stats"
        target_process: "cameraserver"
        target_process: "android.hardware.camera.provider@2.4-service"
    }
}
duration_ms: 10000

2.3 Systrace 工具链搭建

Systrace 虽然逐渐被 Perfetto 取代,但在部分旧平台或快速验证场景中仍不可替代。搭建步骤相对简单:

  1. 安装 Android SDK Tools:确保 systrace 命令可用(位于 platform-tools/systrace/)。
  2. 连接设备:通过 USB 连接已开启开发者选项和 USB 调试的设备。
  3. 执行抓取:使用 python systrace.py -t 10 -o trace.html sched freq idle camera 命令。
  4. 查看结果:用 Chrome 浏览器打开生成的 trace.html 文件。
注意:Systrace 在 Android 12+ 上已被标记为弃用,建议优先使用 Perfetto。若必须使用 Systrace,请确保设备系统版本 ≤ Android 11。

2.4 抓取 Camera HAL 层 Trace 的关键技巧

要获取有效的 HAL 层 Trace,需要在代码中正确插入 Trace 标记,并确保抓取工具能捕获到这些标记。以下是最常用的两种方式:

标记方式 适用层 示例代码
ATRACE_BEGIN/END HAL 层 C++ 代码 ATRACE_BEGIN("HAL_ProcessRequest"); ... ATRACE_END();
ScopedTrace HAL 层 C++ 代码(RAII) ScopedTrace trace("HAL_ConfigureStreams");
Perfetto SDK HAL 层 C++ 代码(推荐) TRACE_EVENT("camera", "HAL_ProcessCaptureRequest");
最佳实践:在 HAL 层的关键函数入口和出口添加 Trace 标记,包括 configure_streams、process_capture_request、flush 等。标记名称应遵循 模块_操作 的命名规范,便于后续分析。

2.5 工具链架构与数据流

下图展示了 Perfetto 工具链从数据采集到可视化分析的整体架构,以及 Camera HAL 层 Trace 数据在其中的流转路径:

Perfetto 工具链架构与 Camera HAL Trace 数据流 Perfetto 工具链架构与 Camera HAL Trace 数据流 Camera HAL 进程 ATRACE / Perfetto SDK 内核 ftrace 事件 sched / power / camera 功耗数据源 BatteryStats / PowerRails Perfetto 服务端 (traced + traced_probes) 数据采集、缓冲、序列化 .perfetto-trace 文件 包含 HAL Trace + 内核事件 + 功耗数据 Perfetto UI (ui.perfetto.dev) 可视化分析、SQL 查询、导出报告 HAL 层 Trace 通过 Perfetto SDK 或 ATRACE 注入,与内核事件、功耗数据合并输出

2.6 常见问题与排查

  • Trace 数据为空:检查是否在代码中正确添加了 Trace 标记,以及 Perfetto 配置文件中是否包含了对应的数据源。
  • 抓取时间过短:Perfetto 默认使用环形缓冲区,若缓冲区过小会导致早期数据被覆盖。建议将 size_kb 设置为 65536 以上。
  • HAL 层进程未出现:确认 target_process 中填写的进程名与 ps -A | grep camera 输出一致。
  • 功耗数据缺失:部分设备需要 root 权限才能访问 Power Rails 数据源,可尝试使用 adb root 后重试。
调试检查清单:
  1. 确认设备 Android 版本 ≥ 10,或已手动推送 Perfetto 二进制文件。
  2. 确认 HAL 层代码已添加 Trace 标记,且标记名称无拼写错误。
  3. 确认 Perfetto 配置文件中 duration_ms 足够覆盖测试场景。
  4. 确认抓取完成后,文件大小不为 0 且能正常导入 UI。

2.7 本章小结