@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.
- package/dist/src/core/CoreNode.js +7 -5
- package/dist/src/core/CoreNode.js.map +1 -1
- package/dist/src/core/CoreTextureManager.d.ts +14 -8
- package/dist/src/core/CoreTextureManager.js +33 -59
- package/dist/src/core/CoreTextureManager.js.map +1 -1
- package/dist/src/core/Stage.d.ts +3 -3
- package/dist/src/core/Stage.js +9 -14
- package/dist/src/core/Stage.js.map +1 -1
- package/dist/src/core/TextureMemoryManager.d.ts +21 -17
- package/dist/src/core/TextureMemoryManager.js +99 -106
- package/dist/src/core/TextureMemoryManager.js.map +1 -1
- package/dist/src/core/lib/WebGlContextWrapper.d.ts +10 -0
- package/dist/src/core/lib/WebGlContextWrapper.js +32 -0
- package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
- package/dist/src/core/lib/textureCompression.js +13 -6
- package/dist/src/core/lib/textureCompression.js.map +1 -1
- package/dist/src/core/platform.js +4 -1
- package/dist/src/core/platform.js.map +1 -1
- package/dist/src/core/renderers/CoreContextTexture.d.ts +1 -0
- package/dist/src/core/renderers/CoreContextTexture.js.map +1 -1
- package/dist/src/core/renderers/canvas/CanvasCoreTexture.d.ts +1 -0
- package/dist/src/core/renderers/canvas/CanvasCoreTexture.js +4 -3
- package/dist/src/core/renderers/canvas/CanvasCoreTexture.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +9 -0
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +59 -29
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +4 -4
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
- package/dist/src/core/textures/ColorTexture.d.ts +2 -2
- package/dist/src/core/textures/ColorTexture.js +1 -2
- package/dist/src/core/textures/ColorTexture.js.map +1 -1
- package/dist/src/core/textures/ImageTexture.d.ts +7 -1
- package/dist/src/core/textures/ImageTexture.js +55 -39
- package/dist/src/core/textures/ImageTexture.js.map +1 -1
- package/dist/src/core/textures/NoiseTexture.js +1 -1
- package/dist/src/core/textures/NoiseTexture.js.map +1 -1
- package/dist/src/core/textures/RenderTexture.js +1 -1
- package/dist/src/core/textures/RenderTexture.js.map +1 -1
- package/dist/src/core/textures/SubTexture.d.ts +1 -2
- package/dist/src/core/textures/SubTexture.js +11 -29
- package/dist/src/core/textures/SubTexture.js.map +1 -1
- package/dist/src/core/textures/Texture.d.ts +51 -7
- package/dist/src/core/textures/Texture.js +130 -15
- package/dist/src/core/textures/Texture.js.map +1 -1
- package/dist/src/main-api/Inspector.d.ts +3 -0
- package/dist/src/main-api/Inspector.js +156 -0
- package/dist/src/main-api/Inspector.js.map +1 -1
- package/dist/src/main-api/Renderer.d.ts +1 -3
- package/dist/src/main-api/Renderer.js +2 -4
- package/dist/src/main-api/Renderer.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/core/CoreNode.ts +8 -4
- package/src/core/CoreTextureManager.ts +59 -65
- package/src/core/Stage.ts +10 -16
- package/src/core/TextureMemoryManager.ts +118 -131
- package/src/core/lib/WebGlContextWrapper.ts +38 -0
- package/src/core/lib/textureCompression.ts +18 -7
- package/src/core/platform.ts +5 -1
- package/src/core/renderers/CoreContextTexture.ts +1 -0
- package/src/core/renderers/canvas/CanvasCoreTexture.ts +5 -3
- package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +78 -40
- package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +10 -4
- package/src/core/textures/ColorTexture.ts +4 -7
- package/src/core/textures/ImageTexture.ts +66 -51
- package/src/core/textures/NoiseTexture.ts +1 -1
- package/src/core/textures/RenderTexture.ts +1 -1
- package/src/core/textures/SubTexture.ts +14 -31
- package/src/core/textures/Texture.ts +154 -21
- package/src/main-api/Inspector.ts +203 -0
- 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);
|
package/src/main-api/Renderer.ts
CHANGED
|
@@ -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(
|
|
758
|
-
this.stage.cleanup(
|
|
755
|
+
cleanup() {
|
|
756
|
+
this.stage.cleanup();
|
|
759
757
|
}
|
|
760
758
|
|
|
761
759
|
/**
|