@lightningjs/renderer 0.8.3 → 0.8.4

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 (133) hide show
  1. package/dist/src/core/CoreNode.d.ts +27 -1
  2. package/dist/src/core/CoreNode.js +130 -5
  3. package/dist/src/core/CoreNode.js.map +1 -1
  4. package/dist/src/core/CoreShaderManager.js +3 -2
  5. package/dist/src/core/CoreShaderManager.js.map +1 -1
  6. package/dist/src/core/CoreTextNode.js +20 -1
  7. package/dist/src/core/CoreTextNode.js.map +1 -1
  8. package/dist/src/core/CoreTextureManager.d.ts +2 -0
  9. package/dist/src/core/CoreTextureManager.js +2 -0
  10. package/dist/src/core/CoreTextureManager.js.map +1 -1
  11. package/dist/src/core/Stage.js +25 -9
  12. package/dist/src/core/Stage.js.map +1 -1
  13. package/dist/src/core/TextureMemoryManager.d.ts +1 -0
  14. package/dist/src/core/TextureMemoryManager.js +3 -1
  15. package/dist/src/core/TextureMemoryManager.js.map +1 -1
  16. package/dist/src/core/lib/ImageWorker.d.ts +2 -1
  17. package/dist/src/core/lib/ImageWorker.js +10 -6
  18. package/dist/src/core/lib/ImageWorker.js.map +1 -1
  19. package/dist/src/core/lib/WebGlContextWrapper.d.ts +26 -1
  20. package/dist/src/core/lib/WebGlContextWrapper.js +37 -1
  21. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
  22. package/dist/src/core/renderers/CoreRenderer.d.ts +11 -0
  23. package/dist/src/core/renderers/CoreRenderer.js +1 -0
  24. package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
  25. package/dist/src/core/renderers/canvas/CanvasCoreRenderer.d.ts +10 -4
  26. package/dist/src/core/renderers/canvas/CanvasCoreRenderer.js +18 -7
  27. package/dist/src/core/renderers/canvas/CanvasCoreRenderer.js.map +1 -1
  28. package/dist/src/core/renderers/canvas/CanvasCoreTexture.d.ts +2 -2
  29. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js +8 -6
  30. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js.map +1 -1
  31. package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.d.ts +1 -1
  32. package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.js +1 -1
  33. package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.js.map +1 -1
  34. package/dist/src/core/renderers/canvas/internal/ColorUtils.js +4 -4
  35. package/dist/src/core/renderers/canvas/internal/ColorUtils.js.map +1 -1
  36. package/dist/src/core/renderers/canvas/shaders/UnsupportedShader.d.ts +1 -1
  37. package/dist/src/core/renderers/canvas/shaders/UnsupportedShader.js +2 -2
  38. package/dist/src/core/renderers/canvas/shaders/UnsupportedShader.js.map +1 -1
  39. package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.d.ts +11 -0
  40. package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.js +51 -0
  41. package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.js.map +1 -0
  42. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +11 -1
  43. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +22 -11
  44. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  45. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.d.ts +4 -1
  46. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js +7 -2
  47. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js.map +1 -1
  48. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +16 -1
  49. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +119 -27
  50. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
  51. package/dist/src/core/renderers/webgl/WebGlCoreShader.js +19 -4
  52. package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +1 -1
  53. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +4 -6
  54. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js.map +1 -1
  55. package/dist/src/core/renderers/webgl/shaders/SdfShader.js +6 -1
  56. package/dist/src/core/renderers/webgl/shaders/SdfShader.js.map +1 -1
  57. package/dist/src/core/text-rendering/TextRenderingUtils.d.ts +12 -0
  58. package/dist/src/core/text-rendering/TextRenderingUtils.js +14 -0
  59. package/dist/src/core/text-rendering/TextRenderingUtils.js.map +1 -0
  60. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +2 -1
  61. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +4 -3
  62. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
  63. package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +2 -1
  64. package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
  65. package/dist/src/core/textures/RenderTexture.d.ts +28 -0
  66. package/dist/src/core/textures/RenderTexture.js +52 -0
  67. package/dist/src/core/textures/RenderTexture.js.map +1 -0
  68. package/dist/src/core/utils.d.ts +6 -1
  69. package/dist/src/core/utils.js +74 -82
  70. package/dist/src/core/utils.js.map +1 -1
  71. package/dist/src/main-api/INode.d.ts +9 -0
  72. package/dist/src/main-api/RendererMain.js +2 -1
  73. package/dist/src/main-api/RendererMain.js.map +1 -1
  74. package/dist/src/render-drivers/main/MainOnlyNode.d.ts +3 -0
  75. package/dist/src/render-drivers/main/MainOnlyNode.js +29 -0
  76. package/dist/src/render-drivers/main/MainOnlyNode.js.map +1 -1
  77. package/dist/src/render-drivers/main/MainOnlyTextNode.js +1 -0
  78. package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +1 -1
  79. package/dist/src/render-drivers/threadx/NodeStruct.d.ts +3 -0
  80. package/dist/src/render-drivers/threadx/NodeStruct.js +9 -0
  81. package/dist/src/render-drivers/threadx/NodeStruct.js.map +1 -1
  82. package/dist/src/render-drivers/threadx/SharedNode.d.ts +1 -0
  83. package/dist/src/render-drivers/threadx/SharedNode.js +1 -0
  84. package/dist/src/render-drivers/threadx/SharedNode.js.map +1 -1
  85. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +2 -0
  86. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -1
  87. package/dist/src/render-drivers/threadx/ThreadXMainNode.d.ts +3 -0
  88. package/dist/src/render-drivers/threadx/ThreadXMainNode.js +7 -0
  89. package/dist/src/render-drivers/threadx/ThreadXMainNode.js.map +1 -1
  90. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +1 -0
  91. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +1 -1
  92. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +1 -0
  93. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +1 -1
  94. package/dist/src/render-drivers/threadx/worker/renderer.js +1 -0
  95. package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
  96. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  97. package/package.json +1 -1
  98. package/src/core/CoreNode.ts +164 -8
  99. package/src/core/CoreShaderManager.ts +6 -3
  100. package/src/core/CoreTextNode.ts +25 -0
  101. package/src/core/CoreTextureManager.ts +3 -0
  102. package/src/core/Stage.ts +32 -11
  103. package/src/core/TextureMemoryManager.ts +3 -1
  104. package/src/core/lib/ImageWorker.ts +12 -7
  105. package/src/core/lib/WebGlContextWrapper.ts +51 -1
  106. package/src/core/renderers/CoreRenderer.ts +15 -1
  107. package/src/core/renderers/canvas/CanvasCoreRenderer.ts +59 -14
  108. package/src/core/renderers/canvas/CanvasCoreTexture.ts +24 -18
  109. package/src/core/renderers/canvas/internal/C2DShaderUtils.ts +6 -3
  110. package/src/core/renderers/canvas/internal/ColorUtils.ts +6 -6
  111. package/src/core/renderers/canvas/shaders/UnsupportedShader.ts +2 -3
  112. package/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.ts +79 -0
  113. package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +26 -24
  114. package/src/core/renderers/webgl/WebGlCoreRenderOp.ts +4 -2
  115. package/src/core/renderers/webgl/WebGlCoreRenderer.ts +166 -33
  116. package/src/core/renderers/webgl/WebGlCoreShader.ts +29 -4
  117. package/src/core/renderers/webgl/shaders/DefaultShader.ts +4 -6
  118. package/src/core/renderers/webgl/shaders/SdfShader.ts +6 -1
  119. package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +8 -1
  120. package/src/core/text-rendering/renderers/TextRenderer.ts +3 -0
  121. package/src/core/textures/RenderTexture.ts +81 -0
  122. package/src/core/utils.ts +101 -93
  123. package/src/main-api/INode.ts +11 -0
  124. package/src/main-api/RendererMain.ts +2 -1
  125. package/src/render-drivers/main/MainOnlyNode.ts +44 -0
  126. package/src/render-drivers/main/MainOnlyTextNode.ts +1 -0
  127. package/src/render-drivers/threadx/NodeStruct.ts +10 -0
  128. package/src/render-drivers/threadx/SharedNode.ts +2 -0
  129. package/src/render-drivers/threadx/ThreadXCoreDriver.ts +2 -0
  130. package/src/render-drivers/threadx/ThreadXMainNode.ts +9 -0
  131. package/src/render-drivers/threadx/worker/ThreadXRendererNode.ts +1 -0
  132. package/src/render-drivers/threadx/worker/ThreadXRendererTextNode.ts +1 -0
  133. package/src/render-drivers/threadx/worker/renderer.ts +1 -0
