@lightningjs/renderer 3.0.0-beta22 → 3.0.0-beta24

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 (190) hide show
  1. package/README.md +93 -0
  2. package/dist/exports/index.d.ts +3 -1
  3. package/dist/exports/index.js +2 -0
  4. package/dist/exports/index.js.map +1 -1
  5. package/dist/exports/platform.d.ts +7 -0
  6. package/dist/exports/platform.js +27 -0
  7. package/dist/exports/platform.js.map +1 -0
  8. package/dist/src/core/AutosizeManager.d.ts +29 -0
  9. package/dist/src/core/AutosizeManager.js +169 -0
  10. package/dist/src/core/AutosizeManager.js.map +1 -0
  11. package/dist/src/core/CoreNode.d.ts +0 -1
  12. package/dist/src/core/CoreNode.js +47 -41
  13. package/dist/src/core/CoreNode.js.map +1 -1
  14. package/dist/src/core/CoreTextureManager.d.ts +0 -13
  15. package/dist/src/core/CoreTextureManager.js +4 -78
  16. package/dist/src/core/CoreTextureManager.js.map +1 -1
  17. package/dist/src/core/Stage.js +2 -12
  18. package/dist/src/core/Stage.js.map +1 -1
  19. package/dist/src/core/animations/Animation.d.ts +21 -0
  20. package/dist/src/core/animations/Animation.js +194 -0
  21. package/dist/src/core/animations/Animation.js.map +1 -0
  22. package/dist/src/core/animations/CoreAnimationController.d.ts +1 -1
  23. package/dist/src/core/animations/CoreAnimationController.js +4 -2
  24. package/dist/src/core/animations/CoreAnimationController.js.map +1 -1
  25. package/dist/src/core/animations/Playback.d.ts +64 -0
  26. package/dist/src/core/animations/Playback.js +169 -0
  27. package/dist/src/core/animations/Playback.js.map +1 -0
  28. package/dist/src/core/animations/Transition.d.ts +27 -0
  29. package/dist/src/core/animations/Transition.js +52 -0
  30. package/dist/src/core/animations/Transition.js.map +1 -0
  31. package/dist/src/core/animations/utils.d.ts +2 -0
  32. package/dist/src/core/animations/utils.js +136 -0
  33. package/dist/src/core/animations/utils.js.map +1 -0
  34. package/dist/src/core/lib/collectionUtils.d.ts +0 -1
  35. package/dist/src/core/lib/collectionUtils.js +0 -28
  36. package/dist/src/core/lib/collectionUtils.js.map +1 -1
  37. package/dist/src/core/lib/utils.d.ts +0 -5
  38. package/dist/src/core/lib/utils.js +0 -63
  39. package/dist/src/core/lib/utils.js.map +1 -1
  40. package/dist/src/core/platforms/GlContextWrapper.d.ts +136 -0
  41. package/dist/src/core/platforms/GlContextWrapper.js +32 -0
  42. package/dist/src/core/platforms/GlContextWrapper.js.map +1 -0
  43. package/dist/src/core/platforms/Platform.d.ts +74 -13
  44. package/dist/src/core/platforms/Platform.js +18 -0
  45. package/dist/src/core/platforms/Platform.js.map +1 -1
  46. package/dist/src/core/platforms/web/WebGlContextWrapper.d.ts +776 -0
  47. package/dist/src/core/platforms/web/WebGlContextWrapper.js +1208 -0
  48. package/dist/src/core/platforms/web/WebGlContextWrapper.js.map +1 -0
  49. package/dist/src/core/platforms/web/WebPlatform.d.ts +13 -2
  50. package/dist/src/core/platforms/web/WebPlatform.js +109 -8
  51. package/dist/src/core/platforms/web/WebPlatform.js.map +1 -1
  52. package/dist/src/core/platforms/web/WebPlatformChrome50.d.ts +17 -0
  53. package/dist/src/core/platforms/web/WebPlatformChrome50.js +50 -0
  54. package/dist/src/core/platforms/web/WebPlatformChrome50.js.map +1 -0
  55. package/dist/src/core/platforms/web/WebPlatformLegacy.d.ts +18 -0
  56. package/dist/src/core/platforms/web/WebPlatformLegacy.js +99 -0
  57. package/dist/src/core/platforms/web/WebPlatformLegacy.js.map +1 -0
  58. package/dist/src/core/platforms/web/WebPlatformNext.d.ts +21 -0
  59. package/dist/src/core/platforms/web/WebPlatformNext.js +52 -0
  60. package/dist/src/core/platforms/web/WebPlatformNext.js.map +1 -0
  61. package/dist/src/core/platforms/web/lib/ImageWorker.d.ts +15 -0
  62. package/dist/src/core/platforms/web/lib/ImageWorker.js +189 -0
  63. package/dist/src/core/platforms/web/lib/ImageWorker.js.map +1 -0
  64. package/dist/src/core/platforms/web/lib/createImageBitmap.d.ts +1 -0
  65. package/dist/src/core/platforms/web/lib/createImageBitmap.js +27 -0
  66. package/dist/src/core/platforms/web/lib/createImageBitmap.js.map +1 -0
  67. package/dist/src/core/platforms/web/lib/textureCompression.d.ts +26 -0
  68. package/dist/src/core/platforms/web/lib/textureCompression.js +301 -0
  69. package/dist/src/core/platforms/web/lib/textureCompression.js.map +1 -0
  70. package/dist/src/core/platforms/web/lib/textureSvg.d.ts +7 -0
  71. package/dist/src/core/platforms/web/lib/textureSvg.js +51 -0
  72. package/dist/src/core/platforms/web/lib/textureSvg.js.map +1 -0
  73. package/dist/src/core/platforms/web/lib/utils.d.ts +5 -0
  74. package/dist/src/core/platforms/web/lib/utils.js +86 -0
  75. package/dist/src/core/platforms/web/lib/utils.js.map +1 -0
  76. package/dist/src/core/renderers/CoreRenderer.d.ts +1 -9
  77. package/dist/src/core/renderers/CoreRenderer.js +2 -4
  78. package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
  79. package/dist/src/core/renderers/canvas/CanvasRenderer.d.ts +3 -2
  80. package/dist/src/core/renderers/canvas/CanvasRenderer.js +6 -5
  81. package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -1
  82. package/dist/src/core/renderers/canvas/CanvasShaderNode.js +3 -3
  83. package/dist/src/core/renderers/canvas/CanvasShaderNode.js.map +1 -1
  84. package/dist/src/core/renderers/webgl/SdfRenderOp.js +3 -2
  85. package/dist/src/core/renderers/webgl/SdfRenderOp.js.map +1 -1
  86. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.d.ts +2 -2
  87. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.js.map +1 -1
  88. package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.d.ts +2 -2
  89. package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.js.map +1 -1
  90. package/dist/src/core/renderers/webgl/WebGlCtxTexture.d.ts +3 -3
  91. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js +1 -2
  92. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js.map +1 -1
  93. package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +5 -5
  94. package/dist/src/core/renderers/webgl/WebGlRenderer.js +10 -11
  95. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
  96. package/dist/src/core/renderers/webgl/WebGlShaderNode.d.ts +2 -2
  97. package/dist/src/core/renderers/webgl/WebGlShaderNode.js +3 -3
  98. package/dist/src/core/renderers/webgl/WebGlShaderNode.js.map +1 -1
  99. package/dist/src/core/renderers/webgl/WebGlShaderProgram.d.ts +2 -2
  100. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +0 -3
  101. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -1
  102. package/dist/src/core/renderers/webgl/internal/RendererUtils.d.ts +4 -4
  103. package/dist/src/core/renderers/webgl/internal/RendererUtils.js.map +1 -1
  104. package/dist/src/core/renderers/webgl/internal/ShaderUtils.d.ts +3 -3
  105. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +3 -2
  106. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -1
  107. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js +24 -8
  108. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js.map +1 -1
  109. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js +25 -8
  110. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js.map +1 -1
  111. package/dist/src/core/shaders/webgl/Border.js +6 -4
  112. package/dist/src/core/shaders/webgl/Border.js.map +1 -1
  113. package/dist/src/core/shaders/webgl/RoundedWithBorder.js +16 -17
  114. package/dist/src/core/shaders/webgl/RoundedWithBorder.js.map +1 -1
  115. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js +19 -21
  116. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js.map +1 -1
  117. package/dist/src/core/shaders/webgl/SdfShadowShader.d.ts +9 -0
  118. package/dist/src/core/shaders/webgl/SdfShadowShader.js +100 -0
  119. package/dist/src/core/shaders/webgl/SdfShadowShader.js.map +1 -0
  120. package/dist/src/core/text-rendering/CanvasFont.d.ts +1 -1
  121. package/dist/src/core/text-rendering/CanvasFont.js +2 -6
  122. package/dist/src/core/text-rendering/CanvasFont.js.map +1 -1
  123. package/dist/src/core/text-rendering/CoreFont.d.ts +1 -1
  124. package/dist/src/core/text-rendering/CoreFont.js +1 -1
  125. package/dist/src/core/text-rendering/CoreFont.js.map +1 -1
  126. package/dist/src/core/text-rendering/FontManager.js +2 -1
  127. package/dist/src/core/text-rendering/FontManager.js.map +1 -1
  128. package/dist/src/core/text-rendering/SdfFontHandler.js +10 -20
  129. package/dist/src/core/text-rendering/SdfFontHandler.js.map +1 -1
  130. package/dist/src/core/text-rendering/SdfTextRenderer.js +10 -12
  131. package/dist/src/core/text-rendering/SdfTextRenderer.js.map +1 -1
  132. package/dist/src/core/textures/ImageTexture.d.ts +24 -11
  133. package/dist/src/core/textures/ImageTexture.js +32 -95
  134. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  135. package/dist/src/core/textures/SubTexture.js +3 -3
  136. package/dist/src/core/textures/SubTexture.js.map +1 -1
  137. package/dist/src/core/textures/Texture.d.ts +1 -1
  138. package/dist/src/core/textures/Texture.js +1 -1
  139. package/dist/src/core/textures/Texture.js.map +1 -1
  140. package/dist/src/main-api/Renderer.js +18 -21
  141. package/dist/src/main-api/Renderer.js.map +1 -1
  142. package/dist/src/utils.d.ts +0 -2
  143. package/dist/src/utils.js +0 -36
  144. package/dist/src/utils.js.map +1 -1
  145. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  146. package/dist/tsconfig.tsbuildinfo +1 -0
  147. package/exports/index.ts +3 -1
  148. package/exports/platform.ts +31 -0
  149. package/package.json +3 -2
  150. package/src/core/CoreNode.ts +52 -49
  151. package/src/core/CoreTextureManager.ts +10 -103
  152. package/src/core/Stage.ts +1 -14
  153. package/src/core/animations/CoreAnimationController.ts +5 -2
  154. package/src/core/lib/collectionUtils.ts +0 -35
  155. package/src/core/lib/utils.ts +0 -78
  156. package/src/core/platforms/GlContextWrapper.ts +291 -0
  157. package/src/core/platforms/Platform.ts +121 -28
  158. package/src/core/{lib → platforms/web}/WebGlContextWrapper.ts +129 -4
  159. package/src/core/platforms/web/WebPlatform.ts +171 -22
  160. package/src/core/platforms/web/WebPlatformChrome50.ts +57 -0
  161. package/src/core/platforms/web/WebPlatformLegacy.ts +140 -0
  162. package/src/core/platforms/web/WebPlatformNext.ts +57 -0
  163. package/src/core/{lib → platforms/web/lib}/ImageWorker.ts +10 -74
  164. package/src/core/platforms/web/lib/createImageBitmap.ts +40 -0
  165. package/src/core/{lib → platforms/web/lib}/textureCompression.ts +19 -138
  166. package/src/core/{lib → platforms/web/lib}/textureSvg.ts +3 -15
  167. package/src/core/platforms/web/lib/utils.ts +105 -0
  168. package/src/core/renderers/CoreRenderer.ts +2 -11
  169. package/src/core/renderers/canvas/CanvasRenderer.ts +8 -6
  170. package/src/core/renderers/canvas/CanvasShaderNode.ts +3 -3
  171. package/src/core/renderers/webgl/SdfRenderOp.ts +3 -2
  172. package/src/core/renderers/webgl/WebGlCtxRenderTexture.ts +2 -2
  173. package/src/core/renderers/webgl/WebGlCtxSubTexture.ts +2 -2
  174. package/src/core/renderers/webgl/WebGlCtxTexture.ts +3 -4
  175. package/src/core/renderers/webgl/WebGlRenderer.ts +15 -22
  176. package/src/core/renderers/webgl/WebGlShaderNode.ts +5 -5
  177. package/src/core/renderers/webgl/WebGlShaderProgram.ts +2 -6
  178. package/src/core/renderers/webgl/internal/RendererUtils.ts +4 -8
  179. package/src/core/renderers/webgl/internal/ShaderUtils.ts +7 -5
  180. package/src/core/shaders/webgl/Border.ts +6 -4
  181. package/src/core/shaders/webgl/RoundedWithBorder.ts +16 -17
  182. package/src/core/shaders/webgl/RoundedWithBorderAndShadow.ts +19 -21
  183. package/src/core/text-rendering/SdfFontHandler.ts +10 -17
  184. package/src/core/text-rendering/SdfTextRenderer.ts +11 -16
  185. package/src/core/textures/ImageTexture.ts +42 -161
  186. package/src/core/textures/SubTexture.ts +3 -3
  187. package/src/core/textures/Texture.ts +2 -2
  188. package/src/main-api/Renderer.ts +24 -22
  189. package/src/utils.ts +0 -47
  190. package/src/core/lib/validateImageBitmap.ts +0 -87
