@lightningjs/renderer 0.5.0 → 0.6.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 (93) hide show
  1. package/README.md +40 -8
  2. package/dist/exports/main-api.d.ts +3 -3
  3. package/dist/exports/main-api.js +3 -3
  4. package/dist/exports/main-api.js.map +1 -1
  5. package/dist/src/core/CoreNode.d.ts +24 -10
  6. package/dist/src/core/CoreNode.js +92 -20
  7. package/dist/src/core/CoreNode.js.map +1 -1
  8. package/dist/src/core/CoreShaderManager.d.ts +4 -0
  9. package/dist/src/core/CoreShaderManager.js +8 -0
  10. package/dist/src/core/CoreShaderManager.js.map +1 -1
  11. package/dist/src/core/CoreTextNode.d.ts +2 -4
  12. package/dist/src/core/CoreTextNode.js +5 -53
  13. package/dist/src/core/CoreTextNode.js.map +1 -1
  14. package/dist/src/core/Stage.d.ts +14 -3
  15. package/dist/src/core/Stage.js +52 -32
  16. package/dist/src/core/Stage.js.map +1 -1
  17. package/dist/src/core/animations/CoreAnimation.d.ts +1 -0
  18. package/dist/src/core/animations/CoreAnimation.js +25 -15
  19. package/dist/src/core/animations/CoreAnimation.js.map +1 -1
  20. package/dist/src/core/lib/utils.d.ts +5 -1
  21. package/dist/src/core/lib/utils.js +17 -12
  22. package/dist/src/core/lib/utils.js.map +1 -1
  23. package/dist/src/core/platform.js +4 -4
  24. package/dist/src/core/platform.js.map +1 -1
  25. package/dist/src/core/renderers/CoreRenderer.d.ts +1 -3
  26. package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
  27. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +11 -17
  28. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +13 -30
  29. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
  30. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +3 -0
  31. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js.map +1 -1
  32. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +5 -28
  33. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
  34. package/dist/src/core/renderers/webgl/shaders/effects/RadialProgressEffect.d.ts +61 -0
  35. package/dist/src/core/renderers/webgl/shaders/effects/RadialProgressEffect.js +126 -0
  36. package/dist/src/core/renderers/webgl/shaders/effects/RadialProgressEffect.js.map +1 -0
  37. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.d.ts +20 -2
  38. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js +98 -45
  39. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js.map +1 -1
  40. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +16 -4
  41. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +80 -42
  42. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
  43. package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +16 -8
  44. package/dist/src/core/text-rendering/renderers/TextRenderer.js +34 -8
  45. package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
  46. package/dist/src/main-api/{IRenderDriver.d.ts → ICoreDriver.d.ts} +3 -2
  47. package/dist/src/main-api/{IRenderDriver.js → ICoreDriver.js} +1 -1
  48. package/dist/src/main-api/ICoreDriver.js.map +1 -0
  49. package/dist/src/main-api/INode.d.ts +2 -2
  50. package/dist/src/main-api/RendererMain.d.ts +16 -6
  51. package/dist/src/main-api/RendererMain.js +9 -3
  52. package/dist/src/main-api/RendererMain.js.map +1 -1
  53. package/dist/src/render-drivers/main/{MainRenderDriver.d.ts → MainCoreDriver.d.ts} +3 -2
  54. package/dist/src/render-drivers/main/{MainRenderDriver.js → MainCoreDriver.js} +14 -4
  55. package/dist/src/render-drivers/main/MainCoreDriver.js.map +1 -0
  56. package/dist/src/render-drivers/threadx/{ThreadXRenderDriver.d.ts → ThreadXCoreDriver.d.ts} +4 -2
  57. package/dist/src/render-drivers/threadx/{ThreadXRenderDriver.js → ThreadXCoreDriver.js} +18 -4
  58. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -0
  59. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.d.ts +9 -0
  60. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js.map +1 -1
  61. package/dist/src/render-drivers/threadx/worker/renderer.js +8 -0
  62. package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
  63. package/dist/src/utils.js +2 -1
  64. package/dist/src/utils.js.map +1 -1
  65. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  66. package/exports/main-api.ts +3 -3
  67. package/package.json +8 -3
  68. package/src/core/CoreNode.ts +107 -21
  69. package/src/core/CoreShaderManager.ts +11 -0
  70. package/src/core/CoreTextNode.ts +5 -58
  71. package/src/core/Stage.ts +65 -34
  72. package/src/core/animations/CoreAnimation.ts +47 -27
  73. package/src/core/lib/utils.ts +39 -13
  74. package/src/core/platform.ts +5 -4
  75. package/src/core/renderers/CoreRenderer.ts +1 -2
  76. package/src/core/renderers/webgl/WebGlCoreRenderer.ts +14 -35
  77. package/src/core/renderers/webgl/shaders/DefaultShader.ts +4 -0
  78. package/src/core/renderers/webgl/shaders/DynamicShader.ts +5 -29
  79. package/src/core/renderers/webgl/shaders/effects/RadialProgressEffect.ts +186 -0
  80. package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +107 -50
  81. package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +95 -44
  82. package/src/core/text-rendering/renderers/TextRenderer.ts +44 -16
  83. package/src/main-api/{IRenderDriver.ts → ICoreDriver.ts} +4 -2
  84. package/src/main-api/INode.ts +2 -2
  85. package/src/main-api/RendererMain.ts +23 -6
  86. package/src/render-drivers/main/{MainRenderDriver.ts → MainCoreDriver.ts} +17 -4
  87. package/src/render-drivers/threadx/{ThreadXRenderDriver.ts → ThreadXCoreDriver.ts} +23 -7
  88. package/src/render-drivers/threadx/ThreadXRendererMessage.ts +11 -0
  89. package/src/render-drivers/threadx/worker/renderer.ts +10 -0
  90. package/src/utils.ts +2 -1
  91. package/dist/src/main-api/IRenderDriver.js.map +0 -1
  92. package/dist/src/render-drivers/main/MainRenderDriver.js.map +0 -1
  93. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js.map +0 -1
