@lightningjs/renderer 2.6.2 → 2.7.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 (215) hide show
  1. package/dist/src/core/CoreNode.d.ts +6 -1
  2. package/dist/src/core/CoreNode.js +109 -64
  3. package/dist/src/core/CoreNode.js.map +1 -1
  4. package/dist/src/core/lib/WebGlContextWrapper.d.ts +1 -1
  5. package/dist/src/core/renderers/canvas/CanvasCoreRenderer.js +40 -3
  6. package/dist/src/core/renderers/canvas/CanvasCoreRenderer.js.map +1 -1
  7. package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.d.ts +9 -1
  8. package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.js +68 -0
  9. package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.js.map +1 -1
  10. package/dist/src/core/renderers/canvas/internal/ColorUtils.d.ts +4 -0
  11. package/dist/src/core/renderers/canvas/internal/ColorUtils.js +13 -0
  12. package/dist/src/core/renderers/canvas/internal/ColorUtils.js.map +1 -1
  13. package/dist/src/core/renderers/canvas/shaders/UnsupportedShader.js +3 -3
  14. package/dist/src/core/renderers/canvas/shaders/UnsupportedShader.js.map +1 -1
  15. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js +4 -0
  16. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js.map +1 -1
  17. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +9 -0
  18. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  19. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +23 -0
  20. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +65 -9
  21. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
  22. package/dist/src/core/renderers/webgl/WebGlCoreShader.js +2 -2
  23. package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +1 -1
  24. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +4 -4
  25. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -1
  26. package/dist/src/core/renderers/webgl/shaders/effects/RadiusEffect.js +18 -0
  27. package/dist/src/core/renderers/webgl/shaders/effects/RadiusEffect.js.map +1 -1
  28. package/dist/src/core/renderers/webgl/shaders/effects/ShaderEffect.js.map +1 -1
  29. package/dist/src/core/textures/ColorTexture.js +14 -3
  30. package/dist/src/core/textures/ColorTexture.js.map +1 -1
  31. package/dist/src/core/textures/Texture.d.ts +1 -1
  32. package/dist/src/core/textures/Texture.js.map +1 -1
  33. package/dist/src/main-api/Inspector.d.ts +1 -1
  34. package/dist/src/main-api/Inspector.js +23 -8
  35. package/dist/src/main-api/Inspector.js.map +1 -1
  36. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  37. package/package.json +1 -2
  38. package/src/core/CoreNode.ts +125 -73
  39. package/src/core/lib/WebGlContextWrapper.ts +1 -1
  40. package/src/core/renderers/canvas/CanvasCoreRenderer.ts +91 -2
  41. package/src/core/renderers/canvas/internal/C2DShaderUtils.ts +102 -1
  42. package/src/core/renderers/canvas/internal/ColorUtils.ts +14 -0
  43. package/src/core/renderers/canvas/shaders/UnsupportedShader.ts +3 -3
  44. package/src/core/renderers/webgl/WebGlCoreCtxSubTexture.ts +6 -0
  45. package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +27 -1
  46. package/src/core/renderers/webgl/WebGlCoreRenderer.ts +78 -9
  47. package/src/core/renderers/webgl/WebGlCoreShader.ts +4 -2
  48. package/src/core/renderers/webgl/internal/ShaderUtils.ts +5 -4
  49. package/src/core/renderers/webgl/shaders/effects/RadiusEffect.ts +0 -2
  50. package/src/core/renderers/webgl/shaders/effects/ShaderEffect.ts +0 -1
  51. package/src/core/textures/ColorTexture.ts +15 -3
  52. package/src/core/textures/Texture.ts +1 -0
  53. package/src/main-api/Inspector.ts +29 -11
  54. package/dist/exports/core-api.d.ts +0 -74
  55. package/dist/exports/core-api.js +0 -96
  56. package/dist/exports/core-api.js.map +0 -1
  57. package/dist/exports/main-api.d.ts +0 -30
  58. package/dist/exports/main-api.js +0 -45
  59. package/dist/exports/main-api.js.map +0 -1
  60. package/dist/src/core/CoreExtension.d.ts +0 -12
  61. package/dist/src/core/CoreExtension.js +0 -29
  62. package/dist/src/core/CoreExtension.js.map +0 -1
  63. package/dist/src/core/CoreStuff.d.ts +0 -1
  64. package/dist/src/core/CoreStuff.js +0 -138
  65. package/dist/src/core/CoreStuff.js.map +0 -1
  66. package/dist/src/core/LngNode.d.ts +0 -736
  67. package/dist/src/core/LngNode.js +0 -1174
  68. package/dist/src/core/LngNode.js.map +0 -1
  69. package/dist/src/core/Matrix2DContext.d.ts +0 -15
  70. package/dist/src/core/Matrix2DContext.js +0 -45
  71. package/dist/src/core/Matrix2DContext.js.map +0 -1
  72. package/dist/src/core/ShaderNode.d.ts +0 -10
  73. package/dist/src/core/ShaderNode.js +0 -30
  74. package/dist/src/core/ShaderNode.js.map +0 -1
  75. package/dist/src/core/TextNode.d.ts +0 -103
  76. package/dist/src/core/TextNode.js +0 -331
  77. package/dist/src/core/TextNode.js.map +0 -1
  78. package/dist/src/core/lib/Coords.d.ts +0 -14
  79. package/dist/src/core/lib/Coords.js +0 -55
  80. package/dist/src/core/lib/Coords.js.map +0 -1
  81. package/dist/src/core/lib/glm/common.d.ts +0 -162
  82. package/dist/src/core/lib/glm/common.js +0 -81
  83. package/dist/src/core/lib/glm/common.js.map +0 -1
  84. package/dist/src/core/lib/glm/index.d.ts +0 -11
  85. package/dist/src/core/lib/glm/index.js +0 -30
  86. package/dist/src/core/lib/glm/index.js.map +0 -1
  87. package/dist/src/core/lib/glm/mat2.d.ts +0 -219
  88. package/dist/src/core/lib/glm/mat2.js +0 -396
  89. package/dist/src/core/lib/glm/mat2.js.map +0 -1
  90. package/dist/src/core/lib/glm/mat2d.d.ts +0 -237
  91. package/dist/src/core/lib/glm/mat2d.js +0 -442
  92. package/dist/src/core/lib/glm/mat2d.js.map +0 -1
  93. package/dist/src/core/lib/glm/mat3.d.ts +0 -283
  94. package/dist/src/core/lib/glm/mat3.js +0 -680
  95. package/dist/src/core/lib/glm/mat3.js.map +0 -1
  96. package/dist/src/core/lib/glm/mat4.d.ts +0 -550
  97. package/dist/src/core/lib/glm/mat4.js +0 -1802
  98. package/dist/src/core/lib/glm/mat4.js.map +0 -1
  99. package/dist/src/core/lib/glm/quat.d.ts +0 -363
  100. package/dist/src/core/lib/glm/quat.js +0 -693
  101. package/dist/src/core/lib/glm/quat.js.map +0 -1
  102. package/dist/src/core/lib/glm/quat2.d.ts +0 -356
  103. package/dist/src/core/lib/glm/quat2.js +0 -754
  104. package/dist/src/core/lib/glm/quat2.js.map +0 -1
  105. package/dist/src/core/lib/glm/vec2.d.ts +0 -365
  106. package/dist/src/core/lib/glm/vec2.js +0 -569
  107. package/dist/src/core/lib/glm/vec2.js.map +0 -1
  108. package/dist/src/core/lib/glm/vec3.d.ts +0 -406
  109. package/dist/src/core/lib/glm/vec3.js +0 -720
  110. package/dist/src/core/lib/glm/vec3.js.map +0 -1
  111. package/dist/src/core/lib/glm/vec4.d.ts +0 -330
  112. package/dist/src/core/lib/glm/vec4.js +0 -608
  113. package/dist/src/core/lib/glm/vec4.js.map +0 -1
  114. package/dist/src/core/renderers/CoreShaderManager.d.ts +0 -19
  115. package/dist/src/core/renderers/CoreShaderManager.js +0 -33
  116. package/dist/src/core/renderers/CoreShaderManager.js.map +0 -1
  117. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.d.ts +0 -27
  118. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.js +0 -82
  119. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.js.map +0 -1
  120. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.d.ts +0 -11
  121. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.js +0 -34
  122. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.js.map +0 -1
  123. package/dist/src/core/scene/Scene.d.ts +0 -59
  124. package/dist/src/core/scene/Scene.js +0 -106
  125. package/dist/src/core/scene/Scene.js.map +0 -1
  126. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.d.ts +0 -20
  127. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js +0 -55
  128. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js.map +0 -1
  129. package/dist/src/main-api/ICoreDriver.d.ts +0 -27
  130. package/dist/src/main-api/ICoreDriver.js +0 -20
  131. package/dist/src/main-api/ICoreDriver.js.map +0 -1
  132. package/dist/src/main-api/IRenderDriver.d.ts +0 -20
  133. package/dist/src/main-api/IRenderDriver.js +0 -20
  134. package/dist/src/main-api/IRenderDriver.js.map +0 -1
  135. package/dist/src/main-api/IShaderController.d.ts +0 -14
  136. package/dist/src/main-api/IShaderController.js +0 -30
  137. package/dist/src/main-api/IShaderController.js.map +0 -1
  138. package/dist/src/main-api/IShaderNode.d.ts +0 -17
  139. package/dist/src/main-api/IShaderNode.js +0 -19
  140. package/dist/src/main-api/IShaderNode.js.map +0 -1
  141. package/dist/src/main-api/RendererMain.d.ts +0 -375
  142. package/dist/src/main-api/RendererMain.js +0 -365
  143. package/dist/src/main-api/RendererMain.js.map +0 -1
  144. package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.d.ts +0 -9
  145. package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.js +0 -38
  146. package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.js.map +0 -1
  147. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.d.ts +0 -56
  148. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.js +0 -101
  149. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.js.map +0 -1
  150. package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.d.ts +0 -32
  151. package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.js +0 -28
  152. package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.js.map +0 -1
  153. package/dist/src/render-drivers/main/MainCoreDriver.d.ts +0 -24
  154. package/dist/src/render-drivers/main/MainCoreDriver.js +0 -118
  155. package/dist/src/render-drivers/main/MainCoreDriver.js.map +0 -1
  156. package/dist/src/render-drivers/main/MainOnlyNode.d.ts +0 -99
  157. package/dist/src/render-drivers/main/MainOnlyNode.js +0 -396
  158. package/dist/src/render-drivers/main/MainOnlyNode.js.map +0 -1
  159. package/dist/src/render-drivers/main/MainOnlyShaderController.d.ts +0 -6
  160. package/dist/src/render-drivers/main/MainOnlyShaderController.js +0 -15
  161. package/dist/src/render-drivers/main/MainOnlyShaderController.js.map +0 -1
  162. package/dist/src/render-drivers/main/MainOnlyShaderNode.d.ts +0 -7
  163. package/dist/src/render-drivers/main/MainOnlyShaderNode.js +0 -34
  164. package/dist/src/render-drivers/main/MainOnlyShaderNode.js.map +0 -1
  165. package/dist/src/render-drivers/main/MainOnlyTextNode.d.ts +0 -47
  166. package/dist/src/render-drivers/main/MainOnlyTextNode.js +0 -205
  167. package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +0 -1
  168. package/dist/src/render-drivers/main/MainRenderDriver.d.ts +0 -17
  169. package/dist/src/render-drivers/main/MainRenderDriver.js +0 -88
  170. package/dist/src/render-drivers/main/MainRenderDriver.js.map +0 -1
  171. package/dist/src/render-drivers/threadx/NodeStruct.d.ts +0 -90
  172. package/dist/src/render-drivers/threadx/NodeStruct.js +0 -281
  173. package/dist/src/render-drivers/threadx/NodeStruct.js.map +0 -1
  174. package/dist/src/render-drivers/threadx/SharedNode.d.ts +0 -39
  175. package/dist/src/render-drivers/threadx/SharedNode.js +0 -60
  176. package/dist/src/render-drivers/threadx/SharedNode.js.map +0 -1
  177. package/dist/src/render-drivers/threadx/TextNodeStruct.d.ts +0 -44
  178. package/dist/src/render-drivers/threadx/TextNodeStruct.js +0 -201
  179. package/dist/src/render-drivers/threadx/TextNodeStruct.js.map +0 -1
  180. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.d.ts +0 -28
  181. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +0 -234
  182. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +0 -1
  183. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.d.ts +0 -20
  184. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js +0 -84
  185. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js.map +0 -1
  186. package/dist/src/render-drivers/threadx/ThreadXMainNode.d.ts +0 -44
  187. package/dist/src/render-drivers/threadx/ThreadXMainNode.js +0 -154
  188. package/dist/src/render-drivers/threadx/ThreadXMainNode.js.map +0 -1
  189. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.d.ts +0 -6
  190. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.js +0 -16
  191. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.js.map +0 -1
  192. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.d.ts +0 -7
  193. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.js +0 -15
  194. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.js.map +0 -1
  195. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.d.ts +0 -28
  196. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js +0 -55
  197. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js.map +0 -1
  198. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.d.ts +0 -21
  199. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js +0 -198
  200. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js.map +0 -1
  201. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.d.ts +0 -70
  202. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js +0 -32
  203. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js.map +0 -1
  204. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.d.ts +0 -19
  205. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +0 -177
  206. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +0 -1
  207. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.d.ts +0 -27
  208. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +0 -108
  209. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +0 -1
  210. package/dist/src/render-drivers/threadx/worker/renderer.d.ts +0 -1
  211. package/dist/src/render-drivers/threadx/worker/renderer.js +0 -145
  212. package/dist/src/render-drivers/threadx/worker/renderer.js.map +0 -1
  213. package/dist/src/render-drivers/utils.d.ts +0 -12
  214. package/dist/src/render-drivers/utils.js +0 -69
  215. package/dist/src/render-drivers/utils.js.map +0 -1