@@ -16,8 +16,9 @@
16
16
  * See the License for the specific language governing permissions and
17
17
  * limitations under the License.
18
18
  */
19
- import { type CompressedData, type TextureData } from '../textures/Texture.js';
20
- import type { WebGlContextWrapper } from './WebGlContextWrapper.js';
19
+ import { type CompressedData } from '../../../textures/Texture.js';
20
+ import type { ImageResponse } from '../../../textures/ImageTexture.js';
21
+ import type { WebGlContextWrapper } from '../WebGlContextWrapper.js';
21
22
 
22
23
  export type UploadCompressedTextureFunction = (
23
24
  glw: WebGlContextWrapper,
@@ -25,18 +26,6 @@ export type UploadCompressedTextureFunction = (
25
26
  data: CompressedData,
26
27
  ) => void;
27
28
 
28
- /**
29
- * Tests if the given location is a compressed texture container
30
- * @param url
31
- * @remarks
32
- * This function is used to determine if the given image url is a compressed
33
- * and only supports the following extensions: .ktx and .pvr
34
- * @returns
35
- */
36
- export function isCompressedTextureContainer(src: string): boolean {
37
- return /\.(ktx|pvr)$/.test(src);
38
- }
39
-
40
29
  const PVR_MAGIC = 0x03525650; // 'PVR3' in little-endian
41
30
  const PVR_TO_GL_INTERNAL_FORMAT: Record<string, number> = {
42
31
  0: 0x8c01,
@@ -72,7 +61,7 @@ const KTX_IDENTIFIER = [
72
61
  */
73
62
  export const loadCompressedTexture = async (
74
63
  url: string,
75
- ): Promise<TextureData> => {
64
+ ): Promise<ImageResponse> => {
76
65
  try {
77
66
  const response = await fetch(url);
78
67
  if (!response.ok) {
@@ -133,7 +122,7 @@ function readUint24(view: DataView, offset: number) {
133
122
  * @param view
134
123
  * @returns
135
124
  */
136
- const loadASTC = async function (view: DataView): Promise<TextureData> {
125
+ const loadASTC = async function (view: DataView): Promise<ImageResponse> {
137
126
  const blockX = view.getUint8(4);
138
127
  const blockY = view.getUint8(5);
139
128
  const sizeX = readUint24(view, 7);
@@ -167,43 +156,18 @@ const loadASTC = async function (view: DataView): Promise<TextureData> {
167
156
  mipmaps,
168
157
  w: sizeX,
169
158
  h: sizeY,
170
- type: 'astc',
159
+ type: 'ASTC',
171
160
  },
172
161
  premultiplyAlpha: false,
173
162
  };
174
163
  };
175
164
 
176
- const uploadASTC = function (
177
- glw: WebGlContextWrapper,
178
- texture: WebGLTexture,
179
- data: CompressedData,
180
- ) {
181
- if (glw.getExtension('WEBGL_compressed_texture_astc') === null) {
182
- throw new Error('ASTC compressed textures not supported by this device');
183
- }
184
-
185
- glw.bindTexture(texture);
186
-
187
- const { glInternalFormat, mipmaps, w, h } = data;
188
- if (mipmaps === undefined) {
189
- return;
190
- }
191
-
192
- const view = new Uint8Array(mipmaps[0]!);
193
-
194
- glw.compressedTexImage2D(0, glInternalFormat, w, h, 0, view);
195
- // ASTC textures MUST use no mipmaps unless stored
196
- glw.texParameteri(glw.TEXTURE_WRAP_S, glw.CLAMP_TO_EDGE);
197
- glw.texParameteri(glw.TEXTURE_WRAP_T, glw.CLAMP_TO_EDGE);
198
- glw.texParameteri(glw.TEXTURE_MAG_FILTER, glw.LINEAR);
199
- glw.texParameteri(glw.TEXTURE_MIN_FILTER, glw.LINEAR);
200
- };
201
165
  /**
202
166
  * Loads a KTX texture container and returns the texture data
203
167
  * @param view
204
168
  * @returns
205
169
  */
206
- const loadKTX = async function (view: DataView): Promise<TextureData> {
170
+ const loadKTX = async function (view: DataView): Promise<ImageResponse> {
207
171
  const endianness = view.getUint32(12, true);
208
172
  const littleEndian = endianness === 0x04030201;
209
173
  if (littleEndian === false && endianness !== 0x01020304) {
@@ -267,58 +231,12 @@ const loadKTX = async function (view: DataView): Promise<TextureData> {
267
231
  mipmaps,
268
232
  w: width,
269
233
  h: height,
270
- type: 'ktx',
234
+ type: 'KTX',
271
235
  },
272
236
  premultiplyAlpha: false,
273
237
  };
274
238
  };
275
239
 
276
- const uploadKTX = function (
277
- glw: WebGlContextWrapper,
278
- texture: WebGLTexture,
279
- data: CompressedData,
280
- ) {
281
- const { glInternalFormat, mipmaps, w: width, h: height, blockInfo } = data;
282
- if (mipmaps === undefined) {
283
- return;
284
- }
285
- glw.bindTexture(texture);
286
-
287
- const blockWidth = blockInfo.width;
288
- const blockHeight = blockInfo.height;
289
- let w = width;
290
- let h = height;
291
-
292
- for (let i = 0; i < mipmaps!.length; i++) {
293
- let view = new Uint8Array(mipmaps![i]!);
294
-
295
- const uploadW = Math.ceil(w / blockWidth) * blockWidth;
296
- const uploadH = Math.ceil(h / blockHeight) * blockHeight;
297
-
298
- const expectedBytes =
299
- Math.ceil(w / blockWidth) * Math.ceil(h / blockHeight) * blockInfo.bytes;
300
-
301
- if (view.byteLength < expectedBytes) {
302
- const padded = new Uint8Array(expectedBytes);
303
- padded.set(view);
304
- view = padded;
305
- }
306
-
307
- glw.compressedTexImage2D(i, glInternalFormat, uploadW, uploadH, 0, view);
308
-
309
- w = Math.max(1, w >> 1);
310
- h = Math.max(1, h >> 1);
311
- }
312
-
313
- glw.texParameteri(glw.TEXTURE_WRAP_S, glw.CLAMP_TO_EDGE);
314
- glw.texParameteri(glw.TEXTURE_WRAP_T, glw.CLAMP_TO_EDGE);
315
- glw.texParameteri(glw.TEXTURE_MAG_FILTER, glw.LINEAR);
316
- glw.texParameteri(
317
- glw.TEXTURE_MIN_FILTER,
318
- mipmaps!.length > 1 ? glw.LINEAR_MIPMAP_LINEAR : glw.LINEAR,
319
- );
320
- };
321
-
322
240
  function pvrtcMipSize(width: number, height: number, bpp: 2 | 4) {
323
241
  const minW = bpp === 2 ? 16 : 8;
324
242
  const minH = 8;
@@ -327,7 +245,7 @@ function pvrtcMipSize(width: number, height: number, bpp: 2 | 4) {
327
245
  return (w * h * bpp) / 8;
328
246
  }
329
247
 
330
- const loadPVR = async function (view: DataView): Promise<TextureData> {
248
+ const loadPVR = async function (view: DataView): Promise<ImageResponse> {
331
249
  const pixelFormatLow = view.getUint32(8, true);
332
250
  const internalFormat = PVR_TO_GL_INTERNAL_FORMAT[pixelFormatLow];
333
251
 
@@ -405,50 +323,22 @@ const loadPVR = async function (view: DataView): Promise<TextureData> {
405
323
  mipmaps,
406
324
  w: width,
407
325
  h: height,
408
- type: 'pvr',
326
+ type: 'PVR',
409
327
  },
410
328
  premultiplyAlpha: false,
411
329
  };
412
330
  };
413
331
 
414
- const uploadPVR = function (
415
- glw: WebGlContextWrapper,
416
- texture: WebGLTexture,
417
- data: CompressedData,
418
- ) {
419
- const { glInternalFormat, mipmaps, w: width, h: height } = data;
420
- if (mipmaps === undefined) {
421
- return;
422
- }
423
- glw.bindTexture(texture);
424
-
425
- let w = width;
426
- let h = height;
427
-
428
- for (let i = 0; i < mipmaps!.length; i++) {
429
- glw.compressedTexImage2D(
430
- i,
431
- glInternalFormat,
432
- w,
433
- h,
434
- 0,
435
- new Uint8Array(mipmaps[i]!),
436
- );
437
-
438
- w = Math.max(1, w >> 1);
439
- h = Math.max(1, h >> 1);
440
- }
441
-
442
- glw.texParameteri(glw.TEXTURE_WRAP_S, glw.CLAMP_TO_EDGE);
443
- glw.texParameteri(glw.TEXTURE_WRAP_T, glw.CLAMP_TO_EDGE);
444
- glw.texParameteri(glw.TEXTURE_MAG_FILTER, glw.LINEAR);
445
- glw.texParameteri(
446
- glw.TEXTURE_MIN_FILTER,
447
- mipmaps.length > 1 ? glw.LINEAR_MIPMAP_LINEAR : glw.LINEAR,
448
- );
449
- };
332
+ export interface CompressedImageData {
333
+ blockInfo: BlockInfo;
334
+ glInternalFormat: number;
335
+ mipmaps: ArrayBuffer[];
336
+ w: number;
337
+ h: number;
338
+ type: 'PVR' | 'KTX' | 'ASTC';
339
+ }
450
340
 
451
- type BlockInfo = {
341
+ export type BlockInfo = {
452
342
  width: number;
453
343
  height: number;
454
344
  bytes: number;
@@ -499,12 +389,3 @@ export const blockInfoMap: { [key: number]: BlockInfo } = {
499
389
  0x93b5: BLOCK_12x12x16, // 12x12
500
390
  0x93d5: BLOCK_12x12x16,
501
391
  };
502
-
503
- export const uploadCompressedTexture: Record<
504
- string,
505
- UploadCompressedTextureFunction
506
- > = {
507
- ktx: uploadKTX,
508
- pvr: uploadPVR,
509
- astc: uploadASTC,
510
- };
@@ -17,20 +17,8 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
- import { assertTruthy } from '../../utils.js';
21
- import { type TextureData } from '../textures/Texture.js';
22
-
23
- /**
24
- * Tests if the given location is a SVG
25
- * @param url
26
- * @remarks
27
- * This function is used to determine if the given image url is a SVG
28
- * image
29
- * @returns
30
- */
31
- export function isSvgImage(url: string): boolean {
32
- return /\.(svg)(\?.*)?$/.test(url);
33
- }
20
+ import { assertTruthy } from '../../../../utils.js';
21
+ import type { ImageResponse } from '../../../textures/ImageTexture.js';
34
22
 
35
23
  /**
36
24
  * Loads a SVG image
@@ -45,7 +33,7 @@ export const loadSvg = (
45
33
  sy: number | null,
46
34
  sw: number | null,
47
35
  sh: number | null,
48
- ): Promise<TextureData> => {
36
+ ): Promise<ImageResponse> => {
49
37
  return new Promise((resolve, reject) => {
50
38
  const canvas = document.createElement('canvas');
51
39
  const ctx = canvas.getContext('2d');
@@ -0,0 +1,105 @@
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 2026 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
+ export const PROTOCOL_REGEX = /^(data|ftps?|https?):/;
21
+
22
+ export function isBase64Image(src: string) {
23
+ return src.startsWith('data:') === true;
24
+ }
25
+
26
+ export function dataURIToBlob(dataURI: string): Blob {
27
+ dataURI = dataURI.replace(/^data:/, '');
28
+
29
+ const type = dataURI.match(/image\/[^;]+/)?.[0] || '';
30
+ const base64 = dataURI.replace(/^[^,]+,/, '');
31
+
32
+ const sliceSize = 1024;
33
+ const byteCharacters = atob(base64);
34
+ const bytesLength = byteCharacters.length;
35
+ const slicesCount = Math.ceil(bytesLength / sliceSize);
36
+ const byteArrays = new Array(slicesCount);
37
+
38
+ for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
39
+ const begin = sliceIndex * sliceSize;
40
+ const end = Math.min(begin + sliceSize, bytesLength);
41
+
42
+ const bytes = new Array(end - begin);
43
+ for (let offset = begin, i = 0; offset < end; ++i, ++offset) {
44
+ bytes[i] = byteCharacters[offset]?.charCodeAt(0);
45
+ }
46
+ byteArrays[sliceIndex] = new Uint8Array(bytes);
47
+ }
48
+ return new Blob(byteArrays, { type });
49
+ }
50
+
51
+ export function convertUrlToAbsolute(url: string): string {
52
+ // handle local file imports if the url isn't remote resource or data blob
53
+ if (self.location.protocol === 'file:' && !PROTOCOL_REGEX.test(url)) {
54
+ const path = self.location.pathname.split('/');
55
+ path.pop();
56
+ const basePath = path.join('/');
57
+ const baseUrl = self.location.protocol + '//' + basePath;
58
+
59
+ // check if url has a leading dot
60
+ if (url.charAt(0) === '.') {
61
+ url = url.slice(1);
62
+ }
63
+
64
+ // check if url has a leading slash
65
+ if (url.charAt(0) === '/') {
66
+ url = url.slice(1);
67
+ }
68
+
69
+ return baseUrl + '/' + url;
70
+ }
71
+
72
+ const absoluteUrl = new URL(url, self.location.href);
73
+ return absoluteUrl.href;
74
+ }
75
+
76
+ export function createWebGLContext(
77
+ canvas: HTMLCanvasElement | OffscreenCanvas,
78
+ forceWebGL2 = false,
79
+ ): WebGLRenderingContext {
80
+ const config: WebGLContextAttributes = {
81
+ alpha: true,
82
+ antialias: false,
83
+ depth: false,
84
+ stencil: true,
85
+ desynchronized: false,
86
+ // Disabled because it prevents Visual Regression Tests from working
87
+ // failIfMajorPerformanceCaveat: true,
88
+ powerPreference: 'high-performance',
89
+ premultipliedAlpha: true,
90
+ preserveDrawingBuffer: false,
91
+ };
92
+ const gl =
93
+ // TODO: Remove this assertion once this issue is fixed in TypeScript
94
+ // https://github.com/microsoft/TypeScript/issues/53614
95
+ (canvas.getContext(forceWebGL2 ? 'webgl2' : 'webgl', config) ||
96
+ canvas.getContext(
97
+ 'experimental-webgl' as 'webgl',
98
+ config,
99
+ )) as unknown as WebGLRenderingContext | null;
100
+ if (!gl) {
101
+ throw new Error('Unable to create WebGL context');
102
+ }
103
+
104
+ return gl;
105
+ }
@@ -25,20 +25,12 @@ import type { Texture, TextureCoords } from '../textures/Texture.js';
25
25
  import { CoreContextTexture } from './CoreContextTexture.js';
26
26
  import type { CoreShaderType, CoreShaderNode } from './CoreShaderNode.js';
27
27
 
28
- export interface CoreRendererOptions {
29
- stage: Stage;
30
- canvas: HTMLCanvasElement | OffscreenCanvas;
31
- contextSpy: ContextSpy | null;
32
- forceWebGL2: boolean;
33
- }
34
-
35
28
  export interface BufferInfo {
36
29
  totalUsed: number;
37
30
  totalAvailable: number;
38
31
  }
39
32
 
40
33
  export abstract class CoreRenderer {
41
- public options: CoreRendererOptions;
42
34
  public mode: 'webgl' | 'canvas' | undefined;
43
35
  defaultTextureCoords: TextureCoords | undefined = undefined;
44
36
  readonly stage: Stage;
@@ -46,9 +38,8 @@ export abstract class CoreRenderer {
46
38
  //// Core Managers
47
39
  rttNodes: CoreNode[] = [];
48
40
 
49
- constructor(options: CoreRendererOptions) {
50
- this.options = options;
51
- this.stage = options.stage;
41
+ constructor(stage: Stage) {
42
+ this.stage = stage;
52
43
  }
53
44
 
54
45
  abstract reset(): void;
@@ -20,11 +20,12 @@ import type { CoreNode } from '../../CoreNode.js';
20
20
  import { SubTexture } from '../../textures/SubTexture.js';
21
21
  import { TextureType, type Texture } from '../../textures/Texture.js';
22
22
  import type { CoreContextTexture } from '../CoreContextTexture.js';
23
- import { CoreRenderer, type CoreRendererOptions } from '../CoreRenderer.js';
23
+ import { CoreRenderer } from '../CoreRenderer.js';
24
24
  import { CanvasTexture } from './CanvasTexture.js';
25
25
  import { parseColor } from '../../lib/colorParser.js';
26
26
  import { CanvasShaderNode, type CanvasShaderType } from './CanvasShaderNode.js';
27
27
  import { normalizeCanvasColor } from '../../lib/colorCache.js';
28
+ import type { Stage } from '../../Stage.js';
28
29
 
29
30
  export class CanvasRenderer extends CoreRenderer {
30
31
  private context: CanvasRenderingContext2D;
@@ -34,15 +35,16 @@ export class CanvasRenderer extends CoreRenderer {
34
35
  public renderToTextureActive = false;
35
36
  activeRttNode: CoreNode | null = null;
36
37
 
37
- constructor(options: CoreRendererOptions) {
38
- super(options);
38
+ constructor(stage: Stage) {
39
+ super(stage);
39
40
 
40
41
  this.mode = 'canvas';
41
- const { canvas } = options;
42
+ const platform = stage.platform!;
43
+ const canvas = platform.canvas!;
42
44
  this.canvas = canvas as HTMLCanvasElement;
43
45
  this.context = canvas.getContext('2d') as CanvasRenderingContext2D;
44
- this.pixelRatio = this.stage.pixelRatio;
45
- this.clearColor = normalizeCanvasColor(this.stage.clearColor);
46
+ this.pixelRatio = stage.pixelRatio;
47
+ this.clearColor = normalizeCanvasColor(stage.clearColor);
46
48
  }
47
49
 
48
50
  reset(): void {
@@ -73,10 +73,10 @@ export class CanvasShaderNode<
73
73
  }
74
74
 
75
75
  if (prevKey.length > 0) {
76
- this.stage.shManager.mutateShaderValueUsage(prevKey, -1);
76
+ stage.shManager.mutateShaderValueUsage(prevKey, -1);
77
77
  }
78
78
 
79
- const computed = this.stage.shManager.getShaderValues(
79
+ const computed = stage.shManager.getShaderValues(
80
80
  this.valueKey,
81
81
  ) as Record<string, unknown>;
82
82
  if (computed !== undefined) {
@@ -84,7 +84,7 @@ export class CanvasShaderNode<
84
84
  }
85
85
  this.computed = {};
86
86
  this.updater!(this.node as CoreNode);
87
- this.stage.shManager.setShaderValues(this.valueKey, this.computed);
87
+ stage.shManager.setShaderValues(this.valueKey, this.computed);
88
88
  };
89
89
  }
90
90
  }
@@ -70,7 +70,8 @@ export class SdfRenderOp extends CoreRenderOp {
70
70
  }
71
71
 
72
72
  draw() {
73
- const { glw, options, stage } = this.renderer;
73
+ const { glw, stage } = this.renderer;
74
+ const canvas = stage.platform!.canvas!;
74
75
 
75
76
  stage.shManager.useShader(this.shader.program);
76
77
  this.shader.program.bindRenderOp(this);
@@ -82,7 +83,7 @@ export class SdfRenderOp extends CoreRenderOp {
82
83
  const clipWidth = Math.round(this.clippingRect.w * pixelRatio);
83
84
  const clipHeight = Math.round(this.clippingRect.h * pixelRatio);
84
85
  let clipY = Math.round(
85
- options.canvas.height - clipHeight - this.clippingRect.y * pixelRatio,
86
+ canvas.height - clipHeight - this.clippingRect.y * pixelRatio,
86
87
  );
87
88
  // if parent has render texture, we need to adjust the scissor rect
88
89
  // to be relative to the parent's framebuffer
@@ -19,7 +19,7 @@
19
19
 
20
20
  import type { Dimensions } from '../../../common/CommonTypes.js';
21
21
  import type { TextureMemoryManager } from '../../TextureMemoryManager.js';
22
- import type { WebGlContextWrapper } from '../../lib/WebGlContextWrapper.js';
22
+ import type { GlContextWrapper } from '../../platforms/GlContextWrapper.js';
23
23
  import type { Bound } from '../../lib/utils.js';
24
24
  import type { RenderTexture } from '../../textures/RenderTexture.js';
25
25
  import { WebGlCtxTexture } from './WebGlCtxTexture.js';
@@ -37,7 +37,7 @@ export class WebGlCtxRenderTexture extends WebGlCtxTexture {
37
37
  };
38
38
 
39
39
  constructor(
40
- glw: WebGlContextWrapper,
40
+ glw: GlContextWrapper,
41
41
  memManager: TextureMemoryManager,
42
42
  textureSource: RenderTexture,
43
43
  ) {
@@ -20,7 +20,7 @@
20
20
  import type { Dimensions } from '../../../common/CommonTypes.js';
21
21
  import { assertTruthy } from '../../../utils.js';
22
22
  import type { TextureMemoryManager } from '../../TextureMemoryManager.js';
23
- import type { WebGlContextWrapper } from '../../lib/WebGlContextWrapper.js';
23
+ import type { GlContextWrapper } from '../../platforms/GlContextWrapper.js';
24
24
  import type { SubTexture } from '../../textures/SubTexture.js';
25
25
  import type { SubTextureProps } from '../../textures/SubTexture.js';
26
26
  import type { CompressedData } from '../../textures/Texture.js';
@@ -28,7 +28,7 @@ import { WebGlCtxTexture } from './WebGlCtxTexture.js';
28
28
 
29
29
  export class WebGlCtxSubTexture extends WebGlCtxTexture {
30
30
  constructor(
31
- glw: WebGlContextWrapper,
31
+ glw: GlContextWrapper,
32
32
  memManager: TextureMemoryManager,
33
33
  textureSource: SubTexture,
34
34
  ) {
@@ -19,9 +19,8 @@
19
19
 
20
20
  import type { Dimensions } from '../../../common/CommonTypes.js';
21
21
  import type { TextureMemoryManager } from '../../TextureMemoryManager.js';
22
- import type { WebGlContextWrapper } from '../../lib/WebGlContextWrapper.js';
22
+ import type { GlContextWrapper } from '../../platforms/GlContextWrapper.js';
23
23
  import type { Texture } from '../../textures/Texture.js';
24
- import { uploadCompressedTexture } from '../../lib/textureCompression.js';
25
24
  import { CoreContextTexture } from '../CoreContextTexture.js';
26
25
  import { isHTMLImageElement } from './internal/RendererUtils.js';
27
26
  import type { Bound } from '../../lib/utils.js';
@@ -53,7 +52,7 @@ export class WebGlCtxTexture extends CoreContextTexture {
53
52
  };
54
53
 
55
54
  constructor(
56
- protected glw: WebGlContextWrapper,
55
+ protected glw: GlContextWrapper,
57
56
  memManager: TextureMemoryManager,
58
57
  textureSource: Texture,
59
58
  ) {
@@ -239,7 +238,7 @@ export class WebGlCtxTexture extends CoreContextTexture {
239
238
  this.setTextureMemUse(TRANSPARENT_TEXTURE_DATA.byteLength);
240
239
  } else if ('mipmaps' in tdata && tdata.mipmaps) {
241
240
  const { mipmaps, type, blockInfo } = tdata;
242
- uploadCompressedTexture[type]!(glw, this._nativeCtxTexture, tdata);
241
+ glw['upload' + type]!(this._nativeCtxTexture, tdata);
243
242
 
244
243
  // Check for errors after compressed texture operations
245
244
  if (this.checkGLError() === true) {
@@ -17,12 +17,7 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
- import { createWebGLContext } from '../../../utils.js';
21
- import {
22
- CoreRenderer,
23
- type BufferInfo,
24
- type CoreRendererOptions,
25
- } from '../CoreRenderer.js';
20
+ import { CoreRenderer, type BufferInfo } from '../CoreRenderer.js';
26
21
  import type { SdfRenderOp } from './SdfRenderOp.js';
27
22
  import type { CoreContextTexture } from '../CoreContextTexture.js';
28
23
  import {
@@ -44,7 +39,6 @@ import { WebGlCtxSubTexture } from './WebGlCtxSubTexture.js';
44
39
  import { BufferCollection } from './internal/BufferCollection.js';
45
40
  import { compareRect, getNormalizedRgbaComponents } from '../../lib/utils.js';
46
41
  import { WebGlShaderProgram } from './WebGlShaderProgram.js';
47
- import { WebGlContextWrapper } from '../../lib/WebGlContextWrapper.js';
48
42
  import { RenderTexture } from '../../textures/RenderTexture.js';
49
43
  import { CoreNodeRenderState, CoreNode } from '../../CoreNode.js';
50
44
  import { WebGlCtxRenderTexture } from './WebGlCtxRenderTexture.js';
@@ -52,8 +46,9 @@ import { Default } from '../../shaders/webgl/Default.js';
52
46
  import type { WebGlShaderType } from './WebGlShaderNode.js';
53
47
  import { WebGlShaderNode } from './WebGlShaderNode.js';
54
48
  import type { Dimensions } from '../../../common/CommonTypes.js';
55
-
56
- export type WebGlRendererOptions = CoreRendererOptions;
49
+ import type { GlContextWrapper } from '../../platforms/GlContextWrapper.js';
50
+ import type { Platform } from '../../platforms/Platform.js';
51
+ import type { Stage } from '../../Stage.js';
57
52
 
58
53
  interface CoreWebGlSystem {
59
54
  parameters: CoreWebGlParameters;
@@ -64,7 +59,7 @@ export type WebGlRenderOp = CoreNode | SdfRenderOp;
64
59
 
65
60
  export class WebGlRenderer extends CoreRenderer {
66
61
  //// WebGL Native Context and Data
67
- glw: WebGlContextWrapper;
62
+ glw: GlContextWrapper;
68
63
  system: CoreWebGlSystem;
69
64
 
70
65
  //// Persistent data
@@ -106,29 +101,27 @@ export class WebGlRenderer extends CoreRenderer {
106
101
  */
107
102
  public renderToTextureActive = false;
108
103
 
109
- constructor(options: WebGlRendererOptions) {
110
- super(options);
104
+ constructor(stage: Stage) {
105
+ super(stage);
111
106
 
112
- this.quadBuffer = new ArrayBuffer(this.stage.options.quadBufferSize);
107
+ this.quadBuffer = new ArrayBuffer(stage.options.quadBufferSize);
113
108
  this.fQuadBuffer = new Float32Array(this.quadBuffer);
114
109
  this.uiQuadBuffer = new Uint32Array(this.quadBuffer);
115
110
 
116
111
  this.mode = 'webgl';
117
112
 
118
- const gl = createWebGLContext(
119
- options.canvas,
120
- options.forceWebGL2,
121
- options.contextSpy,
122
- );
123
- const glw = (this.glw = new WebGlContextWrapper(gl));
124
- glw.viewport(0, 0, options.canvas.width, options.canvas.height);
113
+ const platform = stage.platform;
114
+ const canvas = platform.canvas!;
115
+
116
+ const glw = (this.glw = platform.createContext() as GlContextWrapper);
117
+ glw.viewport(0, 0, canvas.width, canvas.height);
125
118
 
126
- this.updateClearColor(this.stage.clearColor);
119
+ this.updateClearColor(stage.clearColor);
127
120
 
128
121
  glw.setBlend(true);
129
122
  glw.blendFunc(glw.ONE, glw.ONE_MINUS_SRC_ALPHA);
130
123
 
131
- createIndexBuffer(glw, this.stage.bufferMemory);
124
+ createIndexBuffer(glw, stage.bufferMemory);
132
125
 
133
126
  this.system = {
134
127
  parameters: getWebGlParameters(this.glw),
@@ -1,6 +1,6 @@
1
1
  import type { CoreNode } from '../../CoreNode.js';
2
2
  import { getNormalizedRgbaComponents } from '../../lib/utils.js';
3
- import type { WebGlContextWrapper } from '../../lib/WebGlContextWrapper.js';
3
+ import type { GlContextWrapper } from '../../platforms/GlContextWrapper.js';
4
4
  import type { Stage } from '../../Stage.js';
5
5
  import { CoreShaderNode, type CoreShaderType } from '../CoreShaderNode.js';
6
6
  import type {
@@ -40,7 +40,7 @@ export type WebGlShaderType<T extends object = Record<string, unknown>> =
40
40
  *
41
41
  * @warning don't use this in your shader type
42
42
  */
43
- onSdfBind?: (this: WebGlContextWrapper, props: T) => void;
43
+ onSdfBind?: (this: GlContextWrapper, props: T) => void;
44
44
  /**
45
45
  * This function is used to check if the shader can be reused based on quad info
46
46
  * @param props
@@ -94,10 +94,10 @@ export class WebGlShaderNode<
94
94
  }
95
95
 
96
96
  if (prevKey.length > 0) {
97
- this.stage.shManager.mutateShaderValueUsage(prevKey, -1);
97
+ stage.shManager.mutateShaderValueUsage(prevKey, -1);
98
98
  }
99
99
 
100
- const values = this.stage.shManager.getShaderValues(
100
+ const values = stage.shManager.getShaderValues(
101
101
  this.valueKey,
102
102
  ) as unknown as UniformCollection;
103
103
  if (values !== undefined) {
@@ -112,7 +112,7 @@ export class WebGlShaderNode<
112
112
  vec4: {},
113
113
  };
114
114
  this.updater!(this.node as CoreNode);
115
- this.stage.shManager.setShaderValues(
115
+ stage.shManager.setShaderValues(
116
116
  this.valueKey,
117
117
  this.uniforms as unknown as Record<string, unknown>,
118
118
  );