Spaces:
Configuration error
Configuration error
File size: 2,721 Bytes
9f21d0a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | import { getTimestamp } from "@cesium/engine";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Scene = any;
const fmt = (n: number): string => n.toFixed(2).padStart(8);
export interface CesiumPerformanceStatsResult {
avgFps: number;
avgFrameTime: number;
worstFrameTime: number;
}
// Mean and worst frame time over a sample period.
export class CesiumPerformanceStats {
scene: Scene;
sampleCount = 60;
idx = 0;
postRenderTimes: number[] = [];
discardNext = true;
avgFps = 0;
avgFrameTime = 0;
worstFrameTime = 0;
constructor(scene: Scene, logContinuously = false) {
this.scene = scene;
// Render-on-demand skips frames when nothing moved, which would make the gap
// between postRender events a measure of how idle the loop is rather than of
// what a frame costs.
this.scene.requestRenderMode = false;
this.scene.preUpdate.addEventListener(() => {
performance.mark("preUpdate");
});
this.scene.postRender.addEventListener(() => {
performance.mark("postRender");
this.postRenderTimes[this.idx] = getTimestamp();
this.idx = (this.idx + 1) % this.sampleCount;
if (this.idx === 0) {
if (this.discardNext) {
this.discardNext = false;
} else {
this.calculateStats();
if (logContinuously) {
console.log(this.formatStats());
}
}
}
performance.measure("SceneRender", "preUpdate", "postRender");
});
}
calculateStats(): void {
this.worstFrameTime = 0;
for (let i = 0; i < this.sampleCount - 1; i += 1) {
const a = this.postRenderTimes[i + 1];
const b = this.postRenderTimes[i];
if (a === undefined || b === undefined) continue;
const frametime = a - b;
if (frametime > this.worstFrameTime) {
this.worstFrameTime = frametime;
}
}
const last = this.postRenderTimes[this.sampleCount - 1];
const first = this.postRenderTimes[0];
if (last === undefined || first === undefined) return;
const duration = last - first;
this.avgFps = this.sampleCount / (duration / 1000);
this.avgFrameTime = duration / this.sampleCount;
}
reset(discardNext = true): void {
this.idx = 0;
this.discardNext = discardNext;
this.avgFps = 0;
this.avgFrameTime = 0;
this.worstFrameTime = 0;
}
getStats(): CesiumPerformanceStatsResult {
return {
avgFps: this.avgFps,
avgFrameTime: this.avgFrameTime,
worstFrameTime: this.worstFrameTime,
};
}
formatStats(): string {
return `Avg FPS: ${fmt(this.avgFps)}; Avg Frametime: ${fmt(this.avgFrameTime)}; Worst Frametime: ${fmt(this.worstFrameTime)};`;
}
}
|