@eva/plugin-stats 2.0.1-beta.3 → 2.0.1-beta.30

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.
@@ -11,6 +11,9 @@ class StatsComponent extends eva_js.Component {
11
11
  }
12
12
  StatsComponent.componentName = 'Stats';
13
13
 
14
+ /**
15
+ * @author mrdoob / http://mrdoob.com/
16
+ */
14
17
  const Stats = function (style) {
15
18
  style = Object.assign({ width: 20, height: 12, x: 0, y: 0 }, style);
16
19
  const { width, height, x, y } = style;
@@ -27,6 +30,7 @@ const Stats = function (style) {
27
30
  }
28
31
  function showPanel(id) {
29
32
  for (let i = 0; i < container.children.length; i++) {
33
+ // @ts-ignore
30
34
  container.children[i].style.display = i === id ? 'block' : 'none';
31
35
  }
32
36
  mode = id;
@@ -37,6 +41,7 @@ const Stats = function (style) {
37
41
  const dcPanel = addPanel(Stats.Panel('DrawCall', '#330570', '#A69700'));
38
42
  const tcPanel = addPanel(Stats.Panel('TC:', '#A62500', '#00B454'));
39
43
  let memPanel;
44
+ // @ts-ignore
40
45
  if (self.performance && self.performance.memory) {
41
46
  memPanel = addPanel(Stats.Panel('MB', '#f08', '#201'));
42
47
  }
@@ -62,6 +67,7 @@ const Stats = function (style) {
62
67
  prevTime = time;
63
68
  frames = 0;
64
69
  if (memPanel) {
70
+ // @ts-ignore
65
71
  const memory = performance.memory;
66
72
  memPanel.update(memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576);
67
73
  }
@@ -71,6 +77,7 @@ const Stats = function (style) {
71
77
  update: function () {
72
78
  beginTime = this.end();
73
79
  },
80
+ // Backwards Compatibility
74
81
  domElement: container,
75
82
  setMode: showPanel,
76
83
  };
@@ -115,17 +122,41 @@ Stats.Panel = function (name, fg, bg) {
115
122
  };
116
123
  var Stats$1 = Stats;
117
124
 
125
+ /**
126
+ * WebGL 绘制调用 Hook 类
127
+ *
128
+ * GLHook 通过拦截 WebGL 的 drawElements 方法,
129
+ * 统计每帧的绘制调用次数(Draw Calls)。
130
+ * 绘制调用次数是衡量渲染性能的重要指标。
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * const glHook = new GLHook(gl);
135
+ * console.log('Draw Passes:', glHook.drawPasses);
136
+ * glHook.reset(); // 重置计数
137
+ * glHook.release(); // 移除 Hook
138
+ * ```
139
+ */
118
140
  class GLHook {
141
+ /**
142
+ * 构造 GL Hook
143
+ * @param _gl - WebGL 渲染上下文
144
+ */
119
145
  constructor(_gl) {
146
+ /** 绘制调用次数 */
120
147
  this.drawPasses = 0;
148
+ /** 是否已初始化 Hook */
121
149
  this.isInit = false;
150
+ /** 原始的 drawElements 方法 */
122
151
  this.realGLDrawElements = function () { };
123
152
  if (_gl) {
124
153
  if (_gl.__proto__.drawElements) {
125
154
  this.gl = _gl;
126
155
  this.realGLDrawElements = _gl.__proto__.drawElements;
156
+ //replace to new function
127
157
  _gl.__proto__.drawElements = this.fakeGLdrawElements(this);
128
158
  this.isInit = true;
159
+ // console.log("[GLHook] GL was Hooked!");
129
160
  }
130
161
  }
131
162
  else {
@@ -144,26 +175,54 @@ class GLHook {
144
175
  release() {
145
176
  if (this.isInit) {
146
177
  this.gl.__proto__.drawElements = this.realGLDrawElements;
178
+ // console.log("[GLHook] Hook was removed!");
147
179
  }
148
180
  this.isInit = false;
149
181
  }
150
182
  }
151
183
 
184
+ /**
185
+ * WebGL 纹理 Hook 类
186
+ *
187
+ * TextureHook 通过拦截 WebGL 的纹理创建和删除方法,
188
+ * 统计当前活跃的纹理数量和历史最大纹理数量。
189
+ * 纹理数量直接影响显存占用和渲染性能。
190
+ *
191
+ * @example
192
+ * ```typescript
193
+ * const textureHook = new TextureHook(gl);
194
+ * console.log('Current Textures:', textureHook.currentTextureCount);
195
+ * console.log('Max Textures:', textureHook.maxTexturesCount);
196
+ * textureHook.reset(); // 重置统计
197
+ * textureHook.release(); // 移除 Hook
198
+ * ```
199
+ */
152
200
  class TextureHook {
201
+ /**
202
+ * 构造纹理 Hook
203
+ * @param _gl - WebGL 渲染上下文
204
+ */
153
205
  constructor(_gl) {
206
+ /** 当前创建的纹理列表 */
154
207
  this.createdTextures = new Array();
208
+ /** 历史最大纹理数量 */
155
209
  this.maxTexturesCount = 0;
210
+ /** 是否已初始化 Hook */
156
211
  this.isInit = false;
212
+ /** 原始的 createTexture 方法 */
157
213
  this.realGLCreateTexture = function () { };
214
+ /** 原始的 deleteTexture 方法 */
158
215
  this.realGLDeleteTexture = function () { };
159
216
  if (_gl) {
160
217
  if (_gl.__proto__.createTexture) {
161
218
  this.gl = _gl;
162
219
  this.realGLCreateTexture = _gl.__proto__.createTexture;
163
220
  this.realGLDeleteTexture = _gl.__proto__.deleteTexture;
221
+ //replace to new function
164
222
  _gl.__proto__.createTexture = this.fakeGLCreateTexture(this);
165
223
  _gl.__proto__.deleteTexture = this.fakeGLDeleteTexture(this);
166
224
  this.isInit = true;
225
+ // console.log('[TextureHook] GL was Hooked!');
167
226
  }
168
227
  }
169
228
  else {
@@ -174,7 +233,7 @@ class TextureHook {
174
233
  return this.createdTextures.length;
175
234
  }
176
235
  registerTexture(texture) {
177
- this.createdTextures.push(texture);
236
+ this.createdTextures.push(texture); // ++;
178
237
  this.maxTexturesCount = Math.max(this.createdTextures.length, this.maxTexturesCount);
179
238
  }
180
239
  fakeGLCreateTexture(context) {
@@ -207,11 +266,40 @@ class TextureHook {
207
266
  }
208
267
  }
209
268
 
269
+ /**
270
+ * 基础 Hooks 类
271
+ *
272
+ * BaseHooks 用于监控 WebGL 的性能指标。
273
+ * 通过 hook WebGL 的底层方法,收集绘制调用次数、纹理数量等统计信息。
274
+ * 适用于性能分析和优化场景。
275
+ *
276
+ * @example
277
+ * ```typescript
278
+ * const hooks = new BaseHooks();
279
+ * hooks.attach(gl); // gl 是 WebGL 上下文
280
+ *
281
+ * // 每帧获取统计信息
282
+ * console.log('Draw Calls:', hooks.drawCalls);
283
+ * console.log('Textures:', hooks.texturesCount);
284
+ *
285
+ * // 重置统计
286
+ * hooks.reset();
287
+ * ```
288
+ */
210
289
  class BaseHooks {
211
290
  constructor() {
291
+ /** 上一次的绘制调用次数 */
212
292
  this._drawCalls = -1;
293
+ /** 最大增量绘制调用次数 */
213
294
  this._maxDeltaDrawCalls = -1;
214
295
  }
296
+ /**
297
+ * 附加 Hook 到 WebGL 上下文
298
+ *
299
+ * 拦截 WebGL 的绘制和纹理相关方法,开始收集统计信息。
300
+ *
301
+ * @param gl - WebGL 渲染上下文
302
+ */
215
303
  attach(gl) {
216
304
  this.glhook = new GLHook(gl);
217
305
  this.texturehook = new TextureHook(gl);
@@ -273,6 +361,7 @@ class StatsSystem extends eva_js.System {
273
361
  this.renderSystem = this.game.getSystem('Renderer');
274
362
  this.app = this.renderSystem.application;
275
363
  if (this.app && this.show) {
364
+ // @ts-ignore
276
365
  const gl = this.app.renderer.gl;
277
366
  this.hook = new BaseHooks();
278
367
  this.hook.attach(gl);
@@ -284,7 +373,7 @@ class StatsSystem extends eva_js.System {
284
373
  this.component = this.game.scene.addComponent(new StatsComponent());
285
374
  this.stats = Stats$1(this.style);
286
375
  this.component.stats = this.stats;
287
- this.stats.showPanel(0);
376
+ this.stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
288
377
  document.body.appendChild(this.stats.dom);
289
378
  }
290
379
  lateUpdate() {
@@ -7,6 +7,9 @@ class StatsComponent extends Component {
7
7
  }
8
8
  StatsComponent.componentName = 'Stats';
9
9
 
10
+ /**
11
+ * @author mrdoob / http://mrdoob.com/
12
+ */
10
13
  const Stats = function (style) {
11
14
  style = Object.assign({ width: 20, height: 12, x: 0, y: 0 }, style);
12
15
  const { width, height, x, y } = style;
@@ -23,6 +26,7 @@ const Stats = function (style) {
23
26
  }
24
27
  function showPanel(id) {
25
28
  for (let i = 0; i < container.children.length; i++) {
29
+ // @ts-ignore
26
30
  container.children[i].style.display = i === id ? 'block' : 'none';
27
31
  }
28
32
  mode = id;
@@ -33,6 +37,7 @@ const Stats = function (style) {
33
37
  const dcPanel = addPanel(Stats.Panel('DrawCall', '#330570', '#A69700'));
34
38
  const tcPanel = addPanel(Stats.Panel('TC:', '#A62500', '#00B454'));
35
39
  let memPanel;
40
+ // @ts-ignore
36
41
  if (self.performance && self.performance.memory) {
37
42
  memPanel = addPanel(Stats.Panel('MB', '#f08', '#201'));
38
43
  }
@@ -58,6 +63,7 @@ const Stats = function (style) {
58
63
  prevTime = time;
59
64
  frames = 0;
60
65
  if (memPanel) {
66
+ // @ts-ignore
61
67
  const memory = performance.memory;
62
68
  memPanel.update(memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576);
63
69
  }
@@ -67,6 +73,7 @@ const Stats = function (style) {
67
73
  update: function () {
68
74
  beginTime = this.end();
69
75
  },
76
+ // Backwards Compatibility
70
77
  domElement: container,
71
78
  setMode: showPanel,
72
79
  };
@@ -111,17 +118,41 @@ Stats.Panel = function (name, fg, bg) {
111
118
  };
112
119
  var Stats$1 = Stats;
113
120
 
121
+ /**
122
+ * WebGL 绘制调用 Hook 类
123
+ *
124
+ * GLHook 通过拦截 WebGL 的 drawElements 方法,
125
+ * 统计每帧的绘制调用次数(Draw Calls)。
126
+ * 绘制调用次数是衡量渲染性能的重要指标。
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * const glHook = new GLHook(gl);
131
+ * console.log('Draw Passes:', glHook.drawPasses);
132
+ * glHook.reset(); // 重置计数
133
+ * glHook.release(); // 移除 Hook
134
+ * ```
135
+ */
114
136
  class GLHook {
137
+ /**
138
+ * 构造 GL Hook
139
+ * @param _gl - WebGL 渲染上下文
140
+ */
115
141
  constructor(_gl) {
142
+ /** 绘制调用次数 */
116
143
  this.drawPasses = 0;
144
+ /** 是否已初始化 Hook */
117
145
  this.isInit = false;
146
+ /** 原始的 drawElements 方法 */
118
147
  this.realGLDrawElements = function () { };
119
148
  if (_gl) {
120
149
  if (_gl.__proto__.drawElements) {
121
150
  this.gl = _gl;
122
151
  this.realGLDrawElements = _gl.__proto__.drawElements;
152
+ //replace to new function
123
153
  _gl.__proto__.drawElements = this.fakeGLdrawElements(this);
124
154
  this.isInit = true;
155
+ // console.log("[GLHook] GL was Hooked!");
125
156
  }
126
157
  }
127
158
  else {
@@ -140,26 +171,54 @@ class GLHook {
140
171
  release() {
141
172
  if (this.isInit) {
142
173
  this.gl.__proto__.drawElements = this.realGLDrawElements;
174
+ // console.log("[GLHook] Hook was removed!");
143
175
  }
144
176
  this.isInit = false;
145
177
  }
146
178
  }
147
179
 
180
+ /**
181
+ * WebGL 纹理 Hook 类
182
+ *
183
+ * TextureHook 通过拦截 WebGL 的纹理创建和删除方法,
184
+ * 统计当前活跃的纹理数量和历史最大纹理数量。
185
+ * 纹理数量直接影响显存占用和渲染性能。
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * const textureHook = new TextureHook(gl);
190
+ * console.log('Current Textures:', textureHook.currentTextureCount);
191
+ * console.log('Max Textures:', textureHook.maxTexturesCount);
192
+ * textureHook.reset(); // 重置统计
193
+ * textureHook.release(); // 移除 Hook
194
+ * ```
195
+ */
148
196
  class TextureHook {
197
+ /**
198
+ * 构造纹理 Hook
199
+ * @param _gl - WebGL 渲染上下文
200
+ */
149
201
  constructor(_gl) {
202
+ /** 当前创建的纹理列表 */
150
203
  this.createdTextures = new Array();
204
+ /** 历史最大纹理数量 */
151
205
  this.maxTexturesCount = 0;
206
+ /** 是否已初始化 Hook */
152
207
  this.isInit = false;
208
+ /** 原始的 createTexture 方法 */
153
209
  this.realGLCreateTexture = function () { };
210
+ /** 原始的 deleteTexture 方法 */
154
211
  this.realGLDeleteTexture = function () { };
155
212
  if (_gl) {
156
213
  if (_gl.__proto__.createTexture) {
157
214
  this.gl = _gl;
158
215
  this.realGLCreateTexture = _gl.__proto__.createTexture;
159
216
  this.realGLDeleteTexture = _gl.__proto__.deleteTexture;
217
+ //replace to new function
160
218
  _gl.__proto__.createTexture = this.fakeGLCreateTexture(this);
161
219
  _gl.__proto__.deleteTexture = this.fakeGLDeleteTexture(this);
162
220
  this.isInit = true;
221
+ // console.log('[TextureHook] GL was Hooked!');
163
222
  }
164
223
  }
165
224
  else {
@@ -170,7 +229,7 @@ class TextureHook {
170
229
  return this.createdTextures.length;
171
230
  }
172
231
  registerTexture(texture) {
173
- this.createdTextures.push(texture);
232
+ this.createdTextures.push(texture); // ++;
174
233
  this.maxTexturesCount = Math.max(this.createdTextures.length, this.maxTexturesCount);
175
234
  }
176
235
  fakeGLCreateTexture(context) {
@@ -203,11 +262,40 @@ class TextureHook {
203
262
  }
204
263
  }
205
264
 
265
+ /**
266
+ * 基础 Hooks 类
267
+ *
268
+ * BaseHooks 用于监控 WebGL 的性能指标。
269
+ * 通过 hook WebGL 的底层方法,收集绘制调用次数、纹理数量等统计信息。
270
+ * 适用于性能分析和优化场景。
271
+ *
272
+ * @example
273
+ * ```typescript
274
+ * const hooks = new BaseHooks();
275
+ * hooks.attach(gl); // gl 是 WebGL 上下文
276
+ *
277
+ * // 每帧获取统计信息
278
+ * console.log('Draw Calls:', hooks.drawCalls);
279
+ * console.log('Textures:', hooks.texturesCount);
280
+ *
281
+ * // 重置统计
282
+ * hooks.reset();
283
+ * ```
284
+ */
206
285
  class BaseHooks {
207
286
  constructor() {
287
+ /** 上一次的绘制调用次数 */
208
288
  this._drawCalls = -1;
289
+ /** 最大增量绘制调用次数 */
209
290
  this._maxDeltaDrawCalls = -1;
210
291
  }
292
+ /**
293
+ * 附加 Hook 到 WebGL 上下文
294
+ *
295
+ * 拦截 WebGL 的绘制和纹理相关方法,开始收集统计信息。
296
+ *
297
+ * @param gl - WebGL 渲染上下文
298
+ */
211
299
  attach(gl) {
212
300
  this.glhook = new GLHook(gl);
213
301
  this.texturehook = new TextureHook(gl);
@@ -269,6 +357,7 @@ class StatsSystem extends System {
269
357
  this.renderSystem = this.game.getSystem('Renderer');
270
358
  this.app = this.renderSystem.application;
271
359
  if (this.app && this.show) {
360
+ // @ts-ignore
272
361
  const gl = this.app.renderer.gl;
273
362
  this.hook = new BaseHooks();
274
363
  this.hook.attach(gl);
@@ -280,7 +369,7 @@ class StatsSystem extends System {
280
369
  this.component = this.game.scene.addComponent(new StatsComponent());
281
370
  this.stats = Stats$1(this.style);
282
371
  this.component.stats = this.stats;
283
- this.stats.showPanel(0);
372
+ this.stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
284
373
  document.body.appendChild(this.stats.dom);
285
374
  }
286
375
  lateUpdate() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eva/plugin-stats",
3
- "version": "2.0.1-beta.3",
3
+ "version": "2.0.1-beta.30",
4
4
  "description": "@eva/plugin-stats",
5
5
  "main": "index.js",
6
6
  "module": "dist/plugin-stats.esm.js",
@@ -18,7 +18,7 @@
18
18
  "license": "MIT",
19
19
  "homepage": "https://eva.js.org",
20
20
  "dependencies": {
21
- "@eva/eva.js": "2.0.1-beta.3",
21
+ "@eva/eva.js": "2.0.1-beta.30",
22
22
  "lodash-es": "^4.17.21"
23
23
  }
24
24
  }