@lightningjs/renderer 2.16.0 → 2.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/dist/src/core/CoreNode.js +7 -5
  2. package/dist/src/core/CoreNode.js.map +1 -1
  3. package/dist/src/core/CoreTextureManager.d.ts +14 -8
  4. package/dist/src/core/CoreTextureManager.js +33 -59
  5. package/dist/src/core/CoreTextureManager.js.map +1 -1
  6. package/dist/src/core/Stage.d.ts +3 -3
  7. package/dist/src/core/Stage.js +9 -14
  8. package/dist/src/core/Stage.js.map +1 -1
  9. package/dist/src/core/TextureMemoryManager.d.ts +21 -17
  10. package/dist/src/core/TextureMemoryManager.js +99 -124
  11. package/dist/src/core/TextureMemoryManager.js.map +1 -1
  12. package/dist/src/core/lib/WebGlContextWrapper.d.ts +10 -0
  13. package/dist/src/core/lib/WebGlContextWrapper.js +32 -0
  14. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
  15. package/dist/src/core/lib/textureCompression.js +13 -6
  16. package/dist/src/core/lib/textureCompression.js.map +1 -1
  17. package/dist/src/core/platform.js +4 -1
  18. package/dist/src/core/platform.js.map +1 -1
  19. package/dist/src/core/renderers/CoreContextTexture.d.ts +1 -0
  20. package/dist/src/core/renderers/CoreContextTexture.js.map +1 -1
  21. package/dist/src/core/renderers/canvas/CanvasCoreTexture.d.ts +1 -0
  22. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js +4 -3
  23. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js.map +1 -1
  24. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +9 -0
  25. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +59 -29
  26. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  27. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +4 -4
  28. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
  29. package/dist/src/core/textures/ColorTexture.d.ts +2 -2
  30. package/dist/src/core/textures/ColorTexture.js +1 -2
  31. package/dist/src/core/textures/ColorTexture.js.map +1 -1
  32. package/dist/src/core/textures/ImageTexture.d.ts +7 -1
  33. package/dist/src/core/textures/ImageTexture.js +55 -39
  34. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  35. package/dist/src/core/textures/NoiseTexture.js +1 -1
  36. package/dist/src/core/textures/NoiseTexture.js.map +1 -1
  37. package/dist/src/core/textures/RenderTexture.js +1 -1
  38. package/dist/src/core/textures/RenderTexture.js.map +1 -1
  39. package/dist/src/core/textures/SubTexture.d.ts +1 -2
  40. package/dist/src/core/textures/SubTexture.js +11 -29
  41. package/dist/src/core/textures/SubTexture.js.map +1 -1
  42. package/dist/src/core/textures/Texture.d.ts +51 -7
  43. package/dist/src/core/textures/Texture.js +127 -15
  44. package/dist/src/core/textures/Texture.js.map +1 -1
  45. package/dist/src/main-api/Inspector.d.ts +3 -0
  46. package/dist/src/main-api/Inspector.js +156 -0
  47. package/dist/src/main-api/Inspector.js.map +1 -1
  48. package/dist/src/main-api/Renderer.d.ts +1 -3
  49. package/dist/src/main-api/Renderer.js +2 -4
  50. package/dist/src/main-api/Renderer.js.map +1 -1
  51. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  52. package/package.json +1 -1
  53. package/src/core/CoreNode.ts +8 -4
  54. package/src/core/CoreTextureManager.ts +59 -65
  55. package/src/core/Stage.ts +10 -16
  56. package/src/core/TextureMemoryManager.ts +118 -148
  57. package/src/core/lib/WebGlContextWrapper.ts +38 -0
  58. package/src/core/lib/textureCompression.ts +18 -7
  59. package/src/core/platform.ts +5 -1
  60. package/src/core/renderers/CoreContextTexture.ts +1 -0
  61. package/src/core/renderers/canvas/CanvasCoreTexture.ts +5 -3
  62. package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +78 -40
  63. package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +10 -4
  64. package/src/core/textures/ColorTexture.ts +4 -7
  65. package/src/core/textures/ImageTexture.ts +66 -51
  66. package/src/core/textures/NoiseTexture.ts +1 -1
  67. package/src/core/textures/RenderTexture.ts +1 -1
  68. package/src/core/textures/SubTexture.ts +14 -31
  69. package/src/core/textures/Texture.ts +150 -21
  70. package/src/main-api/Inspector.ts +203 -0
  71. package/src/main-api/Renderer.ts +2 -4
  72. package/dist/exports/canvas-shaders.d.ts +0 -10
  73. package/dist/exports/canvas-shaders.js +0 -27
  74. package/dist/exports/canvas-shaders.js.map +0 -1
  75. package/dist/exports/webgl-shaders.d.ts +0 -11
  76. package/dist/exports/webgl-shaders.js +0 -28
  77. package/dist/exports/webgl-shaders.js.map +0 -1
  78. package/dist/src/core/platforms/Platform.d.ts +0 -37
  79. package/dist/src/core/platforms/Platform.js +0 -22
  80. package/dist/src/core/platforms/Platform.js.map +0 -1
  81. package/dist/src/core/platforms/web/WebPlatform.d.ts +0 -9
  82. package/dist/src/core/platforms/web/WebPlatform.js +0 -58
  83. package/dist/src/core/platforms/web/WebPlatform.js.map +0 -1
  84. package/dist/src/core/renderers/CoreShaderNode.d.ts +0 -59
  85. package/dist/src/core/renderers/CoreShaderNode.js +0 -113
  86. package/dist/src/core/renderers/CoreShaderNode.js.map +0 -1
  87. package/dist/src/core/renderers/CoreShaderProgram.d.ts +0 -4
  88. package/dist/src/core/renderers/CoreShaderProgram.js +0 -20
  89. package/dist/src/core/renderers/CoreShaderProgram.js.map +0 -1
  90. package/dist/src/core/renderers/canvas/CanvasRenderer.d.ts +0 -37
  91. package/dist/src/core/renderers/canvas/CanvasRenderer.js +0 -215
  92. package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +0 -1
  93. package/dist/src/core/renderers/canvas/CanvasShaderNode.d.ts +0 -21
  94. package/dist/src/core/renderers/canvas/CanvasShaderNode.js +0 -57
  95. package/dist/src/core/renderers/canvas/CanvasShaderNode.js.map +0 -1
  96. package/dist/src/core/renderers/canvas/CanvasTexture.d.ts +0 -16
  97. package/dist/src/core/renderers/canvas/CanvasTexture.js +0 -124
  98. package/dist/src/core/renderers/canvas/CanvasTexture.js.map +0 -1
  99. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.d.ts +0 -12
  100. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.js +0 -55
  101. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.js.map +0 -1
  102. package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.d.ts +0 -9
  103. package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.js +0 -38
  104. package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.js.map +0 -1
  105. package/dist/src/core/renderers/webgl/WebGlCtxTexture.d.ts +0 -57
  106. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js +0 -224
  107. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js.map +0 -1
  108. package/dist/src/core/renderers/webgl/WebGlRenderOp.d.ts +0 -44
  109. package/dist/src/core/renderers/webgl/WebGlRenderOp.js +0 -125
  110. package/dist/src/core/renderers/webgl/WebGlRenderOp.js.map +0 -1
  111. package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +0 -136
  112. package/dist/src/core/renderers/webgl/WebGlRenderer.js +0 -573
  113. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +0 -1
  114. package/dist/src/core/renderers/webgl/WebGlShaderNode.d.ts +0 -222
  115. package/dist/src/core/renderers/webgl/WebGlShaderNode.js +0 -331
  116. package/dist/src/core/renderers/webgl/WebGlShaderNode.js.map +0 -1
  117. package/dist/src/core/renderers/webgl/WebGlShaderProgram.d.ts +0 -35
  118. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +0 -201
  119. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +0 -1
  120. package/dist/src/core/shaders/canvas/Border.d.ts +0 -9
  121. package/dist/src/core/shaders/canvas/Border.js +0 -57
  122. package/dist/src/core/shaders/canvas/Border.js.map +0 -1
  123. package/dist/src/core/shaders/canvas/HolePunch.d.ts +0 -7
  124. package/dist/src/core/shaders/canvas/HolePunch.js +0 -38
  125. package/dist/src/core/shaders/canvas/HolePunch.js.map +0 -1
  126. package/dist/src/core/shaders/canvas/LinearGradient.d.ts +0 -10
  127. package/dist/src/core/shaders/canvas/LinearGradient.js +0 -48
  128. package/dist/src/core/shaders/canvas/LinearGradient.js.map +0 -1
  129. package/dist/src/core/shaders/canvas/RadialGradient.d.ts +0 -11
  130. package/dist/src/core/shaders/canvas/RadialGradient.js +0 -70
  131. package/dist/src/core/shaders/canvas/RadialGradient.js.map +0 -1
  132. package/dist/src/core/shaders/canvas/Rounded.d.ts +0 -7
  133. package/dist/src/core/shaders/canvas/Rounded.js +0 -33
  134. package/dist/src/core/shaders/canvas/Rounded.js.map +0 -1
  135. package/dist/src/core/shaders/canvas/RoundedWithBorder.d.ts +0 -7
  136. package/dist/src/core/shaders/canvas/RoundedWithBorder.js +0 -43
  137. package/dist/src/core/shaders/canvas/RoundedWithBorder.js.map +0 -1
  138. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.d.ts +0 -8
  139. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.js +0 -41
  140. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.js.map +0 -1
  141. package/dist/src/core/shaders/canvas/RoundedWithShadow.d.ts +0 -7
  142. package/dist/src/core/shaders/canvas/RoundedWithShadow.js +0 -40
  143. package/dist/src/core/shaders/canvas/RoundedWithShadow.js.map +0 -1
  144. package/dist/src/core/shaders/canvas/Shadow.d.ts +0 -8
  145. package/dist/src/core/shaders/canvas/Shadow.js +0 -31
  146. package/dist/src/core/shaders/canvas/Shadow.js.map +0 -1
  147. package/dist/src/core/shaders/canvas/utils/render.d.ts +0 -5
  148. package/dist/src/core/shaders/canvas/utils/render.js +0 -84
  149. package/dist/src/core/shaders/canvas/utils/render.js.map +0 -1
  150. package/dist/src/core/shaders/templates/BorderTemplate.d.ts +0 -37
  151. package/dist/src/core/shaders/templates/BorderTemplate.js +0 -73
  152. package/dist/src/core/shaders/templates/BorderTemplate.js.map +0 -1
  153. package/dist/src/core/shaders/templates/HolePunchTemplate.d.ts +0 -46
  154. package/dist/src/core/shaders/templates/HolePunchTemplate.js +0 -35
  155. package/dist/src/core/shaders/templates/HolePunchTemplate.js.map +0 -1
  156. package/dist/src/core/shaders/templates/LinearGradientTemplate.d.ts +0 -23
  157. package/dist/src/core/shaders/templates/LinearGradientTemplate.js +0 -47
  158. package/dist/src/core/shaders/templates/LinearGradientTemplate.js.map +0 -1
  159. package/dist/src/core/shaders/templates/RadialGradientTemplate.d.ts +0 -31
  160. package/dist/src/core/shaders/templates/RadialGradientTemplate.js +0 -49
  161. package/dist/src/core/shaders/templates/RadialGradientTemplate.js.map +0 -1
  162. package/dist/src/core/shaders/templates/RoundedTemplate.d.ts +0 -29
  163. package/dist/src/core/shaders/templates/RoundedTemplate.js +0 -67
  164. package/dist/src/core/shaders/templates/RoundedTemplate.js.map +0 -1
  165. package/dist/src/core/shaders/templates/RoundedWithBorderAndShadowTemplate.d.ts +0 -7
  166. package/dist/src/core/shaders/templates/RoundedWithBorderAndShadowTemplate.js +0 -24
  167. package/dist/src/core/shaders/templates/RoundedWithBorderAndShadowTemplate.js.map +0 -1
  168. package/dist/src/core/shaders/templates/RoundedWithBorderTemplate.d.ts +0 -6
  169. package/dist/src/core/shaders/templates/RoundedWithBorderTemplate.js +0 -23
  170. package/dist/src/core/shaders/templates/RoundedWithBorderTemplate.js.map +0 -1
  171. package/dist/src/core/shaders/templates/RoundedWithShadowTemplate.d.ts +0 -6
  172. package/dist/src/core/shaders/templates/RoundedWithShadowTemplate.js +0 -23
  173. package/dist/src/core/shaders/templates/RoundedWithShadowTemplate.js.map +0 -1
  174. package/dist/src/core/shaders/templates/ShadowTemplate.d.ts +0 -34
  175. package/dist/src/core/shaders/templates/ShadowTemplate.js +0 -66
  176. package/dist/src/core/shaders/templates/ShadowTemplate.js.map +0 -1
  177. package/dist/src/core/shaders/templates/shaderUtils.d.ts +0 -5
  178. package/dist/src/core/shaders/templates/shaderUtils.js +0 -41
  179. package/dist/src/core/shaders/templates/shaderUtils.js.map +0 -1
  180. package/dist/src/core/shaders/utils.d.ts +0 -5
  181. package/dist/src/core/shaders/utils.js +0 -41
  182. package/dist/src/core/shaders/utils.js.map +0 -1
  183. package/dist/src/core/shaders/webgl/Border.d.ts +0 -3
  184. package/dist/src/core/shaders/webgl/Border.js +0 -110
  185. package/dist/src/core/shaders/webgl/Border.js.map +0 -1
  186. package/dist/src/core/shaders/webgl/Default.d.ts +0 -2
  187. package/dist/src/core/shaders/webgl/Default.js +0 -86
  188. package/dist/src/core/shaders/webgl/Default.js.map +0 -1
  189. package/dist/src/core/shaders/webgl/DefaultBatched.d.ts +0 -2
  190. package/dist/src/core/shaders/webgl/DefaultBatched.js +0 -104
  191. package/dist/src/core/shaders/webgl/DefaultBatched.js.map +0 -1
  192. package/dist/src/core/shaders/webgl/HolePunch.d.ts +0 -3
  193. package/dist/src/core/shaders/webgl/HolePunch.js +0 -65
  194. package/dist/src/core/shaders/webgl/HolePunch.js.map +0 -1
  195. package/dist/src/core/shaders/webgl/LinearGradient.d.ts +0 -3
  196. package/dist/src/core/shaders/webgl/LinearGradient.js +0 -76
  197. package/dist/src/core/shaders/webgl/LinearGradient.js.map +0 -1
  198. package/dist/src/core/shaders/webgl/RadialGradient.d.ts +0 -3
  199. package/dist/src/core/shaders/webgl/RadialGradient.js +0 -74
  200. package/dist/src/core/shaders/webgl/RadialGradient.js.map +0 -1
  201. package/dist/src/core/shaders/webgl/Rounded.d.ts +0 -7
  202. package/dist/src/core/shaders/webgl/Rounded.js +0 -86
  203. package/dist/src/core/shaders/webgl/Rounded.js.map +0 -1
  204. package/dist/src/core/shaders/webgl/RoundedWithBorder.d.ts +0 -3
  205. package/dist/src/core/shaders/webgl/RoundedWithBorder.js +0 -140
  206. package/dist/src/core/shaders/webgl/RoundedWithBorder.js.map +0 -1
  207. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.d.ts +0 -3
  208. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js +0 -162
  209. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js.map +0 -1
  210. package/dist/src/core/shaders/webgl/RoundedWithShadow.d.ts +0 -3
  211. package/dist/src/core/shaders/webgl/RoundedWithShadow.js +0 -84
  212. package/dist/src/core/shaders/webgl/RoundedWithShadow.js.map +0 -1
  213. package/dist/src/core/shaders/webgl/SdfShader.d.ts +0 -32
  214. package/dist/src/core/shaders/webgl/SdfShader.js +0 -116
  215. package/dist/src/core/shaders/webgl/SdfShader.js.map +0 -1
  216. package/dist/src/core/shaders/webgl/Shadow.d.ts +0 -3
  217. package/dist/src/core/shaders/webgl/Shadow.js +0 -110
  218. package/dist/src/core/shaders/webgl/Shadow.js.map +0 -1
  219. package/dist/src/core/shaders/webgl/Spinner.d.ts +0 -1
  220. package/dist/src/core/shaders/webgl/Spinner.js +0 -2
  221. package/dist/src/core/shaders/webgl/Spinner.js.map +0 -1
  222. package/dist/src/core/text-rendering/CanvasFontHandler.d.ts +0 -25
  223. package/dist/src/core/text-rendering/CanvasFontHandler.js +0 -117
  224. package/dist/src/core/text-rendering/CanvasFontHandler.js.map +0 -1
  225. package/dist/src/core/text-rendering/CanvasTextRenderer.d.ts +0 -6
  226. package/dist/src/core/text-rendering/CanvasTextRenderer.js +0 -139
  227. package/dist/src/core/text-rendering/CanvasTextRenderer.js.map +0 -1
  228. package/dist/src/core/text-rendering/SdfFontHandler.d.ts +0 -137
  229. package/dist/src/core/text-rendering/SdfFontHandler.js +0 -336
  230. package/dist/src/core/text-rendering/SdfFontHandler.js.map +0 -1
  231. package/dist/src/core/text-rendering/SdfTextRenderer.d.ts +0 -21
  232. package/dist/src/core/text-rendering/SdfTextRenderer.js +0 -324
  233. package/dist/src/core/text-rendering/SdfTextRenderer.js.map +0 -1
  234. package/dist/src/core/text-rendering/TextRenderer.d.ts +0 -425
  235. package/dist/src/core/text-rendering/TextRenderer.js +0 -70
  236. package/dist/src/core/text-rendering/TextRenderer.js.map +0 -1
  237. package/dist/src/core/text-rendering/Utils.d.ts +0 -71
  238. package/dist/src/core/text-rendering/Utils.js +0 -212
  239. package/dist/src/core/text-rendering/Utils.js.map +0 -1
  240. package/dist/src/core/text-rendering/canvas/Settings.d.ts +0 -53
  241. package/dist/src/core/text-rendering/canvas/Settings.js +0 -20
  242. package/dist/src/core/text-rendering/canvas/Settings.js.map +0 -1
  243. package/dist/src/core/text-rendering/canvas/Utils.d.ts +0 -19
  244. package/dist/src/core/text-rendering/canvas/Utils.js +0 -139
  245. package/dist/src/core/text-rendering/canvas/Utils.js.map +0 -1
  246. package/dist/src/core/text-rendering/canvas/calculateRenderInfo.d.ts +0 -37
  247. package/dist/src/core/text-rendering/canvas/calculateRenderInfo.js +0 -188
  248. package/dist/src/core/text-rendering/canvas/calculateRenderInfo.js.map +0 -1
  249. package/dist/src/core/text-rendering/canvas/draw.d.ts +0 -12
  250. package/dist/src/core/text-rendering/canvas/draw.js +0 -133
  251. package/dist/src/core/text-rendering/canvas/draw.js.map +0 -1
  252. package/dist/src/core/text-rendering/sdf/PeekableGenerator.d.ts +0 -12
  253. package/dist/src/core/text-rendering/sdf/PeekableGenerator.js +0 -61
  254. package/dist/src/core/text-rendering/sdf/PeekableGenerator.js.map +0 -1
  255. package/dist/src/core/text-rendering/sdf/SimpleFontShaper.d.ts +0 -45
  256. package/dist/src/core/text-rendering/sdf/SimpleFontShaper.js +0 -69
  257. package/dist/src/core/text-rendering/sdf/SimpleFontShaper.js.map +0 -1
