summit/frontend/node_modules/stats-gl/dist/main.js

329 lines
10 KiB
JavaScript

import { Panel } from "./panel.js";
const _Stats = class _Stats2 {
constructor({
trackGPU = false,
logsPerSecond = 30,
samplesLog = 60,
samplesGraph = 10,
precision = 2,
minimal = false,
horizontal = true,
mode = 0
} = {}) {
this.gl = null;
this.ext = null;
this.activeQuery = null;
this.gpuQueries = [];
this.threeRendererPatched = false;
this.frames = 0;
this.renderCount = 0;
this.isRunningCPUProfiling = false;
this.totalCpuDuration = 0;
this.totalGpuDuration = 0;
this.totalGpuDurationCompute = 0;
this.totalFps = 0;
this.gpuPanel = null;
this.gpuPanelCompute = null;
this.averageFps = { logs: [], graph: [] };
this.averageCpu = { logs: [], graph: [] };
this.averageGpu = { logs: [], graph: [] };
this.averageGpuCompute = { logs: [], graph: [] };
this.handleClick = (event) => {
event.preventDefault();
this.showPanel(++this.mode % this.dom.children.length);
};
this.handleResize = () => {
this.resizePanel(this.fpsPanel, 0);
this.resizePanel(this.msPanel, 1);
if (this.gpuPanel)
this.resizePanel(this.gpuPanel, 2);
if (this.gpuPanelCompute)
this.resizePanel(this.gpuPanelCompute, 3);
};
this.mode = mode;
this.horizontal = horizontal;
this.minimal = minimal;
this.trackGPU = trackGPU;
this.samplesLog = samplesLog;
this.samplesGraph = samplesGraph;
this.precision = precision;
this.logsPerSecond = logsPerSecond;
this.dom = document.createElement("div");
this.initializeDOM();
this.beginTime = performance.now();
this.prevTime = this.beginTime;
this.prevCpuTime = this.beginTime;
this.fpsPanel = this.addPanel(new _Stats2.Panel("FPS", "#0ff", "#002"), 0);
this.msPanel = this.addPanel(new _Stats2.Panel("CPU", "#0f0", "#020"), 1);
this.setupEventListeners();
}
initializeDOM() {
this.dom.style.cssText = `
position: fixed;
top: 0;
left: 0;
opacity: 0.9;
z-index: 10000;
${this.minimal ? "cursor: pointer;" : ""}
`;
}
setupEventListeners() {
if (this.minimal) {
this.dom.addEventListener("click", this.handleClick);
this.showPanel(this.mode);
} else {
window.addEventListener("resize", this.handleResize);
}
}
async init(canvasOrGL) {
if (!canvasOrGL) {
console.error('Stats: The "canvas" parameter is undefined.');
return;
}
if (this.handleThreeRenderer(canvasOrGL))
return;
if (await this.handleWebGPURenderer(canvasOrGL))
return;
if (!this.initializeWebGL(canvasOrGL))
return;
}
handleThreeRenderer(renderer) {
if (renderer.isWebGLRenderer && !this.threeRendererPatched) {
this.patchThreeRenderer(renderer);
this.gl = renderer.getContext();
if (this.trackGPU) {
this.initializeGPUTracking();
}
return true;
}
return false;
}
async handleWebGPURenderer(renderer) {
if (renderer.isWebGPURenderer) {
if (this.trackGPU) {
renderer.backend.trackTimestamp = true;
if (await renderer.hasFeatureAsync("timestamp-query")) {
this.initializeWebGPUPanels();
}
}
this.info = renderer.info;
return true;
}
return false;
}
initializeWebGPUPanels() {
this.gpuPanel = this.addPanel(new _Stats2.Panel("GPU", "#ff0", "#220"), 2);
this.gpuPanelCompute = this.addPanel(
new _Stats2.Panel("CPT", "#e1e1e1", "#212121"),
3
);
}
initializeWebGL(canvasOrGL) {
if (canvasOrGL instanceof WebGL2RenderingContext) {
this.gl = canvasOrGL;
} else if (canvasOrGL instanceof HTMLCanvasElement || canvasOrGL instanceof OffscreenCanvas) {
this.gl = canvasOrGL.getContext("webgl2");
if (!this.gl) {
console.error("Stats: Unable to obtain WebGL2 context.");
return false;
}
} else {
console.error(
"Stats: Invalid input type. Expected WebGL2RenderingContext, HTMLCanvasElement, or OffscreenCanvas."
);
return false;
}
return true;
}
initializeGPUTracking() {
if (this.gl) {
this.ext = this.gl.getExtension("EXT_disjoint_timer_query_webgl2");
if (this.ext) {
this.gpuPanel = this.addPanel(new _Stats2.Panel("GPU", "#ff0", "#220"), 2);
}
}
}
begin() {
if (!this.isRunningCPUProfiling) {
this.beginProfiling("cpu-started");
}
if (!this.gl || !this.ext)
return;
if (this.activeQuery) {
this.gl.endQuery(this.ext.TIME_ELAPSED_EXT);
}
this.activeQuery = this.gl.createQuery();
if (this.activeQuery) {
this.gl.beginQuery(this.ext.TIME_ELAPSED_EXT, this.activeQuery);
}
}
end() {
this.renderCount++;
if (this.gl && this.ext && this.activeQuery) {
this.gl.endQuery(this.ext.TIME_ELAPSED_EXT);
this.gpuQueries.push({ query: this.activeQuery });
this.activeQuery = null;
}
}
update() {
if (!this.info) {
this.processGpuQueries();
} else {
this.processWebGPUTimestamps();
}
this.endProfiling("cpu-started", "cpu-finished", "cpu-duration");
this.updateAverages();
this.resetCounters();
}
processWebGPUTimestamps() {
this.totalGpuDuration = this.info.render.timestamp;
this.totalGpuDurationCompute = this.info.compute.timestamp;
this.addToAverage(this.totalGpuDurationCompute, this.averageGpuCompute);
}
updateAverages() {
this.addToAverage(this.totalCpuDuration, this.averageCpu);
this.addToAverage(this.totalGpuDuration, this.averageGpu);
}
resetCounters() {
this.renderCount = 0;
if (this.totalCpuDuration === 0) {
this.beginProfiling("cpu-started");
}
this.totalCpuDuration = 0;
this.totalFps = 0;
this.beginTime = this.endInternal();
}
resizePanel(panel, offset) {
panel.canvas.style.position = "absolute";
if (this.minimal) {
panel.canvas.style.display = "none";
} else {
panel.canvas.style.display = "block";
if (this.horizontal) {
panel.canvas.style.top = "0px";
panel.canvas.style.left = offset * panel.WIDTH / panel.PR + "px";
} else {
panel.canvas.style.left = "0px";
panel.canvas.style.top = offset * panel.HEIGHT / panel.PR + "px";
}
}
}
addPanel(panel, offset) {
if (panel.canvas) {
this.dom.appendChild(panel.canvas);
this.resizePanel(panel, offset);
}
return panel;
}
showPanel(id) {
for (let i = 0; i < this.dom.children.length; i++) {
const child = this.dom.children[i];
child.style.display = i === id ? "block" : "none";
}
this.mode = id;
}
processGpuQueries() {
if (!this.gl || !this.ext)
return;
this.totalGpuDuration = 0;
this.gpuQueries.forEach((queryInfo, index) => {
if (this.gl) {
const available = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT_AVAILABLE);
const disjoint = this.gl.getParameter(this.ext.GPU_DISJOINT_EXT);
if (available && !disjoint) {
const elapsed = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT);
const duration = elapsed * 1e-6;
this.totalGpuDuration += duration;
this.gl.deleteQuery(queryInfo.query);
this.gpuQueries.splice(index, 1);
}
}
});
}
endInternal() {
this.frames++;
const time = (performance || Date).now();
const elapsed = time - this.prevTime;
if (time >= this.prevCpuTime + 1e3 / this.logsPerSecond) {
const fps = Math.round(this.frames * 1e3 / elapsed);
this.addToAverage(fps, this.averageFps);
this.updatePanel(this.fpsPanel, this.averageFps, 0);
this.updatePanel(this.msPanel, this.averageCpu, this.precision);
this.updatePanel(this.gpuPanel, this.averageGpu, this.precision);
if (this.gpuPanelCompute) {
this.updatePanel(this.gpuPanelCompute, this.averageGpuCompute);
}
this.frames = 0;
this.prevCpuTime = time;
this.prevTime = time;
}
return time;
}
addToAverage(value, averageArray) {
averageArray.logs.push(value);
if (averageArray.logs.length > this.samplesLog) {
averageArray.logs.shift();
}
averageArray.graph.push(value);
if (averageArray.graph.length > this.samplesGraph) {
averageArray.graph.shift();
}
}
beginProfiling(marker) {
if (window.performance) {
window.performance.mark(marker);
this.isRunningCPUProfiling = true;
}
}
endProfiling(startMarker, endMarker, measureName) {
if (window.performance && endMarker && this.isRunningCPUProfiling) {
window.performance.mark(endMarker);
const cpuMeasure = performance.measure(measureName, startMarker, endMarker);
this.totalCpuDuration += cpuMeasure.duration;
this.isRunningCPUProfiling = false;
}
}
updatePanel(panel, averageArray, precision = 2) {
if (averageArray.logs.length > 0) {
let sumLog = 0;
let max = 0.01;
for (let i = 0; i < averageArray.logs.length; i++) {
sumLog += averageArray.logs[i];
if (averageArray.logs[i] > max) {
max = averageArray.logs[i];
}
}
let sumGraph = 0;
let maxGraph = 0.01;
for (let i = 0; i < averageArray.graph.length; i++) {
sumGraph += averageArray.graph[i];
if (averageArray.graph[i] > maxGraph) {
maxGraph = averageArray.graph[i];
}
}
if (panel) {
panel.update(sumLog / Math.min(averageArray.logs.length, this.samplesLog), sumGraph / Math.min(averageArray.graph.length, this.samplesGraph), max, maxGraph, precision);
}
}
}
get domElement() {
return this.dom;
}
patchThreeRenderer(renderer) {
const originalRenderMethod = renderer.render;
const statsInstance = this;
renderer.render = function(scene, camera) {
statsInstance.begin();
originalRenderMethod.call(this, scene, camera);
statsInstance.end();
};
this.threeRendererPatched = true;
}
};
_Stats.Panel = Panel;
let Stats = _Stats;
export {
Stats as default
};
//# sourceMappingURL=main.js.map