export type MiniStatsSizeOptions = { /** * - Width of the graph area. */ width: number; /** * - Height of the graph area. */ height: number; /** * - Spacing between graphs. */ spacing: number; /** * - Whether to show graphs. */ graphs: boolean; /** * - Show category headers and sub-counters. Defaults to true for * sizes after the first, or when graphs are enabled. */ detailed?: boolean; /** * - Show a peak column in the detailed view. Defaults to the graphs setting. */ peak?: boolean; }; export type MiniStatsProcessorOptions = { /** * - Whether to show the graph. */ enabled: boolean; /** * - Watermark - shown as a line on the graph, useful for displaying a * budget. */ watermark: number; }; export type MiniStatsGraphOptions = { /** * - Display name. */ name: string; /** * - Path to data inside Application.stats. */ stats: string[]; /** * - Number of decimal places (defaults to none). */ decimalPlaces?: number; /** * - Units (defaults to ""). */ unitsName?: string; /** * - Multiplier applied to sampled values, for example to convert * bytes to megabytes. */ multiplier?: number; /** * - Watermark - shown as a line on the graph, useful for displaying * a budget. */ watermark?: number; }; export type MiniStatsOptions = { /** * - Sizes of area to render individual graphs in and * spacing between individual graphs. */ sizes: MiniStatsSizeOptions[]; /** * - Index into sizes array for initial setting. */ startSizeIndex: number; /** * - Text update interval and averaging window in ms (500 in the * default options). Each update shows the arithmetic mean and peak of the frame samples collected * since the previous update, then starts a new window. Graph history samples every frame. */ textRefreshRate: number; /** * - Show tracked resource counts in detailed views. */ resourcesEnabled?: boolean; /** * - Initially collapse the Resources section. */ resourcesCollapsed?: boolean; /** * - CPU graph options. */ cpu: MiniStatsProcessorOptions; /** * - GPU graph options. */ gpu: MiniStatsProcessorOptions; /** * - Array of options to render additional graphs based * on stats collected into Application.stats. Counters sourced exclusively from AppStats.user * are displayed in a collapsible User section in the detailed views. Other additional counters * are grouped under Engine, including DrawCalls and Frame. VRAM keeps its own category. */ stats: MiniStatsGraphOptions[]; /** * - Minimum size index at which to show GPU pass timing * graphs. Defaults to 1. */ gpuTimingMinSize?: number; /** * - Minimum size index at which to show CPU sub-timing * graphs (script, anim, physics, render). Defaults to 1. */ cpuTimingMinSize?: number; /** * - Minimum size index at which to show VRAM subcategory * graphs. Defaults to 1. */ vramTimingMinSize?: number; }; /** * @typedef {object} MiniStatsSizeOptions * @property {number} width - Width of the graph area. * @property {number} height - Height of the graph area. * @property {number} spacing - Spacing between graphs. * @property {boolean} graphs - Whether to show graphs. * @property {boolean} [detailed] - Show category headers and sub-counters. Defaults to true for * sizes after the first, or when graphs are enabled. * @property {boolean} [peak] - Show a peak column in the detailed view. Defaults to the graphs setting. */ /** * @typedef {object} MiniStatsProcessorOptions * @property {boolean} enabled - Whether to show the graph. * @property {number} watermark - Watermark - shown as a line on the graph, useful for displaying a * budget. */ /** * @typedef {object} MiniStatsGraphOptions * @property {string} name - Display name. * @property {string[]} stats - Path to data inside Application.stats. * @property {number} [decimalPlaces] - Number of decimal places (defaults to none). * @property {string} [unitsName] - Units (defaults to ""). * @property {number} [multiplier=1] - Multiplier applied to sampled values, for example to convert * bytes to megabytes. * @property {number} [watermark] - Watermark - shown as a line on the graph, useful for displaying * a budget. */ /** * @typedef {object} MiniStatsOptions * @property {MiniStatsSizeOptions[]} sizes - Sizes of area to render individual graphs in and * spacing between individual graphs. * @property {number} startSizeIndex - Index into sizes array for initial setting. * @property {number} textRefreshRate - Text update interval and averaging window in ms (500 in the * default options). Each update shows the arithmetic mean and peak of the frame samples collected * since the previous update, then starts a new window. Graph history samples every frame. * @property {boolean} [resourcesEnabled=true] - Show tracked resource counts in detailed views. * @property {boolean} [resourcesCollapsed=true] - Initially collapse the Resources section. * @property {MiniStatsProcessorOptions} cpu - CPU graph options. * @property {MiniStatsProcessorOptions} gpu - GPU graph options. * @property {MiniStatsGraphOptions[]} stats - Array of options to render additional graphs based * on stats collected into Application.stats. Counters sourced exclusively from AppStats.user * are displayed in a collapsible User section in the detailed views. Other additional counters * are grouped under Engine, including DrawCalls and Frame. VRAM keeps its own category. * @property {number} [gpuTimingMinSize] - Minimum size index at which to show GPU pass timing * graphs. Defaults to 1. * @property {number} [cpuTimingMinSize] - Minimum size index at which to show CPU sub-timing * graphs (script, anim, physics, render). Defaults to 1. * @property {number} [vramTimingMinSize] - Minimum size index at which to show VRAM subcategory * graphs. Defaults to 1. */ /** * MiniStats is a small graphical overlay that displays realtime performance metrics. By default, * it shows CPU and GPU durations, frame intervals, draw call count and estimated GPU resource * memory. It can also display additional counters from {@link AppBase#stats}. * * The default CPU timings, including render time, draw call count and memory estimates are * available in all builds. GPU timing requires device support and is enabled when MiniStats * creates its GPU timer. Some additional counters, such as {@link AppStats#primitiveCount}, * require a debug or profiler build. See {@link AppStats} for measurement scope and availability. * In the detailed views, click a category heading to collapse or expand its sub-counters. * Click elsewhere in the overlay to change size. Collapsing a category preserves its sampling * and graph history. Resources is enabled and collapsed by default, and displays current counts * of existing tracked resources, including internal resources, in detailed views. Resource counts * refresh at textRefreshRate while visible, including their sum in the collapsed heading; they * have no average or peak. In graph views, resource histories use the latest sampled counts * and scale to accommodate the highest count seen. * * @category Debug */ export class MiniStats { /** * Predefined stat groups included via {@link MiniStats.getDefaultOptions}. * * @type {Object} * @ignore */ static statPresets: { [x: string]: MiniStatsGraphOptions[]; }; /** * Returns options for three sizes: compact core counters, grouped averages, and grouped * averages and peaks with graph history. Engine counters appear first, starting with draw * calls and frame time, followed by User, CPU, GPU and VRAM. In the detailed views, Engine * and User have collapsible headings, omitted when empty. * * @param {string[]} [extraStats] - Presets to include: 'gsplats' or 'gsplatsCopy'. * @returns {MiniStatsOptions} The default options for MiniStats. * @example * const options = MiniStats.getDefaultOptions(['gsplats']); * options.sizes[2].width = 280; * const miniStats = new MiniStats(app, options); */ static getDefaultOptions(extraStats?: string[]): MiniStatsOptions; /** * Create a new MiniStats instance. * * @param {AppBase} app - The application. * @param {MiniStatsOptions} [options] - Options for the MiniStats instance. * @example * const miniStats = new MiniStats(app); */ constructor(app: AppBase, options?: MiniStatsOptions); app: AppBase; device: GraphicsDevice; sizes: { /** * - Width of the graph area. */ width: number; /** * - Height of the graph area. */ height: number; /** * - Spacing between graphs. */ spacing: number; /** * - Whether to show graphs. */ graphs: boolean; /** * - Show category headers and sub-counters. Defaults to true for * sizes after the first, or when graphs are enabled. */ detailed?: boolean; /** * - Show a peak column in the detailed view. Defaults to the graphs setting. */ peak?: boolean; }[]; /** @type {Graph[]} @private */ private graphs; graphRows: Map; freeRows: any[]; nextRowIndex: number; gpuPassGraphs: Map; cpuGraphs: Map; vramGraphs: Map; /** @private */ private collapsedGroups; /** @private */ private _resourcesEnabled; /** @private */ private _resourceElapsed; /** @type {Map} @private */ private _resourceCounts; /** @type {Map} @private */ private _resourceGraphs; gpuTimingMinSize: number; cpuTimingMinSize: number; vramTimingMinSize: number; textRefreshRate: number; _averageLabel: string; frameIndex: number; _enabled: boolean; _showGraphs: boolean; _destroyed: boolean; _geometryDirty: boolean; _layoutDirty: boolean; _scroll: number; _maxScroll: number; _overallHeight: number; clr: number[]; wordAtlas: WordAtlas; render2d: Render2d; drawLayer: import("../../index.js").Layer; div: HTMLDivElement; /** @type {number} @ignore */ set opacity(value: number); /** @type {number} @ignore */ get opacity(): number; /** * Selects the corresponding entry in the sizes array. * * @type {number} * @ignore */ set activeSizeIndex(value: number); /** @type {number} @ignore */ get activeSizeIndex(): number; /** * Destroy the MiniStats instance and release its event listeners, textures and mesh. * * @example * miniStats.destroy(); */ destroy(): void; _activeSizeIndex: number; _detailed: boolean; _showPeak: boolean; gspacing: number; /** @type {number} @ignore */ get overallHeight(): number; /** * Whether the overlay and its counter sampling are enabled. Defaults to true. * * @type {boolean} */ set enabled(value: boolean); /** @type {boolean} */ get enabled(): boolean; /** * Whether the Resources section is shown in detailed views. Defaults to true. Counts use * existing engine resource tracking, including internal resources, and are not a complete * inventory of native GPU objects. Uniform buffers include pooled GPU backing buffers, but * exclude staging buffers and individual transient allocations. Render targets are counted * once initialized; WebGPU pipelines count cached entries. * * @type {boolean} * @example * miniStats.resourcesEnabled = false; */ set resourcesEnabled(value: boolean); /** @type {boolean} */ get resourcesEnabled(): boolean; /** * Whether the Resources section is collapsed in detailed views. Defaults to true. Current * counts are sampled at the configured textRefreshRate while the section is visible and * MiniStats is enabled. The collapsed heading shows their sum to help spot resource growth. * Changing size preserves the collapsed state. * * @type {boolean} * @example * miniStats.resourcesCollapsed = false; */ set resourcesCollapsed(value: boolean); /** @type {boolean} */ get resourcesCollapsed(): boolean; /** * Whether the Engine section is collapsed in detailed views. Defaults to false. * Collapsing hides its counters without stopping sampling or discarding history. The state * is preserved when changing sizes and updated when the heading is clicked. * * @type {boolean} * @example * miniStats.engineCollapsed = true; */ set engineCollapsed(value: boolean); /** @type {boolean} */ get engineCollapsed(): boolean; /** * Whether the User section is collapsed in detailed views. Defaults to false. * Collapsing hides its counters without stopping sampling or discarding history. The state * is preserved when changing sizes and updated when the heading is clicked. * * @type {boolean} * @example * miniStats.userCollapsed = true; */ set userCollapsed(value: boolean); /** @type {boolean} */ get userCollapsed(): boolean; /** * Whether the CPU section is collapsed in detailed views. Defaults to false. * Collapsing hides its sub-counters while keeping the total visible, without stopping sampling * or discarding history. The state is preserved when changing sizes and updated when the * heading is clicked. * * @type {boolean} * @example * miniStats.cpuCollapsed = true; */ set cpuCollapsed(value: boolean); /** @type {boolean} */ get cpuCollapsed(): boolean; /** * Whether the GPU section is collapsed in detailed views. Defaults to false. * Collapsing hides its sub-counters while keeping the total visible, without stopping sampling * or discarding history. The state is preserved when changing sizes and updated when the * heading is clicked. * * @type {boolean} * @example * miniStats.gpuCollapsed = true; */ set gpuCollapsed(value: boolean); /** @type {boolean} */ get gpuCollapsed(): boolean; /** * Whether the VRAM section is collapsed in detailed views. Defaults to false. * Collapsing hides its sub-counters while keeping the total visible, without stopping sampling * or discarding history. The state is preserved when changing sizes and updated when the * heading is clicked. * * @type {boolean} * @example * miniStats.vramCollapsed = true; */ set vramCollapsed(value: boolean); /** @type {boolean} */ get vramCollapsed(): boolean; /** * @private * @param {number} group - Section group. * @param {boolean} collapsed - Whether to hide the section's counters. */ private setGroupCollapsed; /** * @private * @param {MouseEvent} event - Click in the overlay. */ private handleClick; /** * @private * @param {AppBase} app - The application. * @param {GraphicsDevice} device - The graphics device. * @param {MiniStatsOptions} options - Counter configuration. */ private initGraphs; cpuGraph: Graph; gpuGraph: Graph; vramGraph: Graph; /** @type {Graph} @private */ private _resourceGraph; texture: Texture; /** * @private * @param {number} width - Panel width in CSS pixels. * @param {number} height - Row height in CSS pixels. * @param {boolean} showGraphs - Whether to collect and display history. */ private resize; width: number; height: number; /** * @private * @param {Graph} graph - The row to check. * @returns {boolean} Whether the row participates in the current layout. */ private isGraphVisible; /** @private */ private updateDiv; _panelWidth: number; _panelHeight: number; /** * @private * @param {number} delta - Scroll distance in CSS pixels. */ private scroll; /** * @private * @param {number} ms - Elapsed frame time in milliseconds. */ private update; /** @private */ private render; /** @private */ private rebuildGeometry; /** @private */ private loseContext; /** * @private * @param {Graph} graph - The graph receiving a persistent history row. * @returns {number} Allocated row index. */ private allocateRow; /** * @private * @param {number} requiredRows - Minimum number of texture rows. */ private ensureTextureHeight; /** * @private * @param {Graph} graph - The sub-counter to remove. */ private removeGraph; /** * @private * @param {Map} map - Sub-counters to remove. */ private clearSubGraphs; /** * @private * @param {Map} map - Sub-counter lookup. * @param {Graph} parent - The category total. * @param {string} name - The literal stat key. * @param {number} value - Current sampled value. * @param {string} prefix - The stats object containing the key. * @param {boolean} delayed - Wait for a positive sample before adding the row. */ private updateSubStat; /** * @private * @param {number} value - Pass duration in milliseconds. * @param {string} name - Literal GPU pass name. */ private updateGpuPass; /** @private */ private postRender; } import type { AppBase } from '../../framework/app-base.js'; import type { GraphicsDevice } from '../../platform/graphics/graphics-device.js'; import { WordAtlas } from './word-atlas.js'; import { Render2d } from './render2d.js'; import { Graph } from './graph.js'; import { Texture } from '../../platform/graphics/texture.js';