在 Android SurfaceFlinger 中,FrameRateOverrides 主要用于 管理和调整多个应用或窗口的帧率,确保在 不同刷新率的显示设备 上实现流畅的帧率适配。
1. FrameRateOverrides 的作用
- 解决不同应用/窗口的帧率冲突:
当多个应用在不同的帧率下运行时,系统需要协调它们,以匹配 显示屏的刷新率。 - 节能和性能优化:
降低不必要的高帧率,可以减少功耗,提高 GPU 和 CPU 的利用率。 - 适应不同刷新率的屏幕:
在 可变刷新率 (VRR) 显示 或 多层合成 的情况下,确保所有应用的帧率匹配屏幕的刷新率。
2. FrameRateOverrides 的工作方式
SurfaceFlinger 会维护一个 FrameRateOverrides 列表,记录每个应用(或 Layer)实际被限制的帧率,并在适当的时候进行帧率调整。
主要流程:
- 应用请求特定帧率 → 通过
SurfaceControl.setFrameRate()
申请特定的帧率。 - SurfaceFlinger 计算最佳帧率 → 通过
getFrameRateOverrides()
计算一个适合所有图层的帧率。 - HWC(硬件合成器)执行最终帧率设置 → 通过
hwc_presentOrValidateDisplay()
将最终帧率应用到显示设备。
3. 代码示例(Android 14)
在 SurfaceFlinger 中,FrameRateOverrides 相关的逻辑主要出现在 scheduler
目录下,关键代码如下:
// frameworks/native/services/surfaceflinger/Scheduler/FrameRateOverrides.h
struct FrameRateOverrides {
uid_t uid; // 目标应用的 UID
float frameRate; // 被系统调整后的帧率
};
然后,SurfaceFlinger::getFrameRateOverrides()
计算每个应用的帧率:
std::vector<FrameRateOverrides> SurfaceFlinger::getFrameRateOverrides() {
std::vector<FrameRateOverrides> overrides;
for (const auto& [uid, frameRate] : mFrameRateOverridesMap) {
overrides.push_back({uid, frameRate});
}
return overrides;
}
最终,HWC
(Hardware Composer)在 presentOrValidateDisplay()
里应用帧率:
hwc_display->setFrameRateOverrides(frameRateOverrides);
4. 关键点总结
- FrameRateOverrides 记录了 SurfaceFlinger 如何调整每个应用的帧率,以确保匹配显示屏的刷新率。
- 应用的
setFrameRate()
只是一个建议,最终帧率可能会被 SurfaceFlinger 覆盖。 - SurfaceFlinger 计算 FrameRateOverrides 后,由 HWC 负责应用最终的帧率设置。
- 适用于支持 VRR(可变刷新率)的设备,以确保流畅度和功耗优化。