r3f-performance 0.1.0

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.
Files changed (39) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +84 -0
  3. package/dist/components/Graph.d.ts +10 -0
  4. package/dist/components/Graph.d.ts.map +1 -0
  5. package/dist/components/GraphStats.d.ts +9 -0
  6. package/dist/components/GraphStats.d.ts.map +1 -0
  7. package/dist/components/HtmlMinimal.d.ts +10 -0
  8. package/dist/components/HtmlMinimal.d.ts.map +1 -0
  9. package/dist/components/PerfHeadless.d.ts +13 -0
  10. package/dist/components/PerfHeadless.d.ts.map +1 -0
  11. package/dist/components/PerfMonitor.d.ts +12 -0
  12. package/dist/components/PerfMonitor.d.ts.map +1 -0
  13. package/dist/components/Program.d.ts +4 -0
  14. package/dist/components/Program.d.ts.map +1 -0
  15. package/dist/events/react.d.ts +8 -0
  16. package/dist/events/react.d.ts.map +1 -0
  17. package/dist/events/types.d.ts +19 -0
  18. package/dist/events/types.d.ts.map +1 -0
  19. package/dist/events/vanilla.d.ts +14 -0
  20. package/dist/events/vanilla.d.ts.map +1 -0
  21. package/dist/helpers/countGeoDrawCalls.d.ts +3 -0
  22. package/dist/helpers/countGeoDrawCalls.d.ts.map +1 -0
  23. package/dist/helpers/estimateBytesUsed.d.ts +7 -0
  24. package/dist/helpers/estimateBytesUsed.d.ts.map +1 -0
  25. package/dist/helpers/estimateMemory.d.ts +7 -0
  26. package/dist/helpers/estimateMemory.d.ts.map +1 -0
  27. package/dist/helpers/helpers.d.ts +2 -0
  28. package/dist/helpers/helpers.d.ts.map +1 -0
  29. package/dist/index.cjs +2 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.mjs +1386 -0
  33. package/dist/internal.d.ts +99 -0
  34. package/dist/internal.d.ts.map +1 -0
  35. package/dist/store.d.ts +90 -0
  36. package/dist/store.d.ts.map +1 -0
  37. package/dist/types.d.ts +33 -0
  38. package/dist/types.d.ts.map +1 -0
  39. package/package.json +44 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,1386 @@
