stats-gl 3.8.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,28 +1,4 @@
1
- declare class Panel {
2
- canvas: HTMLCanvasElement;
3
- context: CanvasRenderingContext2D | null;
4
- name: string;
5
- fg: string;
6
- bg: string;
7
- gradient: CanvasGradient | null;
8
- id: number;
9
- PR: number;
10
- WIDTH: number;
11
- HEIGHT: number;
12
- TEXT_X: number;
13
- TEXT_Y: number;
14
- GRAPH_X: number;
15
- GRAPH_Y: number;
16
- GRAPH_WIDTH: number;
17
- GRAPH_HEIGHT: number;
18
- constructor(name: string, fg: string, bg: string);
19
- private createGradient;
20
- initializeCanvas(): void;
21
- update(value: number, maxValue: number, decimals?: number): void;
22
- updateGraph(valueGraph: number, maxGraph: number): void;
23
- }
24
-
25
- interface StatsOptions {
1
+ interface StatsCoreOptions {
26
2
  trackGPU?: boolean;
27
3
  trackCPT?: boolean;
28
4
  trackHz?: boolean;
@@ -32,9 +8,9 @@ interface StatsOptions {
32
8
  samplesLog?: number;
33
9
  samplesGraph?: number;
34
10
  precision?: number;
35
- minimal?: boolean;
36
- horizontal?: boolean;
37
- mode?: number;
11
+ }
12
+ interface QueryInfo {
13
+ query: WebGLQuery;
38
14
  }
39
15
  interface AverageData {
40
16
  logs: number[];
@@ -48,11 +24,14 @@ interface InfoData {
48
24
  timestamp: number;
49
25
  };
50
26
  }
51
- declare class Stats {
52
- dom: HTMLDivElement;
53
- mode: number;
54
- horizontal: boolean;
55
- minimal: boolean;
27
+ interface StatsData {
28
+ fps: number;
29
+ cpu: number;
30
+ gpu: number;
31
+ gpuCompute: number;
32
+ isWorker?: boolean;
33
+ }
34
+ declare class StatsCore {
56
35
  trackGPU: boolean;
57
36
  trackHz: boolean;
58
37
  trackFPS: boolean;
@@ -65,64 +44,349 @@ declare class Stats {
65
44
  gl: WebGL2RenderingContext | null;
66
45
  ext: any | null;
67
46
  info?: InfoData;
68
- private activeQuery;
69
- private gpuQueries;
70
- private threeRendererPatched;
71
- private beginTime;
72
- private prevCpuTime;
73
- private frameTimes;
74
- private renderCount;
75
- private totalCpuDuration;
76
- private totalGpuDuration;
77
- private totalGpuDurationCompute;
47
+ gpuDevice: GPUDevice | null;
48
+ gpuBackend: any | null;
49
+ renderer: any | null;
50
+ protected activeQuery: WebGLQuery | null;
51
+ protected gpuQueries: QueryInfo[];
52
+ protected threeRendererPatched: boolean;
53
+ protected webgpuNative: boolean;
54
+ protected gpuQuerySet: GPUQuerySet | null;
55
+ protected gpuResolveBuffer: GPUBuffer | null;
56
+ protected gpuReadBuffers: GPUBuffer[];
57
+ protected gpuWriteBufferIndex: number;
58
+ protected gpuFrameCount: number;
59
+ protected pendingResolve: Promise<number> | null;
60
+ protected beginTime: number;
61
+ protected prevCpuTime: number;
62
+ protected frameTimes: number[];
63
+ protected renderCount: number;
64
+ protected totalCpuDuration: number;
65
+ protected totalGpuDuration: number;
66
+ protected totalGpuDurationCompute: number;
67
+ averageFps: AverageData;
68
+ averageCpu: AverageData;
69
+ averageGpu: AverageData;
70
+ averageGpuCompute: AverageData;
71
+ protected prevGraphTime: number;
72
+ protected prevTextTime: number;
73
+ constructor({ trackGPU, trackCPT, trackHz, trackFPS, logsPerSecond, graphsPerSecond, samplesLog, samplesGraph, precision }?: StatsCoreOptions);
74
+ init(canvasOrGL: WebGL2RenderingContext | HTMLCanvasElement | OffscreenCanvas | GPUDevice | any): Promise<void>;
75
+ protected handleNativeWebGPU(device: any): boolean;
76
+ protected initializeWebGPUTiming(): void;
77
+ protected handleThreeRenderer(renderer: any): boolean;
78
+ protected handleWebGPURenderer(renderer: any): Promise<boolean>;
79
+ protected onWebGPUTimestampSupported(): void;
80
+ protected initializeWebGL(canvasOrGL: WebGL2RenderingContext | HTMLCanvasElement | OffscreenCanvas): boolean;
81
+ protected initializeGPUTracking(): void;
82
+ protected onGPUTrackingInitialized(): void;
83
+ /**
84
+ * Get timestampWrites configuration for WebGPU render pass.
85
+ * Use this when creating your render pass descriptor.
86
+ * @returns timestampWrites object or undefined if not tracking GPU
87
+ */
88
+ getTimestampWrites(): GPURenderPassTimestampWrites | undefined;
89
+ begin(encoder?: GPUCommandEncoder): void;
90
+ end(encoder?: GPUCommandEncoder): void;
91
+ /**
92
+ * Resolve WebGPU timestamp queries. Call this after queue.submit().
93
+ * Returns a promise that resolves to the GPU duration in milliseconds.
94
+ */
95
+ resolveTimestampsAsync(): Promise<number>;
96
+ private _resolveTimestamps;
97
+ protected processGpuQueries(): void;
98
+ protected processWebGPUTimestamps(): void;
99
+ protected beginProfiling(marker: string): void;
100
+ protected endProfiling(startMarker: string | PerformanceMeasureOptions | undefined, endMarker: string | undefined, measureName: string): void;
101
+ protected calculateFps(): number;
102
+ protected updateAverages(): void;
103
+ protected addToAverage(value: number, averageArray: {
104
+ logs: any;
105
+ graph: any;
106
+ }): void;
107
+ protected resetCounters(): void;
108
+ getData(): StatsData;
109
+ protected patchThreeWebGPU(renderer: any): void;
110
+ protected patchThreeRenderer(renderer: any): void;
111
+ /**
112
+ * Dispose of all resources. Call when done using the stats instance.
113
+ */
114
+ dispose(): void;
115
+ }
116
+
117
+ declare class Panel {
118
+ canvas: HTMLCanvasElement;
119
+ context: CanvasRenderingContext2D | null;
120
+ name: string;
121
+ fg: string;
122
+ bg: string;
123
+ gradient: CanvasGradient | null;
124
+ id: number;
125
+ PR: number;
126
+ WIDTH: number;
127
+ HEIGHT: number;
128
+ TEXT_X: number;
129
+ TEXT_Y: number;
130
+ GRAPH_X: number;
131
+ GRAPH_Y: number;
132
+ GRAPH_WIDTH: number;
133
+ GRAPH_HEIGHT: number;
134
+ constructor(name: string, fg: string, bg: string);
135
+ private createGradient;
136
+ initializeCanvas(): void;
137
+ update(value: number, maxValue: number, decimals?: number, suffix?: string): void;
138
+ updateGraph(valueGraph: number, maxGraph: number): void;
139
+ }
140
+
141
+ declare class PanelTexture extends Panel {
142
+ private currentBitmap;
143
+ private sourceAspect;
144
+ constructor(name: string);
145
+ initializeCanvas(): void;
146
+ private drawLabelOverlay;
147
+ /**
148
+ * Set the source texture aspect ratio for proper display
149
+ * @param width - Source texture width
150
+ * @param height - Source texture height
151
+ */
152
+ setSourceSize(width: number, height: number): void;
153
+ updateTexture(bitmap: ImageBitmap): void;
154
+ setLabel(label: string): void;
155
+ update(_value: number, _maxValue: number, _decimals?: number, _suffix?: string): void;
156
+ updateGraph(_valueGraph: number, _maxGraph: number): void;
157
+ /**
158
+ * Dispose of resources
159
+ */
160
+ dispose(): void;
161
+ }
162
+
163
+ declare class TextureCaptureWebGL {
164
+ private gl;
165
+ private previewFbo;
166
+ private previewTexture;
167
+ private pixels;
168
+ private flippedPixels;
169
+ private previewWidth;
170
+ private previewHeight;
171
+ constructor(gl: WebGL2RenderingContext, width?: number, height?: number);
172
+ /**
173
+ * Resize preview dimensions
174
+ */
175
+ resize(width: number, height: number): void;
176
+ private initResources;
177
+ capture(source: WebGLFramebuffer | null, sourceWidth: number, sourceHeight: number, _sourceId?: string): Promise<ImageBitmap | null>;
178
+ private flipY;
179
+ removeSource(_sourceId: string): void;
180
+ dispose(): void;
181
+ }
182
+ declare class TextureCaptureWebGPU {
183
+ private device;
184
+ private previewTexture;
185
+ private stagingBuffer;
186
+ private blitPipeline;
187
+ private sampler;
188
+ private bindGroupLayout;
189
+ private initialized;
190
+ private previewWidth;
191
+ private previewHeight;
192
+ private pixelsBuffer;
193
+ constructor(device: GPUDevice, width?: number, height?: number);
194
+ /**
195
+ * Resize preview dimensions
196
+ */
197
+ resize(width: number, height: number): void;
198
+ private createSizeResources;
199
+ private initResources;
200
+ capture(source: GPUTexture): Promise<ImageBitmap | null>;
201
+ dispose(): void;
202
+ }
203
+ interface ThreeTextureSource {
204
+ isWebGLRenderTarget?: boolean;
205
+ __webglFramebuffer?: WebGLFramebuffer;
206
+ width?: number;
207
+ height?: number;
208
+ isRenderTarget?: boolean;
209
+ texture?: {
210
+ isTexture?: boolean;
211
+ };
212
+ }
213
+
214
+ interface StatsProfilerOptions extends StatsCoreOptions {
215
+ }
216
+ declare class StatsProfiler extends StatsCore {
217
+ private textureCaptureWebGL;
218
+ private textureCaptureWebGPU;
219
+ constructor(options?: StatsProfilerOptions);
220
+ update(): void;
221
+ getData(): StatsData;
222
+ /**
223
+ * Capture a texture/render target to ImageBitmap for transfer to main thread
224
+ * @param source - Three.js RenderTarget, GPUTexture, or WebGLFramebuffer with dimensions
225
+ * @param sourceId - Unique identifier for this texture source (for per-source PBO buffering)
226
+ * @returns ImageBitmap suitable for postMessage transfer
227
+ */
228
+ captureTexture(source: ThreeTextureSource | {
229
+ framebuffer: WebGLFramebuffer;
230
+ width: number;
231
+ height: number;
232
+ } | any, sourceId?: string): Promise<ImageBitmap | null>;
233
+ /**
234
+ * Dispose texture capture resources
235
+ */
236
+ disposeTextureCapture(): void;
237
+ /**
238
+ * Dispose of all resources
239
+ */
240
+ dispose(): void;
241
+ }
242
+
243
+ /**
244
+ * TSL Node capture utilities for stats-gl
245
+ *
246
+ * For WebGPU TSL node capture with proper Node integration, use the addon:
247
+ * import { statsGL } from 'stats-gl/addons/StatsGLNode.js';
248
+ *
249
+ * This file provides a simpler capture system that doesn't require
250
+ * extending Three.js Node class.
251
+ */
252
+ interface StatsGLNodeData {
253
+ canvas: HTMLCanvasElement | OffscreenCanvas;
254
+ canvasTarget: any;
255
+ quad: any;
256
+ material: any;
257
+ node: any;
258
+ }
259
+ /**
260
+ * Manages TSL node capture for stats-gl (used internally)
261
+ */
262
+ declare class StatsGLCapture {
263
+ nodes: Map<string, StatsGLNodeData>;
264
+ width: number;
265
+ height: number;
266
+ private THREE;
267
+ constructor(THREE: any, width?: number, height?: number);
268
+ /**
269
+ * Update capture dimensions (e.g., on resize)
270
+ */
271
+ resize(width: number, height: number): void;
272
+ register(name: string, targetNode: any): StatsGLNodeData;
273
+ capture(name: string, renderer: any): Promise<ImageBitmap | null>;
274
+ remove(name: string): void;
275
+ /**
276
+ * Dispose all capture resources
277
+ */
278
+ dispose(): void;
279
+ }
280
+
281
+ interface StatsOptions extends StatsCoreOptions {
282
+ minimal?: boolean;
283
+ horizontal?: boolean;
284
+ mode?: number;
285
+ }
286
+ declare class Stats extends StatsCore {
287
+ dom: HTMLDivElement;
288
+ mode: number;
289
+ horizontal: boolean;
290
+ minimal: boolean;
78
291
  private _panelId;
79
292
  private fpsPanel;
80
293
  private msPanel;
81
294
  private gpuPanel;
82
295
  private gpuPanelCompute;
83
296
  private vsyncPanel;
84
- averageFps: AverageData;
85
- averageCpu: AverageData;
86
- averageGpu: AverageData;
87
- averageGpuCompute: AverageData;
297
+ private workerCpuPanel;
298
+ texturePanels: Map<string, PanelTexture>;
299
+ private texturePanelRow;
300
+ private textureCaptureWebGL;
301
+ private textureCaptureWebGPU;
302
+ private textureSourcesWebGL;
303
+ private textureSourcesWebGPU;
304
+ private texturePreviewWidth;
305
+ private texturePreviewHeight;
306
+ private lastRendererWidth;
307
+ private lastRendererHeight;
308
+ private textureUpdatePending;
88
309
  private updateCounter;
89
- private prevGraphTime;
90
310
  private lastMin;
91
311
  private lastMax;
92
312
  private lastValue;
93
- private prevTextTime;
94
313
  private readonly VSYNC_RATES;
95
314
  private detectedVSync;
96
315
  private frameTimeHistory;
97
316
  private readonly HISTORY_SIZE;
98
317
  private readonly VSYNC_THRESHOLD;
99
318
  private lastFrameTime;
319
+ private externalData;
320
+ private hasNewExternalData;
321
+ private isWorker;
322
+ private averageWorkerCpu;
100
323
  static Panel: typeof Panel;
324
+ static PanelTexture: typeof PanelTexture;
101
325
  constructor({ trackGPU, trackCPT, trackHz, trackFPS, logsPerSecond, graphsPerSecond, samplesLog, samplesGraph, precision, minimal, horizontal, mode }?: StatsOptions);
102
326
  private initializeDOM;
103
327
  private setupEventListeners;
104
328
  private handleClick;
105
329
  private handleResize;
106
- init(canvasOrGL: WebGL2RenderingContext | HTMLCanvasElement | OffscreenCanvas | any): Promise<void>;
107
- private handleThreeRenderer;
108
- private handleWebGPURenderer;
109
- private initializeWebGPUPanels;
110
- private initializeWebGL;
111
- private initializeGPUTracking;
112
- begin(): void;
113
- end(): void;
330
+ /**
331
+ * Compute and update texture preview dimensions based on renderer aspect ratio
332
+ */
333
+ private updateTexturePreviewDimensions;
334
+ protected onWebGPUTimestampSupported(): void;
335
+ protected onGPUTrackingInitialized(): void;
336
+ setData(data: StatsData): void;
114
337
  update(): void;
115
- private processWebGPUTimestamps;
116
- private resetCounters;
338
+ private updateFromExternalData;
339
+ private updateFromInternalData;
340
+ private renderPanels;
341
+ protected resetCounters(): void;
117
342
  resizePanel(panel: Panel): void;
118
343
  addPanel(panel: Panel): Panel;
119
344
  showPanel(id: number): void;
120
- processGpuQueries(): void;
345
+ /**
346
+ * Add a new texture preview panel
347
+ * @param name - Label for the texture panel
348
+ * @returns The created PanelTexture instance
349
+ */
350
+ addTexturePanel(name: string): PanelTexture;
351
+ /**
352
+ * Set texture source for a panel (Three.js render target)
353
+ * Auto-detects WebGL/WebGPU and extracts native handles
354
+ * @param name - Panel name
355
+ * @param source - Three.js RenderTarget or native texture
356
+ */
357
+ setTexture(name: string, source: ThreeTextureSource | any): void;
358
+ /**
359
+ * Set WebGL framebuffer source with explicit dimensions
360
+ * @param name - Panel name
361
+ * @param framebuffer - WebGL framebuffer
362
+ * @param width - Texture width
363
+ * @param height - Texture height
364
+ */
365
+ setTextureWebGL(name: string, framebuffer: WebGLFramebuffer, width: number, height: number): void;
366
+ /**
367
+ * Set texture from ImageBitmap (for worker mode)
368
+ * @param name - Panel name
369
+ * @param bitmap - ImageBitmap transferred from worker
370
+ * @param sourceWidth - Optional source texture width for aspect ratio
371
+ * @param sourceHeight - Optional source texture height for aspect ratio
372
+ */
373
+ setTextureBitmap(name: string, bitmap: ImageBitmap, sourceWidth?: number, sourceHeight?: number): void;
374
+ /**
375
+ * Remove a texture panel
376
+ * @param name - Panel name to remove
377
+ */
378
+ removeTexturePanel(name: string): void;
379
+ /**
380
+ * Capture and update all texture panels
381
+ * Called automatically during renderPanels at graphsPerSecond rate
382
+ */
383
+ private updateTexturePanels;
384
+ /**
385
+ * Capture StatsGL nodes registered by the addon
386
+ */
387
+ private captureStatsGLNodes;
121
388
  private detectVSync;
122
- endInternal(): number;
123
389
  private updatePanelComponents;
124
- private beginProfiling;
125
- private endProfiling;
126
390
  updatePanel(panel: {
127
391
  update: any;
128
392
  updateGraph: any;
@@ -131,14 +395,11 @@ declare class Stats {
131
395
  logs: number[];
132
396
  graph: number[];
133
397
  }, precision?: number): void;
134
- private updateAverages;
135
- addToAverage(value: number, averageArray: {
136
- logs: any;
137
- graph: any;
138
- }): void;
139
398
  get domElement(): HTMLDivElement;
140
- patchThreeWebGPU(renderer: any): void;
141
- patchThreeRenderer(renderer: any): void;
399
+ /**
400
+ * Dispose of all resources. Call when done using Stats.
401
+ */
402
+ dispose(): void;
142
403
  }
143
404
 
144
- export { Stats as default };
405
+ export { PanelTexture, StatsData, StatsGLCapture, StatsProfiler, TextureCaptureWebGL, TextureCaptureWebGPU, Stats as default };
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ class StatsGLCapture {
4
+ constructor(THREE, width = 90, height = 48) {
5
+ this.nodes = /* @__PURE__ */ new Map();
6
+ this.width = 90;
7
+ this.height = 48;
8
+ this.THREE = THREE;
9
+ this.width = width;
10
+ this.height = height;
11
+ }
12
+ /**
13
+ * Update capture dimensions (e.g., on resize)
14
+ */
15
+ resize(width, height) {
16
+ var _a, _b;
17
+ this.width = width;
18
+ this.height = height;
19
+ for (const [name, data] of this.nodes) {
20
+ if (data.canvas instanceof HTMLCanvasElement) {
21
+ data.canvas.width = width;
22
+ data.canvas.height = height;
23
+ } else if (data.canvas instanceof OffscreenCanvas) {
24
+ const newCanvas = new OffscreenCanvas(width, height);
25
+ data.canvas = newCanvas;
26
+ (_b = (_a = data.canvasTarget).setCanvas) == null ? void 0 : _b.call(_a, newCanvas);
27
+ }
28
+ data.canvasTarget.setSize(width, height);
29
+ }
30
+ }
31
+ register(name, targetNode) {
32
+ if (this.nodes.has(name))
33
+ return this.nodes.get(name);
34
+ const { CanvasTarget, NodeMaterial, QuadMesh, NoToneMapping, LinearSRGBColorSpace } = this.THREE;
35
+ const { renderOutput, vec3, vec4 } = this.THREE;
36
+ const canvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(this.width, this.height) : document.createElement("canvas");
37
+ if (canvas instanceof HTMLCanvasElement) {
38
+ canvas.width = this.width;
39
+ canvas.height = this.height;
40
+ }
41
+ const canvasTarget = new CanvasTarget(canvas);
42
+ canvasTarget.setSize(this.width, this.height);
43
+ const material = new NodeMaterial();
44
+ material.outputNode = renderOutput(
45
+ vec4(vec3(targetNode), 1),
46
+ NoToneMapping,
47
+ LinearSRGBColorSpace
48
+ );
49
+ const quad = new QuadMesh(material);
50
+ const data = { canvas, canvasTarget, quad, material, node: targetNode };
51
+ this.nodes.set(name, data);
52
+ return data;
53
+ }
54
+ async capture(name, renderer) {
55
+ const data = this.nodes.get(name);
56
+ if (!data)
57
+ return null;
58
+ try {
59
+ data.quad.render(renderer, data.canvasTarget);
60
+ return await createImageBitmap(data.canvas);
61
+ } catch (e) {
62
+ return null;
63
+ }
64
+ }
65
+ remove(name) {
66
+ const data = this.nodes.get(name);
67
+ if (data) {
68
+ if (data.material && data.material.dispose) {
69
+ data.material.dispose();
70
+ }
71
+ if (data.canvas instanceof HTMLCanvasElement && data.canvas.parentNode) {
72
+ data.canvas.parentNode.removeChild(data.canvas);
73
+ }
74
+ this.nodes.delete(name);
75
+ }
76
+ }
77
+ /**
78
+ * Dispose all capture resources
79
+ */
80
+ dispose() {
81
+ const names = Array.from(this.nodes.keys());
82
+ for (const name of names) {
83
+ this.remove(name);
84
+ }
85
+ this.nodes.clear();
86
+ }
87
+ }
88
+ exports.StatsGLCapture = StatsGLCapture;
89
+ //# sourceMappingURL=statsGLNode.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statsGLNode.cjs","sources":["../lib/statsGLNode.ts"],"sourcesContent":null,"names":[],"mappings":";;AAqBO,MAAM,eAAe;AAAA,EAM1B,YAAY,OAAY,QAAQ,IAAI,SAAS,IAAI;AALjD,SAAA,4BAA0C;AAClC,SAAA,QAAA;AACC,SAAA,SAAA;AAIP,SAAK,QAAQ;AACb,SAAK,QAAQ;AACb,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,OAAe,QAAsB;;AAC1C,SAAK,QAAQ;AACb,SAAK,SAAS;AAGd,eAAW,CAAC,MAAM,IAAI,KAAK,KAAK,OAAO;AACjC,UAAA,KAAK,kBAAkB,mBAAmB;AAC5C,aAAK,OAAO,QAAQ;AACpB,aAAK,OAAO,SAAS;AAAA,MAAA,WACZ,KAAK,kBAAkB,iBAAiB;AAEjD,cAAM,YAAY,IAAI,gBAAgB,OAAO,MAAM;AACnD,aAAK,SAAS;AACT,yBAAA,cAAa,cAAb,4BAAyB;AAAA,MAChC;AACK,WAAA,aAAa,QAAQ,OAAO,MAAM;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,SAAS,MAAc,YAAkC;AACnD,QAAA,KAAK,MAAM,IAAI,IAAI;AAAU,aAAA,KAAK,MAAM,IAAI,IAAI;AAEpD,UAAM,EAAE,cAAc,cAAc,UAAU,eAAe,yBAAyB,KAAK;AAC3F,UAAM,EAAE,cAAc,MAAM,KAAA,IAAS,KAAK;AAE1C,UAAM,SAAS,OAAO,oBAAoB,cACtC,IAAI,gBAAgB,KAAK,OAAO,KAAK,MAAM,IAC3C,SAAS,cAAc,QAAQ;AACnC,QAAI,kBAAkB,mBAAmB;AACvC,aAAO,QAAQ,KAAK;AACpB,aAAO,SAAS,KAAK;AAAA,IACvB;AAEM,UAAA,eAAe,IAAI,aAAa,MAAM;AAC5C,iBAAa,QAAQ,KAAK,OAAO,KAAK,MAAM;AAEtC,UAAA,WAAW,IAAI;AACrB,aAAS,aAAa;AAAA,MACpB,KAAK,KAAK,UAAU,GAAG,CAAC;AAAA,MACxB;AAAA,MACA;AAAA,IAAA;AAGI,UAAA,OAAO,IAAI,SAAS,QAAQ;AAClC,UAAM,OAAwB,EAAE,QAAQ,cAAc,MAAM,UAAU,MAAM;AACvE,SAAA,MAAM,IAAI,MAAM,IAAI;AAClB,WAAA;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,MAAc,UAA4C;AACtE,UAAM,OAAO,KAAK,MAAM,IAAI,IAAI;AAChC,QAAI,CAAC;AAAa,aAAA;AAEd,QAAA;AACF,WAAK,KAAK,OAAO,UAAU,KAAK,YAAY;AACrC,aAAA,MAAM,kBAAkB,KAAK,MAAM;AAAA,aACnC,GAAG;AACH,aAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,OAAO,MAAoB;AACzB,UAAM,OAAO,KAAK,MAAM,IAAI,IAAI;AAChC,QAAI,MAAM;AAER,UAAI,KAAK,YAAY,KAAK,SAAS,SAAS;AAC1C,aAAK,SAAS;MAChB;AAEA,UAAI,KAAK,kBAAkB,qBAAqB,KAAK,OAAO,YAAY;AACtE,aAAK,OAAO,WAAW,YAAY,KAAK,MAAM;AAAA,MAChD;AACK,WAAA,MAAM,OAAO,IAAI;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AAEd,UAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,MAAM;AAC1C,eAAW,QAAQ,OAAO;AACxB,WAAK,OAAO,IAAI;AAAA,IAClB;AACA,SAAK,MAAM;EACb;AACF;;"}
@@ -0,0 +1,89 @@
1
+ class StatsGLCapture {
2
+ constructor(THREE, width = 90, height = 48) {
3
+ this.nodes = /* @__PURE__ */ new Map();
4
+ this.width = 90;
5
+ this.height = 48;
6
+ this.THREE = THREE;
7
+ this.width = width;
8
+ this.height = height;
9
+ }
10
+ /**
11
+ * Update capture dimensions (e.g., on resize)
12
+ */
13
+ resize(width, height) {
14
+ var _a, _b;
15
+ this.width = width;
16
+ this.height = height;
17
+ for (const [name, data] of this.nodes) {
18
+ if (data.canvas instanceof HTMLCanvasElement) {
19
+ data.canvas.width = width;
20
+ data.canvas.height = height;
21
+ } else if (data.canvas instanceof OffscreenCanvas) {
22
+ const newCanvas = new OffscreenCanvas(width, height);
23
+ data.canvas = newCanvas;
24
+ (_b = (_a = data.canvasTarget).setCanvas) == null ? void 0 : _b.call(_a, newCanvas);
25
+ }
26
+ data.canvasTarget.setSize(width, height);
27
+ }
28
+ }
29
+ register(name, targetNode) {
30
+ if (this.nodes.has(name))
31
+ return this.nodes.get(name);
32
+ const { CanvasTarget, NodeMaterial, QuadMesh, NoToneMapping, LinearSRGBColorSpace } = this.THREE;
33
+ const { renderOutput, vec3, vec4 } = this.THREE;
34
+ const canvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(this.width, this.height) : document.createElement("canvas");
35
+ if (canvas instanceof HTMLCanvasElement) {
36
+ canvas.width = this.width;
37
+ canvas.height = this.height;
38
+ }
39
+ const canvasTarget = new CanvasTarget(canvas);
40
+ canvasTarget.setSize(this.width, this.height);
41
+ const material = new NodeMaterial();
42
+ material.outputNode = renderOutput(
43
+ vec4(vec3(targetNode), 1),
44
+ NoToneMapping,
45
+ LinearSRGBColorSpace
46
+ );
47
+ const quad = new QuadMesh(material);
48
+ const data = { canvas, canvasTarget, quad, material, node: targetNode };
49
+ this.nodes.set(name, data);
50
+ return data;
51
+ }
52
+ async capture(name, renderer) {
53
+ const data = this.nodes.get(name);
54
+ if (!data)
55
+ return null;
56
+ try {
57
+ data.quad.render(renderer, data.canvasTarget);
58
+ return await createImageBitmap(data.canvas);
59
+ } catch (e) {
60
+ return null;
61
+ }
62
+ }
63
+ remove(name) {
64
+ const data = this.nodes.get(name);
65
+ if (data) {
66
+ if (data.material && data.material.dispose) {
67
+ data.material.dispose();
68
+ }
69
+ if (data.canvas instanceof HTMLCanvasElement && data.canvas.parentNode) {
70
+ data.canvas.parentNode.removeChild(data.canvas);
71
+ }
72
+ this.nodes.delete(name);
73
+ }
74
+ }
75
+ /**
76
+ * Dispose all capture resources
77
+ */
78
+ dispose() {
79
+ const names = Array.from(this.nodes.keys());
80
+ for (const name of names) {
81
+ this.remove(name);
82
+ }
83
+ this.nodes.clear();
84
+ }
85
+ }
86
+ export {
87
+ StatsGLCapture
88
+ };
89
+ //# sourceMappingURL=statsGLNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statsGLNode.js","sources":["../lib/statsGLNode.ts"],"sourcesContent":null,"names":[],"mappings":"AAqBO,MAAM,eAAe;AAAA,EAM1B,YAAY,OAAY,QAAQ,IAAI,SAAS,IAAI;AALjD,SAAA,4BAA0C;AAClC,SAAA,QAAA;AACC,SAAA,SAAA;AAIP,SAAK,QAAQ;AACb,SAAK,QAAQ;AACb,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,OAAe,QAAsB;AAfvC;AAgBH,SAAK,QAAQ;AACb,SAAK,SAAS;AAGd,eAAW,CAAC,MAAM,IAAI,KAAK,KAAK,OAAO;AACjC,UAAA,KAAK,kBAAkB,mBAAmB;AAC5C,aAAK,OAAO,QAAQ;AACpB,aAAK,OAAO,SAAS;AAAA,MAAA,WACZ,KAAK,kBAAkB,iBAAiB;AAEjD,cAAM,YAAY,IAAI,gBAAgB,OAAO,MAAM;AACnD,aAAK,SAAS;AACT,yBAAA,cAAa,cAAb,4BAAyB;AAAA,MAChC;AACK,WAAA,aAAa,QAAQ,OAAO,MAAM;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,SAAS,MAAc,YAAkC;AACnD,QAAA,KAAK,MAAM,IAAI,IAAI;AAAU,aAAA,KAAK,MAAM,IAAI,IAAI;AAEpD,UAAM,EAAE,cAAc,cAAc,UAAU,eAAe,yBAAyB,KAAK;AAC3F,UAAM,EAAE,cAAc,MAAM,KAAA,IAAS,KAAK;AAE1C,UAAM,SAAS,OAAO,oBAAoB,cACtC,IAAI,gBAAgB,KAAK,OAAO,KAAK,MAAM,IAC3C,SAAS,cAAc,QAAQ;AACnC,QAAI,kBAAkB,mBAAmB;AACvC,aAAO,QAAQ,KAAK;AACpB,aAAO,SAAS,KAAK;AAAA,IACvB;AAEM,UAAA,eAAe,IAAI,aAAa,MAAM;AAC5C,iBAAa,QAAQ,KAAK,OAAO,KAAK,MAAM;AAEtC,UAAA,WAAW,IAAI;AACrB,aAAS,aAAa;AAAA,MACpB,KAAK,KAAK,UAAU,GAAG,CAAC;AAAA,MACxB;AAAA,MACA;AAAA,IAAA;AAGI,UAAA,OAAO,IAAI,SAAS,QAAQ;AAClC,UAAM,OAAwB,EAAE,QAAQ,cAAc,MAAM,UAAU,MAAM;AACvE,SAAA,MAAM,IAAI,MAAM,IAAI;AAClB,WAAA;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,MAAc,UAA4C;AACtE,UAAM,OAAO,KAAK,MAAM,IAAI,IAAI;AAChC,QAAI,CAAC;AAAa,aAAA;AAEd,QAAA;AACF,WAAK,KAAK,OAAO,UAAU,KAAK,YAAY;AACrC,aAAA,MAAM,kBAAkB,KAAK,MAAM;AAAA,aACnC,GAAG;AACH,aAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,OAAO,MAAoB;AACzB,UAAM,OAAO,KAAK,MAAM,IAAI,IAAI;AAChC,QAAI,MAAM;AAER,UAAI,KAAK,YAAY,KAAK,SAAS,SAAS;AAC1C,aAAK,SAAS;MAChB;AAEA,UAAI,KAAK,kBAAkB,qBAAqB,KAAK,OAAO,YAAY;AACtE,aAAK,OAAO,WAAW,YAAY,KAAK,MAAM;AAAA,MAChD;AACK,WAAA,MAAM,OAAO,IAAI;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AAEd,UAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,MAAM;AAC1C,eAAW,QAAQ,OAAO;AACxB,WAAK,OAAO,IAAI;AAAA,IAClB;AACA,SAAK,MAAM;EACb;AACF;"}