@@ -17,12 +17,12 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
+ import { assertTruthy, createWebGLContext, hasOwn } from '../../../utils.js';
20
21
  import {
21
- assertTruthy,
22
- createWebGLContext,
23
- hasOwn,
24
- } from '../../../utils.js';
25
- import { CoreRenderer, type CoreRendererOptions, type QuadOptions } from '../CoreRenderer.js';
22
+ CoreRenderer,
23
+ type CoreRendererOptions,
24
+ type QuadOptions,
25
+ } from '../CoreRenderer.js';
26
26
  import { WebGlCoreRenderOp } from './WebGlCoreRenderOp.js';
27
27
  import type { CoreContextTexture } from '../CoreContextTexture.js';
28
28
  import {
@@ -47,6 +47,9 @@ import {
47
47
  import type { Dimensions } from '../../../common/CommonTypes.js';
48
48
  import { WebGlCoreShader } from './WebGlCoreShader.js';
49
49
  import { WebGlContextWrapper } from '../../lib/WebGlContextWrapper.js';
50
+ import { RenderTexture } from '../../textures/RenderTexture.js';
51
+ import type { CoreNode } from '../../CoreNode.js';
52
+ import { WebGlCoreCtxRenderTexture } from './WebGlCoreCtxRenderTexture.js';
50
53
 
51
54
  const WORDS_PER_QUAD = 24;
52
55
  // const BYTES_PER_QUAD = WORDS_PER_QUAD * 4;
@@ -72,7 +75,8 @@ export class WebGlCoreRenderer extends CoreRenderer {
72
75
  //// Render Op / Buffer Filling State
73
76
  curBufferIdx = 0;
74
77
  curRenderOp: WebGlCoreRenderOp | null = null;
75
- renderables: Array<QuadOptions | WebGlCoreRenderOp> = [];
78
+ override rttNodes: CoreNode[] = [];
79
+ activeRttNode: CoreNode | null = null;
76
80
 
77
81
  //// Default Shader
78
82
  defaultShader: WebGlCoreShader;
@@ -83,6 +87,11 @@ export class WebGlCoreRenderer extends CoreRenderer {
83
87
  */
84
88
  defaultTexture: Texture;
85
89
 
90
+ /**
91
+ * Whether the renderer is currently rendering to a texture.
92
+ */
93
+ public renderToTextureActive = false;
94
+
86
95
  constructor(options: WebGlCoreRendererOptions) {
87
96
  super(options);
88
97
  this.mode = 'webgl';
@@ -90,6 +99,12 @@ export class WebGlCoreRenderer extends CoreRenderer {
90
99
  const { canvas, clearColor, bufferMemory } = options;
91
100
 
92
101
  this.defaultTexture = new ColorTexture(this.txManager);
102
+
103
+ // Mark the default texture as ALWAYS renderable
104
+ // This prevents it from ever being garbage collected.
105
+ // Fixes https://github.com/lightning-js/renderer/issues/262
106
+ this.defaultTexture.setRenderableOwner(this, true);
107
+
93
108
  // When the default texture is loaded, request a render in case the
94
109
  // RAF is paused. Fixes: https://github.com/lightning-js/renderer/issues/123
95
110
  this.defaultTexture.once('loaded', () => {
@@ -177,6 +192,12 @@ export class WebGlCoreRenderer extends CoreRenderer {
177
192
  this.txMemManager,
178
193
  textureSource,
179
194
  );
195
+ } else if (textureSource instanceof RenderTexture) {
196
+ return new WebGlCoreCtxRenderTexture(
197
+ this.glw,
198
+ this.txMemManager,
199
+ textureSource,
200
+ );
180
201
  }
181
202
  return new WebGlCoreCtxTexture(this.glw, this.txMemManager, textureSource);
182
203
  }
@@ -213,6 +234,9 @@ export class WebGlCoreRenderer extends CoreRenderer {
213
234
  tb,
214
235
  tc,
215
236
  td,
237
+ rtt: renderToTexture,
238
+ parentHasRenderTexture,
239
+ framebufferDimensions,
216
240
  } = params;
217
241
  let { texture } = params;
218
242
 
@@ -234,39 +258,22 @@ export class WebGlCoreRenderer extends CoreRenderer {
234
258
  const targetDims = {
235
259
  width,
236
260
  height,
237
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
238
261
  };
239
262
  const targetShader = shader || this.defaultShader;
240
263
  assertTruthy(targetShader instanceof WebGlCoreShader);
241
- if (curRenderOp) {
242
- // If the current render op is not the same shader, create a new one
243
- // If the current render op's shader props are not compatible with the
244
- // the new shader props, create a new one render op.
245
- if (
246
- curRenderOp.shader !== targetShader ||
247
- !compareRect(curRenderOp.clippingRect, clippingRect) ||
248
- (curRenderOp.shader !== this.defaultShader &&
249
- (!shaderProps ||
250
- !curRenderOp.shader.canBatchShaderProps(
251
- curRenderOp.shaderProps,
252
- shaderProps,
253
- )))
254
- ) {
255
- curRenderOp = null;
256
- }
257
- }
258
- assertTruthy(targetShader instanceof WebGlCoreShader);
259
264
 
260
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
261
- if (!curRenderOp) {
265
+ if (!this.reuseRenderOp(params)) {
262
266
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
263
267
  this.newRenderOp(
264
268
  targetShader,
265
- shaderProps as any,
269
+ shaderProps as Record<string, unknown>,
266
270
  alpha,
267
271
  targetDims,
268
272
  clippingRect,
269
273
  bufferIdx,
274
+ renderToTexture,
275
+ parentHasRenderTexture,
276
+ framebufferDimensions,
270
277
  );
271
278
  curRenderOp = this.curRenderOp;
272
279
  assertTruthy(curRenderOp);
@@ -303,6 +310,7 @@ export class WebGlCoreRenderer extends CoreRenderer {
303
310
  const ctxTexture = txManager.getCtxTexture(texture);
304
311
  assertTruthy(ctxTexture instanceof WebGlCoreCtxTexture);
305
312
  const textureIdx = this.addTexture(ctxTexture, bufferIdx);
313
+
306
314
  curRenderOp = this.curRenderOp;
307
315
  assertTruthy(curRenderOp);
308
316
 
@@ -398,6 +406,9 @@ export class WebGlCoreRenderer extends CoreRenderer {
398
406
  dimensions: Dimensions,
399
407
  clippingRect: RectWithValid,
400
408
  bufferIdx: number,
409
+ renderToTexture?: boolean,
410
+ parentHasRenderTexture?: boolean,
411
+ framebufferDimensions?: Dimensions,
401
412
  ) {
402
413
  const curRenderOp = new WebGlCoreRenderOp(
403
414
  this.glw,
@@ -410,6 +421,9 @@ export class WebGlCoreRenderer extends CoreRenderer {
410
421
  dimensions,
411
422
  bufferIdx,
412
423
  0, // Z-Index is only used for explictly added Render Ops
424
+ renderToTexture,
425
+ parentHasRenderTexture,
426
+ framebufferDimensions,
413
427
  );
414
428
  this.curRenderOp = curRenderOp;
415
429
  this.renderOps.push(curRenderOp);
@@ -456,6 +470,50 @@ export class WebGlCoreRenderer extends CoreRenderer {
456
470
  return textureIdx;
457
471
  }
458
472
 
473
+ /**
474
+ * Test if the current Render operation can be reused for the specified parameters.
475
+ * @param params
476
+ * @returns
477
+ */
478
+ reuseRenderOp(params: QuadOptions) {
479
+ const { shader, shaderProps, parentHasRenderTexture, rtt, clippingRect } =
480
+ params;
481
+
482
+ const targetShader = shader || this.defaultShader;
483
+
484
+ // Switching shader program will require a new render operation
485
+ if (this.curRenderOp?.shader !== targetShader) {
486
+ return false;
487
+ }
488
+
489
+ // Switching clipping rect will require a new render operation
490
+ if (!compareRect(this.curRenderOp.clippingRect, clippingRect)) {
491
+ return false;
492
+ }
493
+
494
+ // Force new render operation if rendering to texture
495
+ // @todo: This needs to be improved, render operations could also be reused
496
+ // for rendering to texture
497
+ if (parentHasRenderTexture || rtt) {
498
+ return false;
499
+ }
500
+
501
+ // Check if the shader can batch the shader properties
502
+ if (
503
+ this.curRenderOp.shader !== this.defaultShader &&
504
+ (!shaderProps ||
505
+ !this.curRenderOp.shader.canBatchShaderProps(
506
+ this.curRenderOp.shaderProps,
507
+ shaderProps,
508
+ ))
509
+ ) {
510
+ return false;
511
+ }
512
+
513
+ // Render operation can be reused
514
+ return true;
515
+ }
516
+
459
517
  /**
460
518
  * add RenderOp to the render pipeline
461
519
  */
@@ -483,16 +541,91 @@ export class WebGlCoreRenderer extends CoreRenderer {
483
541
  if (doLog) {
484
542
  console.log('renderOps', this.renderOps.length);
485
543
  }
544
+
486
545
  this.renderOps.forEach((renderOp, i) => {
487
546
  if (doLog) {
488
- console.log('renderOp', i, renderOp.numQuads);
547
+ console.log('Quads per operation', renderOp.numQuads);
489
548
  }
490
549
  renderOp.draw();
491
550
  });
551
+ }
492
552
 
493
- // clean up
494
- this.renderables = [];
553
+ renderToTexture(node: CoreNode) {
554
+ for (let i = 0; i < this.rttNodes.length; i++) {
555
+ if (this.rttNodes[i] === node) {
556
+ return;
557
+ }
558
+ }
559
+
560
+ // @todo: Better bottom up rendering order
561
+ this.rttNodes.unshift(node);
495
562
  }
496
- }
497
563
 
498
- const idx = 0;
564
+ renderRTTNodes() {
565
+ const { glw } = this;
566
+ const { txManager } = this.stage;
567
+ // Render all associated RTT nodes to their textures
568
+ for (let i = 0; i < this.rttNodes.length; i++) {
569
+ const node = this.rttNodes[i];
570
+
571
+ // Skip nodes that don't have RTT updates
572
+ if (!node || !node.hasRTTupdates) {
573
+ continue;
574
+ }
575
+
576
+ // Set the active RTT node to the current node
577
+ // So we can prevent rendering children of nested RTT nodes
578
+ this.activeRttNode = node;
579
+
580
+ assertTruthy(node.texture, 'RTT node missing texture');
581
+ const ctxTexture = txManager.getCtxTexture(node.texture);
582
+ assertTruthy(ctxTexture instanceof WebGlCoreCtxRenderTexture);
583
+ this.renderToTextureActive = true;
584
+
585
+ // Bind the the texture's framebuffer
586
+ glw.bindFramebuffer(ctxTexture.framebuffer);
587
+
588
+ glw.viewport(0, 0, ctxTexture.w, ctxTexture.h);
589
+ glw.clear();
590
+
591
+ // Render all associated quads to the texture
592
+ for (let i = 0; i < node.children.length; i++) {
593
+ const child = node.children[i];
594
+ if (!child) {
595
+ continue;
596
+ }
597
+ child.update(this.stage.deltaTime, {
598
+ x: 0,
599
+ y: 0,
600
+ width: 0,
601
+ height: 0,
602
+ valid: false,
603
+ });
604
+
605
+ this.stage.addQuads(child);
606
+ child.hasRTTupdates = false;
607
+ }
608
+
609
+ // Render all associated quads to the texture
610
+ this.render();
611
+
612
+ // Reset render operations
613
+ this.renderOps.length = 0;
614
+ node.hasRTTupdates = false;
615
+ }
616
+
617
+ // Bind the default framebuffer
618
+ glw.bindFramebuffer(null);
619
+
620
+ glw.viewport(0, 0, this.glw.canvas.width, this.glw.canvas.height);
621
+ this.renderToTextureActive = false;
622
+ }
623
+
624
+ removeRTTNode(node: CoreNode) {
625
+ const index = this.rttNodes.indexOf(node);
626
+ if (index === -1) {
627
+ return;
628
+ }
629
+ this.rttNodes.splice(index, 1);
630
+ }
631
+ }
@@ -261,10 +261,35 @@ export abstract class WebGlCoreShader extends CoreShader {
261
261
  if (renderOp.textures.length > 0) {
262
262
  this.bindTextures(renderOp.textures);
263
263
  }
264
- const { glw } = renderOp;
265
- // Bind standard automatic uniforms
266
- this.setUniform('u_resolution', [glw.canvas.width, glw.canvas.height]);
267
- this.setUniform('u_pixelRatio', renderOp.options.pixelRatio);
264
+
265
+ const { glw, parentHasRenderTexture, renderToTexture } = renderOp;
266
+
267
+ // Skip if the parent and current operation both have render textures
268
+ if (renderToTexture && parentHasRenderTexture) {
269
+ return;
270
+ }
271
+
272
+ // Bind render texture framebuffer dimensions as resolution
273
+ // if the parent has a render texture
274
+ if (parentHasRenderTexture) {
275
+ const { width, height } = renderOp.framebufferDimensions || {};
276
+ // Force pixel ratio to 1.0 for render textures since they are always 1:1
277
+ // the final render texture will be rendered to the screen with the correct pixel ratio
278
+ this.setUniform('u_pixelRatio', 1.0);
279
+
280
+ // Set resolution to the framebuffer dimensions
281
+ this.setUniform(
282
+ 'u_resolution',
283
+ new Float32Array([width ?? 0, height ?? 0]),
284
+ );
285
+ } else {
286
+ this.setUniform('u_pixelRatio', renderOp.options.pixelRatio);
287
+ this.setUniform(
288
+ 'u_resolution',
289
+ new Float32Array([glw.canvas.width, glw.canvas.height]),
290
+ );
291
+ }
292
+
268
293
  if (props) {
269
294
  // Bind optional automatic uniforms
270
295
  // These are only bound if their keys are present in the props.
@@ -61,16 +61,14 @@ export class DefaultShader extends WebGlCoreShader {
61
61
  varying vec2 v_textureCoordinate;
62
62
 
63
63
  void main() {
64
- vec2 normalized = a_position * u_pixelRatio / u_resolution;
65
- vec2 zero_two = normalized * 2.0;
66
- vec2 clip_space = zero_two - 1.0;
64
+ vec2 normalized = a_position * u_pixelRatio;
65
+ vec2 screenSpace = vec2(2.0 / u_resolution.x, -2.0 / u_resolution.y);
67
66
 
68
- // pass to fragment
69
67
  v_color = a_color;
70
68
  v_textureCoordinate = a_textureCoordinate;
71
69
 
72
- // flip y
73
- gl_Position = vec4(clip_space * vec2(1.0, -1.0), 0, 1);
70
+ gl_Position = vec4(normalized.x * screenSpace.x - 1.0, normalized.y * -abs(screenSpace.y) + 1.0, 0.0, 1.0);
71
+ gl_Position.y = -sign(screenSpace.y) * gl_Position.y;
74
72
  }
75
73
  `,
76
74
  fragment: `
@@ -136,8 +136,13 @@ export class SdfShader extends WebGlCoreShader {
136
136
  void main() {
137
137
  vec2 scrolledPosition = a_position * u_size - vec2(0, u_scrollY);
138
138
  vec2 transformedPosition = (u_transform * vec3(scrolledPosition, 1)).xy;
139
- gl_Position = vec4((transformedPosition * u_pixelRatio / u_resolution * 2.0 - 1.0) * vec2(1, -1), 0, 1);
139
+
140
+ // Calculate screen space with pixel ratio
141
+ vec2 screenSpace = (transformedPosition * u_pixelRatio / u_resolution * 2.0 - 1.0) * vec2(1, -1);
142
+
143
+ gl_Position = vec4(screenSpace, 0.0, 1.0);
140
144
  v_texcoord = a_textureCoordinate;
145
+
141
146
  }
142
147
  `,
143
148
  fragment: `
@@ -56,6 +56,7 @@ import type {
56
56
  import type { WebGlCoreCtxTexture } from '../../../renderers/webgl/WebGlCoreCtxTexture.js';
57
57
  import { EventEmitter } from '../../../../common/EventEmitter.js';
58
58
  import type { Matrix3d } from '../../../lib/Matrix3d.js';
59
+ import type { Dimensions } from '../../../../common/CommonTypes.js';
59
60
  import { WebGlCoreRenderer } from '../../../renderers/webgl/WebGlCoreRenderer.js';
60
61
 
61
62
  declare module '../TextRenderer.js' {
@@ -575,13 +576,16 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
575
576
  transform: Matrix3d,
576
577
  clippingRect: Readonly<RectWithValid>,
577
578
  alpha: number,
579
+ parentHasRenderTexture: boolean,
580
+ framebufferDimensions: Dimensions,
578
581
  ): void {
579
582
  if (!state.vertexBuffer) {
580
583
  // Nothing to draw
581
584
  return;
582
585
  }
583
586
 
584
- const renderer: WebGlCoreRenderer = this.stage.renderer as WebGlCoreRenderer;
587
+ const renderer: WebGlCoreRenderer = this.stage
588
+ .renderer as WebGlCoreRenderer;
585
589
  assertTruthy(renderer instanceof WebGlCoreRenderer);
586
590
 
587
591
  const { fontSize, color, contain, scrollable, zIndex, debug } = state.props;
@@ -681,6 +685,9 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
681
685
  { height: textH, width: textW },
682
686
  0,
683
687
  zIndex,
688
+ false,
689
+ parentHasRenderTexture,
690
+ framebufferDimensions,
684
691
  );
685
692
 
686
693
  const texture = state.trFontFace?.texture;
@@ -17,6 +17,7 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
+ import type { Dimensions } from '../../../common/CommonTypes.js';
20
21
  import type { EventEmitter } from '../../../common/EventEmitter.js';
21
22
  import type { Stage } from '../../Stage.js';
22
23
  import type { Matrix3d } from '../../lib/Matrix3d.js';
@@ -544,5 +545,7 @@ export abstract class TextRenderer<
544
545
  transform: Matrix3d,
545
546
  clippingRect: RectWithValid,
546
547
  alpha: number,
548
+ parentHasRenderTexture: boolean,
549
+ framebufferDimensions: Dimensions | undefined,
547
550
  ): void;
548
551
  }
@@ -0,0 +1,81 @@
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 { CoreTextureManager } from '../CoreTextureManager.js';
21
+ import { Texture, type TextureData } from './Texture.js';
22
+
23
+ /**
24
+ * Properties of the {@link RenderTexture}
25
+ */
26
+ export interface RenderTextureProps {
27
+ /**
28
+ * WebGL Texture width
29
+ * @default 256
30
+ */
31
+ width?: number;
32
+
33
+ /**
34
+ * WebGL Texture height
35
+ * @default 256
36
+ */
37
+ height?: number;
38
+ }
39
+
40
+ export class RenderTexture extends Texture {
41
+ props: Required<RenderTextureProps>;
42
+
43
+ constructor(txManager: CoreTextureManager, props?: RenderTextureProps) {
44
+ super(txManager);
45
+ this.props = RenderTexture.resolveDefaults(props || {});
46
+ }
47
+
48
+ get width() {
49
+ return this.props.width;
50
+ }
51
+
52
+ set width(value: number) {
53
+ this.props.width = value;
54
+ }
55
+
56
+ get height() {
57
+ return this.props.height;
58
+ }
59
+
60
+ set height(value: number) {
61
+ this.props.height = value;
62
+ }
63
+
64
+ override async getTextureData(): Promise<TextureData> {
65
+ return {
66
+ data: null,
67
+ premultiplyAlpha: null,
68
+ };
69
+ }
70
+
71
+ static override resolveDefaults(
72
+ props: RenderTextureProps,
73
+ ): Required<RenderTextureProps> {
74
+ return {
75
+ width: props.width || 256,
76
+ height: props.height || 256,
77
+ };
78
+ }
79
+
80
+ static z$__type__Props: RenderTextureProps;
81
+ }