@lightningjs/renderer 2.12.1 → 2.13.1

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 (185) hide show
  1. package/dist/src/core/CoreNode.d.ts +10 -0
  2. package/dist/src/core/CoreNode.js +90 -14
  3. package/dist/src/core/CoreNode.js.map +1 -1
  4. package/dist/src/core/CoreTextureManager.d.ts +13 -7
  5. package/dist/src/core/CoreTextureManager.js +92 -105
  6. package/dist/src/core/CoreTextureManager.js.map +1 -1
  7. package/dist/src/core/Stage.d.ts +4 -2
  8. package/dist/src/core/Stage.js +23 -7
  9. package/dist/src/core/Stage.js.map +1 -1
  10. package/dist/src/core/TextureMemoryManager.d.ts +16 -6
  11. package/dist/src/core/TextureMemoryManager.js +75 -17
  12. package/dist/src/core/TextureMemoryManager.js.map +1 -1
  13. package/dist/src/core/lib/ImageWorker.d.ts +1 -1
  14. package/dist/src/core/lib/ImageWorker.js +15 -12
  15. package/dist/src/core/lib/ImageWorker.js.map +1 -1
  16. package/dist/src/core/lib/utils.d.ts +4 -0
  17. package/dist/src/core/lib/utils.js +46 -0
  18. package/dist/src/core/lib/utils.js.map +1 -1
  19. package/dist/src/core/lib/validateImageBitmap.d.ts +6 -0
  20. package/dist/src/core/lib/validateImageBitmap.js +68 -0
  21. package/dist/src/core/lib/validateImageBitmap.js.map +1 -0
  22. package/dist/src/core/platform.js +3 -3
  23. package/dist/src/core/platform.js.map +1 -1
  24. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +7 -12
  25. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  26. package/dist/src/core/textures/ImageTexture.d.ts +2 -2
  27. package/dist/src/core/textures/ImageTexture.js +34 -20
  28. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  29. package/dist/src/main-api/ICoreDriver.d.ts +1 -4
  30. package/dist/src/main-api/Inspector.js +16 -2
  31. package/dist/src/main-api/Inspector.js.map +1 -1
  32. package/dist/src/main-api/Renderer.d.ts +27 -1
  33. package/dist/src/main-api/Renderer.js +8 -3
  34. package/dist/src/main-api/Renderer.js.map +1 -1
  35. package/dist/src/main-api/RendererMain.d.ts +5 -2
  36. package/dist/src/main-api/RendererMain.js +6 -4
  37. package/dist/src/main-api/RendererMain.js.map +1 -1
  38. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.js.map +1 -1
  39. package/dist/src/render-drivers/main/MainCoreDriver.d.ts +1 -4
  40. package/dist/src/render-drivers/main/MainCoreDriver.js +1 -4
  41. package/dist/src/render-drivers/main/MainCoreDriver.js.map +1 -1
  42. package/dist/src/render-drivers/main/MainOnlyNode.d.ts +8 -6
  43. package/dist/src/render-drivers/main/MainOnlyNode.js +30 -1
  44. package/dist/src/render-drivers/main/MainOnlyNode.js.map +1 -1
  45. package/dist/src/render-drivers/main/MainOnlyTextNode.d.ts +1 -1
  46. package/dist/src/render-drivers/main/MainOnlyTextNode.js +2 -3
  47. package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +1 -1
  48. package/dist/src/render-drivers/threadx/NodeStruct.d.ts +3 -0
  49. package/dist/src/render-drivers/threadx/NodeStruct.js +9 -0
  50. package/dist/src/render-drivers/threadx/NodeStruct.js.map +1 -1
  51. package/dist/src/render-drivers/threadx/SharedNode.d.ts +1 -0
  52. package/dist/src/render-drivers/threadx/SharedNode.js +1 -0
  53. package/dist/src/render-drivers/threadx/SharedNode.js.map +1 -1
  54. package/dist/src/render-drivers/threadx/TextNodeStruct.js +3 -1
  55. package/dist/src/render-drivers/threadx/TextNodeStruct.js.map +1 -1
  56. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.d.ts +1 -4
  57. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +2 -4
  58. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -1
  59. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.d.ts +8 -4
  60. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js +53 -24
  61. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js.map +1 -1
  62. package/dist/src/render-drivers/threadx/ThreadXMainNode.d.ts +7 -5
  63. package/dist/src/render-drivers/threadx/ThreadXMainNode.js +8 -2
  64. package/dist/src/render-drivers/threadx/ThreadXMainNode.js.map +1 -1
  65. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js.map +1 -1
  66. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +7 -0
  67. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +1 -1
  68. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +1 -0
  69. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +1 -1
  70. package/dist/src/render-drivers/threadx/worker/renderer.js +2 -0
  71. package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
  72. package/dist/src/render-drivers/utils.js +6 -1
  73. package/dist/src/render-drivers/utils.js.map +1 -1
  74. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  75. package/dist/tsconfig.tsbuildinfo +1 -0
  76. package/package.json +1 -1
  77. package/src/core/CoreNode.test.ts +155 -152
  78. package/src/core/CoreNode.ts +136 -22
  79. package/src/core/CoreTextureManager.ts +127 -126
  80. package/src/core/Stage.ts +28 -7
  81. package/src/core/TextureMemoryManager.ts +108 -27
  82. package/src/core/lib/ImageWorker.ts +22 -13
  83. package/src/core/lib/utils.ts +74 -0
  84. package/src/core/lib/validateImageBitmap.ts +76 -0
  85. package/src/core/platform.ts +5 -3
  86. package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +11 -13
  87. package/src/core/textures/ImageTexture.ts +42 -25
  88. package/src/main-api/Inspector.ts +19 -2
  89. package/src/main-api/Renderer.ts +34 -3
  90. package/dist/src/core/CoreStuff.d.ts +0 -1
  91. package/dist/src/core/CoreStuff.js +0 -138
  92. package/dist/src/core/CoreStuff.js.map +0 -1
  93. package/dist/src/core/CoreTexturizer.d.ts +0 -14
  94. package/dist/src/core/CoreTexturizer.js +0 -47
  95. package/dist/src/core/CoreTexturizer.js.map +0 -1
  96. package/dist/src/core/LngNode.d.ts +0 -736
  97. package/dist/src/core/LngNode.js +0 -1174
  98. package/dist/src/core/LngNode.js.map +0 -1
  99. package/dist/src/core/Matrix2DContext.d.ts +0 -15
  100. package/dist/src/core/Matrix2DContext.js +0 -45
  101. package/dist/src/core/Matrix2DContext.js.map +0 -1
  102. package/dist/src/core/ShaderNode.d.ts +0 -10
  103. package/dist/src/core/ShaderNode.js +0 -30
  104. package/dist/src/core/ShaderNode.js.map +0 -1
  105. package/dist/src/core/TextNode.d.ts +0 -103
  106. package/dist/src/core/TextNode.js +0 -331
  107. package/dist/src/core/TextNode.js.map +0 -1
  108. package/dist/src/core/lib/Coords.d.ts +0 -14
  109. package/dist/src/core/lib/Coords.js +0 -55
  110. package/dist/src/core/lib/Coords.js.map +0 -1
  111. package/dist/src/core/lib/glm/common.d.ts +0 -162
  112. package/dist/src/core/lib/glm/common.js +0 -81
  113. package/dist/src/core/lib/glm/common.js.map +0 -1
  114. package/dist/src/core/lib/glm/index.d.ts +0 -11
  115. package/dist/src/core/lib/glm/index.js +0 -30
  116. package/dist/src/core/lib/glm/index.js.map +0 -1
  117. package/dist/src/core/lib/glm/mat2.d.ts +0 -219
  118. package/dist/src/core/lib/glm/mat2.js +0 -396
  119. package/dist/src/core/lib/glm/mat2.js.map +0 -1
  120. package/dist/src/core/lib/glm/mat2d.d.ts +0 -237
  121. package/dist/src/core/lib/glm/mat2d.js +0 -442
  122. package/dist/src/core/lib/glm/mat2d.js.map +0 -1
  123. package/dist/src/core/lib/glm/mat3.d.ts +0 -283
  124. package/dist/src/core/lib/glm/mat3.js +0 -680
  125. package/dist/src/core/lib/glm/mat3.js.map +0 -1
  126. package/dist/src/core/lib/glm/mat4.d.ts +0 -550
  127. package/dist/src/core/lib/glm/mat4.js +0 -1802
  128. package/dist/src/core/lib/glm/mat4.js.map +0 -1
  129. package/dist/src/core/lib/glm/quat.d.ts +0 -363
  130. package/dist/src/core/lib/glm/quat.js +0 -693
  131. package/dist/src/core/lib/glm/quat.js.map +0 -1
  132. package/dist/src/core/lib/glm/quat2.d.ts +0 -356
  133. package/dist/src/core/lib/glm/quat2.js +0 -754
  134. package/dist/src/core/lib/glm/quat2.js.map +0 -1
  135. package/dist/src/core/lib/glm/vec2.d.ts +0 -365
  136. package/dist/src/core/lib/glm/vec2.js +0 -569
  137. package/dist/src/core/lib/glm/vec2.js.map +0 -1
  138. package/dist/src/core/lib/glm/vec3.d.ts +0 -406
  139. package/dist/src/core/lib/glm/vec3.js +0 -720
  140. package/dist/src/core/lib/glm/vec3.js.map +0 -1
  141. package/dist/src/core/lib/glm/vec4.d.ts +0 -330
  142. package/dist/src/core/lib/glm/vec4.js +0 -608
  143. package/dist/src/core/lib/glm/vec4.js.map +0 -1
  144. package/dist/src/core/renderers/CoreShaderManager.d.ts +0 -19
  145. package/dist/src/core/renderers/CoreShaderManager.js +0 -33
  146. package/dist/src/core/renderers/CoreShaderManager.js.map +0 -1
  147. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.d.ts +0 -27
  148. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.js +0 -82
  149. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.js.map +0 -1
  150. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.d.ts +0 -11
  151. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.js +0 -34
  152. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.js.map +0 -1
  153. package/dist/src/core/scene/Scene.d.ts +0 -59
  154. package/dist/src/core/scene/Scene.js +0 -106
  155. package/dist/src/core/scene/Scene.js.map +0 -1
  156. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.d.ts +0 -20
  157. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js +0 -55
  158. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js.map +0 -1
  159. package/dist/src/main-api/IRenderDriver.d.ts +0 -20
  160. package/dist/src/main-api/IRenderDriver.js +0 -20
  161. package/dist/src/main-api/IRenderDriver.js.map +0 -1
  162. package/dist/src/main-api/IShaderController.d.ts +0 -14
  163. package/dist/src/main-api/IShaderController.js +0 -30
  164. package/dist/src/main-api/IShaderController.js.map +0 -1
  165. package/dist/src/main-api/IShaderNode.d.ts +0 -17
  166. package/dist/src/main-api/IShaderNode.js +0 -19
  167. package/dist/src/main-api/IShaderNode.js.map +0 -1
  168. package/dist/src/render-drivers/main/MainOnlyShaderController.d.ts +0 -6
  169. package/dist/src/render-drivers/main/MainOnlyShaderController.js +0 -15
  170. package/dist/src/render-drivers/main/MainOnlyShaderController.js.map +0 -1
  171. package/dist/src/render-drivers/main/MainOnlyShaderNode.d.ts +0 -7
  172. package/dist/src/render-drivers/main/MainOnlyShaderNode.js +0 -34
  173. package/dist/src/render-drivers/main/MainOnlyShaderNode.js.map +0 -1
  174. package/dist/src/render-drivers/main/MainRenderDriver.d.ts +0 -17
  175. package/dist/src/render-drivers/main/MainRenderDriver.js +0 -88
  176. package/dist/src/render-drivers/main/MainRenderDriver.js.map +0 -1
  177. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.d.ts +0 -6
  178. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.js +0 -16
  179. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.js.map +0 -1
  180. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.d.ts +0 -7
  181. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.js +0 -15
  182. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.js.map +0 -1
  183. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.d.ts +0 -21
  184. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js +0 -198
  185. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js.map +0 -1
