@lightningjs/renderer 2.17.0 → 2.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/src/core/CoreNode.js +7 -5
  2. package/dist/src/core/CoreNode.js.map +1 -1
  3. package/dist/src/core/CoreTextureManager.d.ts +14 -8
  4. package/dist/src/core/CoreTextureManager.js +33 -59
  5. package/dist/src/core/CoreTextureManager.js.map +1 -1
  6. package/dist/src/core/Stage.d.ts +3 -3
  7. package/dist/src/core/Stage.js +9 -14
  8. package/dist/src/core/Stage.js.map +1 -1
  9. package/dist/src/core/TextureMemoryManager.d.ts +21 -17
  10. package/dist/src/core/TextureMemoryManager.js +99 -106
  11. package/dist/src/core/TextureMemoryManager.js.map +1 -1
  12. package/dist/src/core/lib/WebGlContextWrapper.d.ts +10 -0
  13. package/dist/src/core/lib/WebGlContextWrapper.js +32 -0
  14. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
  15. package/dist/src/core/lib/textureCompression.js +13 -6
  16. package/dist/src/core/lib/textureCompression.js.map +1 -1
  17. package/dist/src/core/platform.js +4 -1
  18. package/dist/src/core/platform.js.map +1 -1
  19. package/dist/src/core/renderers/CoreContextTexture.d.ts +1 -0
  20. package/dist/src/core/renderers/CoreContextTexture.js.map +1 -1
  21. package/dist/src/core/renderers/canvas/CanvasCoreTexture.d.ts +1 -0
  22. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js +4 -3
  23. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js.map +1 -1
  24. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +9 -0
  25. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +59 -29
  26. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  27. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +4 -4
  28. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
  29. package/dist/src/core/textures/ColorTexture.d.ts +2 -2
  30. package/dist/src/core/textures/ColorTexture.js +1 -2
  31. package/dist/src/core/textures/ColorTexture.js.map +1 -1
  32. package/dist/src/core/textures/ImageTexture.d.ts +7 -1
  33. package/dist/src/core/textures/ImageTexture.js +55 -39
  34. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  35. package/dist/src/core/textures/NoiseTexture.js +1 -1
  36. package/dist/src/core/textures/NoiseTexture.js.map +1 -1
  37. package/dist/src/core/textures/RenderTexture.js +1 -1
  38. package/dist/src/core/textures/RenderTexture.js.map +1 -1
  39. package/dist/src/core/textures/SubTexture.d.ts +1 -2
  40. package/dist/src/core/textures/SubTexture.js +11 -29
  41. package/dist/src/core/textures/SubTexture.js.map +1 -1
  42. package/dist/src/core/textures/Texture.d.ts +51 -7
  43. package/dist/src/core/textures/Texture.js +130 -15
  44. package/dist/src/core/textures/Texture.js.map +1 -1
  45. package/dist/src/main-api/Inspector.d.ts +3 -0
  46. package/dist/src/main-api/Inspector.js +156 -0
  47. package/dist/src/main-api/Inspector.js.map +1 -1
  48. package/dist/src/main-api/Renderer.d.ts +1 -3
  49. package/dist/src/main-api/Renderer.js +2 -4
  50. package/dist/src/main-api/Renderer.js.map +1 -1
  51. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  52. package/package.json +1 -1
  53. package/src/core/CoreNode.ts +8 -4
  54. package/src/core/CoreTextureManager.ts +59 -65
  55. package/src/core/Stage.ts +10 -16
  56. package/src/core/TextureMemoryManager.ts +118 -131
  57. package/src/core/lib/WebGlContextWrapper.ts +38 -0
  58. package/src/core/lib/textureCompression.ts +18 -7
  59. package/src/core/platform.ts +5 -1
  60. package/src/core/renderers/CoreContextTexture.ts +1 -0
  61. package/src/core/renderers/canvas/CanvasCoreTexture.ts +5 -3
  62. package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +78 -40
  63. package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +10 -4
  64. package/src/core/textures/ColorTexture.ts +4 -7
  65. package/src/core/textures/ImageTexture.ts +66 -51
  66. package/src/core/textures/NoiseTexture.ts +1 -1
  67. package/src/core/textures/RenderTexture.ts +1 -1
  68. package/src/core/textures/SubTexture.ts +14 -31
  69. package/src/core/textures/Texture.ts +154 -21
  70. package/src/main-api/Inspector.ts +203 -0
  71. package/src/main-api/Renderer.ts +2 -4
