Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/packages/firebird-ng/display/src/lib/services/perf.service.ts is written in an unsupported language. File is not indexed.

0001 // perf.service.ts (optimized snippet)
0002 import { Injectable } from '@angular/core';
0003 import { BehaviorSubject } from 'rxjs';
0004 import {WebGPURenderer} from "three/webgpu";
0005 export interface PerfLog {
0006   fps: number;
0007   frameTime: number;  // Changed from 'cpu' to 'frameTime'
0008   calls: number;
0009   triangles: number;
0010   /** Render scheduling mode of the loop (config `rendering.mode`). */
0011   mode: 'continuous' | 'on-demand';
0012   /** True when on-demand and nothing rendered in the last interval — the
0013    * display is up to date, not hung. FPS reads 0 by design while idle. */
0014   idle: boolean;
0015 }
0016 
0017 @Injectable({
0018   providedIn: 'root',
0019 })
0020 export class PerfService {
0021   private perfSubject = new BehaviorSubject<PerfLog>({
0022     fps: 0,
0023     frameTime: 0,
0024     calls: 0,
0025     triangles: 0,
0026     mode: 'continuous',
0027     idle: false,
0028   });
0029   public perf$ = this.perfSubject.asObservable();
0030 
0031   private lastUpdateTime = performance.now();
0032   private frameCount = 0;
0033   private frameTimes: number[] = [];
0034   private readonly updateInterval = 250; // milliseconds
0035 
0036   /**
0037    * Called every animation-frame tick. `rendered` says whether this tick
0038    * actually rendered — FPS counts rendered frames only, so an idle
0039    * on-demand loop correctly decays to 0 (flagged `idle`, not a hang).
0040    */
0041   public updateStats(renderer: WebGPURenderer, frameStartTime: number, rendered = true, continuous = true) {
0042     const now = performance.now();
0043 
0044     if (rendered) {
0045       this.frameCount++;
0046       this.frameTimes.push(now - frameStartTime);
0047     }
0048 
0049     // Check if the interval has elapsed
0050     if (now - this.lastUpdateTime >= this.updateInterval) {
0051       const deltaSeconds = (now - this.lastUpdateTime) / 1000;
0052       const fps = this.frameCount / deltaSeconds;
0053 
0054       // Average frame time over rendered frames (0 while idle)
0055       const avgFrameTime = this.frameTimes.length
0056         ? this.frameTimes.reduce((a, b) => a + b, 0) / this.frameTimes.length
0057         : 0;
0058 
0059       // Read renderer info only once
0060       const info = renderer.info.render as { calls: number; triangles: number; drawCalls?: number };
0061 
0062       // WebGPURenderer semantics differ from WebGLRenderer: info.render.calls is a
0063       // cumulative total that never resets, while drawCalls holds the per-frame count.
0064       const callsPerFrame = info.drawCalls !== undefined ? info.drawCalls : info.calls;
0065 
0066       const log: PerfLog = {
0067         fps: fps,
0068         frameTime: avgFrameTime,
0069         calls: callsPerFrame,
0070         triangles: info.triangles,
0071         mode: continuous ? 'continuous' : 'on-demand',
0072         idle: !continuous && this.frameCount === 0,
0073       };
0074 
0075       this.perfSubject.next(log);
0076 
0077       // Reset counters
0078       this.lastUpdateTime = now;
0079       this.frameCount = 0;
0080       this.frameTimes = [];
0081     }
0082   }
0083 }