@@ -17,7 +17,7 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
- import type { CreateImageBitmapSupport } from '../CoreTextureManager.js';
20
+ import type { CreateImageBitmapSupport } from '../lib/validateImageBitmap.js';
21
21
  import { type TextureData } from '../textures/Texture.js';
22
22
 
23
23
  type MessageCallback = [(value: any) => void, (reason: any) => void];
@@ -102,12 +102,13 @@ function createImageWorker() {
102
102
  reject(error);
103
103
  });
104
104
  return;
105
- } else if (supportsOptionsCreateImageBitmap === true) {
106
- createImageBitmap(blob, {
107
- premultiplyAlpha: withAlphaChannel ? 'premultiply' : 'none',
108
- colorSpaceConversion: 'none',
109
- imageOrientation: 'none',
110
- })
105
+ } else if (
106
+ supportsOptionsCreateImageBitmap === false &&
107
+ supportsOptionsCreateImageBitmap === false
108
+ ) {
109
+ // Fallback for browsers that do not support createImageBitmap with options
110
+ // this is supported for Chrome v50 to v52/54 that doesn't support options
111
+ createImageBitmap(blob)
111
112
  .then(function (data) {
112
113
  resolve({ data, premultiplyAlpha: premultiplyAlpha });
113
114
  })
@@ -115,9 +116,11 @@ function createImageWorker() {
115
116
  reject(error);
116
117
  });