@@ -783,6 +783,21 @@ export class CoreNode extends EventEmitter {
783
783
  if (this.textureOptions.preload) {
784
784
  texture.ctxTexture.load();
785
785
  }
786
+
787
+ texture.on('loaded', this.onTextureLoaded);
788
+ texture.on('failed', this.onTextureFailed);
789
+ texture.on('freed', this.onTextureFreed);
790
+
791
+ // If the parent is a render texture, the initial texture status
792
+ // will be set to freed until the texture is processed by the
793
+ // Render RTT nodes. So we only need to listen fo changes and
794
+ // no need to check the texture.state until we restructure how
795
+ // textures are being processed.
796
+ if (this.parentHasRenderTexture) {
797
+ this.notifyParentRTTOfUpdate();
798
+ return;
799
+ }
800
+
786
801
  if (texture.state === 'loaded') {
787
802
  assertTruthy(texture.dimensions);
788
803
  this.onTextureLoaded(texture, texture.dimensions);
@@ -792,9 +807,6 @@ export class CoreNode extends EventEmitter {
792
807
  } else if (texture.state === 'freed') {
793
808
  this.onTextureFreed(texture);
794
809
  }
795
- texture.on('loaded', this.onTextureLoaded);
796
- texture.on('failed', this.onTextureFailed);
797
- texture.on('freed', this.onTextureFreed);
798
810
  });
