2. 帧率基础概念:FPS、刷新率、垂直同步(V-Sync)、帧生成时间(Frame Time)的关系与区别
在 DRM/KMS 显示性能调优中,理解帧率相关的核心概念是第一步。许多开发者容易混淆 FPS、刷新率、垂直同步 和 帧生成时间 这四个术语,导致调优方向错误。本章从 Linux 内核 DRM 驱动视角,厘清它们的定义、关系与区别。
2.1 核心概念定义
| 概念 | 英文 | 定义 | 单位 | 测量对象 |
|---|---|---|---|---|
| 帧率 | FPS | 图形渲染管线每秒生成的完整帧数量 | 帧/秒 (fps) | GPU 渲染端 |
| 刷新率 | Refresh Rate | 显示设备每秒刷新画面的次数 | 赫兹 (Hz) | 显示器端 |
| 垂直同步 | V-Sync | 强制渲染帧率与显示器刷新率对齐的同步机制 | 开/关/自适应 | 渲染-显示接口 |
| 帧生成时间 | Frame Time | 渲染一帧所消耗的实际时间 | 毫秒 (ms) | GPU 渲染端 |
DRM 调优要点: 在 DRM/KMS 驱动中,
drm_crtc 的 mode 结构体直接定义了刷新率(通过 drm_display_mode 的 vrefresh 字段),而 FPS 由用户态渲染管线(如 Mesa/Gallium)控制。调优时需区分这两个层面。
2.2 四者关系:从渲染到显示的完整链路
下图展示了从 GPU 渲染帧到显示器最终呈现的完整数据流,以及四个概念在链路中的位置:
2.3 关键区别与 DRM 调优含义
2.3.1 FPS vs 刷新率:谁决定谁?
- 刷新率是硬上限:显示器在硬件层面决定了每秒最多能显示多少帧。例如 60Hz 显示器每秒最多显示 60 帧。
- FPS 是软输出:GPU 渲染能力决定 FPS。若 FPS > 刷新率,多余帧会被丢弃(tearing)或等待(V-Sync)。
- DRM 实践:通过
drmModeGetCrtc()获取当前drm_display_mode,其vrefresh字段即为硬件刷新率。FPS 需通过用户态工具(如glxgears、vblank_mode)测量。
2.3.2 帧生成时间 vs FPS:毫秒级波动
- FPS 是平均值:1 秒内帧数的平均,掩盖了单帧抖动。
- Frame Time 是瞬时值:每帧的实际耗时,能暴露卡顿(jank)。
- 数学关系:
FPS = 1000 / Frame Time (ms),但仅当 Frame Time 恒定时成立。实际中 Frame Time 波动导致 FPS 不稳定。
调优案例: 某嵌入式设备报告 FPS 稳定在 58-60,但用户感觉卡顿。测量 Frame Time 后发现:大部分帧耗时 16.6ms(60fps),但每 10 帧出现一次 50ms 的尖峰。FPS 平均值掩盖了这 10% 的卡顿帧。DRM 层面需排查
drm_atomic_commit 阻塞时间。
2.3.3 垂直同步(V-Sync)的三种模式
| 模式 | 行为 | FPS 上限 | 画面撕裂 | 输入延迟 | DRM 实现 |
|---|---|---|---|---|---|
| 关闭 | 渲染完成立即送显 | 无上限 | 有 | 最低 | drm_crtc 不等待 vblank |
| 开启 | 等待 vblank 信号再送显 | = 刷新率 | 无 | 较高 | drm_crtc_vblank_get() 阻塞 |
| 自适应 | FPS > 刷新率时开启,否则关闭 | 动态 | 条件性 | 中等 | 用户态策略,内核提供 vblank 事件 |
2.4 帧时间与刷新率的数学关系
在 DRM 驱动中,刷新率决定了 vblank 周期(垂直消隐间隔)。帧生成时间与 vblank 周期的关系决定了显示质量:
// 刷新率 60Hz 时的 vblank 周期
vblank_period_ms = 1000 / refresh_rate = 1000 / 60 ≈ 16.67 ms
// 帧生成时间与 vblank 的关系
if (frame_time <= vblank_period_ms) {
// 帧在 vblank 窗口内完成,无撕裂,FPS = 刷新率
} else if (frame_time > vblank_period_ms) {
// 帧跨多个 vblank,V-Sync 开启时帧率下降
// 实际 FPS = 1000 / frame_time (向下取整到 vblank 倍数)
}
常见误区: 不要认为 FPS 等于刷新率就是最优。若 Frame Time 不稳定(如 10ms、20ms、15ms 交替),即使平均 FPS 为 60,实际体验仍会卡顿。DRM 调优应优先关注 Frame Time 的 95 百分位 和 最大帧时间,而非平均 FPS。
2.5 四者对比总结表
| 对比维度 | FPS | 刷新率 | V-Sync | Frame Time |
|---|---|---|---|---|
| 测量工具 | glxgears, perf |
drmModeGetCrtc, EDID |
vblank_mode, __DRI2_FLUSH |
ftrace, GPUPerfStudio |
| 调优目标 | 稳定接近刷新率 | 匹配应用需求 | 平衡撕裂与延迟 | 降低抖动(jitter) |
| 内核接口 | 无直接接口 | drm_display_mode.vrefresh |
drm_crtc_vblank_get/put |
drm_atomic_state 提交时间戳 |
| 用户态感知 | 流畅度 | 画面闪烁 | 撕裂/延迟 | 卡顿/微卡 |
2.6 实战:使用 DRM 工具测量四要素
以下命令在 Linux 终端中直接测量四个指标:
# 1. 获取显示器刷新率(DRM 内核态)
cat /sys/class/drm/card0-HDMI-A-1/modes
# 输出示例: 1920x1080@60
# 2. 测量 FPS 和 Frame Time(用户态,需安装)
vblank_mode=0 glxgears # V-Sync 关闭,测原始 FPS
vblank_mode=1 glxgears # V-Sync 开启,FPS 上限=刷新率
# 3. 使用 drm_info 查看 crtc 状态
drm_info | grep -A 10 "CRTC"
# 输出包含 vrefresh、vblank 计数等
# 4. 使用 ftrace 追踪帧提交时间
echo 1 > /sys/kernel/debug/tracing/events/drm/drm_vblank_event/enable
cat /sys/kernel/debug/tracing/trace_pipe | grep drm_vblank_event
DRM 调优口诀: 刷新率是天花板,Frame Time 是显微镜,V-Sync 是开关,FPS 是结果。调优时先固定刷新率,再优化 Frame Time 稳定性,最后根据场景决定 V-Sync 策略。