@lightningjs/renderer 0.6.1 → 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.
Files changed (189) hide show
  1. package/dist/src/common/CommonTypes.d.ts +8 -0
  2. package/dist/src/core/CoreNode.js +45 -16
  3. package/dist/src/core/CoreNode.js.map +1 -1
  4. package/dist/src/core/CoreTextNode.d.ts +10 -0
  5. package/dist/src/core/CoreTextNode.js +45 -0
  6. package/dist/src/core/CoreTextNode.js.map +1 -1
  7. package/dist/src/core/CoreTextureManager.d.ts +3 -1
  8. package/dist/src/core/CoreTextureManager.js +4 -1
  9. package/dist/src/core/CoreTextureManager.js.map +1 -1
  10. package/dist/src/core/Stage.d.ts +6 -0
  11. package/dist/src/core/Stage.js +12 -3
  12. package/dist/src/core/Stage.js.map +1 -1
  13. package/dist/src/core/lib/ImageWorker.d.ts +16 -0
  14. package/dist/src/core/lib/ImageWorker.js +111 -0
  15. package/dist/src/core/lib/ImageWorker.js.map +1 -0
  16. package/dist/src/core/lib/WebGlContextWrapper.d.ts +4 -0
  17. package/dist/src/core/lib/WebGlContextWrapper.js +7 -2
  18. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
  19. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.d.ts +2 -1
  20. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js +2 -2
  21. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js.map +1 -1
  22. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +3 -2
  23. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +23 -21
  24. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  25. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.d.ts +3 -2
  26. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js +9 -13
  27. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js.map +1 -1
  28. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +4 -1
  29. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +25 -24
  30. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
  31. package/dist/src/core/renderers/webgl/WebGlCoreShader.d.ts +2 -1
  32. package/dist/src/core/renderers/webgl/WebGlCoreShader.js +24 -24
  33. package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +1 -1
  34. package/dist/src/core/renderers/webgl/internal/RendererUtils.d.ts +8 -5
  35. package/dist/src/core/renderers/webgl/internal/RendererUtils.js +11 -13
  36. package/dist/src/core/renderers/webgl/internal/RendererUtils.js.map +1 -1
  37. package/dist/src/core/renderers/webgl/internal/ShaderUtils.d.ts +3 -2
  38. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +15 -15
  39. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -1
  40. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +3 -6
  41. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js.map +1 -1
  42. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js +3 -3
  43. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js.map +1 -1
  44. package/dist/src/core/renderers/webgl/shaders/DynamicShader.d.ts +1 -0
  45. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +32 -12
  46. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
  47. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js +3 -3
  48. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js.map +1 -1
  49. package/dist/src/core/renderers/webgl/shaders/SdfShader.js +3 -3
  50. package/dist/src/core/renderers/webgl/shaders/SdfShader.js.map +1 -1
  51. package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js +1 -1
  52. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.d.ts +14 -1
  53. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js +15 -5
  54. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js.map +1 -1
  55. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js +3 -3
  56. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js.map +1 -1
  57. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.d.ts +2 -1
  58. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js +4 -2
  59. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js.map +1 -1
  60. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js +25 -0
  61. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js.map +1 -1
  62. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.d.ts +1 -1
  63. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js +6 -6
  64. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js.map +1 -1
  65. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +3 -2
  66. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +82 -50
  67. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
  68. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.d.ts +8 -0
  69. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js +29 -0
  70. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js.map +1 -0
  71. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.d.ts +4 -3
  72. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js +15 -11
  73. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js.map +1 -1
  74. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.d.ts +3 -2
  75. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js +30 -26
  76. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js.map +1 -1
  77. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.d.ts +19 -0
  78. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js +84 -0
  79. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js.map +1 -0
  80. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.d.ts +8 -0
  81. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js +40 -0
  82. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js.map +1 -0
  83. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.d.ts +2 -0
  84. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js +41 -0
  85. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js.map +1 -0
  86. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.d.ts +1 -0
  87. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js +4 -0
  88. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js.map +1 -0
  89. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.d.ts +1 -0
  90. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js +2 -0
  91. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js.map +1 -0
  92. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.d.ts +9 -0
  93. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js +32 -0
  94. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js.map +1 -0
  95. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.d.ts +26 -0
  96. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.js +70 -0
  97. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.js.map +1 -0
  98. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.d.ts +16 -0
  99. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.js +39 -0
  100. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.js.map +1 -0
  101. package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +50 -0
  102. package/dist/src/core/text-rendering/renderers/TextRenderer.js +19 -0
  103. package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
  104. package/dist/src/core/textures/ImageTexture.js +14 -9
  105. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  106. package/dist/src/core/utils.d.ts +1 -6
  107. package/dist/src/core/utils.js +3 -2
  108. package/dist/src/core/utils.js.map +1 -1
  109. package/dist/src/main-api/ICoreDriver.d.ts +2 -1
  110. package/dist/src/main-api/RendererMain.d.ts +25 -0
  111. package/dist/src/main-api/RendererMain.js +14 -5
  112. package/dist/src/main-api/RendererMain.js.map +1 -1
  113. package/dist/src/render-drivers/main/MainCoreDriver.d.ts +2 -1
  114. package/dist/src/render-drivers/main/MainCoreDriver.js +6 -4
  115. package/dist/src/render-drivers/main/MainCoreDriver.js.map +1 -1
  116. package/dist/src/render-drivers/main/MainOnlyTextNode.d.ts +10 -0
  117. package/dist/src/render-drivers/main/MainOnlyTextNode.js +45 -0
  118. package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +1 -1
  119. package/dist/src/render-drivers/threadx/TextNodeStruct.d.ts +10 -0
  120. package/dist/src/render-drivers/threadx/TextNodeStruct.js +45 -0
  121. package/dist/src/render-drivers/threadx/TextNodeStruct.js.map +1 -1
  122. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.d.ts +2 -1
  123. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +8 -1
  124. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -1
  125. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.d.ts +5 -0
  126. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js +5 -0
  127. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js.map +1 -1
  128. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.d.ts +4 -1
  129. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js.map +1 -1
  130. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.d.ts +5 -0
  131. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +10 -0
  132. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +1 -1
  133. package/dist/src/render-drivers/threadx/worker/renderer.js +5 -3
  134. package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
  135. package/dist/src/utils.d.ts +2 -1
  136. package/dist/src/utils.js +22 -3
  137. package/dist/src/utils.js.map +1 -1
  138. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  139. package/package.json +3 -2
  140. package/src/common/CommonTypes.ts +9 -0
  141. package/src/core/CoreNode.ts +67 -34
  142. package/src/core/CoreTextNode.ts +56 -0
  143. package/src/core/CoreTextureManager.ts +4 -2
  144. package/src/core/Stage.ts +32 -3
  145. package/src/core/lib/ContextSpy.ts +41 -0
  146. package/src/core/lib/ImageWorker.ts +124 -0
  147. package/src/core/lib/WebGlContextWrapper.ts +965 -0
  148. package/src/core/renderers/webgl/WebGlCoreCtxSubTexture.ts +3 -2
  149. package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +29 -28
  150. package/src/core/renderers/webgl/WebGlCoreRenderOp.ts +10 -14
  151. package/src/core/renderers/webgl/WebGlCoreRenderer.ts +26 -24
  152. package/src/core/renderers/webgl/WebGlCoreShader.ts +34 -25
  153. package/src/core/renderers/webgl/internal/RendererUtils.ts +13 -16
  154. package/src/core/renderers/webgl/internal/ShaderUtils.ts +16 -15
  155. package/src/core/renderers/webgl/shaders/DefaultShader.ts +3 -7
  156. package/src/core/renderers/webgl/shaders/DefaultShaderBatched.ts +3 -3
  157. package/src/core/renderers/webgl/shaders/DynamicShader.ts +42 -14
  158. package/src/core/renderers/webgl/shaders/RoundedRectangle.ts +3 -3
  159. package/src/core/renderers/webgl/shaders/SdfShader.ts +3 -3
  160. package/src/core/renderers/webgl/shaders/effects/BorderEffect.ts +1 -1
  161. package/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.ts +35 -5
  162. package/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.ts +3 -3
  163. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.test.ts +9 -3
  164. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.ts +4 -2
  165. package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +25 -0
  166. package/src/core/text-rendering/renderers/LightningTextTextureRenderer.ts +7 -7
  167. package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +115 -63
  168. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.ts +26 -18
  169. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.ts +40 -28
  170. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.test.ts +6 -1
  171. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.test.ts +205 -0
  172. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/{makeRenderWindow.ts → setRenderWindow.ts} +50 -21
  173. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.ts +40 -0
  174. package/src/core/text-rendering/renderers/TextRenderer.ts +73 -0
  175. package/src/core/textures/ImageTexture.ts +17 -9
  176. package/src/core/utils.ts +87 -85
  177. package/src/env.d.ts +7 -0
  178. package/src/main-api/ICoreDriver.ts +2 -1
  179. package/src/main-api/RendererMain.ts +43 -5
  180. package/src/render-drivers/main/MainCoreDriver.ts +8 -5
  181. package/src/render-drivers/main/MainOnlyTextNode.ts +55 -1
  182. package/src/render-drivers/threadx/TextNodeStruct.ts +45 -0
  183. package/src/render-drivers/threadx/ThreadXCoreDriver.ts +10 -2
  184. package/src/render-drivers/threadx/ThreadXMainTextNode.ts +10 -0
  185. package/src/render-drivers/threadx/ThreadXRendererMessage.ts +5 -1
  186. package/src/render-drivers/threadx/worker/ThreadXRendererTextNode.ts +15 -0
  187. package/src/render-drivers/threadx/worker/renderer.ts +6 -4
  188. package/src/utils.ts +25 -4
  189. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.test.ts +0 -136