@@ -17,9 +17,8 @@
17
17
  * limitations under the License.
18
18
  */
19
19
  import { isProductionEnvironment } from '../utils.js';
20
- import { getTimeStamp } from './platform.js';
21
20
  import type { Stage } from './Stage.js';
22
- import { Texture, TextureType, type TextureState } from './textures/Texture.js';
21
+ import { Texture, TextureType } from './textures/Texture.js';
23
22
  import { bytesToMb } from './utils.js';
24
23
 
25
24
  export interface TextureMemoryManagerSettings {
@@ -116,14 +115,14 @@ export interface MemoryInfo {
116
115
  */
117
116
  export class TextureMemoryManager {
118
117
  private memUsed = 0;
119
- private loadedTextures: Map<Texture, number> = new Map();
120
- private orphanedTextures: Texture[] = [];
118
+ private loadedTextures: (Texture | null)[] = [];
121
119
  private criticalThreshold: number;
122
120
  private targetThreshold: number;
123
121
  private cleanupInterval: number;
124
122
  private debugLogging: boolean;
125
123
  private lastCleanupTime = 0;
126
124
  private baselineMemoryAllocation: number;
125
+ private needsDefrag = false;
127
126
 
128
127
  public criticalCleanupRequested = false;
129
128
  public doNotExceedCriticalThreshold: boolean;
@@ -181,35 +180,6 @@ export class TextureMemoryManager {
181
180
  }
182
181
  }
183
182
 
184
- /**
185
- * Add a texture to the orphaned textures list
186
- *
187
- * @param texture - The texture to add to the orphaned textures list
188
- */
189
- addToOrphanedTextures(texture: Texture) {
190
- // if the texture is already in the orphaned textures list add it at the end
191
- if (this.orphanedTextures.includes(texture)) {
192
- this.removeFromOrphanedTextures(texture);
193
- }
194
-
195
- // If the texture can be cleaned up, add it to the orphaned textures list
196
- if (texture.preventCleanup === false) {
197
- this.orphanedTextures.push(texture);
198
- }
199
- }
200
-
201
- /**
202
- * Remove a texture from the orphaned textures list
203
- *
204
- * @param texture - The texture to remove from the orphaned textures list
205
- */
206
- removeFromOrphanedTextures(texture: Texture) {
207
- const index = this.orphanedTextures.indexOf(texture);
208
- if (index !== -1) {
209
- this.orphanedTextures.splice(index, 1);
210
- }
211
- }
212
-
213
183
  /**
214
184
  * Set the memory usage of a texture
215
185
  *
@@ -217,17 +187,25 @@ export class TextureMemoryManager {
217
187
  * @param byteSize - The size of the texture in bytes
218
188
  */
219
189
  setTextureMemUse(texture: Texture, byteSize: number) {
220
- if (this.loadedTextures.has(texture)) {
221
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
222
- this.memUsed -= this.loadedTextures.get(texture)!;
223
- }
190
+ // Update global memory counter by subtracting old value
191
+ this.memUsed -= texture.memUsed;
224
192
 
225
193
  if (byteSize === 0) {
226
- this.loadedTextures.delete(texture);
194
+ // PERFORMANCE: Mark for deletion instead of splice (zero overhead)
195
+ const index = this.loadedTextures.indexOf(texture);
196
+ if (index !== -1) {
197
+ this.loadedTextures[index] = null;
198
+ this.needsDefrag = true;
199
+ }
200
+ texture.memUsed = 0;
227
201
  return;
228
202
  } else {
203
+ // Update texture memory and add to tracking if not already present
204
+ texture.memUsed = byteSize;
229
205
  this.memUsed += byteSize;
230
- this.loadedTextures.set(texture, byteSize);
206
+ if (this.loadedTextures.indexOf(texture) === -1) {
207
+ this.loadedTextures.push(texture);
208
+ }
231
209
  }
232
210
 
233
211
  if (this.memUsed > this.criticalThreshold) {
@@ -247,39 +225,21 @@ export class TextureMemoryManager {
247
225
  return this.memUsed > this.criticalThreshold;
248
226
  }
249
227
 
250
- cleanupQuick(critical: boolean) {
251
- // Free non-renderable textures until we reach the target threshold
252
- const memTarget = this.targetThreshold;
253
- const timestamp = getTimeStamp();
254
-
255
- while (
256
- this.memUsed >= memTarget &&
257
- this.orphanedTextures.length > 0 &&
258
- (critical || getTimeStamp() - timestamp < 10)
259
- ) {
260
- const texture = this.orphanedTextures.shift();
261
-
262
- if (texture === undefined) {
263
- continue;
264
- }
265
-
266
- if (texture.renderable === true) {
267
- // If the texture is renderable, we can't free it up
268
- continue;
269
- }
270
-
271
- // Skip textures that are in transitional states - we only want to clean up
272
- // textures that are in a stable state (loaded, failed, or freed)
273
- if (Texture.TRANSITIONAL_TEXTURE_STATES.includes(texture.state)) {
274
- continue;
275
- }
276
-
277
- this.destroyTexture(texture);
278
- }
228
+ /**
229
+ * Check if defragmentation is needed
230
+ *
231
+ * @remarks
232
+ * Returns true if the loadedTextures array has null entries that need
233
+ * to be compacted. Called by platform during idle periods.
234
+ *
235
+ * @returns true if defragmentation should be performed
236
+ */
237
+ checkDefrag() {
238
+ return this.needsDefrag;
279
239
  }
280
240
 
281
241
  /**
282
- * Destroy a texture and remove it from the memory manager
242
+ * Destroy a texture and null out its array position
283
243
  *
284
244
  * @param texture - The texture to destroy
285
245
  */
@@ -290,66 +250,25 @@ export class TextureMemoryManager {
290
250
  );
291
251
  }
292
252
 
253
+ // PERFORMANCE: Null out array position instead of splice (zero overhead)
254
+ const index = this.loadedTextures.indexOf(texture);
255
+ if (index !== -1) {
256
+ this.loadedTextures[index] = null;
257
+ this.needsDefrag = true;
258
+ }
259
+
260
+ // Destroy texture and update memory counters
293
261
  const txManager = this.stage.txManager;
294
- txManager.removeTextureFromQueue(texture);
295
262
  txManager.removeTextureFromCache(texture);
296
263
 
297
264
  texture.destroy();
298
265
 
299
- this.removeFromOrphanedTextures(texture);
300
- this.loadedTextures.delete(texture);
301
- }
302
- cleanupDeep(critical: boolean) {
303
- // Free non-renderable textures until we reach the target threshold
304
- const memTarget = critical ? this.criticalThreshold : this.targetThreshold;
305
-
306
- // sort by renderability
307
- const filteredAndSortedTextures: Texture[] = [];
308
- const textures = [...this.loadedTextures.keys()];
309
- for (let i = 0; i < textures.length; i++) {
310
- const texture = textures[i];
311
- if (texture === undefined) {
312
- continue;
313
- }
314
-
315
- if (
316
- texture.type === TextureType.image ||
317
- texture.type === TextureType.noise ||
318
- texture.type === TextureType.renderToTexture
319
- ) {
320
- if (texture.renderable === true) {
321
- filteredAndSortedTextures.push(texture);
322
- } else {
323
- filteredAndSortedTextures.unshift(texture);
324
- }
325
- }
326
- }
327
-
328
- while (this.memUsed >= memTarget && filteredAndSortedTextures.length > 0) {
329
- const texture = filteredAndSortedTextures.shift();
330
- if (texture === undefined) {
331
- continue;
332
- }
333
-
334
- if (texture.preventCleanup === true) {
335
- continue;
336
- }
337
-
338
- if (texture.renderable === true) {
339
- break;
340
- }
341
-
342
- // Skip textures that are in transitional states - we only want to clean up
343
- // textures that are in a stable state (loaded, failed, or freed)
344
- if (Texture.TRANSITIONAL_TEXTURE_STATES.includes(texture.state)) {
345
- break;
346
- }
347
-
348
- this.destroyTexture(texture);
349
- }
266
+ // Update memory counters
267
+ this.memUsed -= texture.memUsed;
268
+ texture.memUsed = 0;
350
269
  }
351
270
 
352
- cleanup(aggressive: boolean = false) {
271
+ cleanup() {
353
272
  const critical = this.criticalCleanupRequested;
354
273
  this.lastCleanupTime = this.frameTime;
355
274
 
@@ -362,25 +281,41 @@ export class TextureMemoryManager {
362
281
 
363
282
  if (this.debugLogging === true) {
364
283
  console.log(
365
- `[TextureMemoryManager] Cleaning up textures. Critical: ${critical}. Aggressive: ${aggressive}`,
284
+ `[TextureMemoryManager] Cleaning up textures. Critical: ${critical}.`,
366
285
  );
367
286
  }
368
287
 
369
- // Note: We skip textures in transitional states during cleanup:
370
- // - 'initial': These textures haven't started loading yet
371
- // - 'fetching': These textures are in the process of being fetched
372
- // - 'fetched': These textures have been fetched but not yet uploaded to GPU
373
- // - 'loading': These textures are being uploaded to the GPU
374
- //
375
- // For 'failed' and 'freed' states, we only remove them from the tracking
376
- // arrays without trying to free GPU resources that don't exist.
377
-
378
- // try a quick cleanup first
379
- this.cleanupQuick(critical);
380
-
381
- // if we're still above the target threshold, do a deep cleanup
382
- if (aggressive === true && this.memUsed >= this.criticalThreshold) {
383
- this.cleanupDeep(critical);
288
+ // Free non-renderable textures until we reach the target threshold
289
+ const memTarget = critical ? this.criticalThreshold : this.targetThreshold;
290
+
291
+ // PERFORMANCE: Zero-overhead cleanup with null marking
292
+ // Skip null entries, mark cleaned textures as null for later defrag
293
+ let currentMemUsed = this.memUsed;
294
+
295
+ for (let i = 0; i < this.loadedTextures.length; i++) {
296
+ // Early exit: target memory reached
297
+ if (currentMemUsed < memTarget) {
298
+ break;
299
+ }
300
+
301
+ const texture = this.loadedTextures[i];
302
+ if (!texture) continue; // Skip null entries from previous deletions
303
+
304
+ // Fast type check for cleanable textures
305
+ const isCleanableType =
306
+ texture.type === TextureType.image ||
307
+ texture.type === TextureType.noise ||
308
+ texture.type === TextureType.renderToTexture;
309
+
310
+ // Immediate cleanup if eligible
311
+ if (isCleanableType && texture.canBeCleanedUp() === true) {
312
+ // Get memory before destroying
313
+ const textureMemory = texture.memUsed;
314
+
315
+ // Destroy texture (which will null out the array position)
316
+ this.destroyTexture(texture);
317
+ currentMemUsed -= textureMemory;
318
+ }
384
319
  }
385
320
 
386
321
  if (this.memUsed >= this.criticalThreshold) {
@@ -399,6 +334,37 @@ export class TextureMemoryManager {
399
334
  }
400
335
  }
401
336
 
337
+ /**
338
+ * Defragment the loadedTextures array by removing null entries
339
+ *
340
+ * @remarks
341
+ * This should be called during idle periods to compact the array
342
+ * after null-marking deletions. Zero overhead during critical cleanup.
343
+ */
344
+ defragment() {
345
+ if (!this.needsDefrag) {
346
+ return;
347
+ }
348
+
349
+ // PERFORMANCE: Single-pass compaction
350
+ let writeIndex = 0;
351
+ for (
352
+ let readIndex = 0;
353
+ readIndex < this.loadedTextures.length;
354
+ readIndex++
355
+ ) {
356
+ const texture = this.loadedTextures[readIndex];
357
+ if (texture !== null && texture !== undefined) {
358
+ this.loadedTextures[writeIndex] = texture;
359
+ writeIndex++;
360
+ }
361
+ }
362
+
363
+ // Trim array to new size
364
+ this.loadedTextures.length = writeIndex;
365
+ this.needsDefrag = false;
366
+ }
367
+
402
368
  /**
403
369
  * Get the current texture memory usage information
404
370
  *
@@ -408,15 +374,19 @@ export class TextureMemoryManager {
408
374
  */
409
375
  getMemoryInfo(): MemoryInfo {
410
376
  let renderableTexturesLoaded = 0;
411
- const renderableMemUsed = [...this.loadedTextures.keys()].reduce(
412
- (acc, texture) => {
413
- renderableTexturesLoaded += texture.renderable ? 1 : 0;
414
- // Get the memory used by the texture, defaulting to 0 if not found
415
- const textureMemory = this.loadedTextures.get(texture) ?? 0;
416
- return acc + (texture.renderable ? textureMemory : 0);
417
- },
418
- this.baselineMemoryAllocation,
419
- );
377
+ let renderableMemUsed = this.baselineMemoryAllocation;
378
+
379
+ for (const texture of this.loadedTextures) {
380
+ if (texture && texture.renderable) {
381
+ renderableTexturesLoaded += 1;
382
+ renderableMemUsed += texture.memUsed;
383
+ }
384
+ }
385
+
386
+ // Count non-null entries for accurate loaded texture count
387
+ const actualLoadedTextures = this.loadedTextures.filter(
388
+ (t) => t !== null,
389
+ ).length;
420
390
 
421
391
  return {
422
392
  criticalThreshold: this.criticalThreshold,
@@ -424,7 +394,7 @@ export class TextureMemoryManager {
424
394
  renderableMemUsed,
425
395
  memUsed: this.memUsed,
426
396
  renderableTexturesLoaded,
427
- loadedTextures: this.loadedTextures.size,
397
+ loadedTextures: actualLoadedTextures,
428
398
  baselineMemoryAllocation: this.baselineMemoryAllocation,
429
399
  };
430
400
  }
@@ -1277,6 +1277,44 @@ export class WebGlContextWrapper {
1277
1277
  const { gl } = this;
1278
1278
  gl.deleteShader(shader);
1279
1279
  }
1280
+
1281
+ /**
1282
+ * Check for WebGL errors and return error information
1283
+ * @param operation Description of the operation for error reporting
1284
+ * @returns Object with error information or null if no error
1285
+ */
1286
+ checkError(
1287
+ operation: string,
1288
+ ): { error: number; errorName: string; message: string } | null {
1289
+ const error = this.getError();
1290
+ if (error !== 0) {
1291
+ // 0 is GL_NO_ERROR
1292
+ let errorName = 'UNKNOWN_ERROR';
1293
+ switch (error) {
1294
+ case this.INVALID_ENUM:
1295
+ errorName = 'INVALID_ENUM';
1296
+ break;
1297
+ case 0x0501: // GL_INVALID_VALUE
1298
+ errorName = 'INVALID_VALUE';
1299
+ break;
1300
+ case this.INVALID_OPERATION:
1301
+ errorName = 'INVALID_OPERATION';
1302
+ break;
1303
+ case 0x0505: // GL_OUT_OF_MEMORY
1304
+ errorName = 'OUT_OF_MEMORY';
1305
+ break;
1306
+ case 0x9242: // GL_CONTEXT_LOST_WEBGL
1307
+ errorName = 'CONTEXT_LOST_WEBGL';
1308
+ break;
1309
+ }
1310
+
1311
+ const message = `WebGL ${errorName} (0x${error.toString(
1312
+ 16,
1313
+ )}) during ${operation}`;
1314
+ return { error, errorName, message };
1315
+ }
1316
+ return null;
1317
+ }
1280
1318
  }
1281
1319
 
1282
1320
  // prettier-ignore
@@ -39,14 +39,25 @@ export function isCompressedTextureContainer(url: string): boolean {
39
39
  export const loadCompressedTexture = async (
40
40
  url: string,
41
41
  ): Promise<TextureData> => {
42
- const response = await fetch(url);
43
- const arrayBuffer = await response.arrayBuffer();
42
+ try {
43
+ const response = await fetch(url);
44
44
 
45
- if (url.indexOf('.ktx') !== -1) {
46
- return loadKTXData(arrayBuffer);
47
- }
45
+ if (!response.ok) {
46
+ throw new Error(
47
+ `Failed to fetch compressed texture: ${response.status} ${response.statusText}`,
48
+ );
49
+ }
50
+
51
+ const arrayBuffer = await response.arrayBuffer();
52
+
53
+ if (url.indexOf('.ktx') !== -1) {
54
+ return loadKTXData(arrayBuffer);
55
+ }
48
56
 
49
- return loadPVRData(arrayBuffer);
57
+ return loadPVRData(arrayBuffer);
58
+ } catch (error) {
59
+ throw new Error(`Failed to load compressed texture from ${url}: ${error}`);
60
+ }
50
61
  };
51
62
 
52
63
  /**
@@ -111,7 +122,7 @@ const loadPVRData = async (buffer: ArrayBuffer): Promise<TextureData> => {
111
122
  const header = new Int32Array(arrayBuffer, 0, pvrHeaderLength);
112
123
 
113
124
  // @ts-expect-error Object possibly undefined
114
- // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
125
+
115
126
  const dataOffset = header[pvrMetadata] + 52;
116
127
  const pvrtcData = new Uint8Array(arrayBuffer, dataOffset);
117
128
  const mipmaps = [];
@@ -63,7 +63,11 @@ export const startLoop = (stage: Stage) => {
63
63
  }
64
64
 
65
65
  if (stage.txMemManager.checkCleanup() === true) {
66
- stage.txMemManager.cleanup(false);
66
+ stage.txMemManager.cleanup();
67
+ }
68
+
69
+ if (stage.txMemManager.checkDefrag() === true) {
70
+ stage.txMemManager.defragment();
67
71
  }
68
72
 
69
73
  stage.flushFrameEvents();
@@ -35,6 +35,7 @@ export abstract class CoreContextTexture {
35
35
  }
36
36
 
37
37
  abstract load(): Promise<void>;
38
+ abstract release(): void;
38
39
  abstract free(): void;
39
40
 
40
41
  get renderable(): boolean {
@@ -41,18 +41,20 @@ export class CanvasCoreTexture extends CoreContextTexture {
41
41
  try {
42
42
  const size = await this.onLoadRequest();
43
43
  this.textureSource.setState('loaded', size);
44
- this.textureSource.freeTextureData();
45
44
  this.updateMemSize();
46
45
  } catch (err) {
47
46
  this.textureSource.setState('failed', err as Error);
48
- this.textureSource.freeTextureData();
49
47
  throw err;
50
48
  }
51
49
  }
52
50
 
53
- free(): void {
51
+ release(): void {
54
52
  this.image = undefined;
55
53
  this.tintCache = undefined;
54
+ }
55
+
56
+ free(): void {
57
+ this.release();
56
58
  this.textureSource.setState('freed');
57
59
  this.setTextureMemUse(0);
58
60
  this.textureSource.freeTextureData();