799
811
  }
800
812
 
@@ -822,9 +834,8 @@ export class CoreNode extends EventEmitter {
822
834
  this.stage.requestRender();
823
835
 
824
836
  // If parent has a render texture, flag that we need to update
825
- // @todo: Reserve type for RTT updates
826
837
  if (this.parentHasRenderTexture) {
827
- this.setRTTUpdates(1);
838
+ this.notifyParentRTTOfUpdate();
828
839
  }
829
840
 
830
841
  this.emit('loaded', {
@@ -839,6 +850,11 @@ export class CoreNode extends EventEmitter {
839
850
  };
840
851
 
841
852
  private onTextureFailed: TextureFailedEventHandler = (_, error) => {
853
+ // If parent has a render texture, flag that we need to update
854
+ if (this.parentHasRenderTexture) {
855
+ this.notifyParentRTTOfUpdate();
856
+ }
857
+
842
858
  this.emit('failed', {
843
859
  type: 'texture',
844
860
  error,
@@ -846,6 +862,11 @@ export class CoreNode extends EventEmitter {
846
862
  };
847
863
 
848
864
  private onTextureFreed: TextureFreedEventHandler = () => {
865
+ // If parent has a render texture, flag that we need to update
866
+ if (this.parentHasRenderTexture) {
867
+ this.notifyParentRTTOfUpdate();
868
+ }
869
+
849
870
  this.emit('freed', {
850
871
  type: 'texture',
851
872
  } satisfies NodeTextureFreedPayload);
@@ -866,24 +887,10 @@ export class CoreNode extends EventEmitter {
866
887
  const parent = this.props.parent;
867
888
  if (!parent) return;
868
889
 
869
- // Inform the parent if it doesn’t already have a child update
870
890
  if ((parent.updateType & UpdateType.Children) === 0) {
891
+ // Inform the parent if it doesn’t already have a child update
871
892
  parent.setUpdateType(UpdateType.Children);
872
893
  }
873
-
874
- if (this.parentHasRenderTexture === false) return;
875
-
876
- if (this.rtt === false) {
877
- if ((parent.updateType & UpdateType.RenderTexture) === 0) {
878
- this.setRTTUpdates(type);
879
- parent.setUpdateType(UpdateType.RenderTexture);
880
- }
881
- }
882
-
883
- // If this node has outstanding RTT updates, propagate them
884
- if (this.hasRTTupdates) {
885
- this.setRTTUpdates(type);
886
- }
887
894
  }
888
895
 
889
896
  sortChildren() {
@@ -988,24 +995,11 @@ export class CoreNode extends EventEmitter {
988
995
  const parent = this.props.parent;
989
996
  let renderState = null;
990
997
 
991
- if (this.updateType & UpdateType.ParentRenderTexture) {
992
- let p = this.parent;
993
- while (p) {
994
- if (p.rtt) {
995
- this.parentHasRenderTexture = true;
996
- }
997
- p = p.parent;
998
- }
999
- }
1000
-
1001
- // If we have render texture updates and not already running a full update
1002
- if (
1003
- this.updateType ^ UpdateType.All &&
1004
- this.updateType & UpdateType.RenderTexture
1005
- ) {
1006
- for (let i = 0, length = this.children.length; i < length; i++) {
1007
- this.children[i]?.setUpdateType(UpdateType.All);
1008
- }
998
+ // Handle specific RTT updates at this node level
999
+ if (this.updateType & UpdateType.RenderTexture && this.rtt) {
1000
+ // Only the RTT node itself triggers `renderToTexture`
1001
+ this.hasRTTupdates = true;
1002
+ this.stage.renderer?.renderToTexture(this);
1009
1003
  }
1010
1004
 
1011
1005
  if (this.updateType & UpdateType.Global) {
@@ -1130,11 +1124,7 @@ export class CoreNode extends EventEmitter {
1130
1124
  return;
1131
1125
  }
1132
1126
 
1133
- if (
1134
- this.updateType & UpdateType.Children &&
1135
- this.children.length > 0 &&
1136
- this.rtt === false
1137
- ) {
1127
+ if (this.updateType & UpdateType.Children && this.children.length > 0) {
1138
1128
  for (let i = 0, length = this.children.length; i < length; i++) {
1139
1129
  const child = this.children[i] as CoreNode;
1140
1130
 
@@ -1148,6 +1138,13 @@ export class CoreNode extends EventEmitter {
1148
1138
  }
1149
1139
  }
1150
1140
 
1141
+ // If the node has an RTT parent and requires a texture re-render, inform the RTT parent
1142
+ // if (this.parentHasRenderTexture && this.updateType & UpdateType.RenderTexture) {
1143
+ // @TODO have a more scoped down updateType for RTT updates
1144
+ if (this.parentHasRenderTexture && this.updateType > 0) {
1145
+ this.notifyParentRTTOfUpdate();
1146
+ }
1147
+
1151
1148
  // Sorting children MUST happen after children have been updated so
1152
1149
  // that they have the oppotunity to update their calculated zIndex.
1153
1150
  if (this.updateType & UpdateType.ZIndexSortedChildren) {
@@ -1168,6 +1165,31 @@ export class CoreNode extends EventEmitter {
1168
1165
  this.childUpdateType = 0;
1169
1166
  }
1170
1167
 
1168
+ private notifyParentRTTOfUpdate() {
1169
+ if (this.parent === null) {
1170
+ return;
1171
+ }
1172
+
1173
+ let rttNode: CoreNode | null = this.parent;
1174
+ // Traverse up to find the RTT root node
1175
+ while (rttNode && !rttNode.rtt) {
1176
+ rttNode = rttNode.parent;
1177
+ }
1178
+
1179
+ if (!rttNode) {
1180
+ return;
1181
+ }
1182
+
1183
+ // If an RTT node is found, mark it for re-rendering
1184
+ rttNode.hasRTTupdates = true;
1185
+ rttNode.setUpdateType(UpdateType.RenderTexture);
1186
+
1187
+ // if rttNode is nested, also make it update its RTT parent
1188
+ if (rttNode.parentHasRenderTexture === true) {
1189
+ rttNode.notifyParentRTTOfUpdate();
1190
+ }
1191
+ }
1192
+
1171
1193
  //check if CoreNode is renderable based on props
1172
1194
  hasRenderableProperties(): boolean {
1173
1195
  if (this.props.texture) {
@@ -1940,8 +1962,9 @@ export class CoreNode extends EventEmitter {
1940
1962
  UpdateType.Children | UpdateType.ZIndexSortedChildren,
1941
1963
  );
1942
1964
 
1965
+ // If the new parent has an RTT enabled, apply RTT inheritance
1943
1966
  if (newParent.rtt || newParent.parentHasRenderTexture) {
1944
- this.setRTTUpdates(UpdateType.All);
1967
+ this.applyRTTInheritance(newParent);
1945
1968
  }
1946
1969
  }
1947
1970
  this.updateScaleRotateTransform();
@@ -1963,43 +1986,77 @@ export class CoreNode extends EventEmitter {
1963
1986
  }
1964
1987
 
1965
1988
  set rtt(value: boolean) {
1966
- if (this.props.rtt === true) {
1967
- this.props.rtt = value;
1968
-
1969
- // unload texture if we used to have a render texture
1970
- if (value === false && this.texture !== null) {
1971
- this.unloadTexture();
1972
- this.setUpdateType(UpdateType.All);
1973
- for (let i = 0, length = this.children.length; i < length; i++) {
1974
- this.children[i]!.parentHasRenderTexture = false;
1975
- }
1976
- this.stage.renderer?.removeRTTNode(this);
1977
- return;
1978
- }
1989
+ if (this.props.rtt === value) {
1990
+ return;
1979
1991
  }
1992
+ this.props.rtt = value;
1980
1993
 
1981
- // if the new value is false and we didnt have rtt previously, we don't need to do anything
1982
- if (value === false) {
1983
- return;
1994
+ if (value) {
1995
+ this.initRenderTexture();
1996
+ this.markChildrenWithRTT();
1997
+ } else {
1998
+ this.cleanupRenderTexture();
1984
1999
  }
1985
2000
 
1986
- // load texture
2001
+ this.setUpdateType(UpdateType.RenderTexture);
2002
+
2003
+ if (this.parentHasRenderTexture) {
2004
+ this.notifyParentRTTOfUpdate();
2005
+ }
2006
+ }
2007
+ private initRenderTexture() {
1987
2008
  this.texture = this.stage.txManager.loadTexture('RenderTexture', {
1988
2009
  width: this.width,
1989
2010
  height: this.height,
1990
2011
  });
1991
2012
  this.textureOptions.preload = true;
2013
+ this.stage.renderer?.renderToTexture(this); // Only this RTT node
2014
+ }
1992
2015
 
1993
- this.props.rtt = true;
1994
- this.hasRTTupdates = true;
1995
- this.setUpdateType(UpdateType.All);
2016
+ private cleanupRenderTexture() {
2017
+ this.unloadTexture();
2018
+ this.clearRTTInheritance();
1996
2019
 
1997
- for (let i = 0, length = this.children.length; i < length; i++) {
1998
- this.children[i]!.setUpdateType(UpdateType.All);
2020
+ this.stage.renderer?.removeRTTNode(this);
2021
+ this.hasRTTupdates = false;
2022
+ this.texture = null;
2023
+ }
2024
+
2025
+ private markChildrenWithRTT(node: CoreNode | null = null) {
2026
+ const parent = node || this;
2027
+
2028
+ for (const child of parent.children) {
2029
+ child.setUpdateType(UpdateType.All);
2030
+ child.parentHasRenderTexture = true;
2031
+ child.markChildrenWithRTT();
2032
+ }
2033
+ }
2034
+
2035
+ // Apply RTT inheritance when a node has an RTT-enabled parent
2036
+ private applyRTTInheritance(parent: CoreNode) {
2037
+ if (parent.rtt) {
2038
+ // Only the RTT node should be added to `renderToTexture`
2039
+ parent.setUpdateType(UpdateType.RenderTexture);
1999
2040
  }
2000
2041
 
2001
- // Store RTT nodes in a separate list
2002
- this.stage.renderer?.renderToTexture(this);
2042
+ // Propagate `parentHasRenderTexture` downwards
2043
+ this.markChildrenWithRTT(parent);
2044
+ }
2045
+
2046
+ // Clear RTT inheritance when detaching from an RTT chain
2047
+ private clearRTTInheritance() {
2048
+ // if this node is RTT itself stop the propagation important for nested RTT nodes
2049
+ // for the initial RTT node this is already handled in `set rtt`
2050
+ if (this.rtt) {
2051
+ return;
2052
+ }
2053
+
2054
+ for (const child of this.children) {
2055
+ // force child to update everything as the RTT inheritance has changed
2056
+ child.parentHasRenderTexture = false;
2057
+ child.setUpdateType(UpdateType.All);
2058
+ child.clearRTTInheritance();
2059
+ }
2003
2060
  }
2004
2061
 
2005
2062
  get shader(): BaseShaderController {
@@ -2158,11 +2215,6 @@ export class CoreNode extends EventEmitter {
2158
2215
  this.childUpdateType |= UpdateType.RenderBounds | UpdateType.Children;
2159
2216
  }
2160
2217
 
2161
- setRTTUpdates(type: number) {
2162
- this.hasRTTupdates = true;
2163
- this.parent?.setRTTUpdates(type);
2164
- }
2165
-
2166
2218
  animate(
2167
2219
  props: Partial<CoreNodeAnimateProps>,
2168
2220
  settings: Partial<AnimationSettings>,
@@ -299,7 +299,7 @@ export class WebGlContextWrapper {
299
299
  internalformat: GLint,
300
300
  format: GLenum,
301
301
  type: GLenum,
302
- source: TexImageSource,
302
+ source: TexImageSource | Uint8Array,
303
303
  ): void;
304
304
  texImage2D(
305
305
  level: any,
@@ -30,9 +30,10 @@ import {
30
30
  type QuadOptions,
31
31
  } from '../CoreRenderer.js';
32
32
  import { CanvasCoreTexture } from './CanvasCoreTexture.js';
33
- import { getRadius } from './internal/C2DShaderUtils.js';
33
+ import { getBorder, getRadius, strokeLine } from './internal/C2DShaderUtils.js';
34
34
  import {
35
35
  formatRgba,
36
+ parseColorRgba,
36
37
  parseColor,
37
38
  type IParsedColor,
38
39
  } from './internal/ColorUtils.js';
@@ -133,7 +134,9 @@ export class CanvasCoreRenderer extends CoreRenderer {
133
134
  const hasTransform = ta !== 1;
134
135
  const hasClipping = clippingRect.width !== 0 && clippingRect.height !== 0;
135
136
  const hasGradient = colorTl !== colorTr || colorTl !== colorBr;
136
- const radius = quad.shader ? getRadius(quad) : 0;
137
+ const hasQuadShader = Boolean(quad.shader);
138
+ const radius = hasQuadShader ? getRadius(quad) : 0;
139
+ const border = hasQuadShader ? getBorder(quad) : undefined;
137
140
 
138
141
  if (hasTransform || hasClipping || radius) {
139
142
  ctx.save();
@@ -211,6 +214,92 @@ export class CanvasCoreRenderer extends CoreRenderer {
211
214
  ctx.fillRect(tx, ty, width, height);
212
215
  }
213
216
 
217
+ if (border && border.width) {
218
+ const borderWidth = border.width;
219
+ const borderInnerWidth = border.width / 2;
220
+ const borderColor = formatRgba(parseColorRgba(border.color ?? 0));
221
+
222
+ ctx.beginPath();
223
+ ctx.lineWidth = borderWidth;
224
+ ctx.strokeStyle = borderColor;
225
+ ctx.globalAlpha = alpha;
226
+ if (radius) {
227
+ ctx.roundRect(
228
+ tx + borderInnerWidth,
229
+ ty + borderInnerWidth,
230
+ width - borderWidth,
231
+ height - borderWidth,
232
+ radius,
233
+ );
234
+ ctx.stroke();
235
+ } else {
236
+ ctx.strokeRect(
237
+ tx + borderInnerWidth,
238
+ ty + borderInnerWidth,
239
+ width - borderWidth,
240
+ height - borderWidth,
241
+ );
242
+ }
243
+ ctx.globalAlpha = 1;
244
+ } else if (hasQuadShader) {
245
+ const borderTop = getBorder(quad, 'Top');
246
+ const borderRight = getBorder(quad, 'Right');
247
+ const borderBottom = getBorder(quad, 'Bottom');
248
+ const borderLeft = getBorder(quad, 'Left');
249
+
250
+ if (borderTop) {
251
+ strokeLine(
252
+ ctx,
253
+ tx,
254
+ ty,
255
+ width,
256
+ height,
257
+ borderTop.width,
258
+ borderTop.color,
259
+ 'Top',
260
+ );
261
+ }
262
+
263
+ if (borderRight) {
264
+ strokeLine(
265
+ ctx,
266
+ tx,
267
+ ty,
268
+ width,
269
+ height,
270
+ borderRight.width,
271
+ borderRight.color,
272
+ 'Right',
273
+ );
274
+ }
275
+
276
+ if (borderBottom) {
277
+ strokeLine(
278
+ ctx,
279
+ tx,
280
+ ty,
281
+ width,
282
+ height,
283
+ borderBottom.width,
284
+ borderBottom.color,
285
+ 'Bottom',
286
+ );
287
+ }
288
+
289
+ if (borderLeft) {
290
+ strokeLine(
291
+ ctx,
292
+ tx,
293
+ ty,
294
+ width,
295
+ height,
296
+ borderLeft.width,
297
+ borderLeft.color,
298
+ 'Left',
299
+ );
300
+ }
301
+ }
302
+
214
303
  if (hasTransform || hasClipping || radius) {
215
304
  ctx.restore();
216
305
  }
@@ -18,20 +18,121 @@
18
18
  */
19
19
 
20
20
  import type { QuadOptions } from '../../CoreRenderer.js';
21
+ import type { BorderEffectProps } from '../../webgl/shaders/effects/BorderEffect.js';
22
+ import type { RadiusEffectProps } from '../../webgl/shaders/effects/RadiusEffect.js';
23
+ import type { EffectDescUnion } from '../../webgl/shaders/effects/ShaderEffect.js';
21
24
  import {
22
25
  ROUNDED_RECTANGLE_SHADER_TYPE,
23
26
  UnsupportedShader,
24
27
  } from '../shaders/UnsupportedShader.js';
28
+ import { formatRgba, parseColorRgba } from './ColorUtils.js';
29
+
30
+ type Direction = 'Top' | 'Right' | 'Bottom' | 'Left';
25
31
 
26
32
  /**
27
33
  * Extract `RoundedRectangle` shader radius to apply as a clipping
28
34
  */
29
- export function getRadius(quad: QuadOptions): number {
35
+ export function getRadius(quad: QuadOptions): RadiusEffectProps['radius'] {
30
36
  if (quad.shader instanceof UnsupportedShader) {
31
37
  const shType = quad.shader.shType;
32
38
  if (shType === ROUNDED_RECTANGLE_SHADER_TYPE) {
33
39
  return (quad.shaderProps?.radius as number) ?? 0;
40
+ } else if (shType === 'DynamicShader') {
41
+ const effects = quad.shaderProps?.effects as
42
+ | EffectDescUnion[]
43
+ | undefined;
44
+
45
+ if (effects) {
46
+ const effect = effects.find((effect: EffectDescUnion) => {
47
+ return effect.type === 'radius' && effect?.props?.radius;
48
+ });
49
+
50
+ return (effect && effect.type === 'radius' && effect.props.radius) || 0;
51
+ }
34
52
  }
35
53
  }
36
54
  return 0;
37
55
  }
56
+
57
+ /**
58
+ * Extract `RoundedRectangle` shader radius to apply as a clipping */
59
+ export function getBorder(
60
+ quad: QuadOptions,
61
+ direction: '' | Direction = '',
62
+ ): BorderEffectProps | undefined {
63
+ if (quad.shader instanceof UnsupportedShader) {
64
+ const shType = quad.shader.shType;
65
+ if (shType === 'DynamicShader') {
66
+ const effects = quad.shaderProps?.effects as
67
+ | EffectDescUnion[]
68
+ | undefined;
69
+
70
+ if (effects && effects.length) {
71
+ const effect = effects.find((effect: EffectDescUnion) => {
72
+ return (
73
+ effect.type === `border${direction}` &&
74
+ effect.props &&
75
+ effect.props.width
76
+ );
77
+ });
78
+
79
+ return effect && effect.props;
80
+ }
81
+ }
82
+ }
83
+
84
+ return undefined;
85
+ }
86
+
87
+ export function strokeLine(
88
+ ctx: CanvasRenderingContext2D,
89
+ x: number,
90
+ y: number,
91
+ width: number,
92
+ height: number,
93
+ lineWidth = 0,
94
+ color: number | undefined,
95
+ direction: Direction,
96
+ ) {
97
+ if (!lineWidth) {
98
+ return;
99
+ }
100
+
101
+ let sx,
102
+ sy = 0;
103
+ let ex,
104
+ ey = 0;
105
+
106
+ switch (direction) {
107
+ case 'Top':
108
+ sx = x;
109
+ sy = y;
110
+ ex = width + x;
111
+ ey = y;
112
+ break;
113
+ case 'Right':
114
+ sx = x + width;
115
+ sy = y;
116
+ ex = x + width;
117
+ ey = y + height;
118
+ break;
119
+ case 'Bottom':
120
+ sx = x;
121
+ sy = y + height;
122
+ ex = x + width;
123
+ ey = y + height;
124
+ break;
125
+ case 'Left':
126
+ sx = x;
127
+ sy = y;
128
+ ex = x;
129
+ ey = y + height;
130
+ break;
131
+ }
132
+ ctx.beginPath();
133
+ ctx.lineWidth = lineWidth;
134
+ ctx.strokeStyle = formatRgba(parseColorRgba(color ?? 0));
135
+ ctx.moveTo(sx, sy);
136
+ ctx.lineTo(ex, ey);
137
+ ctx.stroke();
138
+ }
@@ -47,6 +47,20 @@ export function parseColor(abgr: number): IParsedColor {
47
47
  return { isWhite: false, a, r, g, b };
48
48
  }
49
49
 
50
+ /**
51
+ * Extract color components
52
+ */
53
+ export function parseColorRgba(rgba: number): IParsedColor {
54
+ if (rgba === 0xffffffff) {
55
+ return WHITE;
56
+ }
57
+ const r = (rgba >>> 24) & 0xff;
58
+ const g = (rgba >>> 16) & 0xff & 0xff;
59
+ const b = (rgba >>> 8) & 0xff & 0xff;
60
+ const a = (rgba & 0xff & 0xff) / 255;
61
+ return { isWhite: false, r, g, b, a };
62
+ }
63
+
50
64
  /**
51
65
  * Format a parsed color into a rgba CSS color
52
66
  */
@@ -27,9 +27,9 @@ export class UnsupportedShader extends CoreShader {
27
27
  constructor(shType: string) {
28
28
  super();
29
29
  this.shType = shType;
30
- if (shType !== ROUNDED_RECTANGLE_SHADER_TYPE) {
31
- console.warn('Unsupported shader:', shType);
32
- }
30
+ // if (shType !== ROUNDED_RECTANGLE_SHADER_TYPE) {
31
+ // console.warn('Unsupported shader:', shType);
32
+ // }
33
33
  }
34
34
 
35
35
  bindRenderOp(): void {
@@ -34,6 +34,12 @@ export class WebGlCoreCtxSubTexture extends WebGlCoreCtxTexture {
34
34
 
35
35
  override async onLoadRequest(): Promise<Dimensions> {
36
36
  const props = await (this.textureSource as SubTexture).getTextureData();
37
+
38
+ if (props.data instanceof Uint8Array) {
39
+ // its a 1x1 Color Texture
40
+ return { width: 1, height: 1 };
41
+ }
42
+
37
43
  return {
38
44
  width: props.data?.width || 0,
39
45
  height: props.data?.height || 0,
@@ -88,7 +88,10 @@ export class WebGlCoreCtxTexture extends CoreContextTexture {
88
88
  this._nativeCtxTexture = this.createNativeCtxTexture();
89
89
  if (this._nativeCtxTexture === null) {
90
90
  this._state = 'failed';
91
- this.textureSource.setState('failed', new Error('Could not create WebGL Texture'));
91
+ this.textureSource.setState(
92
+ 'failed',
93
+ new Error('Could not create WebGL Texture'),
94
+ );
92
95
  console.error('Could not create WebGL Texture');
93
96
  return;
94
97
  }
@@ -201,6 +204,29 @@ export class WebGlCoreCtxTexture extends CoreContextTexture {
201
204
  glw.texParameteri(glw.TEXTURE_MIN_FILTER, glw.LINEAR);
202
205
 
203
206
  this.setTextureMemUse(view.byteLength);
207
+ } else if (textureData.data && textureData.data instanceof Uint8Array) {
208
+ // Color Texture
209
+ width = 1;
210
+ height = 1;
211
+
212
+ glw.bindTexture(this._nativeCtxTexture);
213
+ glw.pixelStorei(
214
+ glw.UNPACK_PREMULTIPLY_ALPHA_WEBGL,
215
+ !!textureData.premultiplyAlpha,
216
+ );
217
+
218
+ glw.texImage2D(
219
+ 0,
220
+ glw.RGBA,
221
+ width,
222
+ height,
223
+ 0,
224
+ glw.RGBA,
225
+ glw.UNSIGNED_BYTE,
226
+ textureData.data,
227
+ );
228
+
229
+ this.setTextureMemUse(width * height * 4);
204
230
  } else {
205
231
  console.error(
206
232
  `WebGlCoreCtxTexture.onLoadRequest: Unexpected textureData returned`,