1. 帧率抖动与回归测试概念
在 AOSP Framework 开发中,帧率抖动(Frame Rate Jitter)、掉帧(Dropped Frame)、Jank 和卡顿(Stutter)是影响用户感知流畅度的核心问题。本章建立统一术语体系,明确回归测试的目的、范围和关键量化指标,为后续章节的 SOP 操作提供概念基础。
适用场景
- 性能基线验证:每次 Framework 代码改动后,需要确认帧率稳定性未退化。
- 渲染管线和调度演进:调整 SurfaceFlinger、Choreographer、HWC 等组件时,排查新引入的帧率抖动。
- 用户反馈复现:针对用户侧“卡顿”“掉帧”报告,建立可量化的回归用例。
前置条件
- 已搭建基于
dumpsys、systrace或Perfetto的帧率采集环境。 - 被测设备(DUT)连接后开启
setprop debug.sf.frames 1或类似调试开关。 - 测试场景(如 Launcher 滑动、微博 Feeds 滚动)已录制为自动化脚本。
- 团队成员理解以下概念差异,避免测试报告混淆。
操作步骤(概念认知步骤)
- 定义抖动模型:
帧率抖动 = 实际帧间隔与目标帧间隔的偏差值(单位:ms)。例如 60fps 目标帧间隔 16.67ms,实际采集到 18.5ms、15.2ms 则存在抖动。 - 识别掉帧:
实际帧间隔超过目标帧间隔 + 容忍阈值(通常为 3ms)时记作一次掉帧。掉帧累计数/总帧数 = 掉帧率。 - 分辨 Jank vs 卡顿:
Jank 指单帧渲染时间超标导致显示器跳过该帧(SurfaceFlinger 直接丢弃);卡顿是用户感知的连续多帧掉帧或大抖动,通常对应 FPS 跌落至 30 以下持续 ≥200ms。 - 提取关键指标:
从 trace/log 计算 AvgFPS、Jitter(ms)、DroppedFrameCount、JankCount、卡顿时长(s)。
输入输出物
| 输入 | 输出 |
|---|---|
| 被测 APK 或系统 App 的待测场景列表 | 术语统一文档(包含本章定义的 4 种异常类型及判断公式) |
| 原始帧时间戳 CSV / Systrace log | 帧率抖动基线报告(包含 AvgFPS、Jitter 95th/99th 百分位、掉帧率) |
| 历史回归测试记录 | 差异对比表(当前版本 vs 基线版本各指标趋势) |
责任边界
- 测试工程师:负责按照概念定义解析 trace,标记 Jank 事件,生成基线。
- Framework 研发:复核测试报告中的“掉帧”是否为预期行为(如低温 throttling),并排除非代码因素。
- QA 管理员:维护术语库和指标阈值,评审异常处理流程。
记录材料
每次回归测试必须生成以下记录文件:
version_1.0_regression_baseline.csv
# 字段: scene, avgFPS, jitterMs_95p, droppedFrameRate, jankCount, stutterDurationMs
version_1.1_changelog.txt
# 记录被测 commit SHA、改动模块、概念解释变更集
异常处理
常见概念混淆及校正
- “掉帧率”和“Jank率”误用:掉帧率 = 掉帧数/总帧数,Jank率 = Jank帧数/总帧数,Jank帧判定严格于掉帧(需满足渲染时间超上限且导致 skip)。
- “卡顿”被主观反馈而非量化:必须用“连续掉帧间隔 ≤ 5 帧且持续 ≥200ms”作为卡顿事件的量化判断条件。
- 忽略屏幕刷新率变化:当设备 dynamic refresh rate 从 60Hz 切到 120Hz 时,帧间隔计算目标值应同步更新。
验收标准
- 团队成员能够口头解释帧率抖动(Jitter)、掉帧(Dropped Frame)、Jank、卡顿(Stutter)的定义及它们之间的逻辑关系。
- 测试报告的关键指标字段与本章表格一致,无歧义。
- 回归测试从 trace 到指标提取的步骤通过一次演示正确性审核。
📌 实际应用示例:在 Launcher 滑动测试中,通过以下命令抓取原始帧时间戳:
adb shell dumpsys gfxinfo com.android.launcher3 framestats
解析输出中的 Draw、Prepare、Process、Execute 时间戳,按本章定义计算 AvgFPS、Jitter 和掉帧数,即可生成回归基线。