@lightningjs/renderer 0.6.0 → 0.7.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.
- package/README.md +1 -1
- package/dist/src/common/CommonTypes.d.ts +8 -0
- package/dist/src/core/CoreNode.d.ts +63 -15
- package/dist/src/core/CoreNode.js +266 -117
- package/dist/src/core/CoreNode.js.map +1 -1
- package/dist/src/core/CoreTextNode.d.ts +11 -0
- package/dist/src/core/CoreTextNode.js +58 -0
- package/dist/src/core/CoreTextNode.js.map +1 -1
- package/dist/src/core/CoreTextureManager.d.ts +3 -1
- package/dist/src/core/CoreTextureManager.js +4 -1
- package/dist/src/core/CoreTextureManager.js.map +1 -1
- package/dist/src/core/Stage.d.ts +12 -2
- package/dist/src/core/Stage.js +36 -24
- package/dist/src/core/Stage.js.map +1 -1
- package/dist/src/core/animations/CoreAnimation.js +11 -2
- package/dist/src/core/animations/CoreAnimation.js.map +1 -1
- package/dist/src/core/lib/ContextSpy.d.ts +12 -0
- package/dist/src/core/lib/ContextSpy.js +38 -0
- package/dist/src/core/lib/ContextSpy.js.map +1 -0
- package/dist/src/core/lib/ImageWorker.d.ts +16 -0
- package/dist/src/core/lib/ImageWorker.js +111 -0
- package/dist/src/core/lib/ImageWorker.js.map +1 -0
- package/dist/src/core/lib/WebGlContext.d.ts +414 -0
- package/dist/src/core/lib/WebGlContext.js +640 -0
- package/dist/src/core/lib/WebGlContext.js.map +1 -0
- package/dist/src/core/lib/WebGlContextWrapper.d.ts +500 -0
- package/dist/src/core/lib/WebGlContextWrapper.js +784 -0
- package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -0
- package/dist/src/core/platform.js +4 -0
- package/dist/src/core/platform.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 -2
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +23 -21
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.d.ts +3 -2
- package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js +9 -13
- package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +4 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +33 -31
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreShader.d.ts +2 -1
- package/dist/src/core/renderers/webgl/WebGlCoreShader.js +24 -24
- package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/internal/RendererUtils.d.ts +8 -5
- package/dist/src/core/renderers/webgl/internal/RendererUtils.js +11 -13
- package/dist/src/core/renderers/webgl/internal/RendererUtils.js.map +1 -1
- package/dist/src/core/renderers/webgl/internal/ShaderUtils.d.ts +3 -2
- package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +15 -15
- package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +3 -6
- package/dist/src/core/renderers/webgl/shaders/DefaultShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js +3 -3
- package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/DynamicShader.d.ts +1 -0
- package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +32 -12
- package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js +3 -3
- package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/SdfShader.js +3 -3
- package/dist/src/core/renderers/webgl/shaders/SdfShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.d.ts +14 -1
- package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js +15 -5
- package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js.map +1 -1
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js +7 -8
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js.map +1 -1
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.d.ts +2 -1
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js +4 -2
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js +40 -13
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.d.ts +1 -1
- package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js +6 -6
- package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +3 -2
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +82 -50
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.d.ts +8 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js +29 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.d.ts +4 -3
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js +15 -11
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.d.ts +3 -2
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js +30 -26
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.d.ts +19 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js +84 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.d.ts +8 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js +40 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.d.ts +2 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js +41 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.d.ts +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js +4 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.d.ts +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js +2 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.d.ts +9 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js +32 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.d.ts +26 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.js +70 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.d.ts +16 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.js +39 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +50 -0
- package/dist/src/core/text-rendering/renderers/TextRenderer.js +19 -0
- package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
- package/dist/src/core/textures/ImageTexture.js +14 -9
- package/dist/src/core/textures/ImageTexture.js.map +1 -1
- package/dist/src/core/utils.d.ts +1 -6
- package/dist/src/core/utils.js +3 -2
- package/dist/src/core/utils.js.map +1 -1
- package/dist/src/main-api/ICoreDriver.d.ts +2 -1
- package/dist/src/main-api/RendererMain.d.ts +25 -0
- package/dist/src/main-api/RendererMain.js +14 -5
- package/dist/src/main-api/RendererMain.js.map +1 -1
- package/dist/src/render-drivers/main/MainCoreDriver.d.ts +2 -1
- package/dist/src/render-drivers/main/MainCoreDriver.js +6 -4
- package/dist/src/render-drivers/main/MainCoreDriver.js.map +1 -1
- package/dist/src/render-drivers/main/MainOnlyTextNode.d.ts +10 -0
- package/dist/src/render-drivers/main/MainOnlyTextNode.js +45 -0
- package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/TextNodeStruct.d.ts +10 -0
- package/dist/src/render-drivers/threadx/TextNodeStruct.js +45 -0
- package/dist/src/render-drivers/threadx/TextNodeStruct.js.map +1 -1
- package/dist/src/render-drivers/threadx/ThreadXCoreDriver.d.ts +2 -1
- package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +8 -1
- package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -1
- package/dist/src/render-drivers/threadx/ThreadXMainTextNode.d.ts +5 -0
- package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js +5 -0
- package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/ThreadXRendererMessage.d.ts +4 -1
- package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.d.ts +5 -0
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +10 -0
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/renderer.js +5 -3
- package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
- package/dist/src/utils.d.ts +2 -1
- package/dist/src/utils.js +22 -3
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/src/common/CommonTypes.ts +9 -0
- package/src/core/CoreNode.ts +325 -148
- package/src/core/CoreTextNode.ts +72 -0
- package/src/core/CoreTextureManager.ts +4 -2
- package/src/core/Stage.ts +60 -34
- package/src/core/animations/CoreAnimation.ts +11 -2
- package/src/core/lib/ContextSpy.ts +41 -0
- package/src/core/lib/ImageWorker.ts +124 -0
- package/src/core/lib/WebGlContextWrapper.ts +965 -0
- package/src/core/platform.ts +5 -0
- package/src/core/renderers/webgl/WebGlCoreCtxSubTexture.ts +3 -2
- package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +29 -28
- package/src/core/renderers/webgl/WebGlCoreRenderOp.ts +10 -14
- package/src/core/renderers/webgl/WebGlCoreRenderer.ts +34 -63
- package/src/core/renderers/webgl/WebGlCoreShader.ts +34 -25
- package/src/core/renderers/webgl/internal/RendererUtils.ts +13 -16
- package/src/core/renderers/webgl/internal/ShaderUtils.ts +16 -15
- package/src/core/renderers/webgl/shaders/DefaultShader.ts +3 -7
- package/src/core/renderers/webgl/shaders/DefaultShaderBatched.ts +3 -3
- package/src/core/renderers/webgl/shaders/DynamicShader.ts +42 -14
- package/src/core/renderers/webgl/shaders/RoundedRectangle.ts +3 -3
- package/src/core/renderers/webgl/shaders/SdfShader.ts +3 -3
- package/src/core/renderers/webgl/shaders/effects/BorderEffect.ts +1 -1
- package/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.ts +35 -5
- package/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.ts +7 -8
- package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.test.ts +9 -3
- package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.ts +4 -2
- package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +44 -15
- package/src/core/text-rendering/renderers/LightningTextTextureRenderer.ts +7 -7
- package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +115 -63
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.ts +26 -18
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.ts +40 -28
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.test.ts +6 -1
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.test.ts +205 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/{makeRenderWindow.ts → setRenderWindow.ts} +50 -21
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.ts +40 -0
- package/src/core/text-rendering/renderers/TextRenderer.ts +73 -0
- package/src/core/textures/ImageTexture.ts +17 -9
- package/src/core/utils.ts +87 -85
- package/src/env.d.ts +7 -0
- package/src/main-api/ICoreDriver.ts +2 -1
- package/src/main-api/RendererMain.ts +43 -5
- package/src/render-drivers/main/MainCoreDriver.ts +8 -5
- package/src/render-drivers/main/MainOnlyTextNode.ts +55 -1
- package/src/render-drivers/threadx/TextNodeStruct.ts +45 -0
- package/src/render-drivers/threadx/ThreadXCoreDriver.ts +10 -2
- package/src/render-drivers/threadx/ThreadXMainTextNode.ts +10 -0
- package/src/render-drivers/threadx/ThreadXRendererMessage.ts +5 -1
- package/src/render-drivers/threadx/worker/ThreadXRendererTextNode.ts +15 -0
- package/src/render-drivers/threadx/worker/renderer.ts +6 -4
- package/src/utils.ts +25 -4
- package/src/core/scene/Scene.ts +0 -120
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.test.ts +0 -136
package/src/core/CoreTextNode.ts
CHANGED
|
@@ -76,6 +76,11 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
|
|
|
76
76
|
fontStyle: props.fontStyle,
|
|
77
77
|
fontWeight: props.fontWeight,
|
|
78
78
|
text: props.text,
|
|
79
|
+
lineHeight: props.lineHeight,
|
|
80
|
+
maxLines: props.maxLines,
|
|
81
|
+
textBaseline: props.textBaseline,
|
|
82
|
+
verticalAlign: props.verticalAlign,
|
|
83
|
+
overflowSuffix: props.overflowSuffix,
|
|
79
84
|
},
|
|
80
85
|
undefined,
|
|
81
86
|
);
|
|
@@ -102,6 +107,9 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
|
|
|
102
107
|
}
|
|
103
108
|
this.updateLocalTransform();
|
|
104
109
|
|
|
110
|
+
// Incase the RAF loop has been stopped already before text was loaded,
|
|
111
|
+
// we request a render so it can be drawn.
|
|
112
|
+
this.stage.requestRender();
|
|
105
113
|
this.emit('loaded', {
|
|
106
114
|
type: 'text',
|
|
107
115
|
dimensions: {
|
|
@@ -148,6 +156,7 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
|
|
|
148
156
|
|
|
149
157
|
set text(value: string) {
|
|
150
158
|
this.textRenderer.set.text(this.trState, value);
|
|
159
|
+
this.checkIsRenderable();
|
|
151
160
|
}
|
|
152
161
|
|
|
153
162
|
get textRendererOverride(): CoreTextNodeProps['textRendererOverride'] {
|
|
@@ -251,6 +260,56 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
|
|
|
251
260
|
this.textRenderer.set.letterSpacing(this.trState, value);
|
|
252
261
|
}
|
|
253
262
|
|
|
263
|
+
get lineHeight(): CoreTextNodeProps['lineHeight'] {
|
|
264
|
+
return this.trState.props.lineHeight;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
set lineHeight(value: CoreTextNodeProps['lineHeight']) {
|
|
268
|
+
if (this.textRenderer.set.lineHeight) {
|
|
269
|
+
this.textRenderer.set.lineHeight(this.trState, value);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
get maxLines(): CoreTextNodeProps['maxLines'] {
|
|
274
|
+
return this.trState.props.maxLines;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
set maxLines(value: CoreTextNodeProps['maxLines']) {
|
|
278
|
+
if (this.textRenderer.set.maxLines) {
|
|
279
|
+
this.textRenderer.set.maxLines(this.trState, value);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
get textBaseline(): CoreTextNodeProps['textBaseline'] {
|
|
284
|
+
return this.trState.props.textBaseline;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
set textBaseline(value: CoreTextNodeProps['textBaseline']) {
|
|
288
|
+
if (this.textRenderer.set.textBaseline) {
|
|
289
|
+
this.textRenderer.set.textBaseline(this.trState, value);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
get verticalAlign(): CoreTextNodeProps['verticalAlign'] {
|
|
294
|
+
return this.trState.props.verticalAlign;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
set verticalAlign(value: CoreTextNodeProps['verticalAlign']) {
|
|
298
|
+
if (this.textRenderer.set.verticalAlign) {
|
|
299
|
+
this.textRenderer.set.verticalAlign(this.trState, value);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
get overflowSuffix(): CoreTextNodeProps['overflowSuffix'] {
|
|
304
|
+
return this.trState.props.overflowSuffix;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
set overflowSuffix(value: CoreTextNodeProps['overflowSuffix']) {
|
|
308
|
+
if (this.textRenderer.set.overflowSuffix) {
|
|
309
|
+
this.textRenderer.set.overflowSuffix(this.trState, value);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
254
313
|
get debug(): CoreTextNodeProps['debug'] {
|
|
255
314
|
return this.trState.props.debug;
|
|
256
315
|
}
|
|
@@ -269,6 +328,18 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
|
|
|
269
328
|
this.textRenderer.set.y(this.trState, this.globalTransform.ty);
|
|
270
329
|
}
|
|
271
330
|
|
|
331
|
+
override checkIsRenderable(): boolean {
|
|
332
|
+
if (super.checkIsRenderable()) {
|
|
333
|
+
return true;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (this.trState.props.text !== '') {
|
|
337
|
+
return (this.isRenderable = true);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return (this.isRenderable = false);
|
|
341
|
+
}
|
|
342
|
+
|
|
272
343
|
override renderQuads(renderer: CoreRenderer) {
|
|
273
344
|
assertTruthy(this.globalTransform);
|
|
274
345
|
this.textRenderer.renderQuads(
|
|
@@ -309,6 +380,7 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
|
|
|
309
380
|
|
|
310
381
|
textRendererState.emitter.on('loaded', this.onTextLoaded);
|
|
311
382
|
textRendererState.emitter.on('failed', this.onTextFailed);
|
|
383
|
+
|
|
312
384
|
resolvedTextRenderer.scheduleUpdateState(textRendererState);
|
|
313
385
|
|
|
314
386
|
return {
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import { assertTruthy } from '../utils.js';
|
|
21
|
+
import { ImageWorkerManager } from './lib/ImageWorker.js';
|
|
21
22
|
import type { CoreContextTexture } from './renderers/CoreContextTexture.js';
|
|
22
23
|
import type { CoreRenderer } from './renderers/CoreRenderer.js';
|
|
23
24
|
import { ColorTexture } from './textures/ColorTexture.js';
|
|
@@ -144,7 +145,7 @@ export class CoreTextureManager {
|
|
|
144
145
|
Texture,
|
|
145
146
|
{ cacheKey: string | false; count: number }
|
|
146
147
|
> = new WeakMap();
|
|
147
|
-
|
|
148
|
+
imageWorkerManager: ImageWorkerManager;
|
|
148
149
|
/**
|
|
149
150
|
* Renderer that this texture manager is associated with
|
|
150
151
|
*
|
|
@@ -154,8 +155,9 @@ export class CoreTextureManager {
|
|
|
154
155
|
*/
|
|
155
156
|
renderer!: CoreRenderer;
|
|
156
157
|
|
|
157
|
-
constructor() {
|
|
158
|
+
constructor(numImageWorkers: number) {
|
|
158
159
|
// Register default known texture types
|
|
160
|
+
this.imageWorkerManager = new ImageWorkerManager(numImageWorkers);
|
|
159
161
|
this.registerTextureType('ImageTexture', ImageTexture);
|
|
160
162
|
this.registerTextureType('ColorTexture', ColorTexture);
|
|
161
163
|
this.registerTextureType('NoiseTexture', NoiseTexture);
|
package/src/core/Stage.ts
CHANGED
|
@@ -16,11 +16,7 @@
|
|
|
16
16
|
* See the License for the specific language governing permissions and
|
|
17
17
|
* limitations under the License.
|
|
18
18
|
*/
|
|
19
|
-
|
|
20
|
-
import { Scene } from './scene/Scene.js';
|
|
21
|
-
|
|
22
19
|
import { startLoop, getTimeStamp } from './platform.js';
|
|
23
|
-
|
|
24
20
|
import { WebGlCoreRenderer } from './renderers/webgl/WebGlCoreRenderer.js';
|
|
25
21
|
import { assertTruthy } from '../utils.js';
|
|
26
22
|
import { AnimationManager } from './animations/AnimationManager.js';
|
|
@@ -36,6 +32,8 @@ import type {
|
|
|
36
32
|
import { SdfTextRenderer } from './text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js';
|
|
37
33
|
import { CanvasTextRenderer } from './text-rendering/renderers/CanvasTextRenderer.js';
|
|
38
34
|
import { EventEmitter } from '../common/EventEmitter.js';
|
|
35
|
+
import { ContextSpy } from './lib/ContextSpy.js';
|
|
36
|
+
import type { FpsUpdatePayload } from '../common/CommonTypes.js';
|
|
39
37
|
|
|
40
38
|
export interface StageOptions {
|
|
41
39
|
rootId: number;
|
|
@@ -46,11 +44,19 @@ export interface StageOptions {
|
|
|
46
44
|
canvas: HTMLCanvasElement | OffscreenCanvas;
|
|
47
45
|
clearColor: number;
|
|
48
46
|
fpsUpdateInterval: number;
|
|
47
|
+
enableContextSpy: boolean;
|
|
48
|
+
numImageWorkers: number;
|
|
49
|
+
|
|
49
50
|
debug?: {
|
|
50
51
|
monitorTextureCache?: boolean;
|
|
51
52
|
};
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
export type StageFpsUpdateHandler = (
|
|
56
|
+
stage: Stage,
|
|
57
|
+
fpsData: FpsUpdatePayload,
|
|
58
|
+
) => void;
|
|
59
|
+
|
|
54
60
|
const bufferMemory = 2e6;
|
|
55
61
|
const autoStart = true;
|
|
56
62
|
|
|
@@ -62,7 +68,7 @@ export class Stage extends EventEmitter {
|
|
|
62
68
|
public readonly textRenderers: Partial<TextRendererMap>;
|
|
63
69
|
public readonly shManager: CoreShaderManager;
|
|
64
70
|
public readonly renderer: WebGlCoreRenderer;
|
|
65
|
-
|
|
71
|
+
public readonly root: CoreNode;
|
|
66
72
|
|
|
67
73
|
/// State
|
|
68
74
|
deltaTime = 0;
|
|
@@ -70,16 +76,31 @@ export class Stage extends EventEmitter {
|
|
|
70
76
|
currentFrameTime = 0;
|
|
71
77
|
private fpsNumFrames = 0;
|
|
72
78
|
private fpsElapsedTime = 0;
|
|
79
|
+
private renderRequested = false;
|
|
80
|
+
|
|
81
|
+
/// Debug data
|
|
82
|
+
contextSpy: ContextSpy | null = null;
|
|
73
83
|
|
|
74
84
|
/**
|
|
75
85
|
* Stage constructor
|
|
76
86
|
*/
|
|
77
87
|
constructor(readonly options: StageOptions) {
|
|
78
88
|
super();
|
|
79
|
-
const {
|
|
80
|
-
|
|
89
|
+
const {
|
|
90
|
+
canvas,
|
|
91
|
+
clearColor,
|
|
92
|
+
rootId,
|
|
93
|
+
debug,
|
|
94
|
+
appWidth,
|
|
95
|
+
appHeight,
|
|
96
|
+
enableContextSpy,
|
|
97
|
+
numImageWorkers,
|
|
98
|
+
} = options;
|
|
99
|
+
|
|
100
|
+
this.txManager = new CoreTextureManager(numImageWorkers);
|
|
81
101
|
this.shManager = new CoreShaderManager();
|
|
82
102
|
this.animationManager = new AnimationManager();
|
|
103
|
+
this.contextSpy = enableContextSpy ? new ContextSpy() : null;
|
|
83
104
|
|
|
84
105
|
if (debug?.monitorTextureCache) {
|
|
85
106
|
setInterval(() => {
|
|
@@ -99,6 +120,7 @@ export class Stage extends EventEmitter {
|
|
|
99
120
|
bufferMemory,
|
|
100
121
|
txManager: this.txManager,
|
|
101
122
|
shManager: this.shManager,
|
|
123
|
+
contextSpy: this.contextSpy,
|
|
102
124
|
});
|
|
103
125
|
|
|
104
126
|
// Must do this after renderer is created
|
|
@@ -146,7 +168,7 @@ export class Stage extends EventEmitter {
|
|
|
146
168
|
shaderProps: null,
|
|
147
169
|
});
|
|
148
170
|
|
|
149
|
-
this.
|
|
171
|
+
this.root = rootNode;
|
|
150
172
|
|
|
151
173
|
// execute platform start loop
|
|
152
174
|
if (autoStart) {
|
|
@@ -158,8 +180,8 @@ export class Stage extends EventEmitter {
|
|
|
158
180
|
* Update animations
|
|
159
181
|
*/
|
|
160
182
|
updateAnimations() {
|
|
161
|
-
const {
|
|
162
|
-
if (!
|
|
183
|
+
const { animationManager } = this;
|
|
184
|
+
if (!this.root) {
|
|
163
185
|
return;
|
|
164
186
|
}
|
|
165
187
|
this.lastFrameTime = this.currentFrameTime;
|
|
@@ -177,34 +199,32 @@ export class Stage extends EventEmitter {
|
|
|
177
199
|
* Check if the scene has updates
|
|
178
200
|
*/
|
|
179
201
|
hasSceneUpdates() {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (!scene?.root) {
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return scene?.root?.hasUpdates;
|
|
202
|
+
return !!this.root.updateType || this.renderRequested;
|
|
187
203
|
}
|
|
188
204
|
|
|
189
205
|
/**
|
|
190
206
|
* Start a new frame draw
|
|
191
207
|
*/
|
|
192
208
|
drawFrame() {
|
|
193
|
-
const { renderer,
|
|
194
|
-
if (!scene?.root) {
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
209
|
+
const { renderer, renderRequested } = this;
|
|
197
210
|
|
|
198
|
-
//
|
|
199
|
-
|
|
211
|
+
// Update tree if needed
|
|
212
|
+
if (this.root.updateType !== 0) {
|
|
213
|
+
this.root.update(this.deltaTime);
|
|
214
|
+
}
|
|
200
215
|
|
|
201
216
|
// test if we need to update the scene
|
|
202
217
|
renderer?.reset();
|
|
203
218
|
|
|
204
|
-
this.addQuads(
|
|
219
|
+
this.addQuads(this.root);
|
|
205
220
|
|
|
206
221
|
renderer?.render();
|
|
207
222
|
|
|
223
|
+
// Reset renderRequested flag if it was set
|
|
224
|
+
if (renderRequested) {
|
|
225
|
+
this.renderRequested = false;
|
|
226
|
+
}
|
|
227
|
+
|
|
208
228
|
// If there's an FPS update interval, emit the FPS update event
|
|
209
229
|
// when the specified interval has elapsed.
|
|
210
230
|
const { fpsUpdateInterval } = this.options;
|
|
@@ -217,7 +237,11 @@ export class Stage extends EventEmitter {
|
|
|
217
237
|
);
|
|
218
238
|
this.fpsNumFrames = 0;
|
|
219
239
|
this.fpsElapsedTime = 0;
|
|
220
|
-
this.emit('fpsUpdate',
|
|
240
|
+
this.emit('fpsUpdate', {
|
|
241
|
+
fps,
|
|
242
|
+
contextSpyData: this.contextSpy?.getData() ?? null,
|
|
243
|
+
} satisfies FpsUpdatePayload);
|
|
244
|
+
this.contextSpy?.reset();
|
|
221
245
|
}
|
|
222
246
|
}
|
|
223
247
|
}
|
|
@@ -225,7 +249,10 @@ export class Stage extends EventEmitter {
|
|
|
225
249
|
addQuads(node: CoreNode) {
|
|
226
250
|
assertTruthy(this.renderer && node.globalTransform);
|
|
227
251
|
|
|
228
|
-
node.
|
|
252
|
+
if (node.isRenderable) {
|
|
253
|
+
node.renderQuads(this.renderer);
|
|
254
|
+
}
|
|
255
|
+
|
|
229
256
|
for (let i = 0; i < node.children.length; i++) {
|
|
230
257
|
const child = node.children[i];
|
|
231
258
|
|
|
@@ -241,6 +268,13 @@ export class Stage extends EventEmitter {
|
|
|
241
268
|
}
|
|
242
269
|
}
|
|
243
270
|
|
|
271
|
+
/**
|
|
272
|
+
* Request a render pass without forcing an update
|
|
273
|
+
*/
|
|
274
|
+
requestRender() {
|
|
275
|
+
this.renderRequested = true;
|
|
276
|
+
}
|
|
277
|
+
|
|
244
278
|
/**
|
|
245
279
|
* Given a font name, and possible renderer override, return the best compatible text renderer.
|
|
246
280
|
*
|
|
@@ -305,12 +339,4 @@ export class Stage extends EventEmitter {
|
|
|
305
339
|
// the covariant state argument in the setter method map
|
|
306
340
|
return resolvedTextRenderer as unknown as TextRenderer;
|
|
307
341
|
}
|
|
308
|
-
|
|
309
|
-
//#region Properties
|
|
310
|
-
|
|
311
|
-
get root() {
|
|
312
|
-
return this.scene?.root || null;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
//#endregion Properties
|
|
316
342
|
}
|
|
@@ -98,7 +98,7 @@ export class CoreAnimation extends EventEmitter {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
update(dt: number) {
|
|
101
|
-
const { duration, loop, easing } = this.settings;
|
|
101
|
+
const { duration, loop, easing, stopMethod } = this.settings;
|
|
102
102
|
if (!duration) {
|
|
103
103
|
this.emit('finished', {});
|
|
104
104
|
return;
|
|
@@ -108,7 +108,13 @@ export class CoreAnimation extends EventEmitter {
|
|
|
108
108
|
|
|
109
109
|
if (this.progress > 1) {
|
|
110
110
|
this.progress = loop ? 0 : 1;
|
|
111
|
-
|
|
111
|
+
if (stopMethod) {
|
|
112
|
+
// If there's a stop method emit finished so the stop method can be applied.
|
|
113
|
+
// TODO: We should probably reevaluate how stopMethod is implemented as currently
|
|
114
|
+
// stop method 'reset' does not work when looping.
|
|
115
|
+
this.emit('finished', {});
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
112
118
|
}
|
|
113
119
|
|
|
114
120
|
for (let i = 0; i < this.propsList.length; i++) {
|
|
@@ -156,5 +162,8 @@ export class CoreAnimation extends EventEmitter {
|
|
|
156
162
|
this.node[propName] =
|
|
157
163
|
startValue + (endValue - startValue) * this.progress;
|
|
158
164
|
}
|
|
165
|
+
if (this.progress === 1) {
|
|
166
|
+
this.emit('finished', {});
|
|
167
|
+
}
|
|
159
168
|
}
|
|
160
169
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
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 2023 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
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Class that keeps track of the invocations of Context methods when
|
|
22
|
+
* the `enableContextSpy` renderer option is enabled.
|
|
23
|
+
*/
|
|
24
|
+
export class ContextSpy {
|
|
25
|
+
private data: Record<string, number> = {};
|
|
26
|
+
|
|
27
|
+
reset() {
|
|
28
|
+
this.data = {};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
increment(name: string) {
|
|
32
|
+
if (!this.data[name]) {
|
|
33
|
+
this.data[name] = 0;
|
|
34
|
+
}
|
|
35
|
+
this.data[name]++;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getData() {
|
|
39
|
+
return { ...this.data };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
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 2023 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
|
+
|
|
20
|
+
import { type TextureData } from '../textures/Texture.js';
|
|
21
|
+
|
|
22
|
+
type MessageCallback = [(value: any) => void, (reason: any) => void];
|
|
23
|
+
|
|
24
|
+
export class ImageWorkerManager {
|
|
25
|
+
isWorkerSupported = !!self.Worker;
|
|
26
|
+
imageWorkersEnabled = true;
|
|
27
|
+
messageManager: Record<string, MessageCallback> = {};
|
|
28
|
+
workers: Worker[] = [];
|
|
29
|
+
workerIndex = 0;
|
|
30
|
+
|
|
31
|
+
constructor(numImageWorkers: number) {
|
|
32
|
+
if (this.isWorkerSupported && numImageWorkers > 0) {
|
|
33
|
+
this.workers = this.createWorkers(numImageWorkers);
|
|
34
|
+
this.workers.forEach((worker) => {
|
|
35
|
+
worker.onmessage = this.handleMessage.bind(this);
|
|
36
|
+
});
|
|
37
|
+
} else {
|
|
38
|
+
this.imageWorkersEnabled = false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private handleMessage(event: MessageEvent) {
|
|
43
|
+
const { src, data, error } = event.data as {
|
|
44
|
+
src: string;
|
|
45
|
+
data?: any;
|
|
46
|
+
error?: string;
|
|
47
|
+
};
|
|
48
|
+
const msg = this.messageManager[src];
|
|
49
|
+
if (msg) {
|
|
50
|
+
const [resolve, reject] = msg;
|
|
51
|
+
delete this.messageManager[src];
|
|
52
|
+
if (error) {
|
|
53
|
+
reject(new Error(error));
|
|
54
|
+
} else {
|
|
55
|
+
resolve({ data: data as ImageBitmap });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private createWorkers(numWorkers = 1): Worker[] {
|
|
61
|
+
const workerCode = `
|
|
62
|
+
async function getImage(src, premultiplyAlpha) {
|
|
63
|
+
const response = await fetch(src);
|
|
64
|
+
const blob = await response.blob();
|
|
65
|
+
return await createImageBitmap(blob, {
|
|
66
|
+
premultiplyAlpha: premultiplyAlpha ? 'premultiply' : 'none',
|
|
67
|
+
colorSpaceConversion: 'none',
|
|
68
|
+
imageOrientation: 'none',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
self.onmessage = async (event) => {
|
|
73
|
+
const { src, premultiplyAlpha } = event.data;
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
const data = await getImage(src, premultiplyAlpha);
|
|
77
|
+
self.postMessage({ src, data }, [data]);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
self.postMessage({ src, error: error.message });
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
`;
|
|
83
|
+
|
|
84
|
+
const blob: Blob = new Blob([workerCode.replace('"use strict";', '')], {
|
|
85
|
+
type: 'application/javascript',
|
|
86
|
+
});
|
|
87
|
+
const blobURL: string = (window.URL ? URL : webkitURL).createObjectURL(
|
|
88
|
+
blob,
|
|
89
|
+
);
|
|
90
|
+
const workers: Worker[] = [];
|
|
91
|
+
for (let i = 0; i < numWorkers; i++) {
|
|
92
|
+
workers.push(new Worker(blobURL));
|
|
93
|
+
}
|
|
94
|
+
return workers;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private getNextWorker(): Worker {
|
|
98
|
+
const worker = this.workers[this.workerIndex];
|
|
99
|
+
this.workerIndex = (this.workerIndex + 1) % this.workers.length;
|
|
100
|
+
return worker!;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private convertUrlToAbsolute(url: string): string {
|
|
104
|
+
const absoluteUrl = new URL(url, self.location.href);
|
|
105
|
+
return absoluteUrl.href;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
getImage(src: string, premultiplyAlpha: boolean): Promise<TextureData> {
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
try {
|
|
111
|
+
if (this.workers) {
|
|
112
|
+
const absoluteSrcUrl = this.convertUrlToAbsolute(src);
|
|
113
|
+
this.messageManager[absoluteSrcUrl] = [resolve, reject];
|
|
114
|
+
this.getNextWorker().postMessage({
|
|
115
|
+
src: absoluteSrcUrl,
|
|
116
|
+
premultiplyAlpha,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
} catch (error) {
|
|
120
|
+
reject(error);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|