@@ -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
  );
@@ -255,6 +260,56 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
255
260
  this.textRenderer.set.letterSpacing(this.trState, value);
256
261
  }
257
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
+
258
313
  get debug(): CoreTextNodeProps['debug'] {
259
314
  return this.trState.props.debug;
260
315
  }
@@ -325,6 +380,7 @@ export class CoreTextNode extends CoreNode implements ICoreTextNode {
325
380
 
326
381
  textRendererState.emitter.on('loaded', this.onTextLoaded);
327
382
  textRendererState.emitter.on('failed', this.onTextFailed);
383
+
328
384
  resolvedTextRenderer.scheduleUpdateState(textRendererState);
329
385
 
330
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
@@ -32,6 +32,8 @@ import type {
32
32
  import { SdfTextRenderer } from './text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js';
33
33
  import { CanvasTextRenderer } from './text-rendering/renderers/CanvasTextRenderer.js';
34
34
  import { EventEmitter } from '../common/EventEmitter.js';
35
+ import { ContextSpy } from './lib/ContextSpy.js';
36
+ import type { FpsUpdatePayload } from '../common/CommonTypes.js';
35
37
 
36
38
  export interface StageOptions {
37
39
  rootId: number;
@@ -42,11 +44,19 @@ export interface StageOptions {
42
44
  canvas: HTMLCanvasElement | OffscreenCanvas;
43
45
  clearColor: number;
44
46
  fpsUpdateInterval: number;
47
+ enableContextSpy: boolean;
48
+ numImageWorkers: number;
49
+
45
50
  debug?: {
46
51
  monitorTextureCache?: boolean;
47
52
  };
48
53
  }
49
54
 
55
+ export type StageFpsUpdateHandler = (
56
+ stage: Stage,
57
+ fpsData: FpsUpdatePayload,
58
+ ) => void;
59
+
50
60
  const bufferMemory = 2e6;
51
61
  const autoStart = true;
52
62
 
@@ -68,15 +78,29 @@ export class Stage extends EventEmitter {
68
78
  private fpsElapsedTime = 0;
69
79
  private renderRequested = false;
70
80
 
81
+ /// Debug data
82
+ contextSpy: ContextSpy | null = null;
83
+
71
84
  /**
72
85
  * Stage constructor
73
86
  */
74
87
  constructor(readonly options: StageOptions) {
75
88
  super();
76
- const { canvas, clearColor, rootId, debug, appWidth, appHeight } = options;
77
- this.txManager = new CoreTextureManager();
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);
78
101
  this.shManager = new CoreShaderManager();
79
102
  this.animationManager = new AnimationManager();
103
+ this.contextSpy = enableContextSpy ? new ContextSpy() : null;
80
104
 
81
105
  if (debug?.monitorTextureCache) {
82
106
  setInterval(() => {
@@ -96,6 +120,7 @@ export class Stage extends EventEmitter {
96
120
  bufferMemory,
97
121
  txManager: this.txManager,
98
122
  shManager: this.shManager,
123
+ contextSpy: this.contextSpy,
99
124
  });
100
125
 
101
126
  // Must do this after renderer is created
@@ -212,7 +237,11 @@ export class Stage extends EventEmitter {
212
237
  );
213
238
  this.fpsNumFrames = 0;
214
239
  this.fpsElapsedTime = 0;
215
- this.emit('fpsUpdate', fps);
240
+ this.emit('fpsUpdate', {
241
+ fps,
242
+ contextSpyData: this.contextSpy?.getData() ?? null,
243
+ } satisfies FpsUpdatePayload);
244
+ this.contextSpy?.reset();
216
245
  }
217
246
  }
218
247
  }
@@ -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
+ }