117
118
  } else {
118
- // Fallback for browsers that do not support createImageBitmap with options
119
- // this is supported for Chrome v50 to v52/54 that doesn't support options
120
- createImageBitmap(blob)
119
+ createImageBitmap(blob, {
120
+ premultiplyAlpha: withAlphaChannel ? 'premultiply' : 'none',
121
+ colorSpaceConversion: 'none',
122
+ imageOrientation: 'none',
123
+ })
121
124
  .then(function (data) {
122
125
  resolve({ data, premultiplyAlpha: premultiplyAlpha });
123
126
  })
@@ -155,7 +158,8 @@ function createImageWorker() {
155
158
  supportsFullCreateImageBitmap,
156
159
  })
157
160
  .then(function (data) {
158
- self.postMessage({ id: id, src: src, data: data });
161
+ // @ts-ignore ts has wrong postMessage signature
162
+ self.postMessage({ id: id, src: src, data: data }, [data.data]);
159
163
  })
160
164
  .catch(function (error) {
161
165
  self.postMessage({ id: id, src: src, error: error.message });
@@ -205,14 +209,19 @@ export class ImageWorkerManager {
205
209
  let workerCode = `(${createImageWorker.toString()})()`;
206
210
 
207
211
  // Replace placeholders with actual initialization values
208
- if (createImageBitmapSupport.options) {
212
+ if (createImageBitmapSupport.options === true) {
209
213
  workerCode = workerCode.replace(
210
214
  'var supportsOptionsCreateImageBitmap = false;',
211
215
  'var supportsOptionsCreateImageBitmap = true;',
212
216
  );
213
217
  }
214
218
 
215
- if (createImageBitmapSupport.full) {
219
+ if (createImageBitmapSupport.full === true) {
220
+ workerCode = workerCode.replace(
221
+ 'var supportsOptionsCreateImageBitmap = false;',
222
+ 'var supportsOptionsCreateImageBitmap = true;',
223
+ );
224
+
216
225
  workerCode = workerCode.replace(
217
226
  'var supportsFullCreateImageBitmap = false;',
218
227
  'var supportsFullCreateImageBitmap = true;',
@@ -308,3 +308,77 @@ export function convertUrlToAbsolute(url: string): string {
308
308
  export function isBase64Image(src: string) {
309
309
  return src.startsWith('data:') === true;
310
310
  }
311
+
312
+ export function calcFactoredRadius(
313
+ radius: number,
314
+ width: number,
315
+ height: number,
316
+ ): number {
317
+ return radius * Math.min(Math.min(width, height) / (2.0 * radius), 1);
318
+ }
319
+
320
+ export function valuesAreEqual(values: number[]) {
321
+ let prevValue = values[0];
322
+ for (let i = 1; i < values.length; i++) {
323
+ if (prevValue !== values[i]) {
324
+ return false;
325
+ }
326
+ }
327
+ return true;
328
+ }
329
+
330
+ export function calcFactoredRadiusArray(
331
+ radius: [number, number, number, number],
332
+ width: number,
333
+ height: number,
334
+ ): [number, number, number, number] {
335
+ const result: [number, number, number, number] = [
336
+ radius[0],
337
+ radius[1],
338
+ radius[2],
339
+ radius[3],
340
+ ];
341
+ const factor = Math.min(
342
+ Math.min(
343
+ Math.min(
344
+ width / Math.max(width, radius[0] + radius[1]),
345
+ width / Math.max(width, radius[2] + radius[3]),
346
+ ),
347
+ Math.min(
348
+ height / Math.max(height, radius[0] + radius[3]),
349
+ height / Math.max(height, radius[1] + radius[2]),
350
+ ),
351
+ ),
352
+ 1,
353
+ );
354
+ result[0] *= factor;
355
+ result[1] *= factor;
356
+ result[2] *= factor;
357
+ result[3] *= factor;
358
+ return result;
359
+ }
360
+
361
+ export function dataURIToBlob(dataURI: string): Blob {
362
+ dataURI = dataURI.replace(/^data:/, '');
363
+
364
+ const type = dataURI.match(/image\/[^;]+/)?.[0] || '';
365
+ const base64 = dataURI.replace(/^[^,]+,/, '');
366
+
367
+ const sliceSize = 1024;
368
+ const byteCharacters = atob(base64);
369
+ const bytesLength = byteCharacters.length;
370
+ const slicesCount = Math.ceil(bytesLength / sliceSize);
371
+ const byteArrays = new Array(slicesCount);
372
+
373
+ for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
374
+ const begin = sliceIndex * sliceSize;
375
+ const end = Math.min(begin + sliceSize, bytesLength);
376
+
377
+ const bytes = new Array(end - begin);
378
+ for (let offset = begin, i = 0; offset < end; ++i, ++offset) {
379
+ bytes[i] = byteCharacters[offset]?.charCodeAt(0);
380
+ }
381
+ byteArrays[sliceIndex] = new Uint8Array(bytes);
382
+ }
383
+ return new Blob(byteArrays, { type });
384
+ }
@@ -0,0 +1,76 @@
1
+ export interface CreateImageBitmapSupport {
2
+ basic: boolean; // Supports createImageBitmap(image)
3
+ options: boolean; // Supports createImageBitmap(image, options)
4
+ full: boolean; // Supports createImageBitmap(image, sx, sy, sw, sh, options)
5
+ }
6
+
7
+ export async function validateCreateImageBitmap(): Promise<CreateImageBitmapSupport> {
8
+ // Test if createImageBitmap is supported using a simple 1x1 PNG image
9
+ // prettier-ignore
10
+ const pngBinaryData = new Uint8Array([
11
+ 0x89, 0x50, 0x4e, 0x47,
12
+ 0x0d, 0x0a, 0x1a, 0x0a, // PNG signature
13
+ 0x00, 0x00, 0x00, 0x0d, // IHDR chunk length
14
+ 0x49, 0x48, 0x44, 0x52, // "IHDR" chunk type
15
+ 0x00, 0x00, 0x00, 0x01, // Width: 1
16
+ 0x00, 0x00, 0x00, 0x01, // Height: 1
17
+ 0x01, // Bit depth: 1
18
+ 0x03, // Color type: Indexed
19
+ 0x00, // Compression method: Deflate
20
+ 0x00, // Filter method: None
21
+ 0x00, // Interlace method: None
22
+ 0x25, 0xdb, 0x56, 0xca, // CRC for IHDR
23
+ 0x00, 0x00, 0x00, 0x03, // PLTE chunk length
24
+ 0x50, 0x4c, 0x54, 0x45, // "PLTE" chunk type
25
+ 0x00, 0x00, 0x00, // Palette entry: Black
26
+ 0xa7, 0x7a, 0x3d, 0xda, // CRC for PLTE
27
+ 0x00, 0x00, 0x00, 0x01, // tRNS chunk length
28
+ 0x74, 0x52, 0x4e, 0x53, // "tRNS" chunk type
29
+ 0x00, // Transparency for black: Fully transparent
30
+ 0x40, 0xe6, 0xd8, 0x66, // CRC for tRNS
31
+ 0x00, 0x00, 0x00, 0x0a, // IDAT chunk length
32
+ 0x49, 0x44, 0x41, 0x54, // "IDAT" chunk type
33
+ 0x08, 0xd7, // Deflate header
34
+ 0x63, 0x60, 0x00, 0x00,
35
+ 0x00, 0x02, 0x00, 0x01, // Zlib-compressed data
36
+ 0xe2, 0x21, 0xbc, 0x33, // CRC for IDAT
37
+ 0x00, 0x00, 0x00, 0x00, // IEND chunk length
38
+ 0x49, 0x45, 0x4e, 0x44, // "IEND" chunk type
39
+ 0xae, 0x42, 0x60, 0x82, // CRC for IEND
40
+ ]);
41
+
42
+ const support: CreateImageBitmapSupport = {
43
+ basic: false,
44
+ options: false,
45
+ full: false,
46
+ };
47
+
48
+ // Test basic createImageBitmap support
49
+ const blob = new Blob([pngBinaryData], { type: 'image/png' });
50
+ const bitmap = await createImageBitmap(blob);
51
+ bitmap.close?.();
52
+ support.basic = true;
53
+
54
+ // Test createImageBitmap with options support
55
+ try {
56
+ const options = { premultiplyAlpha: 'none' as const };
57
+ const bitmapWithOptions = await createImageBitmap(blob, options);
58
+ bitmapWithOptions.close?.();
59
+ support.options = true;
60
+ } catch (e) {
61
+ /* ignore */
62
+ }
63
+
64
+ // Test createImageBitmap with full options support
65
+ try {
66
+ const bitmapWithFullOptions = await createImageBitmap(blob, 0, 0, 1, 1, {
67
+ premultiplyAlpha: 'none',
68
+ });
69
+ bitmapWithFullOptions.close?.();
70
+ support.full = true;
71
+ } catch (e) {
72
+ /* ignore */
73
+ }
74
+
75
+ return support;
76
+ }
@@ -34,12 +34,14 @@ export const startLoop = (stage: Stage) => {
34
34
  setTimeout(runLoop, 16.666666666666668);
35
35
 
36
36
  if (!isIdle) {
37
- if (stage.txMemManager.checkCleanup()) {
38
- stage.txMemManager.cleanup();
39
- }
40
37
  stage.eventBus.emit('idle');
41
38
  isIdle = true;
42
39
  }
40
+
41
+ if (stage.txMemManager.checkCleanup() === true) {
42
+ stage.txMemManager.cleanup(false);
43
+ }
44
+
43
45
  stage.flushFrameEvents();
44
46
  return;
45
47
  }
@@ -120,6 +120,7 @@ export class WebGlCoreCtxTexture extends CoreContextTexture {
120
120
  if (this.state === 'freed') {
121
121
  return;
122
122
  }
123
+
123
124
  this.state = 'failed';
124
125
  this.textureSource.setState('failed', err);
125
126
  this.textureSource.freeTextureData();
@@ -133,17 +134,16 @@ export class WebGlCoreCtxTexture extends CoreContextTexture {
133
134
  async onLoadRequest(): Promise<Dimensions> {
134
135
  const { glw } = this;
135
136
  const textureData = this.textureSource.textureData;
136
- assertTruthy(textureData, 'Texture data is null');
137
+ if (textureData === null || this._nativeCtxTexture === null) {
138
+ throw new Error(
139
+ 'Texture data or native texture is null ' + this.textureSource.type,
140
+ );
141
+ }
137
142
 
138
143
  // Set to a 1x1 transparent texture
139
144
  glw.texImage2D(0, glw.RGBA, 1, 1, 0, glw.RGBA, glw.UNSIGNED_BYTE, null);
140
145
  this.setTextureMemUse(TRANSPARENT_TEXTURE_DATA.byteLength);
141
146
 
142
- // If the texture has been freed while loading, return early.
143
- if (!this._nativeCtxTexture) {
144
- assertTruthy(this.state === 'freed');
145
- return { width: 0, height: 0 };
146
- }
147
147
  let width = 0;
148
148
  let height = 0;
149
149
 
@@ -256,14 +256,12 @@ export class WebGlCoreCtxTexture extends CoreContextTexture {
256
256
  this.textureSource.setState('freed');
257
257
  this._w = 0;
258
258
  this._h = 0;
259
- if (!this._nativeCtxTexture) {
260
- return;
261
- }
262
- const { glw } = this;
263
259
 
264
- glw.deleteTexture(this._nativeCtxTexture);
265
- this.setTextureMemUse(0);
266
- this._nativeCtxTexture = null;
260
+ if (this._nativeCtxTexture !== null) {
261
+ this.glw.deleteTexture(this._nativeCtxTexture);
262
+ this.setTextureMemUse(0);
263
+ this._nativeCtxTexture = null;
264
+ }
267
265
 
268
266
  // if the texture still has source data, free it
269
267
  this.textureSource.freeTextureData();
@@ -23,7 +23,11 @@ import {
23
23
  isCompressedTextureContainer,
24
24
  loadCompressedTexture,
25
25
  } from '../lib/textureCompression.js';
26
- import { convertUrlToAbsolute, isBase64Image } from '../lib/utils.js';
26
+ import {
27
+ convertUrlToAbsolute,
28
+ dataURIToBlob,
29
+ isBase64Image,
30
+ } from '../lib/utils.js';
27
31
  import { isSvgImage, loadSvg } from '../lib/textureSvg.js';
28
32
  import { fetchJson } from '../text-rendering/font-face-types/utils.js';
29
33
 
@@ -40,7 +44,7 @@ export interface ImageTextureProps {
40
44
  *
41
45
  * @default ''
42
46
  */
43
- src?: string | ImageData | (() => ImageData | null);
47
+ src?: string | Blob | ImageData | (() => ImageData | null);
44
48
  /**
45
49
  * Whether to premultiply the alpha channel into the color channels of the
46
50
  * image.
@@ -133,10 +137,10 @@ export class ImageTexture extends Texture {
133
137
  return mimeType.indexOf('image/png') !== -1;
134
138
  }
135
139
 
136
- async loadImageFallback(src: string, hasAlpha: boolean) {
140
+ async loadImageFallback(src: string | Blob, hasAlpha: boolean) {
137
141
  const img = new Image();
138
142
 
139
- if (isBase64Image(src) === false) {
143
+ if (typeof src === 'string' && isBase64Image(src) === false) {
140
144
  img.crossOrigin = 'anonymous';
141
145
  }
142
146
 
@@ -151,7 +155,11 @@ export class ImageTexture extends Texture {
151
155
  resolve({ data: img, premultiplyAlpha: hasAlpha });
152
156
  };
153
157
 
154
- img.src = src;
158
+ if (src instanceof Blob) {
159
+ img.src = URL.createObjectURL(src);
160
+ } else {
161
+ img.src = src;
162
+ }
155
163
  },
156
164
  );
157
165
  }
@@ -170,29 +178,15 @@ export class ImageTexture extends Texture {
170
178
  const hasAlphaChannel = premultiplyAlpha ?? blob.type.includes('image/png');
171
179
  const imageBitmapSupported = this.txManager.imageBitmapSupported;
172
180
 
173
- if (
174
- imageBitmapSupported.full === true &&
175
- sx !== null &&
176
- sy !== null &&
177
- sw !== null &&
178
- sh !== null
179
- ) {
181
+ if (imageBitmapSupported.full === true && sw !== null && sh !== null) {
180
182
  // createImageBitmap with crop
181
- const bitmap = await createImageBitmap(blob, sx, sy, sw, sh, {
182
- premultiplyAlpha: hasAlphaChannel ? 'premultiply' : 'none',
183
- colorSpaceConversion: 'none',
184
- imageOrientation: 'none',
185
- });
186
- return { data: bitmap, premultiplyAlpha: hasAlphaChannel };
187
- } else if (imageBitmapSupported.options === true) {
188
- // createImageBitmap without crop but with options
189
- const bitmap = await createImageBitmap(blob, {
183
+ const bitmap = await createImageBitmap(blob, sx || 0, sy || 0, sw, sh, {
190
184
  premultiplyAlpha: hasAlphaChannel ? 'premultiply' : 'none',
191
185
  colorSpaceConversion: 'none',
192
186
  imageOrientation: 'none',
193
187
  });
194
188
  return { data: bitmap, premultiplyAlpha: hasAlphaChannel };
195
- } else {
189
+ } else if (imageBitmapSupported.basic === true) {
196
190
  // basic createImageBitmap without options or crop
197
191
  // this is supported for Chrome v50 to v52/54 that doesn't support options
198
192
  return {
@@ -200,6 +194,14 @@ export class ImageTexture extends Texture {
200
194
  premultiplyAlpha: hasAlphaChannel,
201
195
  };
202
196
  }
197
+
198
+ // default createImageBitmap without crop but with options
199
+ const bitmap = await createImageBitmap(blob, {
200
+ premultiplyAlpha: hasAlphaChannel ? 'premultiply' : 'none',
201
+ colorSpaceConversion: 'none',
202
+ imageOrientation: 'none',
203
+ });
204
+ return { data: bitmap, premultiplyAlpha: hasAlphaChannel };
203
205
  }
204
206
 
205
207
  async loadImage(src: string) {
@@ -221,9 +223,16 @@ export class ImageTexture extends Texture {
221
223
  );
222
224
  }
223
225
 
224
- const blob = await fetchJson(src, 'blob').then(
225
- (response) => response as Blob,
226
- );
226
+ let blob;
227
+
228
+ if (isBase64Image(src) === true) {
229
+ blob = dataURIToBlob(src);
230
+ } else {
231
+ blob = await fetchJson(src, 'blob').then(
232
+ (response) => response as Blob,
233
+ );
234
+ }
235
+
227
236
  return this.createImageBitmap(blob, premultiplyAlpha, sx, sy, sw, sh);
228
237
  }
229
238
 
@@ -280,6 +289,14 @@ export class ImageTexture extends Texture {
280
289
  }
281
290
 
282
291
  if (typeof src !== 'string') {
292
+ if (src instanceof Blob) {
293
+ if (this.txManager.hasCreateImageBitmap === true) {
294
+ const { sx, sy, sw, sh } = this.props;
295
+ return this.createImageBitmap(src, premultiplyAlpha, sx, sy, sw, sh);
296
+ } else {
297
+ return this.loadImageFallback(src, premultiplyAlpha ?? true);
298
+ }
299
+ }
283
300
  if (src instanceof ImageData) {
284
301
  return {
285
302
  data: src,
@@ -62,13 +62,25 @@ const stylePropertyMap: {
62
62
 
63
63
  return { prop: 'height', value: `${h}px` };
64
64
  },
65
+ fontSize: (fs) => {
66
+ if (fs === 0) {
67
+ return null;
68
+ }
69
+
70
+ return { prop: 'font-size', value: `${fs}px` };
71
+ },
72
+ lineHeight: (lh) => {
73
+ if (lh === 0) {
74
+ return null;
75
+ }
76
+
77
+ return { prop: 'line-height', value: `${lh}px` };
78
+ },
65
79
  zIndex: () => 'z-index',
66
80
  fontFamily: () => 'font-family',
67
- fontSize: () => 'font-size',
68
81
  fontStyle: () => 'font-style',
69
82
  fontWeight: () => 'font-weight',
70
83
  fontStretch: () => 'font-stretch',
71
- lineHeight: () => 'line-height',
72
84
  letterSpacing: () => 'letter-spacing',
73
85
  textAlign: () => 'text-align',
74
86
  overflowSuffix: () => 'overflow-suffix',
@@ -396,6 +408,11 @@ export class Inspector {
396
408
  // return;
397
409
  // }
398
410
 
411
+ if (property === 'rtt' && value) {
412
+ div.setAttribute('data-rtt', String(value));
413
+ return;
414
+ }
415
+
399
416
  // CSS mappable attribute
400
417
  if (stylePropertyMap[property]) {
401
418
  const mappedStyleResponse = stylePropertyMap[property]?.(value);
@@ -288,6 +288,31 @@ export interface RendererMainSettings {
288
288
  * element will be created and appended to the target element.
289
289
  */
290
290
  canvas?: HTMLCanvasElement;
291
+
292
+ /**
293
+ * createImageBitmap support for the runtime
294
+ *
295
+ * @remarks
296
+ * This is used to determine if and which version of the createImageBitmap API
297
+ * is supported by the runtime. This is used to determine if the renderer can
298
+ * use createImageBitmap to load images.
299
+ *
300
+ * Options supported
301
+ * - Auto - Automatically determine the supported version
302
+ * - Basic - Supports createImageBitmap(image)
303
+ * - Options - Supports createImageBitmap(image, options)
304
+ * - Full - Supports createImageBitmap(image, sx, sy, sw, sh, options)
305
+ *
306
+ * Note with auto detection, the renderer will attempt to use the most advanced
307
+ * version of the API available. If the API is not available, the renderer will
308
+ * fall back to the next available version.
309
+ *
310
+ * This will affect startup performance as the renderer will need to determine
311
+ * the supported version of the API.
312
+ *
313
+ * @defaultValue `full`
314
+ */
315
+ createImageBitmapSupport?: 'auto' | 'basic' | 'options' | 'full';
291
316
  }
292
317
 
293
318
  /**
@@ -360,10 +385,12 @@ export class RendererMain extends EventEmitter {
360
385
  const resolvedTxSettings: TextureMemoryManagerSettings = {
361
386
  criticalThreshold: settings.textureMemory?.criticalThreshold || 124e6,
362
387
  targetThresholdLevel: settings.textureMemory?.targetThresholdLevel || 0.5,
363
- cleanupInterval: settings.textureMemory?.cleanupInterval || 30000,
388
+ cleanupInterval: settings.textureMemory?.cleanupInterval || 5000,
364
389
  debugLogging: settings.textureMemory?.debugLogging || false,
365
390
  baselineMemoryAllocation:
366
391
  settings.textureMemory?.baselineMemoryAllocation || 26e6,
392
+ doNotExceedCriticalThreshold:
393
+ settings.textureMemory?.doNotExceedCriticalThreshold || false,
367
394
  };
368
395
 
369
396
  const resolvedSettings: Required<RendererMainSettings> = {
@@ -387,6 +414,7 @@ export class RendererMain extends EventEmitter {
387
414
  strictBounds: settings.strictBounds ?? true,
388
415
  textureProcessingTimeLimit: settings.textureProcessingTimeLimit || 10,
389
416
  canvas: settings.canvas || document.createElement('canvas'),
417
+ createImageBitmapSupport: settings.createImageBitmapSupport || 'full',
390
418
  };
391
419
  this.settings = resolvedSettings;
392
420
 
@@ -430,6 +458,7 @@ export class RendererMain extends EventEmitter {
430
458
  inspector: this.settings.inspector !== null,
431
459
  strictBounds: this.settings.strictBounds,
432
460
  textureProcessingTimeLimit: this.settings.textureProcessingTimeLimit,
461
+ createImageBitmapSupport: this.settings.createImageBitmapSupport,
433
462
  });
434
463
 
435
464
  // Extract the root node
@@ -692,6 +721,8 @@ export class RendererMain extends EventEmitter {
692
721
  /**
693
722
  * Cleanup textures that are not being used
694
723
  *
724
+ * @param aggressive - If true, will cleanup all textures, regardless of render status
725
+ *
695
726
  * @remarks
696
727
  * This can be used to free up GFX memory used by textures that are no longer
697
728
  * being displayed.
@@ -705,8 +736,8 @@ export class RendererMain extends EventEmitter {
705
736
  * **NOTE3**: This will not cleanup textures that are marked as `preventCleanup`.
706
737
  * **NOTE4**: This has nothing to do with the garbage collection of JavaScript.
707
738
  */
708
- cleanup() {
709
- this.stage.cleanup();
739
+ cleanup(aggressive: boolean = false) {
740
+ this.stage.cleanup(aggressive);
710
741
  }
711
742
 
712
743
  /**
@@ -1 +0,0 @@
1
- export {};
@@ -1,138 +0,0 @@
1
- export {};
2
- /*interface InstanceMap {
3
- renderer: CoreRenderer;
4
- effect: CoreEffect;
5
- program: new () => void;
6
- }
7
-
8
- type WebGlInstanceMap = InstanceMap & {
9
- renderer: WebGlCoreRenderer;
10
- effect: WebGlEffect;
11
- };
12
-
13
- interface AdvEffectProp {
14
- default: any;
15
- isColor?: boolean;
16
- validator?: (value: any) => any;
17
- }
18
-
19
- interface EffectProps {
20
- [key: string]: any | AdvEffectProp;
21
- }
22
-
23
- type EffectDescriptor<Effect, Props> = Effect & {
24
- props?: Props;
25
- };
26
-
27
- type InferEffectProps<T> = {
28
- [K in keyof T]: T[K] extends AdvEffectProp ? T[K]['default'] : T[K];
29
- };
30
-
31
- interface CoreEffect {
32
- props?: EffectProps;
33
- update?: (ctx: unknown) => void;
34
- }
35
-
36
- type WebGlEffect = CoreEffect & {
37
- fragment: string;
38
- update?: (glw: WebGLRenderingContext) => void;
39
- };
40
-
41
- type StageOptions<Renderer extends InstanceMap> = {
42
- renderEngine?: new () => Renderer['renderer'];
43
- };
44
-
45
- class Stage<RendererMap extends InstanceMap> {
46
- fxManager: CoreFxManager<RendererMap>;
47
- constructor(options: StageOptions<RendererMap>) {
48
- this.fxManager = new CoreFxManager();
49
- const renderer = new options.renderEngine();
50
- }
51
-
52
- createShader<Effect extends RendererMap['effect'], Props>(
53
- effect: EffectDescriptor<Effect, Props>,
54
- props?: InferEffectProps<Props>
55
- ): EffectNode<Effect, Props> {
56
- return this.fxManager.createShader(effect, props);
57
- }
58
- }
59
-
60
- class CoreRenderer {
61
- mode = 'core';
62
- }
63
-
64
- class WebGlCoreRenderer extends CoreRenderer {
65
- override mode = 'webgl';
66
- }
67
-
68
- class CanvasCoreRenderer extends CoreRenderer {
69
- override mode = 'canvas';
70
- }
71
-
72
- class CoreFxManager<RendererMap extends InstanceMap> {
73
- fxCache: Map<string, RendererMap['effect']> = new Map();
74
-
75
- resolveProps(defaultProps?: EffectProps, props?: EffectProps) {
76
- if(defaultProps !== undefined) {
77
- props = props ?? {}
78
- const keys = Object.keys(defaultProps);
79
- const l = keys.length;
80
- for(let i = 0; i < l; i++) {
81
- if(props[keys[i]] === undefined) {
82
- props[keys[i]] = defaultProps[keys[i]].default || defaultProps[keys[i]]
83
- }
84
- }
85
- }
86
- }
87
-
88
- createShader<Effect extends RendererMap['effect'], Props>(
89
- effect: EffectDescriptor<Effect, Props>,
90
- props?: InferEffectProps<Props>
91
- ): EffectNode<Effect, Props> {
92
-
93
- // const f = JSON.stringify(effect);
94
- // if (this.fxCache.has(f)) {
95
- // console.log('already has this effect');
96
- // } else {
97
- // console.log('create new effect program');
98
- // this.fxCache.set(f, effect);
99
- // }
100
-
101
- return new EffectNode<Effect, Props>(effect, WebGlCoreRenderer, props);
102
- }
103
- }
104
-
105
- class EffectNode<Effect extends CoreEffect, Props extends EffectProps> {
106
- #data: Record<string, any> | undefined = undefined;
107
- constructor(
108
- readonly type: Effect,
109
- readonly program: new () => void,
110
- props?: InferEffectProps<Props>
111
- ) {
112
- this.#data = props;
113
- }
114
- }
115
-
116
- const stage = new Stage<WebGlInstanceMap>({
117
- renderEngine: CanvasCoreRenderer,
118
- });
119
-
120
- stage.createShader(
121
- {
122
- props: {
123
- radius: 10,
124
- },
125
- fragment: '',
126
- },
127
- {
128
- radius: 30,
129
- }
130
- );
131
-
132
- stage.createShader({
133
- props: {
134
- radius: 10,
135
- },
136
- fragment: '',
137
- });*/
138
- //# sourceMappingURL=CoreStuff.js.map