@@ -43,6 +43,11 @@ export interface TextRendererMap {}
43
43
 
44
44
  export interface TextRendererState {
45
45
  props: TrProps;
46
+ /**
47
+ * Whether or not the text renderer state is scheduled to be updated
48
+ * via queueMicrotask.
49
+ */
50
+ updateScheduled: boolean;
46
51
  status: 'initialState' | 'loading' | 'loaded' | 'failed';
47
52
  /**
48
53
  * Event emitter for the text renderer
@@ -198,14 +203,6 @@ export interface TrProps extends TrFontProps {
198
203
  contain: 'none' | 'width' | 'both';
199
204
  width: number;
200
205
  height: number;
201
- /**
202
- * X-Axis scaling factor for text
203
- */
204
- scaleX: number;
205
- /**
206
- * Y-Axis scaling factor for text
207
- */
208
- scaleY: number;
209
206
  /**
210
207
  * Whether or not the text is scrollable
211
208
  *
@@ -289,12 +286,6 @@ const trPropSetterDefaults: TrPropSetters = {
289
286
  fontSize: (state, value) => {
290
287
  state.props.fontSize = value;
291
288
  },
292
- scaleX: (state, value) => {
293
- state.props.scaleX = value;
294
- },
295
- scaleY: (state, value) => {
296
- state.props.scaleY = value;
297
- },
298
289
  text: (state, value) => {
299
290
  state.props.text = value;
300
291
  },
@@ -343,10 +334,26 @@ export abstract class TextRenderer<
343
334
  readonly set: Readonly<TrPropSetters<StateT>>;
344
335
 
345
336
  constructor(protected stage: Stage) {
346
- this.set = Object.freeze({
337
+ const propSetters = {
347
338
  ...trPropSetterDefaults,
348
339
  ...this.getPropertySetters(),
349
- });
340
+ };
341
+ // For each prop setter add a wrapper method that checks if the prop is
342
+ // different before calling the setter
343
+ this.set = Object.freeze(
344
+ Object.fromEntries(
345
+ Object.entries(propSetters).map(([key, setter]) => {
346
+ return [
347
+ key as keyof TrProps,
348
+ (state: StateT, value: TrProps[keyof TrProps]) => {
349
+ if (state.props[key as keyof TrProps] !== value) {
350
+ setter(state, value as never);
351
+ }
352
+ },
353
+ ];
354
+ }),
355
+ ),
356
+ ) as typeof this.set;
350
357
  }
351
358
 
352
359
  setStatus(state: StateT, status: StateT['status'], error?: Error) {
@@ -392,6 +399,27 @@ export abstract class TextRenderer<
392
399
 
393
400
  abstract createState(props: TrProps): StateT;
394
401
 
402
+ /**
403
+ * Schedule a state update via queueMicrotask
404
+ *
405
+ * @remarks
406
+ * This method is used to schedule a state update via queueMicrotask. This
407
+ * method should be called whenever a state update is needed, and it will
408
+ * ensure that the state is only updated once per microtask.
409
+ * @param state
410
+ * @returns
411
+ */
412
+ scheduleUpdateState(state: StateT): void {
413
+ if (state.updateScheduled) {
414
+ return;
415
+ }
416
+ state.updateScheduled = true;
417
+ queueMicrotask(() => {
418
+ state.updateScheduled = false;
419
+ this.updateState(state);
420
+ });
421
+ }
422
+
395
423
  abstract updateState(state: StateT): void;
396
424
 
397
425
  abstract renderQuads(
@@ -29,11 +29,11 @@ import type { RendererMain, RendererMainSettings } from './RendererMain.js';
29
29
  * This interface is to be implemented by Core Drivers
30
30
  *
31
31
  * @remarks
32
- * Both the {@link MainRenderDriver} and the {@link ThreadXRenderDriver} exist
32
+ * Both the {@link MainCoreDriver} and the {@link ThreadXCoreDriver} exist
33
33
  * that implement this interface to support both the single-threaded and
34
34
  * multi-threaded Core modes.
35
35
  */
36
- export interface IRenderDriver {
36
+ export interface ICoreDriver {
37
37
  init(
38
38
  rendererMain: RendererMain,
39
39
  rendererSettings: Required<RendererMainSettings>,
@@ -55,4 +55,6 @@ export interface IRenderDriver {
55
55
  onCreateNode(node: INode): void;
56
56
 
57
57
  onBeforeDestroyNode(node: INode): void;
58
+
59
+ onFpsUpdate(fps: number): void;
58
60
  }
@@ -417,8 +417,8 @@ export interface INodeEvents {
417
417
  * For text rendering, see {@link ITextNode}.
418
418
  *
419
419
  * Nodes are represented by an interface since they may be implemented in
420
- * different ways depending on the Core Driver. For example, the MainRenderDriver
421
- * implements it with it's `MainOnlyNode` while the ThreadXRenderDriver implements
420
+ * different ways depending on the Core Driver. For example, the MainCoreDriver
421
+ * implements it with it's `MainOnlyNode` while the ThreadXCoreDriver implements
422
422
  * it with it's `ThreadXMainNode`.
423
423
  */
424
424
  export interface INode extends INodeWritableProps, IEventEmitter<INodeEvents> {
@@ -30,13 +30,14 @@ import type {
30
30
  ITextNode,
31
31
  ITextNodeWritableProps,
32
32
  } from './INode.js';
33
- import type { IRenderDriver } from './IRenderDriver.js';
33
+ import type { ICoreDriver } from './ICoreDriver.js';
34
34
  import {
35
35
  ManualCountTextureUsageTracker,
36
36
  type ManualCountTextureUsageTrackerOptions,
37
37
  } from './texture-usage-trackers/ManualCountTextureUsageTracker.js';
38
38
  import { FinalizationRegistryTextureUsageTracker } from './texture-usage-trackers/FinalizationRegistryTextureUsageTracker.js';
39
39
  import type { TextureUsageTracker } from './texture-usage-trackers/TextureUsageTracker.js';
40
+ import { EventEmitter } from '../common/EventEmitter.js';
40
41
 
41
42
  /**
42
43
  * An immutable reference to a specific Texture type
@@ -200,6 +201,16 @@ export interface RendererMainSettings {
200
201
  experimental_FinalizationRegistryTextureUsageTracker?: boolean;
201
202
 
202
203
  textureCleanupOptions?: ManualCountTextureUsageTrackerOptions;
204
+
205
+ /**
206
+ * Interval in milliseconds to receive FPS updates
207
+ *
208
+ * @remarks
209
+ * If set to `0`, FPS updates will be disabled.
210
+ *
211
+ * @defaultValue `0` (disabled)
212
+ */
213
+ fpsUpdateInterval?: number;
203
214
  }
204
215
 
205
216
  /**
@@ -213,7 +224,7 @@ export interface RendererMainSettings {
213
224
  *
214
225
  * Example:
215
226
  * ```ts
216
- * import { RendererMain, MainRenderDriver } from '@lightningjs/renderer';
227
+ * import { RendererMain, MainCoreDriver } from '@lightningjs/renderer';
217
228
  *
218
229
  * // Initialize the Renderer
219
230
  * const renderer = new RendererMain(
@@ -222,13 +233,13 @@ export interface RendererMainSettings {
222
233
  * appHeight: 1080
223
234
  * },
224
235
  * 'app',
225
- * new MainRenderDriver(),
236
+ * new MainCoreDriver(),
226
237
  * );
227
238
  * ```
228
239
  */
229
- export class RendererMain {
240
+ export class RendererMain extends EventEmitter {
230
241
  readonly root: INode | null = null;
231
- readonly driver: IRenderDriver;
242
+ readonly driver: ICoreDriver;
232
243
  readonly canvas: HTMLCanvasElement;
233
244
  readonly settings: Readonly<Required<RendererMainSettings>>;
234
245
  private nodes: Map<number, INode> = new Map();
@@ -252,8 +263,9 @@ export class RendererMain {
252
263
  constructor(
253
264
  settings: RendererMainSettings,
254
265
  target: string | HTMLElement,
255
- driver: IRenderDriver,
266
+ driver: ICoreDriver,
256
267
  ) {
268
+ super();
257
269
  const resolvedSettings: Required<RendererMainSettings> = {
258
270
  appWidth: settings.appWidth || 1920,
259
271
  appHeight: settings.appHeight || 1080,
@@ -265,6 +277,7 @@ export class RendererMain {
265
277
  experimental_FinalizationRegistryTextureUsageTracker:
266
278
  settings.experimental_FinalizationRegistryTextureUsageTracker ?? false,
267
279
  textureCleanupOptions: settings.textureCleanupOptions || {},
280
+ fpsUpdateInterval: settings.fpsUpdateInterval || 0,
268
281
  };
269
282
  this.settings = resolvedSettings;
270
283
 
@@ -322,6 +335,10 @@ export class RendererMain {
322
335
  this.nodes.delete(node.id);
323
336
  };
324
337
 
338
+ driver.onFpsUpdate = (fps) => {
339
+ this.emit('fpsUpdate', fps);
340
+ };
341
+
325
342
  targetEl.appendChild(canvas);
326
343
  }
327
344
 
@@ -18,13 +18,13 @@
18
18
  */
19
19
 
20
20
  import { assertTruthy } from '../../utils.js';
21
- import type { IRenderDriver } from '../../main-api/IRenderDriver.js';
21
+ import type { ICoreDriver } from '../../main-api/ICoreDriver.js';
22
22
  import type {
23
23
  INode,
24
24
  INodeWritableProps,
25
25
  ITextNodeWritableProps,
26
26
  } from '../../main-api/INode.js';
27
- import { MainOnlyNode } from './MainOnlyNode.js';
27
+ import { MainOnlyNode, getNewId } from './MainOnlyNode.js';
28
28
  import { Stage } from '../../core/Stage.js';
29
29
  import type {
30
30
  RendererMain,
@@ -33,7 +33,7 @@ import type {
33
33
  import { MainOnlyTextNode } from './MainOnlyTextNode.js';
34
34
  import { loadCoreExtension } from '../utils.js';
35
35
 
36
- export class MainRenderDriver implements IRenderDriver {
36
+ export class MainCoreDriver implements ICoreDriver {
37
37
  private root: MainOnlyNode | null = null;
38
38
  private stage: Stage | null = null;
39
39
  private rendererMain: RendererMain | null = null;
@@ -44,13 +44,14 @@ export class MainRenderDriver implements IRenderDriver {
44
44
  canvas: HTMLCanvasElement,
45
45
  ): Promise<void> {
46
46
  this.stage = new Stage({
47
- rootId: 1,
47
+ rootId: getNewId(),
48
48
  appWidth: rendererSettings.appWidth,
49
49
  appHeight: rendererSettings.appHeight,
50
50
  deviceLogicalPixelRatio: rendererSettings.deviceLogicalPixelRatio,
51
51
  devicePhysicalPixelRatio: rendererSettings.devicePhysicalPixelRatio,
52
52
  clearColor: rendererSettings.clearColor,
53
53
  canvas,
54
+ fpsUpdateInterval: rendererSettings.fpsUpdateInterval,
54
55
  debug: {
55
56
  monitorTextureCache: false,
56
57
  },
@@ -71,6 +72,11 @@ export class MainRenderDriver implements IRenderDriver {
71
72
  if (rendererSettings.coreExtensionModule) {
72
73
  await loadCoreExtension(rendererSettings.coreExtensionModule, this.stage);
73
74
  }
75
+
76
+ // Forward fpsUpdate events from the stage to RendererMain
77
+ this.stage.on('fpsUpdate', (stage: Stage, fps: number) => {
78
+ this.onFpsUpdate(fps);
79
+ });
74
80
  }
75
81
 
76
82
  createNode(props: INodeWritableProps): INode {
@@ -107,6 +113,8 @@ export class MainRenderDriver implements IRenderDriver {
107
113
  return this.root;
108
114
  }
109
115
 
116
+ //#region Event Methods
117
+ // The implementations for these event methods are provided by RendererMain
110
118
  onCreateNode(node: INode): void {
111
119
  throw new Error('Method not implemented.');
112
120
  }
@@ -114,4 +122,9 @@ export class MainRenderDriver implements IRenderDriver {
114
122
  onBeforeDestroyNode(node: INode): void {
115
123
  throw new Error('Method not implemented.');
116
124
  }
125
+
126
+ onFpsUpdate(fps: number) {
127
+ throw new Error('Method not implemented.');
128
+ }
129
+ //#endregion
117
130
  }
@@ -25,16 +25,17 @@ import type {
25
25
  ITextNodeWritableProps,
26
26
  } from '../../main-api/INode.js';
27
27
  import { NodeStruct, type NodeStructWritableProps } from './NodeStruct.js';
28
- import type { IRenderDriver } from '../../main-api/IRenderDriver.js';
28
+ import type { ICoreDriver } from '../../main-api/ICoreDriver.js';
29
29
  import { ThreadXMainNode } from './ThreadXMainNode.js';
30
30
  import { assertTruthy } from '../../utils.js';
31
31
  import type {
32
32
  RendererMain,
33
33
  RendererMainSettings,
34
34
  } from '../../main-api/RendererMain.js';
35
- import type {
36
- ThreadXRendererInitMessage,
37
- ThreadXRendererReleaseTextureMessage,
35
+ import {
36
+ isThreadXRendererMessage,
37
+ type ThreadXRendererInitMessage,
38
+ type ThreadXRendererReleaseTextureMessage,
38
39
  } from './ThreadXRendererMessage.js';
39
40
  import {
40
41
  TextNodeStruct,
@@ -46,11 +47,12 @@ export interface ThreadXRendererSettings {
46
47
  coreWorkerUrl: string;
47
48
  }
48
49
 
49
- export class ThreadXRenderDriver implements IRenderDriver {
50
+ export class ThreadXCoreDriver implements ICoreDriver {
50
51
  private settings: ThreadXRendererSettings;
51
52
  private threadx: ThreadX;
52
53
  private rendererMain: RendererMain | null = null;
53
54
  private root: INode | null = null;
55
+ private fps = 0;
54
56
 
55
57
  constructor(settings: ThreadXRendererSettings) {
56
58
  this.settings = settings;
@@ -74,6 +76,12 @@ export class ThreadXRenderDriver implements IRenderDriver {
74
76
  }
75
77
  return null;
76
78
  },
79
+ onMessage: async (message) => {
80
+ // Forward fpsUpdate events from the renderer worker's Stage to RendererMain
81
+ if (isThreadXRendererMessage('fpsUpdate', message)) {
82
+ this.onFpsUpdate(message.fps);
83
+ }
84
+ },
77
85
  });
78
86
  this.threadx.registerWorker(
79
87
  'renderer',
@@ -99,6 +107,7 @@ export class ThreadXRenderDriver implements IRenderDriver {
99
107
  devicePhysicalPixelRatio: rendererSettings.devicePhysicalPixelRatio,
100
108
  clearColor: rendererSettings.clearColor,
101
109
  coreExtensionModule: rendererSettings.coreExtensionModule,
110
+ fpsUpdateInterval: rendererSettings.fpsUpdateInterval,
102
111
  } satisfies ThreadXRendererInitMessage,
103
112
  [offscreenCanvas],
104
113
  )) as number;
@@ -239,11 +248,18 @@ export class ThreadXRenderDriver implements IRenderDriver {
239
248
  } satisfies ThreadXRendererReleaseTextureMessage);
240
249
  }
241
250
 
251
+ //#region Event Methods
252
+ // The implementations for these event methods are provided by RendererMain
242
253
  onCreateNode(node: INode): void {
243
- return;
254
+ throw new Error('Method not implemented.');
244
255
  }
245
256
 
246
257
  onBeforeDestroyNode(node: INode): void {
247
- return;
258
+ throw new Error('Method not implemented.');
259
+ }
260
+
261
+ onFpsUpdate(fps: number): void {
262
+ throw new Error('Method not implemented.');
248
263
  }
264
+ //#endregion
249
265
  }
@@ -42,6 +42,7 @@ export interface ThreadXRendererInitMessage extends ThreadXRendererMessage {
42
42
  deviceLogicalPixelRatio: number;
43
43
  devicePhysicalPixelRatio: number;
44
44
  clearColor: number;
45
+ fpsUpdateInterval: number;
45
46
  coreExtensionModule: string | null;
46
47
  }
47
48
 
@@ -55,12 +56,22 @@ export interface ThreadXRendererReleaseTextureMessage
55
56
  textureDescId: number;
56
57
  }
57
58
 
59
+ /**
60
+ * A message sent from the renderer worker to the main worker to update the FPS
61
+ */
62
+ export interface ThreadXRendererFpsUpdateMessage
63
+ extends ThreadXRendererMessage {
64
+ type: 'fpsUpdate';
65
+ fps: number;
66
+ }
67
+
58
68
  /**
59
69
  * A map of message types to message shapes
60
70
  */
61
71
  export interface ThreadXRendererMessageMap {
62
72
  init: ThreadXRendererInitMessage;
63
73
  releaseTexture: ThreadXRendererReleaseTextureMessage;
74
+ fpsUpdate: ThreadXRendererFpsUpdateMessage;
64
75
  }
65
76
 
66
77
  /**
@@ -24,6 +24,7 @@ import { Stage } from '../../../core/Stage.js';
24
24
  import { assertTruthy } from '../../../utils.js';
25
25
  import {
26
26
  isThreadXRendererMessage,
27
+ type ThreadXRendererFpsUpdateMessage,
27
28
  type ThreadXRendererMessage,
28
29
  } from '../ThreadXRendererMessage.js';
29
30
  import { TextNodeStruct } from '../TextNodeStruct.js';
@@ -69,6 +70,7 @@ const threadx = ThreadX.init({
69
70
  devicePhysicalPixelRatio: message.devicePhysicalPixelRatio,
70
71
  clearColor: message.clearColor,
71
72
  canvas,
73
+ fpsUpdateInterval: message.fpsUpdateInterval,
72
74
  debug: {
73
75
  monitorTextureCache: false,
74
76
  },
@@ -117,6 +119,14 @@ const threadx = ThreadX.init({
117
119
  await loadCoreExtension(message.coreExtensionModule, stage);
118
120
  }
119
121
 
122
+ // Forward FPS updates to the main worker.
123
+ stage.on('fpsUpdate', (stage: Stage, fps: number) => {
124
+ threadx.sendMessage('parent', {
125
+ type: 'fpsUpdate',
126
+ fps,
127
+ } satisfies ThreadXRendererFpsUpdateMessage);
128
+ });
129
+
120
130
  // Return its ID so the main worker can retrieve it from the shared object
121
131
  // store.
122
132
  return rootNode.id;
package/src/utils.ts CHANGED
@@ -26,7 +26,8 @@ export function createWebGLContext(
26
26
  depth: false,
27
27
  stencil: true,
28
28
  desynchronized: false,
29
- failIfMajorPerformanceCaveat: true,
29
+ // Disabled because it prevents Visual Regression Tests from working
30
+ // failIfMajorPerformanceCaveat: true,
30
31
  powerPreference: 'high-performance',
31
32
  premultipliedAlpha: true,
32
33
  preserveDrawingBuffer: false,
@@ -1 +0,0 @@
1
- {"version":3,"file":"IRenderDriver.js","sourceRoot":"","sources":["../../../src/main-api/IRenderDriver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"MainRenderDriver.js","sourceRoot":"","sources":["../../../../src/render-drivers/main/MainRenderDriver.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ThreadXRenderDriver.js","sourceRoot":"","sources":["../../../../src/render-drivers/threadx/ThreadXRenderDriver.ts"],"names":[],"mappings":"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"}