@@ -8,6 +8,8 @@ import type { AnimationSettings } from '../core/animations/CoreAnimation.js';
8
8
  import type { IAnimationController } from '../common/IAnimationController.js';
9
9
  import { isProductionEnvironment } from '../utils.js';
10
10
  import type { CoreTextNode, CoreTextNodeProps } from '../core/CoreTextNode.js';
11
+ import type { Texture } from '../core/textures/Texture.js';
12
+ import { TextureType } from '../core/textures/Texture.js';
11
13
 
12
14
  /**
13
15
  * Inspector
@@ -154,6 +156,22 @@ const gradientColorPropertyMap = [
154
156
  'colorBr',
155
157
  ];
156
158
 
159
+ const textureTypeNames: Record<number, string> = {
160
+ [TextureType.generic]: 'generic',
161
+ [TextureType.color]: 'color',
162
+ [TextureType.image]: 'image',
163
+ [TextureType.noise]: 'noise',
164
+ [TextureType.renderToTexture]: 'renderToTexture',
165
+ [TextureType.subTexture]: 'subTexture',
166
+ };
167
+
168
+ interface TextureMetrics {
169
+ previousState: string;
170
+ loadedCount: number;
171
+ failedCount: number;
172
+ freedCount: number;
173
+ }
174
+
157
175
  const knownProperties = new Set<string>([
158
176
  ...Object.keys(stylePropertyMap),
159
177
  ...Object.keys(domPropertyMap),
@@ -161,6 +179,7 @@ const knownProperties = new Set<string>([
161
179
  'src',
162
180
  'parent',
163
181
  'data',
182
+ 'texture',
164
183
  ]);
165
184
 
166
185
  export class Inspector {
@@ -170,6 +189,7 @@ export class Inspector {
170
189
  private width = 1920;
171
190
  private scaleX = 1;
172
191
  private scaleY = 1;
192
+ private textureMetrics = new Map<Texture, TextureMetrics>();
173
193
 
174
194
  constructor(canvas: HTMLCanvasElement, settings: RendererMainSettings) {
175
195
  if (isProductionEnvironment()) return;
@@ -284,6 +304,79 @@ export class Inspector {
284
304
  node: CoreNode | CoreTextNode,
285
305
  div: HTMLElement,
286
306
  ): CoreNode | CoreTextNode {
307
+ // Store texture event listeners for cleanup
308
+ const textureListeners = new Map<
309
+ Texture,
310
+ {
311
+ onLoaded: () => void;
312
+ onFailed: () => void;
313
+ onFreed: () => void;
314
+ }
315
+ >();
316
+
317
+ // Helper function to setup texture event listeners
318
+ const setupTextureListeners = (texture: Texture | null) => {
319
+ // Clean up existing listeners first
320
+ textureListeners.forEach((listeners, oldTexture) => {
321
+ oldTexture.off('loaded', listeners.onLoaded);
322
+ oldTexture.off('failed', listeners.onFailed);
323
+ oldTexture.off('freed', listeners.onFreed);
324
+ });
325
+ textureListeners.clear();
326
+
327
+ // Setup new listeners if texture exists
328
+ if (texture) {
329
+ // Initialize metrics if not exists
330
+ if (!this.textureMetrics.has(texture)) {
331
+ this.textureMetrics.set(texture, {
332
+ previousState: texture.state,
333
+ loadedCount: 0,
334
+ failedCount: 0,
335
+ freedCount: 0,
336
+ });
337
+ }
338
+
339
+ const onLoaded = () => {
340
+ const metrics = this.textureMetrics.get(texture);
341
+ if (metrics) {
342
+ metrics.previousState =
343
+ metrics.previousState !== texture.state
344
+ ? metrics.previousState
345
+ : 'loading';
346
+ metrics.loadedCount++;
347
+ }
348
+ this.updateTextureAttributes(div, texture);
349
+ };
350
+ const onFailed = () => {
351
+ const metrics = this.textureMetrics.get(texture);
352
+ if (metrics) {
353
+ metrics.previousState =
354
+ metrics.previousState !== texture.state
355
+ ? metrics.previousState
356
+ : 'loading';
357
+ metrics.failedCount++;
358
+ }
359
+ this.updateTextureAttributes(div, texture);
360
+ };
361
+ const onFreed = () => {
362
+ const metrics = this.textureMetrics.get(texture);
363
+ if (metrics) {
364
+ metrics.previousState =
365
+ metrics.previousState !== texture.state
366
+ ? metrics.previousState
367
+ : texture.state;
368
+ metrics.freedCount++;
369
+ }
370
+ this.updateTextureAttributes(div, texture);
371
+ };
372
+
373
+ texture.on('loaded', onLoaded);
374
+ texture.on('failed', onFailed);
375
+ texture.on('freed', onFreed);
376
+
377
+ textureListeners.set(texture, { onLoaded, onFailed, onFreed });
378
+ }
379
+ };
287
380
  // Define traps for each property in knownProperties
288
381
  knownProperties.forEach((property) => {
289
382
  let originalProp = Object.getOwnPropertyDescriptor(node, property);
@@ -311,6 +404,15 @@ export class Inspector {
311
404
  value,
312
405
  node.props,
313
406
  );
407
+
408
+ // Setup texture event listeners if this is a texture property
409
+ if (property === 'texture') {
410
+ const textureValue =
411
+ value && typeof value === 'object' && 'state' in value
412
+ ? (value as Texture)
413
+ : null;
414
+ setupTextureListeners(textureValue);
415
+ }
314
416
  },
315
417
  configurable: true,
316
418
  enumerable: true,
@@ -320,11 +422,26 @@ export class Inspector {
320
422
  const originalDestroy = node.destroy;
321
423
  Object.defineProperty(node, 'destroy', {
322
424
  value: () => {
425
+ // Clean up texture event listeners and metrics
426
+ textureListeners.forEach((listeners, texture) => {
427
+ texture.off('loaded', listeners.onLoaded);
428
+ texture.off('failed', listeners.onFailed);
429
+ texture.off('freed', listeners.onFreed);
430
+ // Clean up metrics for this texture
431
+ this.textureMetrics.delete(texture);
432
+ });
433
+ textureListeners.clear();
434
+
323
435
  this.destroyNode(node.id);
324
436
  originalDestroy.call(node);
325
437
  },
326
438
  });
327
439
 
440
+ // Setup initial texture listeners if node already has a texture
441
+ if (node.texture) {
442
+ setupTextureListeners(node.texture);
443
+ }
444
+
328
445
  const originalAnimate = node.animate;
329
446
  Object.defineProperty(node, 'animate', {
330
447
  value: (
@@ -353,6 +470,75 @@ export class Inspector {
353
470
  div?.remove();
354
471
  }
355
472
 
473
+ updateTextureAttributes(div: HTMLElement, texture: Texture) {
474
+ // Update texture state
475
+ div.setAttribute('data-texture-state', texture.state);
476
+
477
+ // Update texture type
478
+ div.setAttribute(
479
+ 'data-texture-type',
480
+ textureTypeNames[texture.type] || 'unknown',
481
+ );
482
+
483
+ // Update texture dimensions if available
484
+ if (texture.dimensions) {
485
+ div.setAttribute('data-texture-width', String(texture.dimensions.width));
486
+ div.setAttribute(
487
+ 'data-texture-height',
488
+ String(texture.dimensions.height),
489
+ );
490
+ } else {
491
+ div.removeAttribute('data-texture-width');
492
+ div.removeAttribute('data-texture-height');
493
+ }
494
+
495
+ // Update renderable owners count
496
+ div.setAttribute(
497
+ 'data-texture-owners',
498
+ String(texture.renderableOwners.length),
499
+ );
500
+
501
+ // Update retry count
502
+ div.setAttribute('data-texture-retry-count', String(texture.retryCount));
503
+
504
+ // Update max retry count if available
505
+ if (texture.maxRetryCount !== null) {
506
+ div.setAttribute(
507
+ 'data-texture-max-retry-count',
508
+ String(texture.maxRetryCount),
509
+ );
510
+ } else {
511
+ div.removeAttribute('data-texture-max-retry-count');
512
+ }
513
+
514
+ // Update metrics if available
515
+ const metrics = this.textureMetrics.get(texture);
516
+ if (metrics) {
517
+ div.setAttribute('data-texture-previous-state', metrics.previousState);
518
+ div.setAttribute(
519
+ 'data-texture-loaded-count',
520
+ String(metrics.loadedCount),
521
+ );
522
+ div.setAttribute(
523
+ 'data-texture-failed-count',
524
+ String(metrics.failedCount),
525
+ );
526
+ div.setAttribute('data-texture-freed-count', String(metrics.freedCount));
527
+ } else {
528
+ div.removeAttribute('data-texture-previous-state');
529
+ div.removeAttribute('data-texture-loaded-count');
530
+ div.removeAttribute('data-texture-failed-count');
531
+ div.removeAttribute('data-texture-freed-count');
532
+ }
533
+
534
+ // Update error information if present
535
+ if (texture.error) {
536
+ div.setAttribute('data-texture-error', texture.error.message);
537
+ } else {
538
+ div.removeAttribute('data-texture-error');
539
+ }
540
+ }
541
+
356
542
  updateNodeProperty(
357
543
  div: HTMLElement,
358
544
  property: keyof CoreNodeProps | keyof CoreTextNodeProps,
@@ -413,6 +599,23 @@ export class Inspector {
413
599
  return;
414
600
  }
415
601
 
602
+ // special case for texture information
603
+ if (property === 'texture') {
604
+ if (value && typeof value === 'object' && 'state' in value) {
605
+ const texture = value as Texture;
606
+ this.updateTextureAttributes(div, texture);
607
+ } else {
608
+ // Remove all texture attributes when texture is null
609
+ div.removeAttribute('data-texture-state');
610
+ div.removeAttribute('data-texture-type');
611
+ div.removeAttribute('data-texture-width');
612
+ div.removeAttribute('data-texture-height');
613
+ div.removeAttribute('data-texture-owners');
614
+ div.removeAttribute('data-texture-error');
615
+ }
616
+ return;
617
+ }
618
+
416
619
  // CSS mappable attribute
417
620
  if (stylePropertyMap[property]) {
418
621
  const mappedStyleResponse = stylePropertyMap[property]?.(value);
@@ -739,8 +739,6 @@ export class RendererMain extends EventEmitter {
739
739
  /**
740
740
  * Cleanup textures that are not being used
741
741
  *
742
- * @param aggressive - If true, will cleanup all textures, regardless of render status
743
- *
744
742
  * @remarks
745
743
  * This can be used to free up GFX memory used by textures that are no longer
746
744
  * being displayed.
@@ -754,8 +752,8 @@ export class RendererMain extends EventEmitter {
754
752
  * **NOTE3**: This will not cleanup textures that are marked as `preventCleanup`.
755
753
  * **NOTE4**: This has nothing to do with the garbage collection of JavaScript.
756
754
  */
757
- cleanup(aggressive: boolean = false) {
758
- this.stage.cleanup(aggressive);
755
+ cleanup() {
756
+ this.stage.cleanup();
759
757
  }
760
758
 
761
759
  /**