1
+ (function(){"use strict";try{if(typeof document<"u"){var i=document.createElement("style");i.appendChild(document.createTextNode('._perfS_ans5i_1{position:fixed;z-index:9999;font-family:Roboto Mono,-apple-system,BlinkMacSystemFont,monospace;background-color:#000c;color:#fff;padding:6px 0 6px 6px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;user-select:none;display:flex;flex-direction:column}._containerHeight_ans5i_16{min-height:110px}._topLeft_ans5i_21{top:0;left:0}._topRight_ans5i_22{top:0;right:0}._bottomLeft_ans5i_23{bottom:0;left:0}._bottomRight_ans5i_24{bottom:0;right:0}._minimal_ans5i_26{background-color:#242424d9}._perfIContainer_ans5i_30{display:flex;flex-wrap:wrap;gap:5px 10px}._perfIContainer_ans5i_30{display:flex;flex-wrap:wrap;gap:6px 12px;width:100%;padding-right:6px;box-sizing:border-box}._perfI_ans5i_30{display:flex;flex-direction:column;justify-content:center;align-items:flex-start;width:55px;height:auto;position:relative;margin-right:4px}._perfI_ans5i_30 small{font-size:12px;color:#e0e0e0;font-weight:500;padding-left:0;margin-bottom:2px;white-space:nowrap}._perfB_ans5i_69{position:relative;bottom:auto;right:auto;text-align:left;font-size:8px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;color:#65c5bc;width:100%;opacity:.9}._toggleContainer_ans5i_83{display:flex;justify-content:flex-end;padding-right:4px}._toggle_ans5i_83{cursor:pointer;font-size:10px;background-color:#ffffff1a;color:#fff;padding:4px 8px;border-radius:2px;margin-left:4px;transition:all .2s}._toggle_ans5i_83:hover{background-color:#fff3;color:#fff}._activeTab_ans5i_105{background-color:#65c5bc4d;color:#fff}._containerScroll_ans5i_110{max-height:50vh;overflow-y:auto}._programGeo_ans5i_115{margin-bottom:2px;pointer-events:auto}._programHeader_ans5i_120{display:flex;align-items:center;justify-content:space-between;background-color:#ffffff0f;padding:6px 8px;border-radius:4px;cursor:pointer;transition:background-color .2s;min-height:24px;border:1px solid transparent}._programHeader_ans5i_120:hover{background-color:#ffffff1a;border-color:#ffffff1a}._programHeader_ans5i_120 *{cursor:pointer!important}._programHeader_ans5i_120 small{font-size:9px}._programHeader_ans5i_120>b{margin-right:4px;cursor:pointer}._headerLeft_ans5i_149{display:flex;align-items:center;flex:1;overflow:hidden}._programTitle_ans5i_156{font-weight:700;font-size:12px;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-right:10px}._toggleArrow_ans5i_166{font-size:10px;margin-right:8px;color:#888;width:12px;text-align:center;transition:transform .2s}._toggleVisible_ans5i_175{pointer-events:auto;justify-content:center;cursor:pointer;font-size:12px;background-color:#292b2d;width:auto;margin:0;color:#919191;text-align:center;display:inline-block;vertical-align:middle;padding:4px 6px}._toggleVisible_ans5i_175:hover{background-color:#1f1f1f}._toggleVisible_ans5i_175 svg{width:12px;height:12px;float:left}._programConsole_ans5i_200{font-weight:700;letter-spacing:.02em;background-color:#292b2d;color:#d3d3d3;overflow:hidden;text-overflow:ellipsis;cursor:pointer;display:block;font-size:11px;padding:5px;margin:4px auto;border:none;width:100%;text-align:center}._programsContainer_ans5i_218{margin-top:0}._headerRight_ans5i_222{display:flex;align-items:center;gap:6px}._metricBadge_ans5i_228{display:flex;align-items:center;background-color:#0000004d;padding:2px 6px;border-radius:3px;font-size:10px;color:#aaa;white-space:nowrap}._metricBadge_ans5i_228 b{color:#4fd1c5;margin-right:4px;font-weight:600;font-size:11px}._programsULHeader_ans5i_246{display:flex;position:relative;font-weight:700;color:#fff;line-height:14px;margin:4px 0}._programsULHeader_ans5i_246 svg{margin-right:4px;display:inline-block}._programsUL_ans5i_246{display:block;position:relative;padding-left:10px;margin:6px;list-style:none}._programsUL_ans5i_246 img{max-height:60px;max-width:100%;margin:6px auto;display:block}._programsUL_ans5i_246:after{content:"";position:absolute;left:0;top:0;width:1px;height:100%;background-color:gray;transform:translate(-50%);max-height:50vh;overflow-y:auto}._programsUL_ans5i_246 li{border-bottom:1px solid #313131;display:block;padding:4px;margin:0;line-height:1}._programsUL_ans5i_246 b{font-weight:700}._programsUL_ans5i_246 small{text-align:revert;letter-spacing:1px;font-size:10px;font-weight:500;margin-left:2px;color:#65c5bc}._programsGeoLi_ans5i_309{display:flex!important;height:auto!important}._programsGeoLi_ans5i_309 span{display:block;position:relative}._programsGeoLi_ans5i_309 b{padding-left:12px}._graph_ans5i_324{width:100%;height:66px;overflow:hidden;position:absolute;pointer-events:none;display:flex;top:0;left:0;justify-content:center;z-index:0}._graphpc_ans5i_336{text-align:center;font-weight:700;font-size:12px;line-height:12px;display:flex;justify-content:center;align-items:center;vertical-align:middle;color:#f1f1f1;padding:7px;width:100%;background-color:#242425cc;z-index:1;position:absolute;height:100%}._visibilityBtn_ans5i_354{display:flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:3px;margin-left:4px;color:#666;background:transparent;transition:all .2s}._visibilityBtn_ans5i_354:hover{background-color:#fff3;color:#fff}._visibilityBtn_ans5i_354._active_ans5i_105{color:#fff}')),document.head.appendChild(i)}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
2
+ import { jsx as n, jsxs as y, Fragment as z } from "react/jsx-runtime";
3
+ import { forwardRef as Te, useRef as I, useLayoutEffect as oe, useMemo as Y, useEffect as U, useState as O } from "react";
4
+ import { useThree as we, addEffect as Ae, addAfterEffect as Se, addTail as Ne, Canvas as Re, useFrame as _e } from "@react-three/fiber";
5
+ import { createRoot as Fe } from "react-dom/client";
6
+ import * as E from "three";
7
+ import { MathUtils as Pe } from "three";
8
+ import { createWithEqualityFn as Ue } from "zustand/traditional";
9
+ import { shallow as Ge } from "zustand/shallow";
10
+ import Be from "eventemitter3";
11
+ const be = Te(
12
+ ({ portal: r, className: e, children: t, name: i, ...m }, o) => {
13
+ const a = we((d) => d.gl), c = I(null), v = I(null), s = (r == null ? void 0 : r.current) != null ? r.current : a.domElement.parentNode;
14
+ return oe(() => {
15
+ if (!c.current || !s) return;
16
+ const d = document.createElement("div"), f = v.current = Fe(d);
17
+ return s.appendChild(d), () => {
18
+ f.unmount(), v.current = null, s.removeChild(d);
19
+ };
20
+ }, [s]), oe(() => {
21
+ const d = v.current;
22
+ d && d.render(
23
+ /* @__PURE__ */ n("div", { ref: o, className: e, children: t })
24
+ );
25
+ }), /* @__PURE__ */ n("group", { name: i, ...m, ref: c });
26
+ }
27
+ );
28
+ be.displayName = "HtmlMinimal";
29
+ const ee = Ue((r, e) => {
30
+ function t() {
31
+ var w;
32
+ const { accumulated: i, startTime: m, infos: o, estimatedMemory: a } = e(), c = (w = e().log) == null ? void 0 : w.maxMemory, { totalFrames: v, log: s, gl: d, max: f } = i, p = {
33
+ calls: d.calls / v,
34
+ triangles: d.triangles / v,
35
+ points: d.points / v,
36
+ lines: d.lines / v
37
+ }, h = {
38
+ gpu: s.gpu / v,
39
+ cpu: s.cpu / v,
40
+ mem: s.mem / v,
41
+ fps: s.fps / v
42
+ };
43
+ return {
44
+ sessionTime: (window.performance.now() - m) / 1e3,
45
+ infos: o,
46
+ memory: a,
47
+ // Thêm memory vào report
48
+ log: h,
49
+ gl: p,
50
+ max: f,
51
+ maxMemory: c,
52
+ totalFrames: v
53
+ };
54
+ }
55
+ return {
56
+ log: null,
57
+ paused: !1,
58
+ triggerProgramsUpdate: 0,
59
+ startTime: 0,
60
+ customData: 0,
61
+ fpsLimit: 60,
62
+ overclockingFps: !1,
63
+ // --- ADD: Khởi tạo giá trị mặc định ---
64
+ estimatedMemory: {
65
+ vram: 0,
66
+ tex: 0,
67
+ geo: 0,
68
+ ram: 0
69
+ },
70
+ // -------------------------------------
71
+ accumulated: {
72
+ totalFrames: 0,
73
+ gl: {
74
+ calls: 0,
75
+ triangles: 0,
76
+ points: 0,
77
+ lines: 0,
78
+ counts: 0
79
+ },
80
+ log: {
81
+ gpu: 0,
82
+ cpu: 0,
83
+ mem: 0,
84
+ fps: 0
85
+ },
86
+ max: {
87
+ gl: {
88
+ calls: 0,
89
+ triangles: 0,
90
+ points: 0,
91
+ lines: 0,
92
+ counts: 0
93
+ },
94
+ log: {
95
+ gpu: 0,
96
+ cpu: 0,
97
+ mem: 0,
98
+ fps: 0
99
+ }
100
+ }
101
+ },
102
+ chart: {
103
+ data: {
104
+ fps: [],
105
+ cpu: [],
106
+ gpu: [],
107
+ mem: []
108
+ },
109
+ circularId: 0
110
+ },
111
+ gl: void 0,
112
+ objectWithMaterials: null,
113
+ scene: void 0,
114
+ programs: /* @__PURE__ */ new Map(),
115
+ sceneLength: void 0,
116
+ tab: "infos",
117
+ getReport: t
118
+ };
119
+ }), L = (r) => ee(r, Ge);
120
+ Object.assign(L, ee);
121
+ const { getState: R, setState: M } = ee, S = {
122
+ value: 0,
123
+ fpsLimit: 60,
124
+ isOverLimit: 0
125
+ }, H = (r) => (r == null ? void 0 : r.reduce((e, t) => e + t, 0)) / r.length;
126
+ class De {
127
+ constructor(e = {}) {
128
+ this.names = [""], this.finished = [], this.paused = !1, this.overClock = !1, this.queryHasResult = !1, this.queryCreated = !1, this.isWebGL2 = !0, this.memAccums = [], this.gpuAccums = [], this.activeAccums = [], this.logsAccums = {
129
+ mem: [],
130
+ gpu: [],
131
+ cpu: [],
132
+ fps: [],
133
+ fpsFixed: []
134
+ }, this.fpsChart = [], this.gpuChart = [], this.cpuChart = [], this.memChart = [], this.paramLogger = () => {
135
+ }, this.glFinish = () => {
136
+ }, this.chartLogger = () => {
137
+ }, this.chartLen = 60, this.logsPerSecond = 10, this.maxMemory = 1500, this.chartHz = 10, this.startCpuProfiling = !1, this.lastCalculateFixed = 0, this.chartFrame = 0, this.gpuTimeProcess = 0, this.chartTime = 0, this.activeQueries = 0, this.circularId = 0, this.detected = 0, this.frameId = 0, this.rafId = 0, this.idleCbId = 0, this.checkQueryId = 0, this.uuid = void 0, this.currentCpu = 0, this.currentMem = 0, this.paramFrame = 0, this.paramTime = 0, this.now = () => {
138
+ }, this.t0 = 0, window.GLPerf = window.GLPerf || {}, Object.assign(this, e), this.fpsChart = new Array(this.chartLen).fill(0), this.gpuChart = new Array(this.chartLen).fill(0), this.cpuChart = new Array(this.chartLen).fill(0), this.memChart = new Array(this.chartLen).fill(0), this.now = () => window.performance && window.performance.now ? window.performance.now() : Date.now(), this.initGpu(), this.is120hz();
139
+ }
140
+ initGpu() {
141
+ this.uuid = Pe.generateUUID(), this.gl && (this.isWebGL2 = !0, this.extension || (this.extension = this.gl.getExtension(
142
+ "EXT_disjoint_timer_query_webgl2"
143
+ )), this.extension === null && (this.isWebGL2 = !1));
144
+ }
145
+ /**
146
+ * 120hz device detection
147
+ */
148
+ is120hz() {
149
+ let e = 0;
150
+ const t = (i) => {
151
+ ++e < 20 ? this.rafId = window.requestAnimationFrame(t) : (this.detected = Math.ceil(1e3 * e / (i - this.t0) / 70), window.cancelAnimationFrame(this.rafId)), this.t0 || (this.t0 = i);
152
+ };
153
+ this.rafId = window.requestAnimationFrame(t);
154
+ }
155
+ /**
156
+ * Explicit UI add
157
+ * @param { string | undefined } name
158
+ */
159
+ addUI(e) {
160
+ this.names.indexOf(e) === -1 && (this.names.push(e), this.gpuAccums.push(0), this.activeAccums.push(!1));
161
+ }
162
+ nextFps(e) {
163
+ const t = 16.666666666666668, i = t - e.timeRemaining(), m = t * S.fpsLimit / 10 / i;
164
+ m < 0 || (S.value = m, S.isOverLimit < 25 ? S.isOverLimit++ : M({ overclockingFps: !0 }));
165
+ }
166
+ /**
167
+ * Increase frameID
168
+ * @param { any | undefined } now
169
+ */
170
+ nextFrame(e) {
171
+ this.frameId++;
172
+ const t = e || this.now(), i = t - this.paramTime;
173
+ let m = 0;
174
+ if (this.frameId <= 1)
175
+ this.paramFrame = this.frameId, this.paramTime = t;
176
+ else if (t >= this.paramTime) {
177
+ this.maxMemory = window.performance.memory ? window.performance.memory.jsHeapSizeLimit / 1048576 : 0;
178
+ const o = this.frameId - this.paramFrame, a = o * 1e3 / i, c = R().overclockingFps ? S.value : a;
179
+ if (m = this.isWebGL2 ? this.gpuAccums[0] : this.gpuAccums[0] / i, this.isWebGL2 ? this.gpuAccums[0] = 0 : Promise.all(this.finished).then(() => {
180
+ this.gpuAccums[0] = 0, this.finished = [];
181
+ }), this.currentMem = Math.round(
182
+ window.performance && window.performance.memory ? window.performance.memory.usedJSHeapSize / 1048576 : 0
183
+ ), window.performance && this.startCpuProfiling) {
184
+ window.performance.mark("cpu-finished");
185
+ const v = performance.measure(
186
+ "cpu-duration",
187
+ "cpu-started",
188
+ "cpu-finished"
189
+ );
190
+ this.currentCpu = (v == null ? void 0 : v.duration) || 0, this.logsAccums.cpu.push(this.currentCpu), this.startCpuProfiling = !1;
191
+ }
192
+ this.logsAccums.mem.push(this.currentMem), this.logsAccums.fpsFixed.push(a), this.logsAccums.fps.push(c), this.logsAccums.gpu.push(m), this.overClock && typeof window.requestIdleCallback < "u" && (S.isOverLimit > 0 && c > a ? S.isOverLimit-- : R().overclockingFps && M({ overclockingFps: !1 })), t >= this.paramTime + 1e3 / this.logsPerSecond && (this.paramLogger({
193
+ cpu: H(this.logsAccums.cpu),
194
+ gpu: H(this.logsAccums.gpu),
195
+ mem: H(this.logsAccums.mem),
196
+ fps: H(this.logsAccums.fps),
197
+ duration: Math.round(i),
198
+ maxMemory: this.maxMemory,
199
+ frameCount: o
200
+ }), this.logsAccums.mem = [], this.logsAccums.fps = [], this.logsAccums.gpu = [], this.logsAccums.cpu = [], this.paramFrame = this.frameId, this.paramTime = t), this.overClock && t - this.lastCalculateFixed >= 2 * 1e3 && (this.lastCalculateFixed = e, S.fpsLimit = Math.round(H(this.logsAccums.fpsFixed) / 10) * 100, M({ fpsLimit: S.fpsLimit / 10 }), this.logsAccums.fpsFixed = [], this.paramFrame = this.frameId, this.paramTime = t);
201
+ }
202
+ if (!this.detected || !this.chartFrame)
203
+ this.chartFrame = this.frameId, this.chartTime = t, this.circularId = 0;
204
+ else {
205
+ const o = t - this.chartTime;
206
+ let a = this.chartHz * o / 1e3;
207
+ for (; --a > 0 && this.detected; ) {
208
+ const v = (this.frameId - this.chartFrame) / o * 1e3, s = R().overclockingFps ? S.value : v;
209
+ this.fpsChart[this.circularId % this.chartLen] = s;
210
+ const d = 1e3 / this.currentMem, f = this.currentCpu, p = (this.isWebGL2 ? this.gpuAccums[1] * 2 : Math.round(this.gpuAccums[1] / i * 100)) + 4;
211
+ p > 0 && (this.gpuChart[this.circularId % this.chartLen] = p), f > 0 && (this.cpuChart[this.circularId % this.chartLen] = f), d > 0 && (this.memChart[this.circularId % this.chartLen] = d);
212
+ for (let h = 0; h < this.names.length; h++)
213
+ this.chartLogger({
214
+ i: h,
215
+ data: {
216
+ fps: this.fpsChart,
217
+ gpu: this.gpuChart,
218
+ cpu: this.cpuChart,
219
+ mem: this.memChart
220
+ },
221
+ circularId: this.circularId
222
+ });
223
+ this.circularId++, this.chartFrame = this.frameId, this.chartTime = t;
224
+ }
225
+ }
226
+ }
227
+ startGpu() {
228
+ const e = this.gl, t = this.extension;
229
+ if (!(!e || !t) && this.isWebGL2) {
230
+ let i = !1, m, o;
231
+ if (this.query) {
232
+ this.queryHasResult = !1;
233
+ let a = this.query;
234
+ if (i = e.getQueryParameter(a, e.QUERY_RESULT_AVAILABLE), m = e.getParameter(t.GPU_DISJOINT_EXT), i && !m) {
235
+ o = e.getQueryParameter(this.query, e.QUERY_RESULT);
236
+ const c = o * 1e-6;
237
+ (i || m) && (e.deleteQuery(this.query), a = null), i && c > 0 && (m || this.activeAccums.forEach((v, s) => {
238
+ this.gpuAccums[s] = c;
239
+ }));
240
+ }
241
+ }
242
+ (i || !this.query) && (this.queryCreated = !0, this.query = e.createQuery(), e.beginQuery(t.TIME_ELAPSED_EXT, this.query));
243
+ }
244
+ }
245
+ endGpu() {
246
+ const e = this.extension, t = this.gl;
247
+ this.isWebGL2 && this.queryCreated && t.getQuery(e.TIME_ELAPSED_EXT, t.CURRENT_QUERY) && t.endQuery(e.TIME_ELAPSED_EXT);
248
+ }
249
+ /**
250
+ * Begin named measurement
251
+ * @param { string | undefined } name
252
+ */
253
+ begin(e) {
254
+ this.startGpu(), this.updateAccums(e);
255
+ }
256
+ /**
257
+ * End named measure
258
+ * @param { string | undefined } name
259
+ */
260
+ end(e) {
261
+ this.endGpu(), this.updateAccums(e);
262
+ }
263
+ updateAccums(e) {
264
+ let t = this.names.indexOf(e);
265
+ t === -1 && (t = this.names.length, this.addUI(e));
266
+ const i = this.now();
267
+ this.activeAccums[t] = !this.activeAccums[t], this.t0 = i;
268
+ }
269
+ dispose() {
270
+ const e = this.gl, t = this.extension;
271
+ try {
272
+ this.isWebGL2 && e && t && e.getQuery(t.TIME_ELAPSED_EXT, e.CURRENT_QUERY) && e.endQuery(t.TIME_ELAPSED_EXT);
273
+ } catch {
274
+ }
275
+ if (e && this.query) {
276
+ try {
277
+ e.deleteQuery(this.query);
278
+ } catch {
279
+ }
280
+ this.query = null;
281
+ }
282
+ this.queryCreated = !1, this.queryHasResult = !1;
283
+ }
284
+ }
285
+ const We = (r) => {
286
+ r.forEach((e) => {
287
+ const { meshes: t } = e;
288
+ if (!t)
289
+ return;
290
+ const i = {
291
+ total: 0,
292
+ type: "Triangle",
293
+ data: []
294
+ };
295
+ Object.keys(t).forEach((m) => {
296
+ const o = t[m], { geometry: a, material: c } = o, v = a.index, s = a.attributes.position;
297
+ if (!s) return;
298
+ let d = 1;
299
+ c.wireframe === !0 && (d = 0);
300
+ const f = v !== null ? v.count : s.count, p = a.drawRange.start * d, h = a.drawRange.count * d, u = p, w = Math.min(f, p + h) - 1;
301
+ let g = 1;
302
+ const _ = o.count || 1;
303
+ let x = "Triangle", b = 0;
304
+ o.isMesh ? c.wireframe === !0 ? (x = "Line", g = g / 2) : (x = "Triangle", g = g / 3) : o.isLine ? (x = "Line", o.isLineSegments ? g = g / 2 : o.isLineLoop ? g = g : g = g - 1) : o.isPoints ? (x = "Point", g = g) : o.isSprite && (x = "Triangle", g = g / 3);
305
+ const C = Math.round(
306
+ Math.max(0, w - u + 1) * (g * _)
307
+ );
308
+ C > b && (b = C, i.type = x), i.total += C, i.data.push({ drawCount: C, type: x }), o.userData.drawCount = {
309
+ type: x,
310
+ count: C
311
+ };
312
+ }), e.drawCounts = i;
313
+ });
314
+ }, te = new Be();
315
+ function Oe(r, e, t) {
316
+ return te.on(r, e);
317
+ }
318
+ function ke(r, e, t) {
319
+ te.removeListener(
320
+ r,
321
+ e,
322
+ (t == null ? void 0 : t.context) ?? null,
323
+ t == null ? void 0 : t.once
324
+ );
325
+ }
326
+ function He(r, e) {
327
+ te.emit(r, e);
328
+ }
329
+ function qe(r) {
330
+ let e = 0, t = 0;
331
+ const i = /* @__PURE__ */ new Set(), m = /* @__PURE__ */ new Set();
332
+ return r.traverse((o) => {
333
+ if (o.isMesh) {
334
+ const a = o;
335
+ if (a.geometry && !i.has(a.geometry.uuid)) {
336
+ i.add(a.geometry.uuid);
337
+ const s = a.geometry.attributes;
338
+ for (const d in s) {
339
+ const f = s[d];
340
+ f.array && (t += f.array.byteLength);
341
+ }
342
+ a.geometry.index && a.geometry.index.array && (t += a.geometry.index.array.byteLength);
343
+ }
344
+ const c = a.material;
345
+ (Array.isArray(c) ? c : [c]).forEach((s) => {
346
+ if (s)
347
+ for (const d in s) {
348
+ const f = s[d];
349
+ if (f && f.isTexture) {
350
+ const p = f;
351
+ if (!m.has(p.uuid)) {
352
+ if (m.add(p.uuid), p.isCompressedTexture && p.mipmaps)
353
+ p.mipmaps.forEach((h) => {
354
+ h.data && (e += h.data.byteLength);
355
+ });
356
+ else if (p.image) {
357
+ const h = p.image, u = h.width || 0, w = h.height || 0, g = p.generateMipmaps ? 1.33 : 1;
358
+ e += u * w * 4 * g;
359
+ }
360
+ }
361
+ }
362
+ }
363
+ });
364
+ }
365
+ }), {
366
+ geometry: t,
367
+ texture: e,
368
+ total: t + e
369
+ };
370
+ }
371
+ const ce = E.Object3D.prototype.updateMatrixWorld, le = E.Object3D.prototype.updateWorldMatrix, ue = E.Object3D.prototype.updateMatrix, me = ["calls", "triangles", "points", "lines"], de = ["gpu", "cpu", "mem", "fps"], je = (r) => /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(
372
+ r
373
+ ), pe = (r, e) => {
374
+ r.defines || (r.defines = {}), r.defines.muiPerf || (r.defines = Object.assign(r.defines || {}, {
375
+ muiPerf: r.uuid
376
+ }), r.needsUpdate = !0);
377
+ const t = r.uuid;
378
+ return e[t] || (e[t] = { meshes: {}, material: r }), r.needsUpdate = !1, t;
379
+ }, ze = (r) => r === "muiPerf", Ve = ({
380
+ overClock: r,
381
+ logsPerSecond: e,
382
+ chart: t,
383
+ deepAnalyze: i,
384
+ matrixUpdate: m
385
+ }) => {
386
+ const { gl: o, scene: a } = we();
387
+ M({ gl: o, scene: a });
388
+ const c = 1e3;
389
+ let v = 0;
390
+ const s = Y(() => {
391
+ const d = new De({
392
+ trackGPU: !0,
393
+ overClock: r,
394
+ chartLen: t ? t.length : 120,
395
+ chartHz: t ? t.hz : 60,
396
+ logsPerSecond: e || 10,
397
+ gl: o.getContext(),
398
+ chartLogger: (g) => {
399
+ M({ chart: g });
400
+ },
401
+ paramLogger: (g) => {
402
+ var T;
403
+ const _ = {
404
+ maxMemory: g.maxMemory,
405
+ gpu: g.gpu,
406
+ cpu: g.cpu,
407
+ mem: g.mem,
408
+ fps: g.fps,
409
+ totalTime: g.duration,
410
+ frameCount: g.frameCount
411
+ };
412
+ M({ log: _ });
413
+ const { accumulated: x } = R(), b = o.info.render;
414
+ x.totalFrames++, x.gl.calls += b.calls, x.gl.triangles += b.triangles, x.gl.points += b.points, x.gl.lines += b.lines, x.log.gpu += g.gpu, x.log.cpu += g.cpu, x.log.mem += g.mem, x.log.fps += g.fps;
415
+ for (let F = 0; F < me.length; F++) {
416
+ const A = me[F], P = b[A];
417
+ P > x.max.gl[A] && (x.max.gl[A] = P);
418
+ }
419
+ for (let F = 0; F < de.length; F++) {
420
+ const A = de[F], P = g[A];
421
+ P > x.max.log[A] && (x.max.log[A] = P);
422
+ }
423
+ M({ accumulated: x });
424
+ const C = {
425
+ calls: o.info.render.calls,
426
+ triangles: o.info.render.triangles,
427
+ points: o.info.render.points,
428
+ lines: o.info.render.lines,
429
+ geometries: o.info.memory.geometries,
430
+ textures: o.info.memory.textures,
431
+ programs: ((T = o.info.programs) == null ? void 0 : T.length) || 0
432
+ };
433
+ He("log", [_, C]);
434
+ }
435
+ }), f = o.getContext();
436
+ let p = null, h = null;
437
+ const u = f.getExtension("WEBGL_debug_renderer_info"), w = f.getParameter(f.VERSION);
438
+ return u && (p = f.getParameter(u.UNMASKED_RENDERER_WEBGL), h = f.getParameter(u.UNMASKED_VENDOR_WEBGL)), h || (h = "Unknown vendor"), p || (p = f.getParameter(f.RENDERER)), M({
439
+ startTime: window.performance.now(),
440
+ infos: {
441
+ version: w,
442
+ renderer: p,
443
+ vendor: h
444
+ }
445
+ }), d;
446
+ }, [r, t, e, o]);
447
+ return U(() => {
448
+ s && (s.overClock = r || !1, r === !1 && (M({ overclockingFps: !1 }), S.value = 0, S.isOverLimit = 0), s.chartHz = (t == null ? void 0 : t.hz) || 60, s.chartLen = (t == null ? void 0 : t.length) || 120);
449
+ }, [s, r, t == null ? void 0 : t.hz, t == null ? void 0 : t.length]), U(() => {
450
+ if (!o.info) return;
451
+ o.info.autoReset = !1, m && (E.Object3D.prototype.updateMatrixWorld = function(...p) {
452
+ return this.matrixWorldNeedsUpdate || p[0], ce.apply(this, p);
453
+ }, E.Object3D.prototype.updateWorldMatrix = function(...p) {
454
+ return le.apply(this, p);
455
+ }, E.Object3D.prototype.updateMatrix = function(...p) {
456
+ return ue.apply(this, p);
457
+ });
458
+ const d = Ae(() => {
459
+ R().paused && M({ paused: !1 }), s == null || s.begin("profiler"), window.performance && (window.performance.mark("cpu-started"), s.startCpuProfiling = !0), o.info.reset();
460
+ }), f = Se(() => {
461
+ var w, g;
462
+ s == null || s.end("profiler"), s && !s.paused && (s.nextFrame(window.performance.now()), r && typeof window.requestIdleCallback < "u" && (s.idleCbId = requestIdleCallback(s.nextFps)));
463
+ const p = window.performance.now();
464
+ if (p - v > c) {
465
+ v = p;
466
+ const _ = qe(a), x = s.currentMem || 0;
467
+ M({
468
+ estimatedMemory: {
469
+ vram: _.total / 1024 / 1024,
470
+ // Đổi ra MB
471
+ tex: _.texture / 1024 / 1024,
472
+ geo: _.geometry / 1024 / 1024,
473
+ ram: x
474
+ // Đã là MB
475
+ }
476
+ });
477
+ }
478
+ if (!i) return;
479
+ const h = {}, u = /* @__PURE__ */ new Map();
480
+ a.traverse((_) => {
481
+ if (_ instanceof E.Mesh || _ instanceof E.Points) {
482
+ if (!_.material) return;
483
+ let x = _.material.uuid;
484
+ const b = Array.isArray(_.material) && _.material.length > 1;
485
+ x = pe(b ? _.material[1] : _.material, h), h[x].meshes[_.uuid] = _;
486
+ }
487
+ }), (g = (w = o == null ? void 0 : o.info) == null ? void 0 : w.programs) == null || g.forEach((_) => {
488
+ const x = _.cacheKey.split(","), b = x[x.findIndex(ze) + 1];
489
+ if (je(b) && h[b]) {
490
+ const { material: C, meshes: T } = h[b];
491
+ u.set(b, {
492
+ program: _,
493
+ material: C,
494
+ meshes: T,
495
+ drawCounts: { total: 0, type: "triangle", data: [] },
496
+ expand: !1,
497
+ visible: !0
498
+ });
499
+ }
500
+ }), u.size !== R().programs.size && (We(u), M({
501
+ programs: u,
502
+ triggerProgramsUpdate: R().triggerProgramsUpdate + 1
503
+ }));
504
+ });
505
+ return () => {
506
+ var p;
507
+ s && typeof window.cancelIdleCallback < "u" && window.cancelIdleCallback(s.idleCbId), (p = s == null ? void 0 : s.dispose) == null || p.call(s), m && (E.Object3D.prototype.updateMatrixWorld = ce, E.Object3D.prototype.updateWorldMatrix = le, E.Object3D.prototype.updateMatrix = ue), d(), f();
508
+ };
509
+ }, [s, o, a, i, r, m]), U(() => {
510
+ const d = Ne(() => (s && (s.paused = !0, M({
511
+ paused: !0,
512
+ log: {
513
+ maxMemory: 0,
514
+ gpu: 0,
515
+ mem: 0,
516
+ cpu: 0,
517
+ fps: 0,
518
+ totalTime: 0,
519
+ frameCount: 0
520
+ }
521
+ })), !1));
522
+ return () => d();
523
+ }, [s]), null;
524
+ };
525
+ function re(r, e, t = [], i) {
526
+ const m = I(e);
527
+ U(() => {
528
+ m.current = e;
529
+ }, [e]), U(() => {
530
+ const o = (c) => {
531
+ var v;
532
+ return (v = m.current) == null ? void 0 : v.call(m, c);
533
+ }, a = Oe(r, o);
534
+ return () => ke(r, o, {
535
+ ...i,
536
+ context: a
537
+ });
538
+ }, [r, i == null ? void 0 : i.once, ...t]);
539
+ }
540
+ function $e(r) {
541
+ let e = 0;
542
+ for (const i in r.attributes) {
543
+ const m = r.getAttribute(i);
544
+ e += m.count * m.itemSize * m.array.BYTES_PER_ELEMENT;
545
+ }
546
+ const t = r.getIndex();
547
+ return e += t ? t.count * t.itemSize * t.array.BYTES_PER_ELEMENT : 0, e;
548
+ }
549
+ const Qe = "_perfS_ans5i_1", Xe = "_containerHeight_ans5i_16", Ye = "_topLeft_ans5i_21", Ke = "_topRight_ans5i_22", Je = "_bottomLeft_ans5i_23", Ze = "_bottomRight_ans5i_24", et = "_minimal_ans5i_26", tt = "_perfIContainer_ans5i_30", rt = "_perfI_ans5i_30", st = "_perfB_ans5i_69", nt = "_toggleContainer_ans5i_83", it = "_toggle_ans5i_83", at = "_activeTab_ans5i_105", ot = "_containerScroll_ans5i_110", ct = "_programGeo_ans5i_115", lt = "_programHeader_ans5i_120", ut = "_headerLeft_ans5i_149", mt = "_programTitle_ans5i_156", dt = "_toggleArrow_ans5i_166", pt = "_programConsole_ans5i_200", ft = "_programsContainer_ans5i_218", ht = "_headerRight_ans5i_222", gt = "_metricBadge_ans5i_228", yt = "_programsULHeader_ans5i_246", vt = "_programsUL_ans5i_246", xt = "_programsGeoLi_ans5i_309", wt = "_graph_ans5i_324", _t = "_visibilityBtn_ans5i_354", bt = "_active_ans5i_105", l = {
550
+ perfS: Qe,
551
+ containerHeight: Xe,
552
+ topLeft: Ye,
553
+ topRight: Ke,
554
+ bottomLeft: Je,
555
+ bottomRight: Ze,
556
+ minimal: et,
557
+ perfIContainer: tt,
558
+ perfI: rt,
559
+ perfB: st,
560
+ toggleContainer: nt,
561
+ toggle: it,
562
+ activeTab: at,
563
+ containerScroll: ot,
564
+ programGeo: ct,
565
+ programHeader: lt,
566
+ headerLeft: ut,
567
+ programTitle: mt,
568
+ toggleArrow: dt,
569
+ programConsole: pt,
570
+ programsContainer: ft,
571
+ headerRight: ht,
572
+ metricBadge: gt,
573
+ programsULHeader: yt,
574
+ programsUL: vt,
575
+ programsGeoLi: xt,
576
+ graph: wt,
577
+ visibilityBtn: _t,
578
+ active: bt
579
+ }, fe = (r, e) => {
580
+ var m, o;
581
+ const t = (a) => {
582
+ switch (a) {
583
+ case 1e3:
584
+ return "RepeatWrapping";
585
+ case 1001:
586
+ return "ClampToEdgeWrapping";
587
+ case 1002:
588
+ return "MirroredRepeatWrapping";
589
+ default:
590
+ return "ClampToEdgeWrapping";
591
+ }
592
+ }, i = (a) => {
593
+ switch (a) {
594
+ case 3e3:
595
+ return "LinearEncoding";
596
+ case 3001:
597
+ return "sRGBEncoding";
598
+ case 3002:
599
+ return "RGBEEncoding";
600
+ case 3003:
601
+ return "LogLuvEncoding";
602
+ case 3004:
603
+ return "RGBM7Encoding";
604
+ case 3005:
605
+ return "RGBM16Encoding";
606
+ case 3006:
607
+ return "RGBDEncoding";
608
+ case 3007:
609
+ return "GammaEncoding";
610
+ default:
611
+ return "ClampToEdgeWrapping";
612
+ }
613
+ };
614
+ return {
615
+ name: r,
616
+ url: (m = e == null ? void 0 : e.image) == null ? void 0 : m.currentSrc,
617
+ encoding: i(e.encoding),
618
+ wrapT: t(e.wrapT),
619
+ flipY: (o = e.flipY) == null ? void 0 : o.toString()
620
+ };
621
+ }, Z = ({
622
+ value: r,
623
+ label: e,
624
+ unit: t,
625
+ title: i
626
+ }) => r == null || r === 0 || r === "0" ? null : /* @__PURE__ */ y("div", { className: l.metricBadge, title: i, children: [
627
+ /* @__PURE__ */ n("b", { children: r }),
628
+ " ",
629
+ t || e
630
+ ] }), Ct = ({ program: r, material: e, setTexNumber: t }) => {
631
+ const i = L((a) => a.gl), [m, o] = O(null);
632
+ return U(() => {
633
+ if (i) {
634
+ const a = r == null ? void 0 : r.getUniforms();
635
+ let c = 0;
636
+ const v = /* @__PURE__ */ new Map();
637
+ a && a.seq && a.seq.forEach((s) => {
638
+ if (!s.id.includes("uTroika") && ![
639
+ "isOrthographic",
640
+ "uvTransform",
641
+ "lightProbe",
642
+ "projectionMatrix",
643
+ "viewMatrix",
644
+ "normalMatrix",
645
+ "modelMatrix",
646
+ "modelViewMatrix"
647
+ ].includes(s.id)) {
648
+ const d = [], f = { name: s.id };
649
+ s.cache && (s.cache.forEach((p) => {
650
+ typeof p < "u" && d.push(p.toString().substring(0, 4));
651
+ }), f.value = d.join(), e[s.id] && e[s.id].image && (c++, f.value = fe(s.id, e[s.id])), f.value || (f.value = "empty"), v.set(s.id, f));
652
+ }
653
+ }), e.uniforms && Object.keys(e.uniforms).forEach((s) => {
654
+ const d = e.uniforms[s];
655
+ if (d.value) {
656
+ const { value: f } = d, p = { name: s };
657
+ if (s.includes("uTroika")) return;
658
+ if (f.isTexture)
659
+ c++, p.value = fe(s, f);
660
+ else {
661
+ let h = JSON.stringify(f);
662
+ try {
663
+ h = JSON.stringify(f);
664
+ } catch {
665
+ h = f.toString();
666
+ }
667
+ p.value = h;
668
+ }
669
+ v.set(s, p);
670
+ }
671
+ }), t(c), o(v);
672
+ }
673
+ }, [i, e, r, t]), /* @__PURE__ */ n("ul", { className: l.programsUL, children: m && Array.from(m.values()).map((a) => /* @__PURE__ */ n("span", { children: typeof a.value == "string" ? /* @__PURE__ */ n("li", { children: /* @__PURE__ */ y("span", { children: [
674
+ a.name,
675
+ " :",
676
+ " ",
677
+ /* @__PURE__ */ y("b", { children: [
678
+ a.value.substring(0, 30),
679
+ a.value.length > 30 ? "..." : ""
680
+ ] })
681
+ ] }) }) : /* @__PURE__ */ y(z, { children: [
682
+ /* @__PURE__ */ n("li", { children: /* @__PURE__ */ y("b", { children: [
683
+ a.value.name,
684
+ ":"
685
+ ] }) }),
686
+ /* @__PURE__ */ y("div", { children: [
687
+ Object.keys(a.value).map(
688
+ (c) => c !== "name" ? /* @__PURE__ */ n("div", { children: c === "url" ? /* @__PURE__ */ n(
689
+ "a",
690
+ {
691
+ href: a.value[c],
692
+ target: "_blank",
693
+ rel: "noreferrer",
694
+ children: /* @__PURE__ */ n("img", { src: a.value[c], alt: "texture" })
695
+ }
696
+ ) : /* @__PURE__ */ y("li", { children: [
697
+ c,
698
+ ": ",
699
+ /* @__PURE__ */ n("b", { children: a.value[c] })
700
+ ] }) }, c) : null
701
+ ),
702
+ /* @__PURE__ */ y(
703
+ "button",
704
+ {
705
+ className: l.programConsole,
706
+ onClick: () => {
707
+ var c;
708
+ console.info(
709
+ e[a.value.name] || ((c = e == null ? void 0 : e.uniforms[a.value.name]) == null ? void 0 : c.value)
710
+ );
711
+ },
712
+ children: [
713
+ "console.info(",
714
+ a.value.name,
715
+ ");"
716
+ ]
717
+ }
718
+ )
719
+ ] })
720
+ ] }) }, a.name)) });
721
+ }, Et = ({ el: r }) => {
722
+ const [e, t] = O(r.visible), [i, m] = O(r.expand), [o, a] = O(0), { meshes: c, program: v, material: s } = r, d = L((u) => u.gl), f = () => {
723
+ if (!d || !d.info || !d.info.render) return 0;
724
+ const u = d.info.render.triangles + d.info.render.lines + d.info.render.points;
725
+ if (u === 0) return 0;
726
+ const w = Math.round(r.drawCounts.total / u * 100 * 10) / 10;
727
+ return isFinite(w) && w || 0;
728
+ }, p = Object.keys(c).length, h = f();
729
+ return /* @__PURE__ */ y("div", { className: l.programGeo, children: [
730
+ /* @__PURE__ */ y(
731
+ "div",
732
+ {
733
+ className: l.programHeader,
734
+ onClick: () => {
735
+ Object.keys(c).forEach((u) => {
736
+ c[u].material.wireframe = !1;
737
+ }), m(!i);
738
+ },
739
+ children: [
740
+ /* @__PURE__ */ y("div", { className: l.headerLeft, children: [
741
+ /* @__PURE__ */ n(
742
+ "div",
743
+ {
744
+ className: l.toggleArrow,
745
+ style: {
746
+ transform: i ? "rotate(90deg)" : "rotate(0deg)"
747
+ },
748
+ children: "▶"
749
+ }
750
+ ),
751
+ v && /* @__PURE__ */ n("span", { className: l.programTitle, children: v.name })
752
+ ] }),
753
+ /* @__PURE__ */ y("div", { className: l.headerRight, children: [
754
+ /* @__PURE__ */ n(
755
+ Z,
756
+ {
757
+ value: p,
758
+ unit: p > 1 ? "users" : "user"
759
+ }
760
+ ),
761
+ /* @__PURE__ */ n(Z, { value: o, unit: "tex" }),
762
+ r.drawCounts.total > 0 && /* @__PURE__ */ y(
763
+ "div",
764
+ {
765
+ className: l.metricBadge,
766
+ title: `${h}% of total render`,
767
+ children: [
768
+ /* @__PURE__ */ n("b", { children: r.drawCounts.total }),
769
+ r.drawCounts.type === "Triangle" ? "tris" : r.drawCounts.type,
770
+ r.visible && !r.material.wireframe && /* @__PURE__ */ y(
771
+ "span",
772
+ {
773
+ style: { marginLeft: "4px", opacity: 0.6, fontSize: "9px" },
774
+ children: [
775
+ "(",
776
+ h,
777
+ "%)"
778
+ ]
779
+ }
780
+ )
781
+ ]
782
+ }
783
+ ),
784
+ s.glslVersion === "300 es" && /* @__PURE__ */ n(Z, { value: "300", unit: "es" }),
785
+ /* @__PURE__ */ n(
786
+ "div",
787
+ {
788
+ className: `${l.visibilityBtn} ${e ? l.active : ""}`,
789
+ onPointerEnter: () => {
790
+ Object.keys(c).forEach(
791
+ (u) => c[u].material.wireframe = !0
792
+ );
793
+ },
794
+ onPointerLeave: () => {
795
+ Object.keys(c).forEach(
796
+ (u) => c[u].material.wireframe = !1
797
+ );
798
+ },
799
+ onClick: (u) => {
800
+ u.stopPropagation();
801
+ const w = !e;
802
+ Object.keys(c).forEach((g) => {
803
+ c[g] && (c[g].visible = w);
804
+ }), t(w);
805
+ },
806
+ children: e ? "👁" : "×"
807
+ }
808
+ )
809
+ ] })
810
+ ]
811
+ }
812
+ ),
813
+ /* @__PURE__ */ y("div", { style: { display: i ? "block" : "none" }, children: [
814
+ /* @__PURE__ */ n("div", { className: l.programsULHeader, style: { marginTop: "4px" }, children: "Uniforms" }),
815
+ /* @__PURE__ */ n(
816
+ Ct,
817
+ {
818
+ program: v,
819
+ material: s,
820
+ setTexNumber: a
821
+ }
822
+ ),
823
+ /* @__PURE__ */ n("div", { className: l.programsULHeader, children: "Geometries" }),
824
+ /* @__PURE__ */ n("ul", { className: l.programsUL, children: c && Object.keys(c).map(
825
+ (u) => c[u] && c[u].geometry && /* @__PURE__ */ n("li", { className: l.programsGeoLi, children: /* @__PURE__ */ y(
826
+ "div",
827
+ {
828
+ style: {
829
+ width: "100%",
830
+ display: "flex",
831
+ justifyContent: "space-between",
832
+ alignItems: "center"
833
+ },
834
+ children: [
835
+ /* @__PURE__ */ n("span", { children: c[u].geometry.type }),
836
+ c[u].userData && c[u].userData.drawCount && /* @__PURE__ */ y(
837
+ "span",
838
+ {
839
+ style: {
840
+ color: "#aaa",
841
+ fontSize: "10px",
842
+ display: "flex",
843
+ gap: "6px"
844
+ },
845
+ children: [
846
+ /* @__PURE__ */ y("span", { children: [
847
+ /* @__PURE__ */ n("b", { children: c[u].userData.drawCount.count }),
848
+ " ",
849
+ c[u].userData.drawCount.type,
850
+ "s"
851
+ ] }),
852
+ /* @__PURE__ */ n("span", { style: { opacity: 0.3 }, children: "|" }),
853
+ /* @__PURE__ */ y("span", { children: [
854
+ /* @__PURE__ */ n("b", { children: Math.round(
855
+ $e(c[u].geometry) / 1024 * 100
856
+ ) / 100 }),
857
+ " ",
858
+ "KB"
859
+ ] })
860
+ ]
861
+ }
862
+ )
863
+ ]
864
+ }
865
+ ) }, u)
866
+ ) }),
867
+ /* @__PURE__ */ y(
868
+ "button",
869
+ {
870
+ className: l.programConsole,
871
+ onClick: () => console.info(s),
872
+ children: [
873
+ "Log Material (",
874
+ s.type,
875
+ ")"
876
+ ]
877
+ }
878
+ )
879
+ ] })
880
+ ] });
881
+ }, Mt = () => {
882
+ L((e) => e.triggerProgramsUpdate);
883
+ const r = L((e) => e.programs);
884
+ return /* @__PURE__ */ n(
885
+ "div",
886
+ {
887
+ className: l.programsContainer,
888
+ onWheel: (e) => e.stopPropagation(),
889
+ children: r && Array.from(r.values()).map((e) => e ? /* @__PURE__ */ n(Et, { el: e }, e.material.uuid) : null)
890
+ }
891
+ );
892
+ }, It = ({
893
+ minimal: r,
894
+ chart: e = { length: 120, hz: 60 }
895
+ }) => {
896
+ const t = Y(() => ({
897
+ fps: new Float32Array(e.length * 3),
898
+ cpu: new Float32Array(e.length * 3),
899
+ gpu: new Float32Array(e.length * 3)
900
+ }), [e]), i = I(null), m = I(null), o = I(null), a = I(null), c = Y(() => new E.Vector3(0, 0, 0), []), v = (s, d = 1, f, p) => {
901
+ let h = 0;
902
+ const { width: u, height: w } = p, g = R().chart.data[s];
903
+ if (!g || g.length === 0)
904
+ return;
905
+ const _ = r ? 2 : 6, x = r ? 12 : 50, b = g.length;
906
+ for (let C = 0; C < b; C++) {
907
+ const T = (R().chart.circularId + C + 1) % b;
908
+ g[T] !== void 0 && (g[T] > h && (h = g[T] * d), c.set(
909
+ _ + C / (b - 1) * (u - _ * 2) - u / 2,
910
+ Math.min(100, g[T]) * d / 100 * (w - _ * 2 - x) - w / 2,
911
+ 0
912
+ ), c.toArray(f.attributes.position.array, C * 3));
913
+ }
914
+ f.attributes.position.needsUpdate = !0;
915
+ };
916
+ return _e(function({ viewport: d }) {
917
+ v("fps", 1, i.current, d), m.current && m.current.color.set(
918
+ R().overclockingFps ? N.overClock : N.fps
919
+ ), v("gpu", 5, o.current, d), v("cpu", 5, a.current, d);
920
+ }), /* @__PURE__ */ y(z, { children: [
921
+ /* @__PURE__ */ y(
922
+ "line",
923
+ {
924
+ onUpdate: (s) => {
925
+ s.updateMatrix(), s.matrixWorld.copy(s.matrix);
926
+ },
927
+ children: [
928
+ /* @__PURE__ */ n("bufferGeometry", { ref: i, children: /* @__PURE__ */ n(
929
+ "bufferAttribute",
930
+ {
931
+ attach: "attributes-position",
932
+ count: e.length,
933
+ args: [t.fps, 3],
934
+ array: t.fps,
935
+ itemSize: 3,
936
+ usage: E.DynamicDrawUsage,
937
+ needsUpdate: !0
938
+ }
939
+ ) }),
940
+ /* @__PURE__ */ n(
941
+ "lineBasicMaterial",
942
+ {
943
+ ref: m,
944
+ color: N.fps,
945
+ transparent: !0,
946
+ opacity: 0.5
947
+ }
948
+ )
949
+ ]
950
+ }
951
+ ),
952
+ /* @__PURE__ */ y(
953
+ "line",
954
+ {
955
+ onUpdate: (s) => {
956
+ s.updateMatrix(), s.matrixWorld.copy(s.matrix);
957
+ },
958
+ children: [
959
+ /* @__PURE__ */ n("bufferGeometry", { ref: o, children: /* @__PURE__ */ n(
960
+ "bufferAttribute",
961
+ {
962
+ attach: "attributes-position",
963
+ count: e.length,
964
+ array: t.gpu,
965
+ args: [t.gpu, 3],
966
+ itemSize: 3,
967
+ usage: E.DynamicDrawUsage,
968
+ needsUpdate: !0
969
+ }
970
+ ) }),
971
+ /* @__PURE__ */ n("lineBasicMaterial", { color: N.gpu, transparent: !0, opacity: 0.5 })
972
+ ]
973
+ }
974
+ ),
975
+ /* @__PURE__ */ y(
976
+ "line",
977
+ {
978
+ onUpdate: (s) => {
979
+ s.updateMatrix(), s.matrixWorld.copy(s.matrix);
980
+ },
981
+ children: [
982
+ /* @__PURE__ */ n("bufferGeometry", { ref: a, children: /* @__PURE__ */ n(
983
+ "bufferAttribute",
984
+ {
985
+ attach: "attributes-position",
986
+ count: e.length,
987
+ array: t.cpu,
988
+ args: [t.cpu, 3],
989
+ itemSize: 3,
990
+ usage: E.DynamicDrawUsage,
991
+ needsUpdate: !0
992
+ }
993
+ ) }),
994
+ /* @__PURE__ */ n("lineBasicMaterial", { color: N.cpu, transparent: !0, opacity: 0.5 })
995
+ ]
996
+ }
997
+ )
998
+ ] });
999
+ }, Lt = ({
1000
+ chart: r,
1001
+ showGraph: e = !0,
1002
+ antialias: t = !0,
1003
+ minimal: i
1004
+ }) => {
1005
+ const m = I(void 0), o = L((a) => a.paused);
1006
+ return /* @__PURE__ */ n(
1007
+ "div",
1008
+ {
1009
+ className: l.graph,
1010
+ style: {
1011
+ display: "flex",
1012
+ marginTop: 6,
1013
+ position: "absolute",
1014
+ width: "100%",
1015
+ height: `${i ? 37 : e ? 100 : 60}px`
1016
+ },
1017
+ children: /* @__PURE__ */ n(
1018
+ Re,
1019
+ {
1020
+ ref: m,
1021
+ orthographic: !0,
1022
+ camera: { rotation: [0, 0, 0] },
1023
+ dpr: t ? [1, 2] : 1,
1024
+ gl: {
1025
+ antialias: !0,
1026
+ alpha: !0,
1027
+ stencil: !1,
1028
+ depth: !1
1029
+ },
1030
+ onCreated: ({ scene: a }) => {
1031
+ a.traverse((c) => {
1032
+ c.matrixWorldAutoUpdate = !1, c.matrixAutoUpdate = !1;
1033
+ });
1034
+ },
1035
+ flat: !0,
1036
+ style: {
1037
+ marginBottom: "-42px",
1038
+ position: "relative",
1039
+ pointerEvents: "none",
1040
+ background: "transparent !important",
1041
+ width: "100%",
1042
+ height: `${i ? 37 : e ? 100 : 60}px`
1043
+ },
1044
+ children: o ? null : /* @__PURE__ */ y(z, { children: [
1045
+ /* @__PURE__ */ n(Tt, {}),
1046
+ e && /* @__PURE__ */ n(It, { minimal: i, chart: r })
1047
+ ] })
1048
+ }
1049
+ )
1050
+ }
1051
+ );
1052
+ }, Tt = () => (_e(function({ gl: e, scene: t, camera: i }) {
1053
+ i.updateMatrix(), i.matrixWorld.copy(i.matrix), i.matrixWorldInverse.copy(i.matrixWorld).invert(), e.render(t, i);
1054
+ }, 1 / 0), null), he = {
1055
+ fps: { fg: "#00ffff", bg: "#000022" },
1056
+ // Chỉnh màu nền đậm hơn chút
1057
+ cpu: { fg: "#00ff00", bg: "#002200" },
1058
+ gpu: { fg: "#ff0080", bg: "#220011" }
1059
+ }, D = [
1060
+ { key: "fps", label: "FPS", maxVal: 120 },
1061
+ { key: "cpu", label: "CPU", maxVal: 40 },
1062
+ { key: "gpu", label: "GPU", maxVal: 40 }
1063
+ ], W = 48, Ce = 15, Q = 2, j = Ce, q = W - j - 2, X = 6, At = 15, ge = 1e3 / At;
1064
+ function St({
1065
+ show: r = !0,
1066
+ opacity: e = 1,
1067
+ // Tăng opacity lên 1 để bớt trong suốt
1068
+ className: t,
1069
+ style: i
1070
+ }) {
1071
+ const m = L((h) => h.paused), o = I(null), a = I(null), [c, v] = O(300), s = Y(
1072
+ () => Math.max(1, Math.round(window.devicePixelRatio || 1)),
1073
+ []
1074
+ );
1075
+ U(() => {
1076
+ if (!a.current) return;
1077
+ const h = new ResizeObserver((u) => {
1078
+ for (const w of u)
1079
+ v(w.contentRect.width);
1080
+ });
1081
+ return h.observe(a.current), () => h.disconnect();
1082
+ }, []);
1083
+ const d = (D.length - 1) * X, f = Math.max(0, (c - d) / D.length), p = Math.max(0, f - Q);
1084
+ return U(() => {
1085
+ const h = o.current;
1086
+ if (!h) return;
1087
+ h.width = c * s, h.height = W * s, h.style.width = "100%", h.style.height = `${W}px`;
1088
+ const u = h.getContext("2d");
1089
+ if (u) {
1090
+ u.setTransform(1, 0, 0, 1, 0, 0), u.scale(s, s), u.imageSmoothingEnabled = !1, u.font = "bold 9px Roboto Mono, monospace", u.textBaseline = "top", u.clearRect(0, 0, c, W);
1091
+ for (let w = 0; w < D.length; w++) {
1092
+ const { key: g } = D[w], _ = w * (f + X), { bg: x } = he[g];
1093
+ u.fillStyle = x, u.globalAlpha = e, u.fillRect(_, 0, f, W), u.globalAlpha = 1;
1094
+ }
1095
+ }
1096
+ }, [s, c, f, e]), U(() => {
1097
+ if (!r) return;
1098
+ const h = o.current;
1099
+ if (!h) return;
1100
+ const u = h.getContext("2d");
1101
+ if (!u) return;
1102
+ let w = 0, g = 0;
1103
+ const _ = {
1104
+ fps: { min: 1 / 0, max: 0 },
1105
+ cpu: { min: 1 / 0, max: 0 },
1106
+ gpu: { min: 1 / 0, max: 0 }
1107
+ };
1108
+ function x(b) {
1109
+ if (!h || !u || (w = requestAnimationFrame(x), m)) return;
1110
+ const C = b - g;
1111
+ if (C < ge) return;
1112
+ g = b - C % ge;
1113
+ const T = R(), F = T.chart.circularId;
1114
+ for (let A = 0; A < D.length; A++) {
1115
+ const { key: P, label: Ee, maxVal: se } = D[A], k = A * (f + X), { fg: ne, bg: ie } = he[P], V = T.chart.data[P], K = (V == null ? void 0 : V.length) || 0;
1116
+ let $ = 0;
1117
+ if (K > 0) {
1118
+ const Le = (F - 1 + K) % K;
1119
+ $ = V[Le] ?? 0;
1120
+ }
1121
+ const B = _[P];
1122
+ B.min = Math.min(B.min, $), B.max = Math.max(B.max, $), u.fillStyle = ie, u.globalAlpha = 1, u.fillRect(k, 0, f, Ce), u.fillStyle = ne;
1123
+ const Me = `${Ee} (${Math.round(B.min)}-${Math.round(B.max)})`;
1124
+ u.fillText(Me, k + 3, 2), p > 1 && u.drawImage(
1125
+ h,
1126
+ (k + Q + 1) * s,
1127
+ j * s,
1128
+ (p - 1) * s,
1129
+ q * s,
1130
+ k + Q,
1131
+ j,
1132
+ p - 1,
1133
+ q
1134
+ );
1135
+ const ae = k + Q + p - 1;
1136
+ u.fillStyle = ie, u.globalAlpha = 1, u.fillRect(ae, j, 1, q), u.fillStyle = ne, u.globalAlpha = 1;
1137
+ const Ie = Math.min($, se) / se, J = Math.round(Ie * q);
1138
+ J > 0 && u.fillRect(ae, j + q - J, 1, J);
1139
+ }
1140
+ }
1141
+ return w = requestAnimationFrame(x), () => cancelAnimationFrame(w);
1142
+ }, [m, r, s, f, p]), r ? /* @__PURE__ */ n(
1143
+ "div",
1144
+ {
1145
+ ref: a,
1146
+ className: t,
1147
+ style: { width: "100%", ...i, marginTop: X },
1148
+ children: /* @__PURE__ */ n(
1149
+ "canvas",
1150
+ {
1151
+ ref: o,
1152
+ style: {
1153
+ display: "block",
1154
+ pointerEvents: "none",
1155
+ width: "100%",
1156
+ height: `${W}px`
1157
+ }
1158
+ }
1159
+ )
1160
+ }
1161
+ ) : null;
1162
+ }
1163
+ const N = {
1164
+ overClock: "#ff6eff",
1165
+ fps: "#00FFFF",
1166
+ // 0,255,255
1167
+ cpu: "#00FF00",
1168
+ // 0,255,0
1169
+ gpu: "#FD007F",
1170
+ // 253,0,127
1171
+ memory: "#FFD000",
1172
+ // 255,208,0
1173
+ vram: "#FF8C00"
1174
+ // 255,140,0
1175
+ }, ye = ({
1176
+ metric: r,
1177
+ decimal: e = 0,
1178
+ suffix: t = ""
1179
+ }) => {
1180
+ const i = I(null);
1181
+ return re("log", (m) => {
1182
+ const [o] = m;
1183
+ if (o && i.current) {
1184
+ const a = o[r];
1185
+ i.current.innerText = (typeof a == "number" ? a.toFixed(e) : "0") + t;
1186
+ }
1187
+ }), /* @__PURE__ */ y("span", { ref: i, children: [
1188
+ "0",
1189
+ t
1190
+ ] });
1191
+ }, G = ({
1192
+ metric: r,
1193
+ suffix: e = ""
1194
+ }) => {
1195
+ const t = I(null);
1196
+ return re("log", (i) => {
1197
+ const [, m] = i;
1198
+ if (m && t.current) {
1199
+ let o = m[r];
1200
+ r === "calls" && o === 1 && (o = "--"), t.current.innerText = o + e;
1201
+ }
1202
+ }), /* @__PURE__ */ y("span", { ref: t, children: [
1203
+ "0",
1204
+ e
1205
+ ] });
1206
+ }, ve = ({ type: r }) => {
1207
+ const e = L((t) => t.estimatedMemory[r]);
1208
+ return /* @__PURE__ */ y("span", { children: [
1209
+ e.toFixed(0),
1210
+ " MB"
1211
+ ] });
1212
+ }, Nt = () => {
1213
+ const r = L((m) => m.overclockingFps), e = L((m) => m.fpsLimit), t = I(null);
1214
+ re("log", (m) => {
1215
+ const [o] = m;
1216
+ o && t.current && (t.current.innerText = Math.round(o.fps).toString());
1217
+ });
1218
+ const i = r ? N.overClock : N.fps;
1219
+ return /* @__PURE__ */ y("div", { className: l.perfI, children: [
1220
+ /* @__PURE__ */ y("span", { className: l.perfB, style: { color: i }, children: [
1221
+ "FPS ",
1222
+ r ? ` ${e}🚀` : ""
1223
+ ] }),
1224
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, ref: t, children: "0" })
1225
+ ] });
1226
+ }, Rt = ({ showGraph: r, minimal: e }) => L((i) => i.gl) ? /* @__PURE__ */ y("div", { className: l.perfIContainer, children: [
1227
+ /* @__PURE__ */ n(Nt, { showGraph: r }),
1228
+ /* @__PURE__ */ y("div", { className: l.perfI, children: [
1229
+ /* @__PURE__ */ n("span", { className: l.perfB, style: { color: N.cpu }, children: "CPU" }),
1230
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, children: /* @__PURE__ */ n(ye, { metric: "cpu", decimal: 2, suffix: " ms" }) })
1231
+ ] }),
1232
+ /* @__PURE__ */ y("div", { className: l.perfI, children: [
1233
+ /* @__PURE__ */ n("span", { className: l.perfB, style: { color: N.gpu }, children: "GPU" }),
1234
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, children: /* @__PURE__ */ n(ye, { metric: "gpu", decimal: 2, suffix: " ms" }) })
1235
+ ] }),
1236
+ /* @__PURE__ */ y("div", { className: l.perfI, children: [
1237
+ /* @__PURE__ */ n("span", { className: l.perfB, style: { color: N.memory }, children: "MEMORY" }),
1238
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, children: /* @__PURE__ */ n(ve, { type: "ram" }) })
1239
+ ] }),
1240
+ /* @__PURE__ */ y("div", { className: l.perfI, children: [
1241
+ /* @__PURE__ */ n("span", { className: l.perfB, style: { color: N.vram }, children: "VRAM" }),
1242
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, children: /* @__PURE__ */ n(ve, { type: "vram" }) })
1243
+ ] }),
1244
+ !e && /* @__PURE__ */ y("div", { className: l.perfI, children: [
1245
+ /* @__PURE__ */ n("span", { className: l.perfB, children: "Calls" }),
1246
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, children: /* @__PURE__ */ n(G, { metric: "calls" }) })
1247
+ ] })
1248
+ ] }) : null, Ft = ({ matrixUpdate: r }) => /* @__PURE__ */ y("div", { className: l.perfIContainer, children: [
1249
+ /* @__PURE__ */ y("div", { className: l.perfI, children: [
1250
+ /* @__PURE__ */ n("span", { className: l.perfB, children: "Geometries" }),
1251
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, children: /* @__PURE__ */ n(G, { metric: "geometries" }) })
1252
+ ] }),
1253
+ /* @__PURE__ */ y("div", { className: l.perfI, children: [
1254
+ /* @__PURE__ */ n("span", { className: l.perfB, children: "Textures" }),
1255
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, children: /* @__PURE__ */ n(G, { metric: "textures" }) })
1256
+ ] }),
1257
+ /* @__PURE__ */ y("div", { className: l.perfI, children: [
1258
+ /* @__PURE__ */ n("span", { className: l.perfB, children: "Shaders" }),
1259
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, children: /* @__PURE__ */ n(G, { metric: "programs" }) })
1260
+ ] }),
1261
+ /* @__PURE__ */ y("div", { className: l.perfI, children: [
1262
+ /* @__PURE__ */ n("span", { className: l.perfB, children: "Triangles" }),
1263
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, children: /* @__PURE__ */ n(G, { metric: "triangles" }) })
1264
+ ] }),
1265
+ /* @__PURE__ */ y("div", { className: l.perfI, children: [
1266
+ /* @__PURE__ */ n("span", { className: l.perfB, children: "Lines" }),
1267
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, children: /* @__PURE__ */ n(G, { metric: "lines" }) })
1268
+ ] }),
1269
+ /* @__PURE__ */ y("div", { className: l.perfI, children: [
1270
+ /* @__PURE__ */ n("span", { className: l.perfB, children: "Points" }),
1271
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, children: /* @__PURE__ */ n(G, { metric: "points" }) })
1272
+ ] }),
1273
+ r && /* @__PURE__ */ y("div", { className: l.perfI, children: [
1274
+ /* @__PURE__ */ n("span", { className: l.perfB, children: "Matrices" }),
1275
+ /* @__PURE__ */ n("small", { className: l.perfSmallI, children: r })
1276
+ ] })
1277
+ ] }), xe = ({ tab: r, title: e, set: t }) => {
1278
+ const i = L((m) => m.tab);
1279
+ return /* @__PURE__ */ n(
1280
+ "div",
1281
+ {
1282
+ className: `${l.toggle} ${i === r ? l.activeTab : ""}`,
1283
+ onClick: () => {
1284
+ t(!0), M({ tab: r });
1285
+ },
1286
+ children: e
1287
+ }
1288
+ );
1289
+ }, Pt = ({
1290
+ openByDefault: r,
1291
+ showGraph: e,
1292
+ deepAnalyze: t,
1293
+ matrixUpdate: i,
1294
+ graphType: m,
1295
+ perfContainerRef: o,
1296
+ antialias: a,
1297
+ chart: c,
1298
+ minimal: v
1299
+ }) => {
1300
+ const [s, d] = O(r || !1), f = L((p) => p.tab);
1301
+ return /* @__PURE__ */ y(z, { children: [
1302
+ /* @__PURE__ */ y("div", { style: { display: s ? "block" : "none", marginTop: "4px" }, children: [
1303
+ /* @__PURE__ */ n(Ft, { matrixUpdate: i }),
1304
+ e && (m === "bar" ? /* @__PURE__ */ n(St, {}) : /* @__PURE__ */ n(
1305
+ Lt,
1306
+ {
1307
+ perfContainerRef: o,
1308
+ chart: c,
1309
+ showGraph: e,
1310
+ antialias: a,
1311
+ minimal: v,
1312
+ matrixUpdate: i
1313
+ }
1314
+ )),
1315
+ s && /* @__PURE__ */ n("div", { className: l.containerScroll, children: f === "programs" && /* @__PURE__ */ n(Mt, {}) })
1316
+ ] }),
1317
+ r && !t ? null : /* @__PURE__ */ y(
1318
+ "div",
1319
+ {
1320
+ className: l.toggleContainer,
1321
+ style: s && e && m === "line" ? { marginTop: 50 } : { marginTop: 6 },
1322
+ children: [
1323
+ t && /* @__PURE__ */ n(xe, { tab: "programs", title: "Programs", set: d }),
1324
+ t && /* @__PURE__ */ n(xe, { tab: "infos", title: "Infos", set: d }),
1325
+ /* @__PURE__ */ n("div", { className: l.toggle, onClick: () => d(!s), children: s ? "Minimize" : "More" })
1326
+ ]
1327
+ }
1328
+ )
1329
+ ] });
1330
+ }, qt = ({
1331
+ showGraph: r = !0,
1332
+ openByDefault: e = !0,
1333
+ className: t,
1334
+ overClock: i = !1,
1335
+ graphType: m = "bar",
1336
+ style: o,
1337
+ position: a = "top-right",
1338
+ chart: c,
1339
+ logsPerSecond: v,
1340
+ deepAnalyze: s = !1,
1341
+ antialias: d = !0,
1342
+ matrixUpdate: f,
1343
+ minimal: p
1344
+ }) => {
1345
+ const h = I(null), u = a === "top-left" ? l.topLeft : a === "bottom-left" ? l.bottomLeft : a === "bottom-right" ? l.bottomRight : l.topRight, w = r && m === "line" && !s;
1346
+ return /* @__PURE__ */ y(z, { children: [
1347
+ /* @__PURE__ */ n(
1348
+ Ve,
1349
+ {
1350
+ logsPerSecond: v,
1351
+ chart: c,
1352
+ overClock: i,
1353
+ deepAnalyze: s,
1354
+ matrixUpdate: f
1355
+ }
1356
+ ),
1357
+ /* @__PURE__ */ n(be, { name: "r3f-perf", children: /* @__PURE__ */ y(
1358
+ "div",
1359
+ {
1360
+ className: `${l.perfS} ${u} ${p ? l.minimal : ""} ${t || ""} ${w ? l.containerHeight : ""}`,
1361
+ style: o,
1362
+ ref: h,
1363
+ children: [
1364
+ /* @__PURE__ */ n(Rt, { showGraph: r, minimal: p }),
1365
+ !p && /* @__PURE__ */ n(
1366
+ Pt,
1367
+ {
1368
+ showGraph: r,
1369
+ deepAnalyze: s,
1370
+ matrixUpdate: f,
1371
+ openByDefault: e,
1372
+ graphType: m,
1373
+ perfContainerRef: h,
1374
+ antialias: d,
1375
+ chart: c,
1376
+ minimal: p
1377
+ }
1378
+ )
1379
+ ]
1380
+ }
1381
+ ) })
1382
+ ] });
1383
+ };
1384
+ export {
1385
+ qt as PerformanceMonitor
1386
+ };