@lightningjs/renderer 0.7.6 → 0.8.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/README.md +4 -0
- package/dist/src/common/CommonTypes.d.ts +6 -0
- package/dist/src/core/CoreNode.d.ts +65 -8
- package/dist/src/core/CoreNode.js +104 -28
- package/dist/src/core/CoreNode.js.map +1 -1
- package/dist/src/core/CoreShaderManager.d.ts +2 -0
- package/dist/src/core/CoreShaderManager.js +2 -0
- package/dist/src/core/CoreShaderManager.js.map +1 -1
- package/dist/src/core/CoreTextNode.d.ts +5 -0
- package/dist/src/core/CoreTextNode.js +15 -10
- package/dist/src/core/CoreTextNode.js.map +1 -1
- package/dist/src/core/CoreTextureManager.js +2 -0
- package/dist/src/core/CoreTextureManager.js.map +1 -1
- package/dist/src/core/Stage.d.ts +4 -0
- package/dist/src/core/Stage.js +8 -1
- package/dist/src/core/Stage.js.map +1 -1
- package/dist/src/core/TextureMemoryManager.d.ts +12 -0
- package/dist/src/core/TextureMemoryManager.js +42 -0
- package/dist/src/core/TextureMemoryManager.js.map +1 -0
- package/dist/src/core/platform.js +8 -0
- package/dist/src/core/platform.js.map +1 -1
- package/dist/src/core/renderers/CoreContextTexture.d.ts +5 -1
- package/dist/src/core/renderers/CoreContextTexture.js +3 -1
- package/dist/src/core/renderers/CoreContextTexture.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.d.ts +2 -1
- package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js +2 -2
- package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +3 -1
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +22 -5
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +3 -0
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +4 -2
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/HolePunchEffect.d.ts +58 -0
- package/dist/src/core/renderers/webgl/shaders/effects/HolePunchEffect.js +112 -0
- package/dist/src/core/renderers/webgl/shaders/effects/HolePunchEffect.js.map +1 -0
- package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js +17 -30
- package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.d.ts +1 -0
- package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js +24 -30
- package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.d.ts +2 -0
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js +18 -0
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +8 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +26 -4
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js +4 -3
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +19 -0
- package/dist/src/core/text-rendering/renderers/TextRenderer.js +26 -0
- package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
- package/dist/src/core/textures/Texture.d.ts +26 -1
- package/dist/src/core/textures/Texture.js +30 -1
- package/dist/src/core/textures/Texture.js.map +1 -1
- package/dist/src/main-api/ICoreDriver.d.ts +1 -0
- package/dist/src/main-api/Inspector.js +2 -1
- package/dist/src/main-api/Inspector.js.map +1 -1
- package/dist/src/main-api/RendererMain.d.ts +10 -1
- package/dist/src/main-api/RendererMain.js +6 -1
- package/dist/src/main-api/RendererMain.js.map +1 -1
- package/dist/src/render-drivers/main/MainCoreDriver.d.ts +1 -0
- package/dist/src/render-drivers/main/MainCoreDriver.js +7 -0
- package/dist/src/render-drivers/main/MainCoreDriver.js.map +1 -1
- package/dist/src/render-drivers/main/MainOnlyNode.d.ts +1 -0
- package/dist/src/render-drivers/main/MainOnlyNode.js +10 -6
- package/dist/src/render-drivers/main/MainOnlyNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +1 -0
- package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -1
- package/dist/src/render-drivers/threadx/ThreadXRendererMessage.d.ts +1 -0
- package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +3 -0
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/renderer.js +1 -0
- package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
- package/dist/src/utils.d.ts +6 -0
- package/dist/src/utils.js +9 -1
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/common/CommonTypes.ts +7 -0
- package/src/core/CoreNode.ts +118 -34
- package/src/core/CoreShaderManager.ts +3 -0
- package/src/core/CoreTextNode.ts +44 -43
- package/src/core/CoreTextureManager.ts +2 -0
- package/src/core/Stage.ts +10 -0
- package/src/core/TextureMemoryManager.ts +66 -0
- package/src/core/platform.ts +8 -0
- package/src/core/renderers/CoreContextTexture.ts +6 -1
- package/src/core/renderers/webgl/WebGlCoreCtxSubTexture.ts +7 -2
- package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +34 -6
- package/src/core/renderers/webgl/WebGlCoreRenderer.ts +10 -2
- package/src/core/renderers/webgl/shaders/effects/HolePunchEffect.ts +166 -0
- package/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.ts +16 -32
- package/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.ts +26 -32
- package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +23 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +32 -4
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.ts +4 -3
- package/src/core/text-rendering/renderers/TextRenderer.ts +32 -0
- package/src/core/textures/Texture.ts +39 -2
- package/src/main-api/ICoreDriver.ts +2 -0
- package/src/main-api/Inspector.ts +2 -1
- package/src/main-api/RendererMain.ts +19 -2
- package/src/render-drivers/main/MainCoreDriver.ts +9 -0
- package/src/render-drivers/main/MainOnlyNode.ts +12 -6
- package/src/render-drivers/threadx/ThreadXCoreDriver.ts +1 -0
- package/src/render-drivers/threadx/ThreadXRendererMessage.ts +1 -0
- package/src/render-drivers/threadx/worker/ThreadXRendererNode.ts +7 -0
- package/src/render-drivers/threadx/worker/renderer.ts +1 -0
- package/src/utils.ts +10 -1
|
@@ -74,6 +74,13 @@ export type NodeTextureFailedPayload = {
|
|
|
74
74
|
error: Error;
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Payload for when texture failed to load
|
|
79
|
+
*/
|
|
80
|
+
export type NodeTextureFreedPayload = {
|
|
81
|
+
type: 'texture';
|
|
82
|
+
};
|
|
83
|
+
|
|
77
84
|
/**
|
|
78
85
|
* Combined type for all failed payloads
|
|
79
86
|
*/
|
package/src/core/CoreNode.ts
CHANGED
|
@@ -30,10 +30,12 @@ import type { Stage } from './Stage.js';
|
|
|
30
30
|
import type {
|
|
31
31
|
Texture,
|
|
32
32
|
TextureFailedEventHandler,
|
|
33
|
+
TextureFreedEventHandler,
|
|
33
34
|
TextureLoadedEventHandler,
|
|
34
35
|
} from './textures/Texture.js';
|
|
35
36
|
import type {
|
|
36
37
|
NodeTextureFailedPayload,
|
|
38
|
+
NodeTextureFreedPayload,
|
|
37
39
|
NodeTextureLoadedPayload,
|
|
38
40
|
} from '../common/CommonTypes.js';
|
|
39
41
|
import { EventEmitter } from '../common/EventEmitter.js';
|
|
@@ -111,47 +113,99 @@ export enum UpdateType {
|
|
|
111
113
|
|
|
112
114
|
/**
|
|
113
115
|
* Scale/Rotate transform update
|
|
116
|
+
*
|
|
117
|
+
* @remarks
|
|
118
|
+
* CoreNode Properties Updated:
|
|
119
|
+
* - `scaleRotateTransform`
|
|
114
120
|
*/
|
|
115
121
|
ScaleRotate = 2,
|
|
116
122
|
|
|
117
123
|
/**
|
|
118
124
|
* Translate transform update (x/y/width/height/pivot/mount)
|
|
125
|
+
*
|
|
126
|
+
* @remarks
|
|
127
|
+
* CoreNode Properties Updated:
|
|
128
|
+
* - `localTransform`
|
|
119
129
|
*/
|
|
120
130
|
Local = 4,
|
|
121
131
|
|
|
122
132
|
/**
|
|
123
|
-
* Global
|
|
133
|
+
* Global Transform update
|
|
134
|
+
*
|
|
135
|
+
* @remarks
|
|
136
|
+
* CoreNode Properties Updated:
|
|
137
|
+
* - `globalTransform`
|
|
138
|
+
* - `renderCoords`
|
|
139
|
+
* - `renderBound`
|
|
124
140
|
*/
|
|
125
141
|
Global = 8,
|
|
126
142
|
|
|
127
143
|
/**
|
|
128
144
|
* Clipping rect update
|
|
145
|
+
*
|
|
146
|
+
* @remarks
|
|
147
|
+
* CoreNode Properties Updated:
|
|
148
|
+
* - `clippingRect`
|
|
129
149
|
*/
|
|
130
150
|
Clipping = 16,
|
|
131
151
|
|
|
132
152
|
/**
|
|
133
153
|
* Calculated ZIndex update
|
|
154
|
+
*
|
|
155
|
+
* @remarks
|
|
156
|
+
* CoreNode Properties Updated:
|
|
157
|
+
* - `calcZIndex`
|
|
134
158
|
*/
|
|
135
159
|
CalculatedZIndex = 32,
|
|
136
160
|
|
|
137
161
|
/**
|
|
138
162
|
* Z-Index Sorted Children update
|
|
163
|
+
*
|
|
164
|
+
* @remarks
|
|
165
|
+
* CoreNode Properties Updated:
|
|
166
|
+
* - `children` (sorts children by their `calcZIndex`)
|
|
139
167
|
*/
|
|
140
168
|
ZIndexSortedChildren = 64,
|
|
141
169
|
|
|
142
170
|
/**
|
|
143
|
-
* Premultiplied Colors
|
|
171
|
+
* Premultiplied Colors update
|
|
172
|
+
*
|
|
173
|
+
* @remarks
|
|
174
|
+
* CoreNode Properties Updated:
|
|
175
|
+
* - `premultipliedColorTl`
|
|
176
|
+
* - `premultipliedColorTr`
|
|
177
|
+
* - `premultipliedColorBl`
|
|
178
|
+
* - `premultipliedColorBr`
|
|
144
179
|
*/
|
|
145
180
|
PremultipliedColors = 128,
|
|
146
181
|
|
|
147
182
|
/**
|
|
148
|
-
* World Alpha
|
|
183
|
+
* World Alpha update
|
|
149
184
|
*
|
|
150
185
|
* @remarks
|
|
151
|
-
*
|
|
186
|
+
* CoreNode Properties Updated:
|
|
187
|
+
* - `worldAlpha` = `parent.worldAlpha` * `alpha`
|
|
152
188
|
*/
|
|
153
189
|
WorldAlpha = 256,
|
|
154
190
|
|
|
191
|
+
/**
|
|
192
|
+
* Render State update
|
|
193
|
+
*
|
|
194
|
+
* @remarks
|
|
195
|
+
* CoreNode Properties Updated:
|
|
196
|
+
* - `renderState`
|
|
197
|
+
*/
|
|
198
|
+
RenderState = 512,
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Is Renderable update
|
|
202
|
+
*
|
|
203
|
+
* @remarks
|
|
204
|
+
* CoreNode Properties Updated:
|
|
205
|
+
* - `isRenderable`
|
|
206
|
+
*/
|
|
207
|
+
IsRenderable = 1024,
|
|
208
|
+
|
|
155
209
|
/**
|
|
156
210
|
* None
|
|
157
211
|
*/
|
|
@@ -160,7 +214,7 @@ export enum UpdateType {
|
|
|
160
214
|
/**
|
|
161
215
|
* All
|
|
162
216
|
*/
|
|
163
|
-
All =
|
|
217
|
+
All = 2047,
|
|
164
218
|
}
|
|
165
219
|
|
|
166
220
|
export class CoreNode extends EventEmitter implements ICoreNode {
|
|
@@ -219,7 +273,7 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
219
273
|
|
|
220
274
|
this.props.texture = texture;
|
|
221
275
|
this.props.textureOptions = options;
|
|
222
|
-
this.
|
|
276
|
+
this.setUpdateType(UpdateType.IsRenderable);
|
|
223
277
|
|
|
224
278
|
// If texture is already loaded / failed, trigger loaded event manually
|
|
225
279
|
// so that users get a consistent event experience.
|
|
@@ -230,20 +284,26 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
230
284
|
this.onTextureLoaded(texture, texture.dimensions!);
|
|
231
285
|
} else if (texture.state === 'failed') {
|
|
232
286
|
this.onTextureFailed(texture, texture.error!);
|
|
287
|
+
} else if (texture.state === 'freed') {
|
|
288
|
+
this.onTextureFreed(texture);
|
|
233
289
|
}
|
|
234
290
|
texture.on('loaded', this.onTextureLoaded);
|
|
235
291
|
texture.on('failed', this.onTextureFailed);
|
|
292
|
+
texture.on('freed', this.onTextureFreed);
|
|
236
293
|
});
|
|
237
294
|
}
|
|
238
295
|
|
|
239
296
|
unloadTexture(): void {
|
|
240
297
|
if (this.props.texture) {
|
|
241
|
-
|
|
242
|
-
|
|
298
|
+
const { texture } = this.props;
|
|
299
|
+
texture.off('loaded', this.onTextureLoaded);
|
|
300
|
+
texture.off('failed', this.onTextureFailed);
|
|
301
|
+
texture.off('freed', this.onTextureFreed);
|
|
302
|
+
texture.setRenderableOwner(this, false);
|
|
243
303
|
}
|
|
244
304
|
this.props.texture = null;
|
|
245
305
|
this.props.textureOptions = null;
|
|
246
|
-
this.
|
|
306
|
+
this.setUpdateType(UpdateType.IsRenderable);
|
|
247
307
|
}
|
|
248
308
|
|
|
249
309
|
private onTextureLoaded: TextureLoadedEventHandler = (target, dimensions) => {
|
|
@@ -262,6 +322,12 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
262
322
|
error,
|
|
263
323
|
} satisfies NodeTextureFailedPayload);
|
|
264
324
|
};
|
|
325
|
+
|
|
326
|
+
private onTextureFreed: TextureFreedEventHandler = (target: Texture) => {
|
|
327
|
+
this.emit('freed', {
|
|
328
|
+
type: 'texture',
|
|
329
|
+
} satisfies NodeTextureFreedPayload);
|
|
330
|
+
};
|
|
265
331
|
//#endregion Textures
|
|
266
332
|
|
|
267
333
|
loadShader<Type extends keyof ShaderMap>(
|
|
@@ -273,7 +339,7 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
273
339
|
const { shader, props: p } = shManager.loadShader(shaderType, props);
|
|
274
340
|
this.props.shader = shader;
|
|
275
341
|
this.props.shaderProps = p;
|
|
276
|
-
this.
|
|
342
|
+
this.setUpdateType(UpdateType.IsRenderable);
|
|
277
343
|
}
|
|
278
344
|
|
|
279
345
|
/**
|
|
@@ -353,8 +419,9 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
353
419
|
}
|
|
354
420
|
this.calculateRenderCoords();
|
|
355
421
|
this.updateBoundingRect();
|
|
356
|
-
this.
|
|
357
|
-
|
|
422
|
+
this.setUpdateType(
|
|
423
|
+
UpdateType.Clipping | UpdateType.RenderState | UpdateType.Children,
|
|
424
|
+
);
|
|
358
425
|
childUpdateType |= UpdateType.Global;
|
|
359
426
|
}
|
|
360
427
|
|
|
@@ -408,9 +475,15 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
408
475
|
true,
|
|
409
476
|
);
|
|
410
477
|
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
if (this.updateType & UpdateType.RenderState) {
|
|
481
|
+
this.updateRenderState(parentClippingRect);
|
|
482
|
+
this.setUpdateType(UpdateType.IsRenderable);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (this.updateType & UpdateType.IsRenderable) {
|
|
411
486
|
this.updateIsRenderable();
|
|
412
|
-
this.setUpdateType(UpdateType.Children);
|
|
413
|
-
childUpdateType |= UpdateType.PremultipliedColors;
|
|
414
487
|
}
|
|
415
488
|
|
|
416
489
|
// No need to update zIndex if there is no parent
|
|
@@ -501,25 +574,24 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
501
574
|
return false;
|
|
502
575
|
}
|
|
503
576
|
|
|
504
|
-
checkRenderBounds(): CoreNodeRenderState {
|
|
505
|
-
assertTruthy(this.clippingRect);
|
|
577
|
+
checkRenderBounds(parentClippingRect: RectWithValid): CoreNodeRenderState {
|
|
506
578
|
assertTruthy(this.renderBound);
|
|
507
|
-
const rectW =
|
|
508
|
-
const rectH =
|
|
579
|
+
const rectW = parentClippingRect.width || this.stage.root.width;
|
|
580
|
+
const rectH = parentClippingRect.height || this.stage.root.height;
|
|
509
581
|
this.strictBound = createBound(
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
rectW,
|
|
513
|
-
rectH,
|
|
582
|
+
parentClippingRect.x,
|
|
583
|
+
parentClippingRect.y,
|
|
584
|
+
parentClippingRect.x + rectW,
|
|
585
|
+
parentClippingRect.y + rectH,
|
|
514
586
|
this.strictBound,
|
|
515
587
|
);
|
|
516
588
|
|
|
517
589
|
const renderM = this.stage.boundsMargin;
|
|
518
590
|
this.preloadBound = createBound(
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
591
|
+
parentClippingRect.x - renderM[3],
|
|
592
|
+
parentClippingRect.y - renderM[0],
|
|
593
|
+
parentClippingRect.x + rectW + renderM[1],
|
|
594
|
+
parentClippingRect.y + rectH + renderM[2],
|
|
523
595
|
this.preloadBound,
|
|
524
596
|
);
|
|
525
597
|
|
|
@@ -533,13 +605,13 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
533
605
|
return CoreNodeRenderState.OutOfBounds;
|
|
534
606
|
}
|
|
535
607
|
|
|
536
|
-
updateRenderState() {
|
|
537
|
-
const renderState = this.checkRenderBounds();
|
|
608
|
+
updateRenderState(parentClippingRect: RectWithValid) {
|
|
609
|
+
const renderState = this.checkRenderBounds(parentClippingRect);
|
|
538
610
|
if (renderState !== this.renderState) {
|
|
539
611
|
const previous = this.renderState;
|
|
540
612
|
this.renderState = renderState;
|
|
541
613
|
if (previous === CoreNodeRenderState.InViewport) {
|
|
542
|
-
this.emit('
|
|
614
|
+
this.emit('outOfViewport', {
|
|
543
615
|
previous,
|
|
544
616
|
current: renderState,
|
|
545
617
|
});
|
|
@@ -551,7 +623,6 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
551
623
|
current: renderState,
|
|
552
624
|
});
|
|
553
625
|
}
|
|
554
|
-
this.updateIsRenderable();
|
|
555
626
|
}
|
|
556
627
|
|
|
557
628
|
setRenderState(state: CoreNodeRenderState) {
|
|
@@ -561,13 +632,26 @@ export class CoreNode extends EventEmitter implements ICoreNode {
|
|
|
561
632
|
}
|
|
562
633
|
}
|
|
563
634
|
|
|
564
|
-
|
|
565
|
-
|
|
635
|
+
/**
|
|
636
|
+
* This function updates the `isRenderable` property based on certain conditions.
|
|
637
|
+
*
|
|
638
|
+
* @returns
|
|
639
|
+
*/
|
|
566
640
|
updateIsRenderable() {
|
|
641
|
+
let newIsRenderable;
|
|
567
642
|
if (!this.checkRenderProps()) {
|
|
568
|
-
|
|
643
|
+
newIsRenderable = false;
|
|
644
|
+
} else {
|
|
645
|
+
newIsRenderable = this.renderState > CoreNodeRenderState.OutOfBounds;
|
|
646
|
+
}
|
|
647
|
+
if (this.isRenderable !== newIsRenderable) {
|
|
648
|
+
this.isRenderable = newIsRenderable;
|
|
649
|
+
this.onChangeIsRenderable(newIsRenderable);
|
|
569
650
|
}
|
|
570
|
-
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
onChangeIsRenderable(isRenderable: boolean) {
|
|
654
|
+
this.props.texture?.setRenderableOwner(this, isRenderable);
|
|
571
655
|
}
|
|
572
656
|
|
|
573
657
|
calculateRenderCoords() {
|
|
@@ -60,6 +60,7 @@ import {
|
|
|
60
60
|
RadialProgressEffect,
|
|
61
61
|
type RadialProgressEffectProps,
|
|
62
62
|
} from './renderers/webgl/shaders/effects/RadialProgressEffect.js';
|
|
63
|
+
import { HolePunchEffect } from './renderers/webgl/shaders/effects/HolePunchEffect.js';
|
|
63
64
|
|
|
64
65
|
export type { FadeOutEffectProps };
|
|
65
66
|
export type { LinearGradientEffectProps };
|
|
@@ -94,6 +95,7 @@ export interface EffectMap {
|
|
|
94
95
|
grayscale: typeof GrayscaleEffect;
|
|
95
96
|
glitch: typeof GlitchEffect;
|
|
96
97
|
radialProgress: typeof RadialProgressEffect;
|
|
98
|
+
holePunch: typeof HolePunchEffect;
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
export type EffectProps =
|
|
@@ -131,6 +133,7 @@ export class CoreShaderManager {
|
|
|
131
133
|
this.registerEffectType('glitch', GlitchEffect);
|
|
132
134
|
this.registerEffectType('radius', RadiusEffect);
|
|
133
135
|
this.registerEffectType('radialProgress', RadialProgressEffect);
|
|
136
|
+
this.registerEffectType('holePunch', HolePunchEffect);
|
|
134
137
|
}
|
|
135
138
|
|
|
136
139
|
registerShaderType<Type extends keyof ShaderMap>(
|
package/src/core/CoreTextNode.ts
CHANGED
|
@@ -55,35 +55,32 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
|
|
|
55
55
|
super(stage, props);
|
|
56
56
|
this._textRendererOverride = props.textRendererOverride;
|
|
57
57
|
const { resolvedTextRenderer, textRendererState } =
|
|
58
|
-
this.resolveTextRendererAndState(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
},
|
|
85
|
-
undefined,
|
|
86
|
-
);
|
|
58
|
+
this.resolveTextRendererAndState({
|
|
59
|
+
x: this.absX,
|
|
60
|
+
y: this.absY,
|
|
61
|
+
width: props.width,
|
|
62
|
+
height: props.height,
|
|
63
|
+
textAlign: props.textAlign,
|
|
64
|
+
color: props.color,
|
|
65
|
+
zIndex: props.zIndex,
|
|
66
|
+
contain: props.contain,
|
|
67
|
+
scrollable: props.scrollable,
|
|
68
|
+
scrollY: props.scrollY,
|
|
69
|
+
offsetY: props.offsetY,
|
|
70
|
+
letterSpacing: props.letterSpacing,
|
|
71
|
+
debug: props.debug,
|
|
72
|
+
fontFamily: props.fontFamily,
|
|
73
|
+
fontSize: props.fontSize,
|
|
74
|
+
fontStretch: props.fontStretch,
|
|
75
|
+
fontStyle: props.fontStyle,
|
|
76
|
+
fontWeight: props.fontWeight,
|
|
77
|
+
text: props.text,
|
|
78
|
+
lineHeight: props.lineHeight,
|
|
79
|
+
maxLines: props.maxLines,
|
|
80
|
+
textBaseline: props.textBaseline,
|
|
81
|
+
verticalAlign: props.verticalAlign,
|
|
82
|
+
overflowSuffix: props.overflowSuffix,
|
|
83
|
+
});
|
|
87
84
|
this.textRenderer = resolvedTextRenderer;
|
|
88
85
|
this.trState = textRendererState;
|
|
89
86
|
}
|
|
@@ -179,8 +176,10 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
|
|
|
179
176
|
set textRendererOverride(value: CoreTextNodeProps['textRendererOverride']) {
|
|
180
177
|
this._textRendererOverride = value;
|
|
181
178
|
|
|
179
|
+
this.textRenderer.destroyState(this.trState);
|
|
180
|
+
|
|
182
181
|
const { resolvedTextRenderer, textRendererState } =
|
|
183
|
-
this.resolveTextRendererAndState(this.trState.props
|
|
182
|
+
this.resolveTextRendererAndState(this.trState.props);
|
|
184
183
|
this.textRenderer = resolvedTextRenderer;
|
|
185
184
|
this.trState = textRendererState;
|
|
186
185
|
}
|
|
@@ -348,6 +347,11 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
|
|
|
348
347
|
return super.checkRenderProps();
|
|
349
348
|
}
|
|
350
349
|
|
|
350
|
+
override onChangeIsRenderable(isRenderable: boolean) {
|
|
351
|
+
super.onChangeIsRenderable(isRenderable);
|
|
352
|
+
this.textRenderer.setIsRenderable(this.trState, isRenderable);
|
|
353
|
+
}
|
|
354
|
+
|
|
351
355
|
override renderQuads(renderer: CoreRenderer) {
|
|
352
356
|
assertTruthy(this.globalTransform);
|
|
353
357
|
this.textRenderer.renderQuads(
|
|
@@ -358,15 +362,21 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
|
|
|
358
362
|
);
|
|
359
363
|
}
|
|
360
364
|
|
|
365
|
+
/**
|
|
366
|
+
* Destroy the node and cleanup all resources
|
|
367
|
+
*/
|
|
368
|
+
override destroy(): void {
|
|
369
|
+
super.destroy();
|
|
370
|
+
|
|
371
|
+
this.textRenderer.destroyState(this.trState);
|
|
372
|
+
}
|
|
373
|
+
|
|
361
374
|
/**
|
|
362
375
|
* Resolve a text renderer and a new state based on the current text renderer props provided
|
|
363
376
|
* @param props
|
|
364
377
|
* @returns
|
|
365
378
|
*/
|
|
366
|
-
private resolveTextRendererAndState(
|
|
367
|
-
props: TrProps,
|
|
368
|
-
prevState?: TextRendererState,
|
|
369
|
-
): {
|
|
379
|
+
private resolveTextRendererAndState(props: TrProps): {
|
|
370
380
|
resolvedTextRenderer: TextRenderer;
|
|
371
381
|
textRendererState: TextRendererState;
|
|
372
382
|
} {
|
|
@@ -377,15 +387,6 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
|
|
|
377
387
|
|
|
378
388
|
const textRendererState = resolvedTextRenderer.createState(props);
|
|
379
389
|
|
|
380
|
-
const stateEvents = ['loading', 'loaded', 'failed'];
|
|
381
|
-
|
|
382
|
-
if (prevState) {
|
|
383
|
-
// Remove the old event listeners from previous state obj there was one
|
|
384
|
-
stateEvents.forEach((eventName) => {
|
|
385
|
-
prevState.emitter.off(eventName);
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
|
|
389
390
|
textRendererState.emitter.on('loaded', this.onTextLoaded);
|
|
390
391
|
textRendererState.emitter.on('failed', this.onTextFailed);
|
|
391
392
|
|
package/src/core/Stage.ts
CHANGED
|
@@ -37,11 +37,13 @@ import type {
|
|
|
37
37
|
FpsUpdatePayload,
|
|
38
38
|
FrameTickPayload,
|
|
39
39
|
} from '../common/CommonTypes.js';
|
|
40
|
+
import { TextureMemoryManager } from './TextureMemoryManager.js';
|
|
40
41
|
|
|
41
42
|
export interface StageOptions {
|
|
42
43
|
rootId: number;
|
|
43
44
|
appWidth: number;
|
|
44
45
|
appHeight: number;
|
|
46
|
+
txMemByteThreshold: number;
|
|
45
47
|
boundsMargin: number | [number, number, number, number];
|
|
46
48
|
deviceLogicalPixelRatio: number;
|
|
47
49
|
devicePhysicalPixelRatio: number;
|
|
@@ -73,6 +75,7 @@ export class Stage extends EventEmitter {
|
|
|
73
75
|
/// Module Instances
|
|
74
76
|
public readonly animationManager: AnimationManager;
|
|
75
77
|
public readonly txManager: CoreTextureManager;
|
|
78
|
+
public readonly txMemManager: TextureMemoryManager;
|
|
76
79
|
public readonly fontManager: TrFontManager;
|
|
77
80
|
public readonly textRenderers: Partial<TextRendererMap>;
|
|
78
81
|
public readonly shManager: CoreShaderManager;
|
|
@@ -106,9 +109,11 @@ export class Stage extends EventEmitter {
|
|
|
106
109
|
boundsMargin,
|
|
107
110
|
enableContextSpy,
|
|
108
111
|
numImageWorkers,
|
|
112
|
+
txMemByteThreshold,
|
|
109
113
|
} = options;
|
|
110
114
|
|
|
111
115
|
this.txManager = new CoreTextureManager(numImageWorkers);
|
|
116
|
+
this.txMemManager = new TextureMemoryManager(txMemByteThreshold);
|
|
112
117
|
this.shManager = new CoreShaderManager();
|
|
113
118
|
this.animationManager = new AnimationManager();
|
|
114
119
|
this.contextSpy = enableContextSpy ? new ContextSpy() : null;
|
|
@@ -138,6 +143,7 @@ export class Stage extends EventEmitter {
|
|
|
138
143
|
clearColor: clearColor ?? 0xff000000,
|
|
139
144
|
bufferMemory,
|
|
140
145
|
txManager: this.txManager,
|
|
146
|
+
txMemManager: this.txMemManager,
|
|
141
147
|
shManager: this.shManager,
|
|
142
148
|
contextSpy: this.contextSpy,
|
|
143
149
|
});
|
|
@@ -243,11 +249,15 @@ export class Stage extends EventEmitter {
|
|
|
243
249
|
|
|
244
250
|
renderer?.render();
|
|
245
251
|
|
|
252
|
+
this.calculateFps();
|
|
253
|
+
|
|
246
254
|
// Reset renderRequested flag if it was set
|
|
247
255
|
if (renderRequested) {
|
|
248
256
|
this.renderRequested = false;
|
|
249
257
|
}
|
|
258
|
+
}
|
|
250
259
|
|
|
260
|
+
calculateFps() {
|
|
251
261
|
// If there's an FPS update interval, emit the FPS update event
|
|
252
262
|
// when the specified interval has elapsed.
|
|
253
263
|
const { fpsUpdateInterval } = this.options;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* If not stated otherwise in this file or this component's LICENSE file the
|
|
3
|
+
* following copyright and licenses apply:
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2024 Comcast Cable Communications Management, LLC.
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the License);
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
import type { CoreContextTexture } from './renderers/CoreContextTexture.js';
|
|
20
|
+
|
|
21
|
+
export class TextureMemoryManager {
|
|
22
|
+
private memUsed = 0;
|
|
23
|
+
private textures: Map<CoreContextTexture, number> = new Map();
|
|
24
|
+
private threshold: number;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param byteThreshold Number of texture bytes to trigger garbage collection
|
|
28
|
+
*/
|
|
29
|
+
constructor(byteThreshold: number) {
|
|
30
|
+
this.threshold = byteThreshold;
|
|
31
|
+
|
|
32
|
+
// If the threshold is 0, we disable the memory manager by replacing the
|
|
33
|
+
// setTextureMemUse method with a no-op function.
|
|
34
|
+
if (byteThreshold === 0) {
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
36
|
+
this.setTextureMemUse = () => {};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
setTextureMemUse(ctxTexture: CoreContextTexture, byteSize: number) {
|
|
41
|
+
if (this.textures.has(ctxTexture)) {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
43
|
+
this.memUsed -= this.textures.get(ctxTexture)!;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (byteSize === 0) {
|
|
47
|
+
this.textures.delete(ctxTexture);
|
|
48
|
+
return;
|
|
49
|
+
} else {
|
|
50
|
+
this.memUsed += byteSize;
|
|
51
|
+
this.textures.set(ctxTexture, byteSize);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (this.memUsed > this.threshold) {
|
|
55
|
+
this.gc();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
gc() {
|
|
60
|
+
this.textures.forEach((byteSize, ctxTexture) => {
|
|
61
|
+
if (!ctxTexture.renderable) {
|
|
62
|
+
ctxTexture.free();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
package/src/core/platform.ts
CHANGED
|
@@ -23,14 +23,22 @@ import type { Stage } from './Stage.js';
|
|
|
23
23
|
* Platform render loop initiator
|
|
24
24
|
*/
|
|
25
25
|
export const startLoop = (stage: Stage) => {
|
|
26
|
+
let isIdle = false;
|
|
26
27
|
const runLoop = () => {
|
|
27
28
|
stage.updateAnimations();
|
|
28
29
|
|
|
29
30
|
if (!stage.hasSceneUpdates()) {
|
|
31
|
+
// We still need to calculate the fps else it looks like the app is frozen
|
|
32
|
+
stage.calculateFps();
|
|
30
33
|
setTimeout(runLoop, 16.666666666666668);
|
|
34
|
+
if (!isIdle) {
|
|
35
|
+
stage.emit('idle');
|
|
36
|
+
isIdle = true;
|
|
37
|
+
}
|
|
31
38
|
return;
|
|
32
39
|
}
|
|
33
40
|
|
|
41
|
+
isIdle = false;
|
|
34
42
|
stage.drawFrame();
|
|
35
43
|
requestAnimationFrame(runLoop);
|
|
36
44
|
};
|
|
@@ -17,14 +17,19 @@
|
|
|
17
17
|
* limitations under the License.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
+
import type { TextureMemoryManager } from '../TextureMemoryManager.js';
|
|
20
21
|
import type { Texture } from '../textures/Texture.js';
|
|
21
22
|
|
|
22
23
|
export abstract class CoreContextTexture {
|
|
24
|
+
readonly memManager: TextureMemoryManager;
|
|
23
25
|
readonly textureSource: Texture;
|
|
24
26
|
|
|
25
|
-
constructor(textureSource: Texture) {
|
|
27
|
+
constructor(memManager: TextureMemoryManager, textureSource: Texture) {
|
|
28
|
+
this.memManager = memManager;
|
|
26
29
|
this.textureSource = textureSource;
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
abstract load(): void;
|
|
33
|
+
abstract free(): void;
|
|
34
|
+
abstract get renderable(): boolean;
|
|
30
35
|
}
|
|
@@ -18,13 +18,18 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import type { Dimensions } from '../../../common/CommonTypes.js';
|
|
21
|
+
import type { TextureMemoryManager } from '../../TextureMemoryManager.js';
|
|
21
22
|
import type { WebGlContextWrapper } from '../../lib/WebGlContextWrapper.js';
|
|
22
23
|
import type { SubTexture } from '../../textures/SubTexture.js';
|
|
23
24
|
import { WebGlCoreCtxTexture } from './WebGlCoreCtxTexture.js';
|
|
24
25
|
|
|
25
26
|
export class WebGlCoreCtxSubTexture extends WebGlCoreCtxTexture {
|
|
26
|
-
constructor(
|
|
27
|
-
|
|
27
|
+
constructor(
|
|
28
|
+
glw: WebGlContextWrapper,
|
|
29
|
+
memManager: TextureMemoryManager,
|
|
30
|
+
textureSource: SubTexture,
|
|
31
|
+
) {
|
|
32
|
+
super(glw, memManager, textureSource);
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
override async onLoadRequest(): Promise<Dimensions> {
|