回复
Harmony Next 和 OpenHarmony 获取屏幕刷新率、fps 原创
msdone
发布于 2024-11-18 18:18
浏览
0收藏
@toc
概述
已在 Harmony Next 和 OpenHarmony 5.0+ 上测试通过
本功能使用 @ohos.graphics.displaySync 接口实现,并采用"帧间隔法"计算 fps(当然可以使用其他计算 fps 的方法):
这是一种基于时间戳差值(Time Delta)来计算 FPS 的方法,也称为"帧时间法"或"帧间隔法"。
具体计算过程如下:
获取相邻两帧的时间戳差值(Frame Time/Delta Time)
收集一定数量的帧时间样本(使用数组存储最近60帧的数据)
计算平均帧时间
let avg_frame_time = sum / this.frame_times.length;
使用公式 FPS = 1000/平均帧时间(毫秒) 计算最终的 FPS
let fps = 1000.0 / avg_frame_time;
这种方法的特点是:
实时性好,能够反映当前实际的帧率状况
通过收集多帧样本并平均,可以平滑瞬时波动
计算简单,开销小
适合用于性能监控和调试
代码
import displaySync from '@ohos.graphics.displaySync';
@Entry
@Component
struct Index {
@State fps: number = 0;
private frame_times: number[] = [];
private last_time: number = 0;
private sum: number = 0;
private backDisplaySync: displaySync.DisplaySync = displaySync.create();
private round(value: number, decimals: number): number {
const factor = Math.pow(10, decimals);
return Math.round(value * factor) / factor;
}
private callback = (frameInfo: displaySync.IntervalInfo) => {
console.info("20241113DisplaySync", 'TimeStamp:' + frameInfo.timestamp + ' TargetTimeStamp: ' + frameInfo.targetTimestamp);
if (this.last_time === 0) {
this.last_time = Number(frameInfo.timestamp);
return;
}
// 计算帧时间(转换为毫秒)
let current_time = Number(frameInfo.timestamp);
console.info("20241113DisplaySync", "1111111111111111111111: " + current_time);
let frame_time = (current_time - this.last_time) / 1000000; // 转换纳秒为毫秒
console.info("20241113DisplaySync", "2222222222222222222222: " + frame_time);
this.last_time = current_time;
console.info("20241113DisplaySync", "3333333333333333333333: " + this.last_time);
if (frame_time > 0 && frame_time < 1000) { // 添加合理性检查,帧时间应该在 0-1000ms 之间
this.frame_times.push(frame_time);
console.info("20241113DisplaySync", "AAAAAAAAAAAAAAAAAAAAAA: " + this.frame_times);
if (this.frame_times.length > 60) {
this.sum -= this.frame_times.shift()!;
this.sum += frame_time;
} else {
this.sum += frame_time;
}
console.info("20241113DisplaySync", "BBBBBBBBBBBBBBBBBBBBBB: " + this.sum);
let avg_frame_time = this.sum / this.frame_times.length;
console.info("20241113DisplaySync", "CCCCCCCCCCCCCCCCCCCCCC: " + avg_frame_time);
let fps = 1000.0 / avg_frame_time; // 毫秒转换为秒并计算 FPS
console.info("20241113DisplaySync", "DDDDDDDDDDDDDDDDDDDDDD: " + fps);
this.fps = this.round(fps, 1);
console.info("20241113DisplaySync", "EEEEEEEEEEEEEEEEEEEEEE: " + this.fps);
}
}
build() {
Row() {
Text(this.fps.toString())
.fontColor(Color.Red)
.fontSize(40)
Button("stop")
.onClick(() => {
try {
this.backDisplaySync?.off("frame", this.callback);
this.backDisplaySync?.stop();
console.info("20241113DisplaySync", ' stop successfully!');
} catch (e) {
console.info("20241113DisplaySync", ' stop Error:' + JSON.stringify(e));
}
})
Button("start")
.onClick(() => {
try {
this.frame_times = []; // 清空历史数据
this.last_time = 0; // 重置时间戳
this.backDisplaySync.on("frame", this.callback)
this.backDisplaySync?.start()
} catch (e) {
console.info("20241113DisplaySync", 'Error:' + JSON.stringify(e));
}
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
效果
低帧率
高帧率
系统设置帧率
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2024-11-18 18:34:54修改
赞
收藏
回复
相关推荐