@luma.gl/core 9.0.0-alpha.9 → 9.0.0-beta.2

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 (306) hide show
  1. package/LICENSE +3 -1
  2. package/README.md +4 -4
  3. package/dist/adapter/attribute-utils/get-attribute-from-layouts.d.ts +52 -0
  4. package/dist/adapter/attribute-utils/get-attribute-from-layouts.d.ts.map +1 -0
  5. package/dist/adapter/attribute-utils/get-attribute-from-layouts.js +130 -0
  6. package/dist/adapter/attribute-utils/get-attribute-from-layouts.js.map +1 -0
  7. package/dist/adapter/canvas-context.d.ts +109 -0
  8. package/dist/adapter/canvas-context.d.ts.map +1 -0
  9. package/dist/adapter/canvas-context.js +254 -0
  10. package/dist/adapter/canvas-context.js.map +1 -0
  11. package/dist/adapter/device.d.ts +219 -0
  12. package/dist/adapter/device.d.ts.map +1 -0
  13. package/dist/adapter/device.js +99 -0
  14. package/dist/adapter/device.js.map +1 -0
  15. package/dist/adapter/resources/buffer.d.ts +56 -0
  16. package/dist/adapter/resources/buffer.d.ts.map +1 -0
  17. package/dist/adapter/resources/buffer.js +62 -0
  18. package/dist/adapter/resources/buffer.js.map +1 -0
  19. package/dist/adapter/resources/command-buffer.d.ts +12 -0
  20. package/dist/adapter/resources/command-buffer.d.ts.map +1 -0
  21. package/dist/adapter/resources/command-buffer.js +15 -0
  22. package/dist/adapter/resources/command-buffer.js.map +1 -0
  23. package/dist/adapter/resources/command-encoder.d.ts +113 -0
  24. package/dist/adapter/resources/command-encoder.d.ts.map +1 -0
  25. package/dist/adapter/resources/command-encoder.js +19 -0
  26. package/dist/adapter/resources/command-encoder.js.map +1 -0
  27. package/dist/adapter/resources/compute-pass.d.ts +31 -0
  28. package/dist/adapter/resources/compute-pass.d.ts.map +1 -0
  29. package/dist/adapter/resources/compute-pass.js +15 -0
  30. package/dist/adapter/resources/compute-pass.js.map +1 -0
  31. package/dist/adapter/resources/compute-pipeline.d.ts +24 -0
  32. package/dist/adapter/resources/compute-pipeline.d.ts.map +1 -0
  33. package/dist/adapter/resources/compute-pipeline.js +20 -0
  34. package/dist/adapter/resources/compute-pipeline.js.map +1 -0
  35. package/dist/adapter/resources/external-texture.d.ts +12 -0
  36. package/dist/adapter/resources/external-texture.d.ts.map +1 -0
  37. package/dist/adapter/resources/external-texture.js +17 -0
  38. package/dist/adapter/resources/external-texture.js.map +1 -0
  39. package/dist/adapter/resources/framebuffer.d.ts +50 -0
  40. package/dist/adapter/resources/framebuffer.d.ts.map +1 -0
  41. package/dist/adapter/resources/framebuffer.js +102 -0
  42. package/dist/adapter/resources/framebuffer.js.map +1 -0
  43. package/dist/adapter/resources/render-pass.d.ts +51 -0
  44. package/dist/adapter/resources/render-pass.d.ts.map +1 -0
  45. package/dist/adapter/resources/render-pass.js +23 -0
  46. package/dist/adapter/resources/render-pass.js.map +1 -0
  47. package/dist/adapter/resources/render-pipeline.d.ts +89 -0
  48. package/dist/adapter/resources/render-pipeline.d.ts.map +1 -0
  49. package/dist/adapter/resources/render-pipeline.js +36 -0
  50. package/dist/adapter/resources/render-pipeline.js.map +1 -0
  51. package/dist/adapter/resources/resource.d.ts +73 -0
  52. package/dist/adapter/resources/resource.d.ts.map +1 -0
  53. package/dist/adapter/resources/resource.js +101 -0
  54. package/dist/adapter/resources/resource.js.map +1 -0
  55. package/dist/adapter/resources/sampler.d.ts +42 -0
  56. package/dist/adapter/resources/sampler.d.ts.map +1 -0
  57. package/dist/adapter/resources/sampler.js +26 -0
  58. package/dist/adapter/resources/sampler.js.map +1 -0
  59. package/dist/adapter/resources/shader.d.ts +45 -0
  60. package/dist/adapter/resources/shader.d.ts.map +1 -0
  61. package/dist/adapter/resources/shader.js +90 -0
  62. package/dist/adapter/resources/shader.js.map +1 -0
  63. package/dist/adapter/resources/texture.d.ts +90 -0
  64. package/dist/adapter/resources/texture.d.ts.map +1 -0
  65. package/dist/adapter/resources/texture.js +45 -0
  66. package/dist/adapter/resources/texture.js.map +1 -0
  67. package/dist/adapter/resources/transform-feedback.d.ts +30 -0
  68. package/dist/adapter/resources/transform-feedback.d.ts.map +1 -0
  69. package/dist/adapter/resources/transform-feedback.js +17 -0
  70. package/dist/adapter/resources/transform-feedback.js.map +1 -0
  71. package/dist/adapter/resources/vertex-array.d.ts +40 -0
  72. package/dist/adapter/resources/vertex-array.d.ts.map +1 -0
  73. package/dist/adapter/resources/vertex-array.js +24 -0
  74. package/dist/adapter/resources/vertex-array.js.map +1 -0
  75. package/dist/adapter/type-utils/decode-attribute-type.d.ts +20 -0
  76. package/dist/adapter/type-utils/decode-attribute-type.d.ts.map +1 -0
  77. package/dist/adapter/type-utils/decode-attribute-type.js +60 -0
  78. package/dist/adapter/type-utils/decode-attribute-type.js.map +1 -0
  79. package/dist/adapter/type-utils/decode-data-type.d.ts +16 -0
  80. package/dist/adapter/type-utils/decode-data-type.d.ts.map +1 -0
  81. package/dist/adapter/type-utils/decode-data-type.js +43 -0
  82. package/dist/adapter/type-utils/decode-data-type.js.map +1 -0
  83. package/dist/adapter/type-utils/decode-shader-types.d.ts +9 -0
  84. package/dist/adapter/type-utils/decode-shader-types.d.ts.map +1 -0
  85. package/dist/adapter/type-utils/decode-shader-types.js +103 -0
  86. package/dist/adapter/type-utils/decode-shader-types.js.map +1 -0
  87. package/dist/adapter/type-utils/decode-texture-format.d.ts +19 -0
  88. package/dist/adapter/type-utils/decode-texture-format.d.ts.map +1 -0
  89. package/dist/adapter/type-utils/decode-texture-format.js +101 -0
  90. package/dist/adapter/type-utils/decode-texture-format.js.map +1 -0
  91. package/dist/adapter/type-utils/decode-vertex-format.d.ts +22 -0
  92. package/dist/adapter/type-utils/decode-vertex-format.d.ts.map +1 -0
  93. package/dist/adapter/type-utils/decode-vertex-format.js +25 -0
  94. package/dist/adapter/type-utils/decode-vertex-format.js.map +1 -0
  95. package/dist/adapter/type-utils/vertex-format-from-attribute.d.ts +10 -0
  96. package/dist/adapter/type-utils/vertex-format-from-attribute.d.ts.map +1 -0
  97. package/dist/adapter/type-utils/vertex-format-from-attribute.js +76 -0
  98. package/dist/adapter/type-utils/vertex-format-from-attribute.js.map +1 -0
  99. package/dist/adapter/type-utils/wgsl-utils.d.ts +4 -0
  100. package/dist/adapter/type-utils/wgsl-utils.d.ts.map +1 -0
  101. package/dist/adapter/type-utils/wgsl-utils.js +15 -0
  102. package/dist/adapter/type-utils/wgsl-utils.js.map +1 -0
  103. package/dist/adapter/types/accessor.d.ts +23 -0
  104. package/dist/adapter/types/accessor.d.ts.map +1 -0
  105. package/dist/adapter/types/accessor.js +2 -0
  106. package/dist/adapter/types/accessor.js.map +1 -0
  107. package/dist/adapter/types/buffer-layout.d.ts +59 -0
  108. package/dist/adapter/types/buffer-layout.d.ts.map +1 -0
  109. package/dist/adapter/types/buffer-layout.js +2 -0
  110. package/dist/adapter/types/buffer-layout.js.map +1 -0
  111. package/dist/adapter/types/parameters.d.ts +97 -0
  112. package/dist/adapter/types/parameters.d.ts.map +1 -0
  113. package/dist/adapter/types/parameters.js +28 -0
  114. package/dist/adapter/types/parameters.js.map +1 -0
  115. package/dist/adapter/types/shader-layout.d.ts +145 -0
  116. package/dist/adapter/types/shader-layout.d.ts.map +1 -0
  117. package/dist/adapter/types/shader-layout.js +2 -0
  118. package/dist/adapter/types/shader-layout.js.map +1 -0
  119. package/dist/adapter/types/shader-types.d.ts +21 -0
  120. package/dist/adapter/types/shader-types.d.ts.map +1 -0
  121. package/dist/adapter/types/shader-types.js +2 -0
  122. package/dist/adapter/types/shader-types.js.map +1 -0
  123. package/dist/adapter/types/texture-formats.d.ts +12 -0
  124. package/dist/adapter/types/texture-formats.d.ts.map +1 -0
  125. package/dist/adapter/types/texture-formats.js +2 -0
  126. package/dist/adapter/types/texture-formats.js.map +1 -0
  127. package/dist/adapter/types/types.d.ts +90 -0
  128. package/dist/adapter/types/types.d.ts.map +1 -0
  129. package/dist/adapter/types/types.js +2 -0
  130. package/dist/adapter/types/types.js.map +1 -0
  131. package/dist/adapter/types/vertex-formats.d.ts +14 -0
  132. package/dist/adapter/types/vertex-formats.d.ts.map +1 -0
  133. package/dist/adapter/types/vertex-formats.js +2 -0
  134. package/dist/adapter/types/vertex-formats.js.map +1 -0
  135. package/dist/dist.dev.js +2976 -0
  136. package/dist/index.cjs +2445 -0
  137. package/dist/index.d.ts +81 -128
  138. package/dist/index.d.ts.map +1 -1
  139. package/dist/index.js +45 -18
  140. package/dist/index.js.map +1 -1
  141. package/dist/init.d.ts +5 -0
  142. package/dist/init.d.ts.map +1 -0
  143. package/dist/init.js +24 -0
  144. package/dist/init.js.map +1 -0
  145. package/dist/lib/compiler-log/compiler-message.d.ts +8 -0
  146. package/dist/lib/compiler-log/compiler-message.d.ts.map +1 -0
  147. package/dist/lib/compiler-log/compiler-message.js +2 -0
  148. package/dist/lib/compiler-log/compiler-message.js.map +1 -0
  149. package/dist/lib/compiler-log/format-compiler-log.d.ts +8 -0
  150. package/dist/lib/compiler-log/format-compiler-log.d.ts.map +1 -0
  151. package/dist/lib/compiler-log/format-compiler-log.js +64 -0
  152. package/dist/lib/compiler-log/format-compiler-log.js.map +1 -0
  153. package/dist/lib/compiler-log/get-shader-info.d.ts +9 -0
  154. package/dist/lib/compiler-log/get-shader-info.d.ts.map +1 -0
  155. package/dist/lib/compiler-log/get-shader-info.js +25 -0
  156. package/dist/lib/compiler-log/get-shader-info.js.map +1 -0
  157. package/dist/lib/luma.d.ts +22 -0
  158. package/dist/lib/luma.d.ts.map +1 -0
  159. package/dist/lib/luma.js +63 -0
  160. package/dist/lib/luma.js.map +1 -0
  161. package/dist/lib/uniforms/uniform-block.d.ts +29 -0
  162. package/dist/lib/uniforms/uniform-block.d.ts.map +1 -0
  163. package/dist/lib/uniforms/uniform-block.js +48 -0
  164. package/dist/lib/uniforms/uniform-block.js.map +1 -0
  165. package/dist/lib/uniforms/uniform-buffer-layout.d.ts +27 -0
  166. package/dist/lib/uniforms/uniform-buffer-layout.d.ts.map +1 -0
  167. package/dist/lib/uniforms/uniform-buffer-layout.js +76 -0
  168. package/dist/lib/uniforms/uniform-buffer-layout.js.map +1 -0
  169. package/dist/lib/uniforms/uniform-store.d.ts +62 -0
  170. package/dist/lib/uniforms/uniform-store.d.ts.map +1 -0
  171. package/dist/lib/uniforms/uniform-store.js +89 -0
  172. package/dist/lib/uniforms/uniform-store.js.map +1 -0
  173. package/dist/lib/uniforms/uniform.d.ts +10 -0
  174. package/dist/lib/uniforms/uniform.d.ts.map +1 -0
  175. package/dist/lib/uniforms/uniform.js +20 -0
  176. package/dist/lib/uniforms/uniform.js.map +1 -0
  177. package/dist/types.d.ts +19 -0
  178. package/dist/types.d.ts.map +1 -0
  179. package/dist/types.js +3 -0
  180. package/dist/types.js.map +1 -0
  181. package/dist/utils/array-equal.d.ts +5 -0
  182. package/dist/utils/array-equal.d.ts.map +1 -0
  183. package/dist/utils/array-equal.js +28 -0
  184. package/dist/utils/array-equal.js.map +1 -0
  185. package/dist/utils/array-utils-flat.d.ts +10 -0
  186. package/dist/utils/array-utils-flat.d.ts.map +1 -0
  187. package/dist/utils/array-utils-flat.js +36 -0
  188. package/dist/utils/array-utils-flat.js.map +1 -0
  189. package/dist/utils/assert.d.ts +2 -0
  190. package/dist/utils/assert.d.ts.map +1 -0
  191. package/dist/utils/assert.js +6 -0
  192. package/dist/utils/assert.js.map +1 -0
  193. package/dist/utils/cast.d.ts +3 -0
  194. package/dist/utils/cast.d.ts.map +1 -0
  195. package/dist/utils/cast.js +4 -0
  196. package/dist/utils/cast.js.map +1 -0
  197. package/dist/utils/check-props.d.ts +7 -0
  198. package/dist/utils/check-props.d.ts.map +1 -0
  199. package/dist/utils/check-props.js +32 -0
  200. package/dist/utils/check-props.js.map +1 -0
  201. package/dist/utils/deep-equal.d.ts +9 -0
  202. package/dist/utils/deep-equal.d.ts.map +1 -0
  203. package/dist/utils/deep-equal.js +40 -0
  204. package/dist/utils/deep-equal.js.map +1 -0
  205. package/dist/utils/format-value.d.ts +7 -0
  206. package/dist/utils/format-value.d.ts.map +1 -0
  207. package/dist/utils/format-value.js +42 -0
  208. package/dist/utils/format-value.js.map +1 -0
  209. package/dist/utils/is-array.d.ts +16 -0
  210. package/dist/utils/is-array.d.ts.map +1 -0
  211. package/dist/utils/is-array.js +10 -0
  212. package/dist/utils/is-array.js.map +1 -0
  213. package/dist/utils/load-file.d.ts +35 -0
  214. package/dist/utils/load-file.d.ts.map +1 -0
  215. package/dist/utils/load-file.js +48 -0
  216. package/dist/utils/load-file.js.map +1 -0
  217. package/dist/utils/log.d.ts +4 -0
  218. package/dist/utils/log.d.ts.map +1 -0
  219. package/dist/utils/log.js +5 -0
  220. package/dist/utils/log.js.map +1 -0
  221. package/dist/utils/random.d.ts +5 -0
  222. package/dist/utils/random.d.ts.map +1 -0
  223. package/dist/utils/random.js +14 -0
  224. package/dist/utils/random.js.map +1 -0
  225. package/dist/utils/request-animation-frame.d.ts +3 -0
  226. package/dist/utils/request-animation-frame.d.ts.map +1 -0
  227. package/dist/utils/request-animation-frame.js +7 -0
  228. package/dist/utils/request-animation-frame.js.map +1 -0
  229. package/dist/utils/stats-manager.d.ts +12 -0
  230. package/dist/utils/stats-manager.d.ts.map +1 -0
  231. package/dist/utils/stats-manager.js +19 -0
  232. package/dist/utils/stats-manager.js.map +1 -0
  233. package/dist/utils/stub-methods.d.ts +2 -0
  234. package/dist/utils/stub-methods.d.ts.map +1 -0
  235. package/dist/utils/stub-methods.js +16 -0
  236. package/dist/utils/stub-methods.js.map +1 -0
  237. package/dist/utils/utils.d.ts +15 -0
  238. package/dist/utils/utils.d.ts.map +1 -0
  239. package/dist/utils/utils.js +19 -0
  240. package/dist/utils/utils.js.map +1 -0
  241. package/dist.min.js +33 -0
  242. package/package.json +17 -12
  243. package/src/adapter/attribute-utils/get-attribute-from-layouts.ts +259 -0
  244. package/src/adapter/canvas-context.ts +433 -0
  245. package/src/adapter/device.ts +435 -0
  246. package/src/adapter/resources/buffer.ts +106 -0
  247. package/src/adapter/resources/command-buffer.ts +38 -0
  248. package/src/adapter/resources/command-encoder.ts +172 -0
  249. package/src/adapter/resources/compute-pass.ts +52 -0
  250. package/src/adapter/resources/compute-pipeline.ts +39 -0
  251. package/src/adapter/resources/external-texture.ts +20 -0
  252. package/src/adapter/resources/framebuffer.ts +230 -0
  253. package/src/adapter/resources/render-pass.ts +117 -0
  254. package/src/adapter/resources/render-pipeline.ts +133 -0
  255. package/src/adapter/resources/resource.ts +176 -0
  256. package/src/adapter/resources/sampler.ts +69 -0
  257. package/src/adapter/resources/shader.ts +143 -0
  258. package/src/adapter/resources/texture.ts +140 -0
  259. package/src/adapter/resources/transform-feedback.ts +45 -0
  260. package/src/adapter/resources/vertex-array.ts +65 -0
  261. package/src/adapter/type-utils/decode-attribute-type.ts +82 -0
  262. package/src/adapter/type-utils/decode-data-type.ts +62 -0
  263. package/src/adapter/type-utils/decode-shader-types.ts +48 -0
  264. package/src/adapter/type-utils/decode-texture-format.ts +190 -0
  265. package/src/adapter/type-utils/decode-vertex-format.ts +49 -0
  266. package/src/adapter/type-utils/vertex-format-from-attribute.ts +103 -0
  267. package/src/adapter/type-utils/wgsl-utils.ts +18 -0
  268. package/src/adapter/types/accessor.ts +34 -0
  269. package/src/adapter/types/buffer-layout.ts +62 -0
  270. package/src/adapter/types/parameters.ts +250 -0
  271. package/src/adapter/types/shader-layout.ts +193 -0
  272. package/src/adapter/types/shader-types.ts +77 -0
  273. package/src/adapter/types/texture-formats.ts +168 -0
  274. package/src/adapter/types/types.ts +109 -0
  275. package/src/adapter/types/vertex-formats.ts +91 -0
  276. package/src/index.ts +160 -92
  277. package/src/init.ts +47 -0
  278. package/src/lib/compiler-log/compiler-message.ts +10 -0
  279. package/src/lib/compiler-log/format-compiler-log.ts +113 -0
  280. package/src/lib/compiler-log/get-shader-info.ts +41 -0
  281. package/src/lib/luma.ts +84 -0
  282. package/src/lib/uniforms/uniform-block.ts +80 -0
  283. package/src/lib/uniforms/uniform-buffer-layout.ts +109 -0
  284. package/src/lib/uniforms/uniform-store.ts +173 -0
  285. package/src/lib/uniforms/uniform.ts +25 -0
  286. package/src/types.ts +33 -0
  287. package/src/utils/array-equal.ts +33 -0
  288. package/src/utils/array-utils-flat.ts +43 -0
  289. package/src/utils/assert.ts +7 -0
  290. package/src/utils/cast.ts +4 -0
  291. package/src/utils/check-props.ts +74 -0
  292. package/src/utils/deep-equal.ts +47 -0
  293. package/src/utils/format-value.ts +40 -0
  294. package/src/utils/is-array.ts +24 -0
  295. package/src/utils/load-file.ts +89 -0
  296. package/src/utils/log.ts +4 -0
  297. package/src/utils/random.ts +17 -0
  298. package/src/utils/request-animation-frame.ts +15 -0
  299. package/src/utils/stats-manager.ts +23 -0
  300. package/src/utils/stub-methods.ts +20 -0
  301. package/src/utils/utils.ts +36 -0
  302. package/dist/bundle.d.ts +0 -2
  303. package/dist/bundle.d.ts.map +0 -1
  304. package/dist/bundle.js +0 -5
  305. package/dist/bundle.js.map +0 -1
  306. package/src/bundle.ts +0 -4
package/dist/index.cjs ADDED
@@ -0,0 +1,2445 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __export = (target, all) => {
8
+ for (var name2 in all)
9
+ __defProp(target, name2, { get: all[name2], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var __publicField = (obj, key, value) => {
21
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
22
+ return value;
23
+ };
24
+
25
+ // src/index.ts
26
+ var src_exports = {};
27
+ __export(src_exports, {
28
+ Buffer: () => Buffer2,
29
+ CanvasContext: () => CanvasContext,
30
+ CommandBuffer: () => CommandBuffer,
31
+ CommandEncoder: () => CommandEncoder,
32
+ ComputePass: () => ComputePass,
33
+ ComputePipeline: () => ComputePipeline,
34
+ Device: () => Device,
35
+ ExternalTexture: () => ExternalTexture,
36
+ Framebuffer: () => Framebuffer,
37
+ RenderPass: () => RenderPass,
38
+ RenderPipeline: () => RenderPipeline,
39
+ Resource: () => Resource,
40
+ Sampler: () => Sampler,
41
+ Shader: () => Shader,
42
+ StatsManager: () => StatsManager,
43
+ Texture: () => Texture,
44
+ TransformFeedback: () => TransformFeedback,
45
+ UniformBlock: () => UniformBlock,
46
+ UniformBufferLayout: () => UniformBufferLayout,
47
+ UniformStore: () => UniformStore,
48
+ VERSION: () => VERSION,
49
+ VertexArray: () => VertexArray,
50
+ assert: () => assert,
51
+ cancelAnimationFrame: () => cancelAnimationFrame,
52
+ cast: () => cast,
53
+ checkProps: () => checkProps,
54
+ decodeShaderAttributeType: () => decodeShaderAttributeType,
55
+ decodeShaderUniformType: () => decodeShaderUniformType,
56
+ decodeTextureFormat: () => decodeTextureFormat,
57
+ decodeVertexFormat: () => decodeVertexFormat,
58
+ deepEqual: () => deepEqual,
59
+ fillArray: () => fillArray,
60
+ formatCompilerLog: () => formatCompilerLog,
61
+ formatValue: () => formatValue,
62
+ getAttributeInfosFromLayouts: () => getAttributeInfosFromLayouts,
63
+ getDataTypeFromTypedArray: () => getDataTypeFromTypedArray,
64
+ getScratchArray: () => getScratchArray,
65
+ getScratchArrayBuffer: () => getScratchArrayBuffer,
66
+ getTypedArrayFromDataType: () => getTypedArrayFromDataType,
67
+ getVertexFormatFromAttribute: () => getVertexFormatFromAttribute,
68
+ glsl: () => glsl,
69
+ isNumberArray: () => isNumberArray,
70
+ isObjectEmpty: () => isObjectEmpty,
71
+ isPowerOfTwo: () => isPowerOfTwo,
72
+ isTypedArray: () => isTypedArray,
73
+ isUniformValue: () => isUniformValue,
74
+ loadFile: () => loadFile,
75
+ loadImage: () => loadImage,
76
+ loadImageBitmap: () => loadImageBitmap,
77
+ loadScript: () => loadScript,
78
+ log: () => log,
79
+ luma: () => luma,
80
+ makeRandomNumberGenerator: () => makeRandomNumberGenerator,
81
+ mergeShaderLayout: () => mergeShaderLayout,
82
+ random: () => random,
83
+ requestAnimationFrame: () => requestAnimationFrame,
84
+ setPathPrefix: () => setPathPrefix,
85
+ splitUniformsAndBindings: () => splitUniformsAndBindings,
86
+ stubRemovedMethods: () => stubRemovedMethods,
87
+ uid: () => uid
88
+ });
89
+ module.exports = __toCommonJS(src_exports);
90
+
91
+ // src/init.ts
92
+ var import_env = require("@probe.gl/env");
93
+
94
+ // src/utils/log.ts
95
+ var import_log = require("@probe.gl/log");
96
+ var log = new import_log.Log({ id: "luma.gl" });
97
+
98
+ // src/utils/stats-manager.ts
99
+ var import_stats = require("@probe.gl/stats");
100
+ var StatsManager = class {
101
+ stats = /* @__PURE__ */ new Map();
102
+ getStats(name2) {
103
+ return this.get(name2);
104
+ }
105
+ get(name2) {
106
+ if (!this.stats.has(name2)) {
107
+ this.stats.set(name2, new import_stats.Stats({ id: name2 }));
108
+ }
109
+ return this.stats.get(name2);
110
+ }
111
+ };
112
+ var lumaStats = new StatsManager();
113
+
114
+ // src/init.ts
115
+ function initializeLuma() {
116
+ const VERSION2 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "running from source";
117
+ const STARTUP_MESSAGE = "set luma.log.level=1 (or higher) to trace rendering";
118
+ if (globalThis.luma && globalThis.luma.VERSION !== VERSION2) {
119
+ throw new Error(`luma.gl - multiple VERSIONs detected: ${globalThis.luma.VERSION} vs ${VERSION2}`);
120
+ }
121
+ if (!globalThis.luma) {
122
+ if ((0, import_env.isBrowser)()) {
123
+ log.log(1, `${VERSION2} - ${STARTUP_MESSAGE}`)();
124
+ }
125
+ globalThis.luma = globalThis.luma || {
126
+ VERSION: VERSION2,
127
+ version: VERSION2,
128
+ log,
129
+ // A global stats object that various components can add information to
130
+ // E.g. see webgl/resource.js
131
+ stats: lumaStats
132
+ };
133
+ }
134
+ return VERSION2;
135
+ }
136
+ var VERSION = initializeLuma();
137
+
138
+ // src/utils/is-array.ts
139
+ function isTypedArray(value) {
140
+ return ArrayBuffer.isView(value) && !(value instanceof DataView) ? value : null;
141
+ }
142
+ function isNumberArray(value) {
143
+ if (Array.isArray(value)) {
144
+ return value.length === 0 || typeof value[0] === "number" ? value : null;
145
+ }
146
+ return isTypedArray(value);
147
+ }
148
+
149
+ // src/utils/utils.ts
150
+ var uidCounters = {};
151
+ function uid(id = "id") {
152
+ uidCounters[id] = uidCounters[id] || 1;
153
+ const count = uidCounters[id]++;
154
+ return `${id}-${count}`;
155
+ }
156
+ function isPowerOfTwo(n) {
157
+ return n > 0 && (n & n - 1) === 0;
158
+ }
159
+ function isObjectEmpty(obj) {
160
+ let isEmpty = true;
161
+ for (const key in obj) {
162
+ isEmpty = false;
163
+ break;
164
+ }
165
+ return isEmpty;
166
+ }
167
+
168
+ // src/adapter/resources/resource.ts
169
+ var Resource = class {
170
+ /** props.id, for debugging. */
171
+ id;
172
+ props;
173
+ userData = {};
174
+ _device;
175
+ /** Whether this resource has been destroyed */
176
+ destroyed = false;
177
+ /** For resources that allocate GPU memory */
178
+ allocatedBytes = 0;
179
+ /** Attached resources will be destroyed when this resource is destroyed. Tracks auto-created "sub" resources. */
180
+ _attachedResources = /* @__PURE__ */ new Set();
181
+ /**
182
+ * Create a new Resource. Called from Subclass
183
+ */
184
+ constructor(device, props, defaultProps) {
185
+ if (!device) {
186
+ throw new Error("no device");
187
+ }
188
+ this._device = device;
189
+ this.props = selectivelyMerge(props, defaultProps);
190
+ const id = this.props.id !== "undefined" ? this.props.id : uid(this[Symbol.toStringTag]);
191
+ this.props.id = id;
192
+ this.id = id;
193
+ this.userData = this.props.userData || {};
194
+ this.addStats();
195
+ }
196
+ /**
197
+ * destroy can be called on any resource to release it before it is garbage collected.
198
+ */
199
+ destroy() {
200
+ this.destroyResource();
201
+ }
202
+ /** @deprecated Use destroy() */
203
+ delete() {
204
+ this.destroy();
205
+ return this;
206
+ }
207
+ toString() {
208
+ return `${this[Symbol.toStringTag] || this.constructor.name}(${this.id})`;
209
+ }
210
+ /**
211
+ * Combines a map of user props and default props, only including props from defaultProps
212
+ * @returns returns a map of overridden default props
213
+ */
214
+ getProps() {
215
+ return this.props;
216
+ }
217
+ // ATTACHED RESOURCES
218
+ /**
219
+ * Attaches a resource. Attached resources are auto destroyed when this resource is destroyed
220
+ * Called automatically when sub resources are auto created but can be called by application
221
+ */
222
+ attachResource(resource) {
223
+ this._attachedResources.add(resource);
224
+ }
225
+ /**
226
+ * Detach an attached resource. The resource will no longer be auto-destroyed when this resource is destroyed.
227
+ */
228
+ detachResource(resource) {
229
+ this._attachedResources.delete(resource);
230
+ }
231
+ /**
232
+ * Destroys a resource (only if owned), and removes from the owned (auto-destroy) list for this resource.
233
+ */
234
+ destroyAttachedResource(resource) {
235
+ if (this._attachedResources.delete(resource)) {
236
+ resource.destroy();
237
+ }
238
+ }
239
+ /** Destroy all owned resources. Make sure the resources are no longer needed before calling. */
240
+ destroyAttachedResources() {
241
+ for (const resource of Object.values(this._attachedResources)) {
242
+ resource.destroy();
243
+ }
244
+ this._attachedResources = /* @__PURE__ */ new Set();
245
+ }
246
+ // PROTECTED METHODS
247
+ /** Perform all destroy steps. Can be called by derived resources when overriding destroy() */
248
+ destroyResource() {
249
+ this.destroyAttachedResources();
250
+ this.removeStats();
251
+ this.destroyed = true;
252
+ }
253
+ /** Called by .destroy() to track object destruction. Subclass must call if overriding destroy() */
254
+ removeStats() {
255
+ const stats = this._device.statsManager.getStats("Resource Counts");
256
+ const name2 = this[Symbol.toStringTag];
257
+ stats.get(`${name2}s Active`).decrementCount();
258
+ }
259
+ /** Called by subclass to track memory allocations */
260
+ trackAllocatedMemory(bytes, name2 = this[Symbol.toStringTag]) {
261
+ const stats = this._device.statsManager.getStats("Resource Counts");
262
+ stats.get("GPU Memory").addCount(bytes);
263
+ stats.get(`${name2} Memory`).addCount(bytes);
264
+ this.allocatedBytes = bytes;
265
+ }
266
+ /** Called by subclass to track memory deallocations */
267
+ trackDeallocatedMemory(name2 = this[Symbol.toStringTag]) {
268
+ const stats = this._device.statsManager.getStats("Resource Counts");
269
+ stats.get("GPU Memory").subtractCount(this.allocatedBytes);
270
+ stats.get(`${name2} Memory`).subtractCount(this.allocatedBytes);
271
+ this.allocatedBytes = 0;
272
+ }
273
+ /** Called by resource constructor to track object creation */
274
+ addStats() {
275
+ const stats = this._device.statsManager.getStats("Resource Counts");
276
+ const name2 = this[Symbol.toStringTag];
277
+ stats.get("Resources Created").incrementCount();
278
+ stats.get(`${name2}s Created`).incrementCount();
279
+ stats.get(`${name2}s Active`).incrementCount();
280
+ }
281
+ };
282
+ /** Default properties for resource */
283
+ __publicField(Resource, "defaultProps", {
284
+ id: "undefined",
285
+ handle: void 0,
286
+ userData: void 0
287
+ });
288
+ function selectivelyMerge(props, defaultProps) {
289
+ const mergedProps = { ...defaultProps };
290
+ for (const key in props) {
291
+ if (props[key] !== void 0) {
292
+ mergedProps[key] = props[key];
293
+ }
294
+ }
295
+ return mergedProps;
296
+ }
297
+
298
+ // src/adapter/resources/buffer.ts
299
+ var _Buffer = class extends Resource {
300
+ get [Symbol.toStringTag]() {
301
+ return "Buffer";
302
+ }
303
+ /** The usage with which this buffer was created */
304
+ usage;
305
+ /** For index buffers, whether indices are 16 or 32 bit */
306
+ indexType;
307
+ constructor(device, props) {
308
+ const deducedProps = { ...props };
309
+ if ((props.usage || 0) & _Buffer.INDEX && !props.indexType) {
310
+ if (props.data instanceof Uint32Array) {
311
+ deducedProps.indexType = "uint32";
312
+ } else if (props.data instanceof Uint16Array) {
313
+ deducedProps.indexType = "uint16";
314
+ }
315
+ }
316
+ super(device, deducedProps, _Buffer.defaultProps);
317
+ this.usage = props.usage || 0;
318
+ this.indexType = deducedProps.indexType;
319
+ }
320
+ /** Read data synchronously. @note WebGL2 only */
321
+ readSyncWebGL2(byteOffset, byteLength) {
322
+ throw new Error("not implemented");
323
+ }
324
+ /** A partial CPU-side copy of the data in this buffer, for debugging purposes */
325
+ debugData = new ArrayBuffer(0);
326
+ /** This doesn't handle partial non-zero offset updates correctly */
327
+ _setDebugData(data, byteOffset, byteLength) {
328
+ const buffer = ArrayBuffer.isView(data) ? data.buffer : data;
329
+ const debugDataLength = Math.min(data ? data.byteLength : byteLength, _Buffer.DEBUG_DATA_MAX_LENGTH);
330
+ if (data === null) {
331
+ this.debugData = new ArrayBuffer(debugDataLength);
332
+ } else if (byteOffset === 0 && byteLength === data.byteLength) {
333
+ this.debugData = buffer.slice(0, debugDataLength);
334
+ } else {
335
+ this.debugData = buffer.slice(byteOffset, byteOffset + debugDataLength);
336
+ }
337
+ }
338
+ };
339
+ var Buffer2 = _Buffer;
340
+ __publicField(Buffer2, "defaultProps", {
341
+ ...Resource.defaultProps,
342
+ usage: 0,
343
+ // Buffer.COPY_DST | Buffer.COPY_SRC
344
+ byteLength: 0,
345
+ byteOffset: 0,
346
+ data: null,
347
+ indexType: "uint16",
348
+ mappedAtCreation: false
349
+ });
350
+ // Usage Flags
351
+ __publicField(Buffer2, "MAP_READ", 1);
352
+ __publicField(Buffer2, "MAP_WRITE", 2);
353
+ __publicField(Buffer2, "COPY_SRC", 4);
354
+ __publicField(Buffer2, "COPY_DST", 8);
355
+ /** Index buffer */
356
+ __publicField(Buffer2, "INDEX", 16);
357
+ /** Vertex buffer */
358
+ __publicField(Buffer2, "VERTEX", 32);
359
+ /** Uniform buffer */
360
+ __publicField(Buffer2, "UNIFORM", 64);
361
+ /** Storage buffer */
362
+ __publicField(Buffer2, "STORAGE", 128);
363
+ __publicField(Buffer2, "INDIRECT", 256);
364
+ __publicField(Buffer2, "QUERY_RESOLVE", 512);
365
+ // PROTECTED METHODS (INTENDED FOR USE BY OTHER FRAMEWORK CODE ONLY)
366
+ /** Max amount of debug data saved. Two vec4's */
367
+ __publicField(Buffer2, "DEBUG_DATA_MAX_LENGTH", 32);
368
+
369
+ // src/adapter/device.ts
370
+ var _Device = class {
371
+ get [Symbol.toStringTag]() {
372
+ return "Device";
373
+ }
374
+ constructor(props) {
375
+ this.props = { ..._Device.defaultProps, ...props };
376
+ this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase());
377
+ }
378
+ /** id of this device, primarily for debugging */
379
+ id;
380
+ /** stats */
381
+ statsManager = lumaStats;
382
+ /** A copy of the device props */
383
+ props;
384
+ /** Available for the application to store data on the device */
385
+ userData = {};
386
+ /** Used by other luma.gl modules to store data on the device */
387
+ _lumaData = {};
388
+ /**
389
+ * Trigger device loss.
390
+ * @returns `true` if context loss could actually be triggered.
391
+ * @note primarily intended for testing how application reacts to device loss
392
+ */
393
+ loseDevice() {
394
+ return false;
395
+ }
396
+ /** Returns the default / primary canvas context. Throws an error if no canvas context is available (a WebGPU compute device) */
397
+ getCanvasContext() {
398
+ if (!this.canvasContext) {
399
+ throw new Error("Device has no CanvasContext");
400
+ }
401
+ return this.canvasContext;
402
+ }
403
+ createTexture(props) {
404
+ if (props instanceof Promise || typeof props === "string") {
405
+ props = { data: props };
406
+ }
407
+ return this._createTexture(props);
408
+ }
409
+ createCommandEncoder(props = {}) {
410
+ throw new Error("not implemented");
411
+ }
412
+ // WebGL specific HACKS - enables app to remove webgl import
413
+ // Use until we have a better way to handle these
414
+ /** @deprecated - will be removed - should use command encoder */
415
+ readPixelsToArrayWebGL(source, options) {
416
+ throw new Error("not implemented");
417
+ }
418
+ /** @deprecated - will be removed - should use command encoder */
419
+ readPixelsToBufferWebGL2(source, options) {
420
+ throw new Error("not implemented");
421
+ }
422
+ /** @deprecated - will be removed - should use WebGPU parameters (pipeline) */
423
+ setParametersWebGL(parameters) {
424
+ throw new Error("not implemented");
425
+ }
426
+ /** @deprecated - will be removed - should use WebGPU parameters (pipeline) */
427
+ withParametersWebGL(parameters, func) {
428
+ throw new Error("not implemented");
429
+ }
430
+ /** @deprecated - will be removed - should use clear arguments in RenderPass */
431
+ clearWebGL(options) {
432
+ throw new Error("not implemented");
433
+ }
434
+ // Implementation
435
+ _getBufferProps(props) {
436
+ if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) {
437
+ props = { data: props };
438
+ }
439
+ const newProps = { ...props };
440
+ if ((props.usage || 0) & Buffer2.INDEX && !props.indexType) {
441
+ if (props.data instanceof Uint32Array) {
442
+ newProps.indexType = "uint32";
443
+ } else if (props.data instanceof Uint16Array) {
444
+ newProps.indexType = "uint16";
445
+ } else {
446
+ log.warn("indices buffer content must be of integer type")();
447
+ }
448
+ }
449
+ return newProps;
450
+ }
451
+ };
452
+ var Device = _Device;
453
+ __publicField(Device, "defaultProps", {
454
+ id: null,
455
+ type: "best-available",
456
+ canvas: null,
457
+ container: null,
458
+ webgl2: true,
459
+ // Attempt to create a WebGL2 context
460
+ webgl1: true,
461
+ // Attempt to create a WebGL1 context (false to fail if webgl2 not available)
462
+ manageState: true,
463
+ width: 800,
464
+ // width are height are only used by headless gl
465
+ height: 600,
466
+ debug: Boolean(log.get("debug")),
467
+ // Instrument context (at the expense of performance)
468
+ break: [],
469
+ // alpha: undefined,
470
+ // depth: undefined,
471
+ // stencil: undefined,
472
+ // antialias: undefined,
473
+ // premultipliedAlpha: undefined,
474
+ // preserveDrawingBuffer: undefined,
475
+ // failIfMajorPerformanceCaveat: undefined
476
+ gl: null
477
+ });
478
+ __publicField(Device, "VERSION", VERSION);
479
+
480
+ // src/utils/assert.ts
481
+ function assert(condition, message) {
482
+ if (!condition) {
483
+ throw new Error(message || "luma.gl: assertion failed.");
484
+ }
485
+ }
486
+
487
+ // src/lib/luma.ts
488
+ var deviceList = /* @__PURE__ */ new Map();
489
+ var luma = class {
490
+ static registerDevices(deviceClasses) {
491
+ for (const deviceClass of deviceClasses) {
492
+ assert(deviceClass.type && deviceClass.isSupported && deviceClass.create);
493
+ deviceList.set(deviceClass.type, deviceClass);
494
+ }
495
+ }
496
+ static getAvailableDevices() {
497
+ return Array.from(deviceList).map((Device2) => Device2.type);
498
+ }
499
+ static getSupportedDevices() {
500
+ return Array.from(deviceList).filter((Device2) => Device2.isSupported()).map((Device2) => Device2.type);
501
+ }
502
+ static setDefaultDeviceProps(props) {
503
+ Object.assign(Device.defaultProps, props);
504
+ }
505
+ /** Creates a device. Asynchronously. */
506
+ static async createDevice(props = {}) {
507
+ props = { ...Device.defaultProps, ...props };
508
+ if (props.gl) {
509
+ props.type = "webgl";
510
+ }
511
+ let DeviceClass;
512
+ switch (props.type) {
513
+ case "webgpu":
514
+ DeviceClass = deviceList.get("webgpu");
515
+ if (DeviceClass) {
516
+ return await DeviceClass.create(props);
517
+ }
518
+ break;
519
+ case "webgl":
520
+ case "webgl1":
521
+ case "webgl2":
522
+ DeviceClass = deviceList.get("webgl");
523
+ if (DeviceClass) {
524
+ return await DeviceClass.create(props);
525
+ }
526
+ break;
527
+ case "best-available":
528
+ DeviceClass = deviceList.get("webgpu");
529
+ if (DeviceClass && DeviceClass.isSupported()) {
530
+ return await DeviceClass.create(props);
531
+ }
532
+ DeviceClass = deviceList.get("webgl");
533
+ if (DeviceClass && DeviceClass.isSupported()) {
534
+ return await DeviceClass.create(props);
535
+ }
536
+ break;
537
+ }
538
+ throw new Error("No matching device found. Ensure `@luma.gl/webgl` and/or `@luma.gl/webgpu` modules are imported.");
539
+ }
540
+ };
541
+ /** Global stats for all devices */
542
+ __publicField(luma, "stats", lumaStats);
543
+ /** Global log */
544
+ __publicField(luma, "log", log);
545
+
546
+ // src/adapter/canvas-context.ts
547
+ var import_env2 = require("@probe.gl/env");
548
+ var isPage = (0, import_env2.isBrowser)() && typeof document !== "undefined";
549
+ var isPageLoaded = () => isPage && document.readyState === "complete";
550
+ var DEFAULT_CANVAS_CONTEXT_PROPS = {
551
+ canvas: null,
552
+ width: 800,
553
+ // width are height are only used by headless gl
554
+ height: 600,
555
+ useDevicePixels: true,
556
+ autoResize: true,
557
+ container: null,
558
+ visible: true,
559
+ colorSpace: "srgb",
560
+ alphaMode: "opaque"
561
+ };
562
+ var CanvasContext = class {
563
+ id;
564
+ props;
565
+ canvas;
566
+ htmlCanvas;
567
+ offscreenCanvas;
568
+ type;
569
+ width = 1;
570
+ height = 1;
571
+ resizeObserver;
572
+ /** State used by luma.gl classes: TODO - move to canvasContext*/
573
+ _canvasSizeInfo = { clientWidth: 0, clientHeight: 0, devicePixelRatio: 1 };
574
+ /** Check if the DOM is loaded */
575
+ static get isPageLoaded() {
576
+ return isPageLoaded();
577
+ }
578
+ constructor(props) {
579
+ this.props = { ...DEFAULT_CANVAS_CONTEXT_PROPS, ...props };
580
+ props = this.props;
581
+ if (!(0, import_env2.isBrowser)()) {
582
+ this.id = "node-canvas-context";
583
+ this.type = "node";
584
+ this.width = this.props.width;
585
+ this.height = this.props.height;
586
+ this.canvas = null;
587
+ return;
588
+ }
589
+ if (!props.canvas) {
590
+ const canvas = createCanvas(props);
591
+ const container = getContainer((props == null ? void 0 : props.container) || null);
592
+ container.insertBefore(canvas, container.firstChild);
593
+ this.canvas = canvas;
594
+ if (!(props == null ? void 0 : props.visible)) {
595
+ this.canvas.style.visibility = "hidden";
596
+ }
597
+ } else if (typeof props.canvas === "string") {
598
+ this.canvas = getCanvasFromDOM(props.canvas);
599
+ } else {
600
+ this.canvas = props.canvas;
601
+ }
602
+ if (this.canvas instanceof HTMLCanvasElement) {
603
+ this.id = this.canvas.id;
604
+ this.type = "html-canvas";
605
+ this.htmlCanvas = this.canvas;
606
+ } else {
607
+ this.id = "offscreen-canvas";
608
+ this.type = "offscreen-canvas";
609
+ this.offscreenCanvas = this.canvas;
610
+ }
611
+ if (this.canvas instanceof HTMLCanvasElement && props.autoResize) {
612
+ this.resizeObserver = new ResizeObserver((entries) => {
613
+ for (const entry of entries) {
614
+ if (entry.target === this.canvas) {
615
+ this.update();
616
+ }
617
+ }
618
+ });
619
+ this.resizeObserver.observe(this.canvas);
620
+ }
621
+ }
622
+ /**
623
+ * Returns the current DPR, if props.useDevicePixels is true
624
+ * Device refers to physical
625
+ */
626
+ getDevicePixelRatio(useDevicePixels) {
627
+ if (typeof OffscreenCanvas !== "undefined" && this.canvas instanceof OffscreenCanvas) {
628
+ return 1;
629
+ }
630
+ useDevicePixels = useDevicePixels === void 0 ? this.props.useDevicePixels : useDevicePixels;
631
+ if (!useDevicePixels || useDevicePixels <= 0) {
632
+ return 1;
633
+ }
634
+ if (useDevicePixels === true) {
635
+ const dpr = typeof window !== "undefined" && window.devicePixelRatio;
636
+ return dpr || 1;
637
+ }
638
+ return useDevicePixels;
639
+ }
640
+ /**
641
+ * Returns the size of drawing buffer in device pixels.
642
+ * @note This can be different from the 'CSS' size of a canvas, and also from the
643
+ * canvas' internal drawing buffer size (.width, .height).
644
+ * This is the size required to cover the canvas, adjusted for DPR
645
+ */
646
+ getPixelSize() {
647
+ switch (this.type) {
648
+ case "node":
649
+ return [this.width, this.height];
650
+ case "offscreen-canvas":
651
+ return [this.canvas.width, this.canvas.height];
652
+ case "html-canvas":
653
+ const dpr = this.getDevicePixelRatio();
654
+ const canvas = this.canvas;
655
+ return canvas.parentElement ? [canvas.clientWidth * dpr, canvas.clientHeight * dpr] : [this.canvas.width, this.canvas.height];
656
+ default:
657
+ throw new Error(this.type);
658
+ }
659
+ }
660
+ getAspect() {
661
+ const [width, height] = this.getPixelSize();
662
+ return width / height;
663
+ }
664
+ /**
665
+ * Returns multiplier need to convert CSS size to Device size
666
+ */
667
+ cssToDeviceRatio() {
668
+ try {
669
+ const [drawingBufferWidth] = this.getDrawingBufferSize();
670
+ const { clientWidth } = this._canvasSizeInfo;
671
+ return clientWidth ? drawingBufferWidth / clientWidth : 1;
672
+ } catch {
673
+ return 1;
674
+ }
675
+ }
676
+ /**
677
+ * Maps CSS pixel position to device pixel position
678
+ */
679
+ cssToDevicePixels(cssPixel, yInvert = true) {
680
+ const ratio = this.cssToDeviceRatio();
681
+ const [width, height] = this.getDrawingBufferSize();
682
+ return scalePixels(cssPixel, ratio, width, height, yInvert);
683
+ }
684
+ /**
685
+ * Use devicePixelRatio to set canvas width and height
686
+ * @note this is a raw port of luma.gl v8 code. Might be worth a review
687
+ */
688
+ setDevicePixelRatio(devicePixelRatio, options = {}) {
689
+ if (!this.htmlCanvas) {
690
+ return;
691
+ }
692
+ let clientWidth = "width" in options ? options.width : this.htmlCanvas.clientWidth;
693
+ let clientHeight = "height" in options ? options.height : this.htmlCanvas.clientHeight;
694
+ if (!clientWidth || !clientHeight) {
695
+ log.log(1, "Canvas clientWidth/clientHeight is 0")();
696
+ devicePixelRatio = 1;
697
+ clientWidth = this.htmlCanvas.width || 1;
698
+ clientHeight = this.htmlCanvas.height || 1;
699
+ }
700
+ const cachedSize = this._canvasSizeInfo;
701
+ if (cachedSize.clientWidth !== clientWidth || cachedSize.clientHeight !== clientHeight || cachedSize.devicePixelRatio !== devicePixelRatio) {
702
+ let clampedPixelRatio = devicePixelRatio;
703
+ const canvasWidth = Math.floor(clientWidth * clampedPixelRatio);
704
+ const canvasHeight = Math.floor(clientHeight * clampedPixelRatio);
705
+ this.htmlCanvas.width = canvasWidth;
706
+ this.htmlCanvas.height = canvasHeight;
707
+ const [drawingBufferWidth, drawingBufferHeight] = this.getDrawingBufferSize();
708
+ if (drawingBufferWidth !== canvasWidth || drawingBufferHeight !== canvasHeight) {
709
+ clampedPixelRatio = Math.min(
710
+ drawingBufferWidth / clientWidth,
711
+ drawingBufferHeight / clientHeight
712
+ );
713
+ this.htmlCanvas.width = Math.floor(clientWidth * clampedPixelRatio);
714
+ this.htmlCanvas.height = Math.floor(clientHeight * clampedPixelRatio);
715
+ log.warn("Device pixel ratio clamped")();
716
+ }
717
+ this._canvasSizeInfo.clientWidth = clientWidth;
718
+ this._canvasSizeInfo.clientHeight = clientHeight;
719
+ this._canvasSizeInfo.devicePixelRatio = devicePixelRatio;
720
+ }
721
+ }
722
+ // PRIVATE
723
+ /** @todo Major hack done to port the CSS methods above, base canvas context should not depend on WebGL */
724
+ getDrawingBufferSize() {
725
+ const gl = this.device.gl;
726
+ if (!gl) {
727
+ throw new Error("canvas size");
728
+ }
729
+ return [gl.drawingBufferWidth, gl.drawingBufferHeight];
730
+ }
731
+ /**
732
+ * Allows subclass constructor to override the canvas id for auto created canvases.
733
+ * This can really help when debugging DOM in apps that create multiple devices
734
+ */
735
+ _setAutoCreatedCanvasId(id) {
736
+ var _a;
737
+ if (((_a = this.htmlCanvas) == null ? void 0 : _a.id) === "lumagl-auto-created-canvas") {
738
+ this.htmlCanvas.id = id;
739
+ }
740
+ }
741
+ };
742
+ /**
743
+ * Get a 'lazy' promise that resolves when the DOM is loaded.
744
+ * @note Since there may be limitations on number of `load` event listeners,
745
+ * it is recommended avoid calling this function until actually needed.
746
+ * I.e. don't call it until you know that you will be looking up a string in the DOM.
747
+ */
748
+ __publicField(CanvasContext, "pageLoaded", getPageLoadPromise());
749
+ function getPageLoadPromise() {
750
+ if (isPageLoaded() || typeof window === "undefined") {
751
+ return Promise.resolve();
752
+ }
753
+ return new Promise((resolve) => {
754
+ window.addEventListener("load", () => resolve());
755
+ });
756
+ }
757
+ function getContainer(container) {
758
+ if (typeof container === "string") {
759
+ const element = document.getElementById(container);
760
+ if (!element && !isPageLoaded()) {
761
+ throw new Error(`Accessing '${container}' before page was loaded`);
762
+ }
763
+ if (!element) {
764
+ throw new Error(`${container} is not an HTML element`);
765
+ }
766
+ return element;
767
+ } else if (container) {
768
+ return container;
769
+ }
770
+ return document.body;
771
+ }
772
+ function getCanvasFromDOM(canvasId) {
773
+ const canvas = document.getElementById(canvasId);
774
+ if (!canvas && !isPageLoaded()) {
775
+ throw new Error(`Accessing '${canvasId}' before page was loaded`);
776
+ }
777
+ if (!(canvas instanceof HTMLCanvasElement)) {
778
+ throw new Error("Object is not a canvas element");
779
+ }
780
+ return canvas;
781
+ }
782
+ function createCanvas(props) {
783
+ const { width, height } = props;
784
+ const targetCanvas = document.createElement("canvas");
785
+ targetCanvas.id = "lumagl-auto-created-canvas";
786
+ targetCanvas.width = width || 1;
787
+ targetCanvas.height = height || 1;
788
+ targetCanvas.style.width = Number.isFinite(width) ? `${width}px` : "100%";
789
+ targetCanvas.style.height = Number.isFinite(height) ? `${height}px` : "100%";
790
+ return targetCanvas;
791
+ }
792
+ function scalePixels(pixel, ratio, width, height, yInvert) {
793
+ const point = pixel;
794
+ const x = scaleX(point[0], ratio, width);
795
+ let y = scaleY(point[1], ratio, height, yInvert);
796
+ let t = scaleX(point[0] + 1, ratio, width);
797
+ const xHigh = t === width - 1 ? t : t - 1;
798
+ t = scaleY(point[1] + 1, ratio, height, yInvert);
799
+ let yHigh;
800
+ if (yInvert) {
801
+ t = t === 0 ? t : t + 1;
802
+ yHigh = y;
803
+ y = t;
804
+ } else {
805
+ yHigh = t === height - 1 ? t : t - 1;
806
+ }
807
+ return {
808
+ x,
809
+ y,
810
+ // when ratio < 1, current css pixel and next css pixel may point to same device pixel, set width/height to 1 in those cases.
811
+ width: Math.max(xHigh - x + 1, 1),
812
+ height: Math.max(yHigh - y + 1, 1)
813
+ };
814
+ }
815
+ function scaleX(x, ratio, width) {
816
+ const r = Math.min(Math.round(x * ratio), width - 1);
817
+ return r;
818
+ }
819
+ function scaleY(y, ratio, height, yInvert) {
820
+ return yInvert ? Math.max(0, height - 1 - Math.round(y * ratio)) : Math.min(Math.round(y * ratio), height - 1);
821
+ }
822
+
823
+ // src/adapter/resources/texture.ts
824
+ var _Texture = class extends Resource {
825
+ get [Symbol.toStringTag]() {
826
+ return "Texture";
827
+ }
828
+ /** dimension of this texture */
829
+ dimension;
830
+ /** format of this texture */
831
+ format;
832
+ /** width in pixels of this texture */
833
+ width;
834
+ /** height in pixels of this texture */
835
+ height;
836
+ /** depth of this texture */
837
+ depth;
838
+ constructor(device, props, defaultProps = _Texture.defaultProps) {
839
+ super(device, props, defaultProps);
840
+ this.dimension = this.props.dimension;
841
+ this.format = this.props.format;
842
+ this.width = this.props.width;
843
+ this.height = this.props.height;
844
+ this.depth = this.props.depth;
845
+ }
846
+ };
847
+ var Texture = _Texture;
848
+ __publicField(Texture, "defaultProps", {
849
+ ...Resource.defaultProps,
850
+ data: null,
851
+ dimension: "2d",
852
+ format: "rgba8unorm",
853
+ width: void 0,
854
+ height: void 0,
855
+ depth: 1,
856
+ mipmaps: true,
857
+ sampler: {},
858
+ // type: undefined,
859
+ compressed: false,
860
+ // mipLevels: 1,
861
+ usage: 0,
862
+ // usage: GPUTextureUsage.COPY_DST
863
+ mipLevels: void 0,
864
+ samples: void 0,
865
+ type: void 0
866
+ });
867
+ __publicField(Texture, "COPY_SRC", 1);
868
+ __publicField(Texture, "COPY_DST", 2);
869
+ __publicField(Texture, "TEXTURE_BINDING", 4);
870
+ __publicField(Texture, "STORAGE_BINDING", 8);
871
+ __publicField(Texture, "RENDER_ATTACHMENT", 16);
872
+
873
+ // src/adapter/resources/external-texture.ts
874
+ var _ExternalTexture = class extends Resource {
875
+ get [Symbol.toStringTag]() {
876
+ return "ExternalTexture";
877
+ }
878
+ constructor(device, props) {
879
+ super(device, props, _ExternalTexture.defaultProps);
880
+ }
881
+ };
882
+ var ExternalTexture = _ExternalTexture;
883
+ __publicField(ExternalTexture, "defaultProps", {
884
+ ...Resource.defaultProps,
885
+ source: null,
886
+ colorSpace: "srgb"
887
+ });
888
+
889
+ // src/lib/compiler-log/format-compiler-log.ts
890
+ function formatCompilerLog(shaderLog, source, options) {
891
+ let formattedLog = "";
892
+ const lines = source.split(/\r?\n/);
893
+ const log2 = shaderLog.slice().sort((a, b) => a.lineNum - b.lineNum);
894
+ switch ((options == null ? void 0 : options.showSourceCode) || "no") {
895
+ case "all":
896
+ let currentMessage = 0;
897
+ for (let lineNum = 1; lineNum <= lines.length; lineNum++) {
898
+ formattedLog += getNumberedLine(lines[lineNum - 1], lineNum, options);
899
+ while (log2.length > currentMessage && log2[currentMessage].lineNum === lineNum) {
900
+ const message = log2[currentMessage++];
901
+ formattedLog += formatCompilerMessage(message, lines, message.lineNum, {
902
+ ...options,
903
+ inlineSource: false
904
+ });
905
+ }
906
+ }
907
+ return formattedLog;
908
+ case "issues":
909
+ case "no":
910
+ for (const message of shaderLog) {
911
+ formattedLog += formatCompilerMessage(message, lines, message.lineNum, {
912
+ inlineSource: (options == null ? void 0 : options.showSourceCode) !== "no"
913
+ });
914
+ }
915
+ return formattedLog;
916
+ }
917
+ }
918
+ function formatCompilerMessage(message, lines, lineNum, options) {
919
+ if (options == null ? void 0 : options.inlineSource) {
920
+ const numberedLines = getNumberedLines(lines, lineNum);
921
+ const positionIndicator = message.linePos > 0 ? `${" ".repeat(message.linePos + 5)}^^^
922
+ ` : "";
923
+ return `
924
+ ${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.message}
925
+
926
+ `;
927
+ }
928
+ return (options == null ? void 0 : options.html) ? `<div class='luma-compiler-log-error' style="color:red;"><b> ${message.type.toUpperCase()}: ${message.message}</b></div>` : `${message.type.toUpperCase()}: ${message.message}`;
929
+ }
930
+ function getNumberedLines(lines, lineNum, options) {
931
+ let numberedLines = "";
932
+ for (let lineIndex = lineNum - 2; lineIndex <= lineNum; lineIndex++) {
933
+ const sourceLine = lines[lineIndex - 1];
934
+ if (sourceLine !== void 0) {
935
+ numberedLines += getNumberedLine(sourceLine, lineNum, options);
936
+ }
937
+ }
938
+ return numberedLines;
939
+ }
940
+ function getNumberedLine(line, lineNum, options) {
941
+ const escapedLine = (options == null ? void 0 : options.html) ? escapeHTML(line) : line;
942
+ return `${padLeft(String(lineNum), 4)}: ${escapedLine}${(options == null ? void 0 : options.html) ? "<br/>" : "\n"}`;
943
+ }
944
+ function padLeft(string, paddedLength) {
945
+ let result = "";
946
+ for (let i = string.length; i < paddedLength; ++i) {
947
+ result += " ";
948
+ }
949
+ return result + string;
950
+ }
951
+ function escapeHTML(unsafe) {
952
+ return unsafe.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#039;");
953
+ }
954
+
955
+ // src/lib/compiler-log/get-shader-info.ts
956
+ function getShaderInfo(source, defaultName) {
957
+ return {
958
+ name: getShaderName(source, defaultName),
959
+ language: "glsl",
960
+ version: getShaderVersion(source)
961
+ };
962
+ }
963
+ function getShaderName(shader, defaultName = "unnamed") {
964
+ const SHADER_NAME_REGEXP = /#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/;
965
+ const match = SHADER_NAME_REGEXP.exec(shader);
966
+ return match ? match[1] : defaultName;
967
+ }
968
+ function getShaderVersion(source) {
969
+ let version = 100;
970
+ const words = source.match(/[^\s]+/g);
971
+ if (words && words.length >= 2 && words[0] === "#version") {
972
+ const v = parseInt(words[1], 10);
973
+ if (Number.isFinite(v)) {
974
+ version = v;
975
+ }
976
+ }
977
+ return version;
978
+ }
979
+
980
+ // src/adapter/resources/shader.ts
981
+ var _Shader = class extends Resource {
982
+ get [Symbol.toStringTag]() {
983
+ return "Shader";
984
+ }
985
+ /** The stage of this shader */
986
+ stage;
987
+ /** The source code of this shader */
988
+ source;
989
+ /** The compilation status of this shader. May be 'pending' if compilation is done asynchronously */
990
+ compilationStatus = "pending";
991
+ /** Create a new Shader instance */
992
+ constructor(device, props) {
993
+ super(device, { id: getShaderIdFromProps(props), ...props }, _Shader.defaultProps);
994
+ this.stage = this.props.stage;
995
+ this.source = this.props.source;
996
+ }
997
+ /** Get compiler log synchronously (WebGL only) */
998
+ getCompilationInfoSync() {
999
+ return null;
1000
+ }
1001
+ // PORTABLE HELPERS
1002
+ /** In browser logging of errors */
1003
+ async debugShader() {
1004
+ switch (this.props.debug) {
1005
+ case "never":
1006
+ return;
1007
+ case "errors":
1008
+ if (this.compilationStatus === "success") {
1009
+ return;
1010
+ }
1011
+ break;
1012
+ case "warnings":
1013
+ case "always":
1014
+ break;
1015
+ }
1016
+ const messages = await this.getCompilationInfo();
1017
+ if (this.props.debug === "warnings" && (messages == null ? void 0 : messages.length) === 0) {
1018
+ return;
1019
+ }
1020
+ this._displayShaderLog(messages);
1021
+ }
1022
+ // PRIVATE
1023
+ /** In-browser UI logging of errors */
1024
+ _displayShaderLog(messages) {
1025
+ var _a;
1026
+ if (typeof document === "undefined" || !(document == null ? void 0 : document.createElement)) {
1027
+ return;
1028
+ }
1029
+ const shaderName = getShaderInfo(this.source).name;
1030
+ const shaderTitle = `${this.stage} ${shaderName}`;
1031
+ const htmlLog = formatCompilerLog(messages, this.source, { showSourceCode: "all", html: true });
1032
+ const button = document.createElement("Button");
1033
+ button.innerHTML = `
1034
+ <h1>Shader Compilation Error in ${shaderTitle}</h1><br /><br />
1035
+ <code style="user-select:text;"><pre>
1036
+ ${htmlLog}
1037
+ </pre></code>`;
1038
+ button.style.top = "10px";
1039
+ button.style.left = "10px";
1040
+ button.style.position = "absolute";
1041
+ button.style.zIndex = "9999";
1042
+ button.style.width = "100%";
1043
+ button.style.textAlign = "left";
1044
+ document.body.appendChild(button);
1045
+ const errors = document.getElementsByClassName("luma-compiler-log-error");
1046
+ if ((_a = errors[0]) == null ? void 0 : _a.scrollIntoView) {
1047
+ errors[0].scrollIntoView();
1048
+ }
1049
+ button.onclick = () => {
1050
+ const dataURI = `data:text/plain,${encodeURIComponent(this.source)}`;
1051
+ navigator.clipboard.writeText(dataURI);
1052
+ };
1053
+ }
1054
+ };
1055
+ var Shader = _Shader;
1056
+ __publicField(Shader, "defaultProps", {
1057
+ ...Resource.defaultProps,
1058
+ language: "auto",
1059
+ stage: "vertex",
1060
+ source: "",
1061
+ sourceMap: null,
1062
+ entryPoint: "main",
1063
+ debug: "errors"
1064
+ });
1065
+ function getShaderIdFromProps(props) {
1066
+ return getShaderInfo(props.source).name || props.id || uid(`unnamed ${props.stage}-shader`);
1067
+ }
1068
+
1069
+ // src/adapter/resources/sampler.ts
1070
+ var _Sampler = class extends Resource {
1071
+ get [Symbol.toStringTag]() {
1072
+ return "Sampler";
1073
+ }
1074
+ constructor(device, props) {
1075
+ super(device, props, _Sampler.defaultProps);
1076
+ }
1077
+ };
1078
+ var Sampler = _Sampler;
1079
+ __publicField(Sampler, "defaultProps", {
1080
+ ...Resource.defaultProps,
1081
+ type: "color-sampler",
1082
+ addressModeU: "clamp-to-edge",
1083
+ addressModeV: "clamp-to-edge",
1084
+ addressModeW: "clamp-to-edge",
1085
+ magFilter: "nearest",
1086
+ minFilter: "nearest",
1087
+ mipmapFilter: "nearest",
1088
+ lodMinClamp: 0,
1089
+ lodMaxClamp: 32,
1090
+ // Per WebGPU spec
1091
+ compare: "less-equal",
1092
+ maxAnisotropy: 1
1093
+ });
1094
+
1095
+ // src/adapter/resources/framebuffer.ts
1096
+ var _Framebuffer = class extends Resource {
1097
+ get [Symbol.toStringTag]() {
1098
+ return "Framebuffer";
1099
+ }
1100
+ /** Width of all attachments in this framebuffer */
1101
+ width;
1102
+ /** Height of all attachments in this framebuffer */
1103
+ height;
1104
+ /** Color attachments */
1105
+ colorAttachments = [];
1106
+ /** Depth-stencil attachment, if provided */
1107
+ depthStencilAttachment = null;
1108
+ constructor(device, props = {}) {
1109
+ super(device, props, _Framebuffer.defaultProps);
1110
+ this.width = this.props.width;
1111
+ this.height = this.props.height;
1112
+ }
1113
+ resize(size) {
1114
+ let updateSize = !size;
1115
+ if (size) {
1116
+ const [width, height] = Array.isArray(size) ? size : [size.width, size.height];
1117
+ updateSize = updateSize || height !== this.height || width !== this.width;
1118
+ this.width = width;
1119
+ this.height = height;
1120
+ }
1121
+ if (updateSize) {
1122
+ log.log(2, `Resizing framebuffer ${this.id} to ${this.width}x${this.height}`)();
1123
+ this.resizeAttachments(this.width, this.height);
1124
+ }
1125
+ }
1126
+ // /** Returns fully populated attachment object. */
1127
+ // protected normalizeColorAttachment(
1128
+ // attachment: Texture | ColorTextureFormat
1129
+ // ): Required<ColorAttachment> {
1130
+ // const COLOR_ATTACHMENT_DEFAULTS: Required<ColorAttachment> = {
1131
+ // texture: undefined!,
1132
+ // format: undefined!,
1133
+ // clearValue: [0.0, 0.0, 0.0, 0.0],
1134
+ // loadOp: 'clear',
1135
+ // storeOp: 'store'
1136
+ // };
1137
+ // if (attachment instanceof Texture) {
1138
+ // return {...COLOR_ATTACHMENT_DEFAULTS, texture: attachment};
1139
+ // }
1140
+ // if (typeof attachment === 'string') {
1141
+ // return {...COLOR_ATTACHMENT_DEFAULTS, format: attachment};
1142
+ // }
1143
+ // return {...COLOR_ATTACHMENT_DEFAULTS, ...attachment};
1144
+ // }
1145
+ // /** Wraps texture inside fully populated attachment object. */
1146
+ // protected normalizeDepthStencilAttachment(
1147
+ // attachment: DepthStencilAttachment | Texture | DepthStencilTextureFormat
1148
+ // ): Required<DepthStencilAttachment> {
1149
+ // const DEPTH_STENCIL_ATTACHMENT_DEFAULTS: Required<DepthStencilAttachment> = {
1150
+ // texture: undefined!,
1151
+ // format: undefined!,
1152
+ // depthClearValue: 1.0,
1153
+ // depthLoadOp: 'clear',
1154
+ // depthStoreOp: 'store',
1155
+ // depthReadOnly: false,
1156
+ // stencilClearValue: 0,
1157
+ // stencilLoadOp: 'clear',
1158
+ // stencilStoreOp: 'store',
1159
+ // stencilReadOnly: false
1160
+ // };
1161
+ // if (typeof attachment === 'string') {
1162
+ // return {...DEPTH_STENCIL_ATTACHMENT_DEFAULTS, format: attachment};
1163
+ // }
1164
+ // // @ts-expect-error attachment instanceof Texture doesn't cover Renderbuffer
1165
+ // if (attachment.handle || attachment instanceof Texture) {
1166
+ // return {...DEPTH_STENCIL_ATTACHMENT_DEFAULTS, texture: attachment as Texture};
1167
+ // }
1168
+ // return {...DEPTH_STENCIL_ATTACHMENT_DEFAULTS, ...attachment};
1169
+ // }
1170
+ /** Auto creates any textures */
1171
+ autoCreateAttachmentTextures() {
1172
+ this.colorAttachments = this.props.colorAttachments.map((attachment) => {
1173
+ if (typeof attachment === "string") {
1174
+ const texture = this.createColorTexture(attachment);
1175
+ this.attachResource(texture);
1176
+ return texture;
1177
+ }
1178
+ return attachment;
1179
+ });
1180
+ if (this.props.depthStencilAttachment) {
1181
+ if (typeof this.props.depthStencilAttachment === "string") {
1182
+ const texture = this.createDepthStencilTexture(this.props.depthStencilAttachment);
1183
+ this.attachResource(texture);
1184
+ this.depthStencilAttachment = texture;
1185
+ } else {
1186
+ this.depthStencilAttachment = this.props.depthStencilAttachment;
1187
+ }
1188
+ }
1189
+ }
1190
+ /** Create a color texture */
1191
+ createColorTexture(format) {
1192
+ return this.device.createTexture({
1193
+ id: "color-attachment",
1194
+ usage: Texture.RENDER_ATTACHMENT,
1195
+ format,
1196
+ width: this.width,
1197
+ height: this.height
1198
+ });
1199
+ }
1200
+ /** Create depth stencil texture */
1201
+ createDepthStencilTexture(format) {
1202
+ return this.device.createTexture({
1203
+ id: "depth-stencil-attachment",
1204
+ usage: Texture.RENDER_ATTACHMENT,
1205
+ format,
1206
+ width: this.width,
1207
+ height: this.height
1208
+ });
1209
+ }
1210
+ /**
1211
+ * Default implementation of resize
1212
+ * Creates new textures with correct size for all attachments.
1213
+ * and destroys existing textures if owned
1214
+ */
1215
+ resizeAttachments(width, height) {
1216
+ for (let i = 0; i < this.colorAttachments.length; ++i) {
1217
+ if (this.colorAttachments[i]) {
1218
+ const resizedTexture = this.device._createTexture({
1219
+ ...this.colorAttachments[i].props,
1220
+ width,
1221
+ height
1222
+ });
1223
+ this.destroyAttachedResource(this.colorAttachments[i]);
1224
+ this.colorAttachments[i] = resizedTexture;
1225
+ this.attachResource(resizedTexture);
1226
+ }
1227
+ }
1228
+ if (this.depthStencilAttachment) {
1229
+ const resizedTexture = this.device._createTexture({
1230
+ ...this.depthStencilAttachment.props,
1231
+ width,
1232
+ height
1233
+ });
1234
+ this.destroyAttachedResource(this.depthStencilAttachment);
1235
+ this.depthStencilAttachment = resizedTexture;
1236
+ this.attachResource(resizedTexture);
1237
+ }
1238
+ }
1239
+ /** Create a color attachment for WebGL *
1240
+ protected override createColorTexture(colorAttachment: Required<ColorAttachment>): Required<ColorAttachment> {
1241
+ return this.device._createTexture({
1242
+ id: `${this.id}-color`,
1243
+ data: null, // reserves texture memory, but texels are undefined
1244
+ format,
1245
+ // type: GL.UNSIGNED_BYTE,
1246
+ width: this.width,
1247
+ height: this.height,
1248
+ // Note: Mipmapping can be disabled by texture resource when we resize the texture
1249
+ // to a non-power-of-two dimenstion (NPOT texture) under WebGL1. To have consistant
1250
+ // behavior we always disable mipmaps.
1251
+ mipmaps: false,
1252
+ // Set MIN and MAG filtering parameters so mipmaps are not used in sampling.
1253
+ // Use LINEAR so subpixel algos like fxaa work.
1254
+ // Set WRAP modes that support NPOT textures too.
1255
+ sampler: {
1256
+ minFilter: 'linear',
1257
+ magFilter: 'linear',
1258
+ addressModeU: 'clamp-to-edge',
1259
+ addressModeV: 'clamp-to-edge'
1260
+ }
1261
+ // parameters: {
1262
+ // [GL.TEXTURE_MIN_FILTER]: GL.LINEAR,
1263
+ // [GL.TEXTURE_MAG_FILTER]: GL.LINEAR,
1264
+ // [GL.TEXTURE_WRAP_S]: GL.CLAMP_TO_EDGE,
1265
+ // [GL.TEXTURE_WRAP_T]: GL.CLAMP_TO_EDGE
1266
+ // }
1267
+ });
1268
+ }
1269
+ */
1270
+ };
1271
+ var Framebuffer = _Framebuffer;
1272
+ __publicField(Framebuffer, "defaultProps", {
1273
+ ...Resource.defaultProps,
1274
+ width: 1,
1275
+ height: 1,
1276
+ colorAttachments: [],
1277
+ // ['rgba8unorm-unsized'],
1278
+ depthStencilAttachment: null
1279
+ // 'depth24plus-stencil8'
1280
+ });
1281
+
1282
+ // src/adapter/resources/render-pipeline.ts
1283
+ var _RenderPipeline = class extends Resource {
1284
+ get [Symbol.toStringTag]() {
1285
+ return "RenderPipeline";
1286
+ }
1287
+ hash = "";
1288
+ /** The merged layout */
1289
+ shaderLayout;
1290
+ /** Buffer map describing buffer interleaving etc */
1291
+ bufferLayout;
1292
+ constructor(device, props) {
1293
+ super(device, props, _RenderPipeline.defaultProps);
1294
+ this.shaderLayout = this.props.shaderLayout;
1295
+ this.bufferLayout = this.props.bufferLayout || [];
1296
+ }
1297
+ };
1298
+ var RenderPipeline = _RenderPipeline;
1299
+ __publicField(RenderPipeline, "defaultProps", {
1300
+ ...Resource.defaultProps,
1301
+ vs: null,
1302
+ vsEntryPoint: "",
1303
+ // main
1304
+ vsConstants: {},
1305
+ fs: null,
1306
+ fsEntryPoint: "",
1307
+ // main
1308
+ fsConstants: {},
1309
+ shaderLayout: null,
1310
+ bufferLayout: [],
1311
+ topology: "triangle-list",
1312
+ parameters: {},
1313
+ vertexCount: 0,
1314
+ instanceCount: 0,
1315
+ bindings: {},
1316
+ uniforms: {}
1317
+ });
1318
+
1319
+ // src/adapter/resources/compute-pipeline.ts
1320
+ var _ComputePipeline = class extends Resource {
1321
+ get [Symbol.toStringTag]() {
1322
+ return "ComputePipeline";
1323
+ }
1324
+ hash = "";
1325
+ constructor(device, props) {
1326
+ super(device, props, _ComputePipeline.defaultProps);
1327
+ }
1328
+ };
1329
+ var ComputePipeline = _ComputePipeline;
1330
+ __publicField(ComputePipeline, "defaultProps", {
1331
+ ...Resource.defaultProps,
1332
+ cs: void 0,
1333
+ csEntryPoint: void 0,
1334
+ csConstants: {},
1335
+ shaderLayout: []
1336
+ });
1337
+
1338
+ // src/adapter/resources/render-pass.ts
1339
+ var _RenderPass = class extends Resource {
1340
+ get [Symbol.toStringTag]() {
1341
+ return "RenderPass";
1342
+ }
1343
+ constructor(device, props) {
1344
+ super(device, props, _RenderPass.defaultProps);
1345
+ }
1346
+ // writeTimestamp(querySet: GPUQuerySet, queryIndex: number): void;
1347
+ // beginOcclusionQuery(queryIndex: number): void;
1348
+ // endOcclusionQuery(): void;
1349
+ // executeBundles(bundles: Iterable<GPURenderBundle>): void;
1350
+ // In WebGPU the following methods are on the renderpass.
1351
+ // luma.gl keeps them on the pipeline for now
1352
+ /*
1353
+ setPipeline(pipeline: RenderPipeline): void {}
1354
+
1355
+ setIndexBuffer(
1356
+ buffer: Buffer,
1357
+ indexFormat: 'uint16' | 'uint32',
1358
+ offset?: number,
1359
+ size?: number
1360
+ ): void {}
1361
+
1362
+ abstract setVertexBuffer(slot: number, buffer: Buffer, offset: number): void;
1363
+
1364
+ abstract setBindings(bindings: Record<string, Binding>): void;
1365
+
1366
+ abstract setParameters(parameters: RenderPassParameters);
1367
+
1368
+ draw(options: {
1369
+ vertexCount?: number; // Either vertexCount or indexCount must be provided
1370
+ indexCount?: number; // Activates indexed drawing (call setIndexBuffer())
1371
+ instanceCount?: number; //
1372
+ firstVertex?: number;
1373
+ firstIndex?: number; // requires device.features.has('indirect-first-instance')?
1374
+ firstInstance?: number;
1375
+ baseVertex?: number;
1376
+ }): void {}
1377
+
1378
+ drawIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): void;
1379
+ drawIndexedIndirect(indirectBuffer: GPUBuffer, indirectOffset: number): void;
1380
+ */
1381
+ };
1382
+ var RenderPass = _RenderPass;
1383
+ /** Default properties for RenderPass */
1384
+ __publicField(RenderPass, "defaultProps", {
1385
+ ...Resource.defaultProps,
1386
+ framebuffer: null,
1387
+ parameters: void 0,
1388
+ clearColor: [0, 0, 0, 0],
1389
+ clearDepth: 1,
1390
+ clearStencil: 0,
1391
+ depthReadOnly: false,
1392
+ stencilReadOnly: false,
1393
+ discard: false
1394
+ });
1395
+
1396
+ // src/adapter/resources/compute-pass.ts
1397
+ var ComputePass = class extends Resource {
1398
+ get [Symbol.toStringTag]() {
1399
+ return "ComputePass";
1400
+ }
1401
+ constructor(device, props) {
1402
+ super(device, props, Resource.defaultProps);
1403
+ }
1404
+ // writeTimestamp(querySet: GPUQuerySet, queryIndex: number): void;
1405
+ // beginPipelineStatisticsQuery(querySet: GPUQuerySet, queryIndex: number): void;
1406
+ // endPipelineStatisticsQuery(querySet: GPUQuerySet, queryIndex: number): void;
1407
+ };
1408
+ __publicField(ComputePass, "defaultProps", {
1409
+ ...Resource.defaultProps
1410
+ });
1411
+
1412
+ // src/adapter/resources/command-encoder.ts
1413
+ var _CommandEncoder = class extends Resource {
1414
+ get [Symbol.toStringTag]() {
1415
+ return "CommandEncoder";
1416
+ }
1417
+ constructor(device, props) {
1418
+ super(device, props, _CommandEncoder.defaultProps);
1419
+ }
1420
+ pushDebugGroup(groupLabel) {
1421
+ }
1422
+ popDebugGroup() {
1423
+ }
1424
+ insertDebugMarker(markerLabel) {
1425
+ }
1426
+ // writeTimestamp(querySet: Query, queryIndex: number): void;
1427
+ // resolveQuerySet(options: {
1428
+ // querySet: GPUQuerySet,
1429
+ // firstQuery: number,
1430
+ // queryCount: number,
1431
+ // destination: Buffer,
1432
+ // destinationOffset?: number;
1433
+ // }): void;
1434
+ };
1435
+ var CommandEncoder = _CommandEncoder;
1436
+ __publicField(CommandEncoder, "defaultProps", {
1437
+ ...Resource.defaultProps,
1438
+ measureExecutionTime: void 0
1439
+ });
1440
+
1441
+ // src/adapter/resources/command-buffer.ts
1442
+ var _CommandBuffer = class extends Resource {
1443
+ get [Symbol.toStringTag]() {
1444
+ return "CommandBuffer";
1445
+ }
1446
+ constructor(device, props) {
1447
+ super(device, props, _CommandBuffer.defaultProps);
1448
+ }
1449
+ };
1450
+ var CommandBuffer = _CommandBuffer;
1451
+ __publicField(CommandBuffer, "defaultProps", {
1452
+ ...Resource.defaultProps
1453
+ });
1454
+
1455
+ // src/adapter/type-utils/decode-attribute-type.ts
1456
+ function decodeShaderAttributeType(attributeType) {
1457
+ const [dataType, components] = TYPE_INFO[attributeType];
1458
+ const integer = dataType === "i32" || dataType === "u32";
1459
+ const signed = dataType !== "u32";
1460
+ const byteLength = TYPE_SIZES[dataType] * components;
1461
+ const defaultVertexFormat = getCompatibleVertexFormat(dataType, components);
1462
+ return {
1463
+ dataType,
1464
+ components,
1465
+ defaultVertexFormat,
1466
+ byteLength,
1467
+ integer,
1468
+ signed
1469
+ };
1470
+ }
1471
+ function getCompatibleVertexFormat(dataType, components) {
1472
+ let vertexType;
1473
+ switch (dataType) {
1474
+ case "f32":
1475
+ vertexType = "float32";
1476
+ break;
1477
+ case "i32":
1478
+ vertexType = "sint32";
1479
+ break;
1480
+ case "u32":
1481
+ vertexType = "uint32";
1482
+ break;
1483
+ case "f16":
1484
+ return components <= 2 ? "float16x2" : "float16x4";
1485
+ }
1486
+ if (components === 1) {
1487
+ return vertexType;
1488
+ }
1489
+ return `${vertexType}x${components}`;
1490
+ }
1491
+ var TYPE_INFO = {
1492
+ f32: ["f32", 1],
1493
+ "vec2<f32>": ["f32", 2],
1494
+ "vec3<f32>": ["f32", 3],
1495
+ "vec4<f32>": ["f32", 4],
1496
+ f16: ["f16", 1],
1497
+ "vec2<f16>": ["f16", 2],
1498
+ "vec3<f16>": ["f16", 3],
1499
+ "vec4<f16>": ["f16", 4],
1500
+ i32: ["i32", 1],
1501
+ "vec2<i32>": ["i32", 2],
1502
+ "vec3<i32>": ["i32", 3],
1503
+ "vec4<i32>": ["i32", 4],
1504
+ u32: ["u32", 1],
1505
+ "vec2<u32>": ["u32", 2],
1506
+ "vec3<u32>": ["u32", 3],
1507
+ "vec4<u32>": ["u32", 4]
1508
+ };
1509
+ var TYPE_SIZES = {
1510
+ f32: 4,
1511
+ f16: 2,
1512
+ i32: 4,
1513
+ u32: 4
1514
+ // 'bool-webgl': 4,
1515
+ };
1516
+
1517
+ // src/adapter/type-utils/decode-data-type.ts
1518
+ function decodeVertexType(type) {
1519
+ const dataType = TYPE_MAP[type];
1520
+ const bytes = getDataTypeBytes(dataType);
1521
+ const normalized = type.includes("norm");
1522
+ const integer = !normalized && !type.startsWith("float");
1523
+ const signed = type.startsWith("s");
1524
+ return {
1525
+ dataType: TYPE_MAP[type],
1526
+ byteLength: bytes,
1527
+ integer,
1528
+ signed,
1529
+ normalized
1530
+ };
1531
+ }
1532
+ function getDataTypeBytes(type) {
1533
+ const bytes = TYPE_SIZES2[type];
1534
+ return bytes;
1535
+ }
1536
+ var TYPE_MAP = {
1537
+ uint8: "uint8",
1538
+ sint8: "sint8",
1539
+ unorm8: "uint8",
1540
+ snorm8: "sint8",
1541
+ uint16: "uint16",
1542
+ sint16: "sint16",
1543
+ unorm16: "uint16",
1544
+ snorm16: "sint16",
1545
+ float16: "float16",
1546
+ float32: "float32",
1547
+ uint32: "uint32",
1548
+ sint32: "sint32"
1549
+ };
1550
+ var TYPE_SIZES2 = {
1551
+ uint8: 1,
1552
+ sint8: 1,
1553
+ uint16: 2,
1554
+ sint16: 2,
1555
+ float16: 2,
1556
+ float32: 4,
1557
+ uint32: 4,
1558
+ sint32: 4
1559
+ };
1560
+
1561
+ // src/adapter/type-utils/decode-vertex-format.ts
1562
+ function decodeVertexFormat(format) {
1563
+ let webglOnly;
1564
+ if (format.endsWith("-webgl")) {
1565
+ format.replace("-webgl", "");
1566
+ webglOnly = true;
1567
+ }
1568
+ const [type_, count] = format.split("x");
1569
+ const type = type_;
1570
+ const components = count ? parseInt(count) : 1;
1571
+ const decodedType = decodeVertexType(type);
1572
+ const result = {
1573
+ type,
1574
+ components,
1575
+ byteLength: decodedType.byteLength * components,
1576
+ integer: decodedType.integer,
1577
+ signed: decodedType.signed,
1578
+ normalized: decodedType.normalized
1579
+ };
1580
+ if (webglOnly) {
1581
+ result.webglOnly = true;
1582
+ }
1583
+ return result;
1584
+ }
1585
+
1586
+ // src/adapter/attribute-utils/get-attribute-from-layouts.ts
1587
+ function getAttributeInfosFromLayouts(shaderLayout, bufferLayout) {
1588
+ const attributeInfos = {};
1589
+ for (const attribute of shaderLayout.attributes) {
1590
+ attributeInfos[attribute.name] = getAttributeInfoFromLayouts(
1591
+ shaderLayout,
1592
+ bufferLayout,
1593
+ attribute.name
1594
+ );
1595
+ }
1596
+ return attributeInfos;
1597
+ }
1598
+ function getAttributeInfosByLocation(shaderLayout, bufferLayout, maxVertexAttributes = 16) {
1599
+ const attributeInfos = getAttributeInfosFromLayouts(shaderLayout, bufferLayout);
1600
+ const locationInfos = new Array(maxVertexAttributes).fill(null);
1601
+ for (const attributeInfo of Object.values(attributeInfos)) {
1602
+ locationInfos[attributeInfo.location] = attributeInfo;
1603
+ }
1604
+ return locationInfos;
1605
+ }
1606
+ function getAttributeInfoFromLayouts(shaderLayout, bufferLayout, name2) {
1607
+ const shaderDeclaration = getAttributeFromShaderLayout(shaderLayout, name2);
1608
+ const bufferMapping = getAttributeFromBufferLayout(bufferLayout, name2);
1609
+ if (!shaderDeclaration) {
1610
+ return null;
1611
+ }
1612
+ const attributeTypeInfo = decodeShaderAttributeType(shaderDeclaration.type);
1613
+ const vertexFormat = (bufferMapping == null ? void 0 : bufferMapping.vertexFormat) || attributeTypeInfo.defaultVertexFormat;
1614
+ const vertexFormatInfo = decodeVertexFormat(vertexFormat);
1615
+ return {
1616
+ attributeName: (bufferMapping == null ? void 0 : bufferMapping.attributeName) || shaderDeclaration.name,
1617
+ bufferName: (bufferMapping == null ? void 0 : bufferMapping.bufferName) || shaderDeclaration.name,
1618
+ location: shaderDeclaration.location,
1619
+ shaderType: shaderDeclaration.type,
1620
+ shaderDataType: attributeTypeInfo.dataType,
1621
+ shaderComponents: attributeTypeInfo.components,
1622
+ vertexFormat,
1623
+ bufferDataType: vertexFormatInfo.type,
1624
+ bufferComponents: vertexFormatInfo.components,
1625
+ // normalized is a property of the buffer's vertex format
1626
+ normalized: vertexFormatInfo.normalized,
1627
+ // integer is a property of the shader declaration
1628
+ integer: attributeTypeInfo.integer,
1629
+ stepMode: (bufferMapping == null ? void 0 : bufferMapping.stepMode) || shaderDeclaration.stepMode,
1630
+ byteOffset: (bufferMapping == null ? void 0 : bufferMapping.byteOffset) || 0,
1631
+ byteStride: (bufferMapping == null ? void 0 : bufferMapping.byteStride) || 0
1632
+ };
1633
+ }
1634
+ function getAttributeFromShaderLayout(shaderLayout, name2) {
1635
+ const attribute = shaderLayout.attributes.find((attr) => attr.name === name2);
1636
+ if (!attribute) {
1637
+ log.warn(`shader layout attribute "${name2}" not present in shader`);
1638
+ }
1639
+ return attribute || null;
1640
+ }
1641
+ function getAttributeFromBufferLayout(bufferLayouts, name2) {
1642
+ checkBufferLayouts(bufferLayouts);
1643
+ let bufferLayoutInfo = getAttributeFromShortHand(bufferLayouts, name2);
1644
+ if (bufferLayoutInfo) {
1645
+ return bufferLayoutInfo;
1646
+ }
1647
+ bufferLayoutInfo = getAttributeFromAttributesList(bufferLayouts, name2);
1648
+ if (bufferLayoutInfo) {
1649
+ return bufferLayoutInfo;
1650
+ }
1651
+ log.warn(`layout for attribute "${name2}" not present in buffer layout`);
1652
+ return null;
1653
+ }
1654
+ function checkBufferLayouts(bufferLayouts) {
1655
+ for (const bufferLayout of bufferLayouts) {
1656
+ if (bufferLayout.attributes && bufferLayout.format || !bufferLayout.attributes && !bufferLayout.format) {
1657
+ log.warn(`BufferLayout ${name} must have either 'attributes' or 'format' field`);
1658
+ }
1659
+ }
1660
+ }
1661
+ function getAttributeFromShortHand(bufferLayouts, name2) {
1662
+ for (const bufferLayout of bufferLayouts) {
1663
+ if (bufferLayout.format && bufferLayout.name === name2) {
1664
+ return {
1665
+ attributeName: bufferLayout.name,
1666
+ bufferName: name2,
1667
+ stepMode: bufferLayout.stepMode,
1668
+ vertexFormat: bufferLayout.format,
1669
+ // If offset is needed, use `attributes` field.
1670
+ byteOffset: 0,
1671
+ byteStride: bufferLayout.byteStride || 0
1672
+ };
1673
+ }
1674
+ }
1675
+ return null;
1676
+ }
1677
+ function getAttributeFromAttributesList(bufferLayouts, name2) {
1678
+ var _a;
1679
+ for (const bufferLayout of bufferLayouts) {
1680
+ let byteStride = bufferLayout.byteStride;
1681
+ if (typeof bufferLayout.byteStride !== "number") {
1682
+ for (const attributeMapping2 of bufferLayout.attributes || []) {
1683
+ const info = decodeVertexFormat(attributeMapping2.format);
1684
+ byteStride += info.byteLength;
1685
+ }
1686
+ }
1687
+ const attributeMapping = (_a = bufferLayout.attributes) == null ? void 0 : _a.find((mapping) => mapping.attribute === name2);
1688
+ if (attributeMapping) {
1689
+ return {
1690
+ attributeName: attributeMapping.attribute,
1691
+ bufferName: bufferLayout.name,
1692
+ stepMode: bufferLayout.stepMode,
1693
+ vertexFormat: attributeMapping.format,
1694
+ byteOffset: attributeMapping.byteOffset,
1695
+ byteStride
1696
+ };
1697
+ }
1698
+ }
1699
+ return null;
1700
+ }
1701
+ function mergeShaderLayout(baseLayout, overrideLayout) {
1702
+ const mergedLayout = {
1703
+ ...baseLayout,
1704
+ attributes: baseLayout.attributes.map((attribute) => ({ ...attribute }))
1705
+ };
1706
+ for (const attribute of (overrideLayout == null ? void 0 : overrideLayout.attributes) || []) {
1707
+ const baseAttribute = mergedLayout.attributes.find((attr) => attr.name === attribute.name);
1708
+ if (!baseAttribute) {
1709
+ log.warn(`shader layout attribute ${attribute.name} not present in shader`);
1710
+ } else {
1711
+ baseAttribute.type = attribute.type || baseAttribute.type;
1712
+ baseAttribute.stepMode = attribute.stepMode || baseAttribute.stepMode;
1713
+ }
1714
+ }
1715
+ return mergedLayout;
1716
+ }
1717
+
1718
+ // src/adapter/resources/vertex-array.ts
1719
+ var _VertexArray = class extends Resource {
1720
+ get [Symbol.toStringTag]() {
1721
+ return "VertexArray";
1722
+ }
1723
+ /** Max number of vertex attributes */
1724
+ maxVertexAttributes;
1725
+ /** Attribute infos indexed by location - TODO only needed by webgl module? */
1726
+ attributeInfos;
1727
+ /** Index buffer */
1728
+ indexBuffer = null;
1729
+ /** Attributes indexed by buffer slot */
1730
+ attributes;
1731
+ constructor(device, props) {
1732
+ super(device, props, _VertexArray.defaultProps);
1733
+ this.maxVertexAttributes = device.limits.maxVertexAttributes;
1734
+ this.attributes = new Array(this.maxVertexAttributes).fill(null);
1735
+ this.attributeInfos = getAttributeInfosByLocation(
1736
+ props.renderPipeline.shaderLayout,
1737
+ props.renderPipeline.bufferLayout,
1738
+ this.maxVertexAttributes
1739
+ );
1740
+ }
1741
+ };
1742
+ var VertexArray = _VertexArray;
1743
+ __publicField(VertexArray, "defaultProps", {
1744
+ ...Resource.defaultProps,
1745
+ renderPipeline: null
1746
+ });
1747
+
1748
+ // src/adapter/resources/transform-feedback.ts
1749
+ var _TransformFeedback = class extends Resource {
1750
+ get [Symbol.toStringTag]() {
1751
+ return "TransformFeedback";
1752
+ }
1753
+ constructor(device, props) {
1754
+ super(device, props, _TransformFeedback.defaultProps);
1755
+ }
1756
+ };
1757
+ var TransformFeedback = _TransformFeedback;
1758
+ __publicField(TransformFeedback, "defaultProps", {
1759
+ ...Resource.defaultProps,
1760
+ layout: void 0,
1761
+ buffers: {}
1762
+ });
1763
+
1764
+ // src/adapter/type-utils/decode-shader-types.ts
1765
+ var UNIFORM_FORMATS = {
1766
+ "f32": { type: "f32", components: 1 },
1767
+ "i32": { type: "i32", components: 1 },
1768
+ "u32": { type: "u32", components: 1 },
1769
+ // 'bool-webgl': {type: 'bool-webgl', components: 1},
1770
+ "vec2<f32>": { type: "f32", components: 2 },
1771
+ "vec3<f32>": { type: "f32", components: 3 },
1772
+ "vec4<f32>": { type: "f32", components: 4 },
1773
+ "vec2<i32>": { type: "i32", components: 2 },
1774
+ "vec3<i32>": { type: "i32", components: 3 },
1775
+ "vec4<i32>": { type: "i32", components: 4 },
1776
+ "vec2<u32>": { type: "u32", components: 2 },
1777
+ "vec3<u32>": { type: "u32", components: 3 },
1778
+ "vec4<u32>": { type: "u32", components: 4 },
1779
+ "mat2x2<f32>": { type: "f32", components: 4 },
1780
+ "mat2x3<f32>": { type: "f32", components: 6 },
1781
+ "mat2x4<f32>": { type: "f32", components: 8 },
1782
+ "mat3x2<f32>": { type: "f32", components: 6 },
1783
+ "mat3x3<f32>": { type: "f32", components: 9 },
1784
+ "mat3x4<f32>": { type: "f32", components: 12 },
1785
+ "mat4x2<f32>": { type: "f32", components: 8 },
1786
+ "mat4x3<f32>": { type: "f32", components: 12 },
1787
+ "mat4x4<f32>": { type: "f32", components: 16 }
1788
+ };
1789
+ function decodeShaderUniformType(format) {
1790
+ const decoded = UNIFORM_FORMATS[format];
1791
+ assert(format);
1792
+ return decoded;
1793
+ }
1794
+ function alignTo(size, count) {
1795
+ switch (count) {
1796
+ case 1:
1797
+ return size;
1798
+ case 2:
1799
+ return size + size % 2;
1800
+ default:
1801
+ return size + (4 - size % 4) % 4;
1802
+ }
1803
+ }
1804
+
1805
+ // src/utils/array-utils-flat.ts
1806
+ var arrayBuffer;
1807
+ function getScratchArrayBuffer(byteLength) {
1808
+ if (!arrayBuffer || arrayBuffer.byteLength < byteLength) {
1809
+ arrayBuffer = new ArrayBuffer(byteLength);
1810
+ }
1811
+ return arrayBuffer;
1812
+ }
1813
+ function getScratchArray(Type, length) {
1814
+ const scratchArrayBuffer = getScratchArrayBuffer(Type.BYTES_PER_ELEMENT * length);
1815
+ return new Type(scratchArrayBuffer, 0, length);
1816
+ }
1817
+ function fillArray(options) {
1818
+ const { target, source, start = 0, count = 1 } = options;
1819
+ const length = source.length;
1820
+ const total = count * length;
1821
+ let copied = 0;
1822
+ for (let i = start; copied < length; copied++) {
1823
+ target[i++] = source[copied];
1824
+ }
1825
+ while (copied < total) {
1826
+ if (copied < total - copied) {
1827
+ target.copyWithin(start + copied, start, start + copied);
1828
+ copied *= 2;
1829
+ } else {
1830
+ target.copyWithin(start + copied, start, start + total - copied);
1831
+ copied = total;
1832
+ }
1833
+ }
1834
+ return options.target;
1835
+ }
1836
+
1837
+ // src/lib/uniforms/uniform-buffer-layout.ts
1838
+ var minBufferSize = 1024;
1839
+ var UniformBufferLayout = class {
1840
+ layout = {};
1841
+ /** number of bytes needed for buffer allocation */
1842
+ byteLength;
1843
+ /** Create a new UniformBufferLayout given a map of attributes. */
1844
+ constructor(uniformTypes) {
1845
+ let size = 0;
1846
+ for (const [key, uniformType] of Object.entries(uniformTypes)) {
1847
+ const typeAndComponents = decodeShaderUniformType(uniformType);
1848
+ const { type, components: count } = typeAndComponents;
1849
+ size = alignTo(size, count);
1850
+ const offset = size;
1851
+ size += count;
1852
+ this.layout[key] = { type, size: count, offset };
1853
+ }
1854
+ size += (4 - size % 4) % 4;
1855
+ const actualByteLength = size * 4;
1856
+ this.byteLength = Math.max(actualByteLength, minBufferSize);
1857
+ }
1858
+ /** Get the data for the complete buffer */
1859
+ getData(uniformValues) {
1860
+ const bufferSize = Math.max(this.byteLength, minBufferSize);
1861
+ const arrayBuffer2 = getScratchArrayBuffer(bufferSize);
1862
+ const typedArrays = {
1863
+ i32: new Int32Array(arrayBuffer2),
1864
+ u32: new Uint32Array(arrayBuffer2),
1865
+ f32: new Float32Array(arrayBuffer2),
1866
+ // TODO not implemented
1867
+ f16: new Uint16Array(arrayBuffer2)
1868
+ };
1869
+ for (const [name2, value] of Object.entries(uniformValues)) {
1870
+ const uniformLayout = this.layout[name2];
1871
+ if (!uniformLayout) {
1872
+ log.warn(`Supplied uniform value ${name2} not present in uniform block layout`)();
1873
+ continue;
1874
+ }
1875
+ const { type, size, offset } = uniformLayout;
1876
+ const typedArray = typedArrays[type];
1877
+ if (size === 1) {
1878
+ if (typeof value !== "number" && typeof value !== "boolean") {
1879
+ log.warn(`Supplied value for single component uniform ${name2} is not a number: ${value}`)();
1880
+ continue;
1881
+ }
1882
+ typedArray[offset] = Number(value);
1883
+ } else {
1884
+ const numericArray = isNumberArray(value);
1885
+ if (!numericArray) {
1886
+ log.warn(`Supplied value for multi component / array uniform ${name2} is not a numeric array: ${value}`)();
1887
+ continue;
1888
+ }
1889
+ typedArray.set(numericArray, offset);
1890
+ }
1891
+ }
1892
+ return new Uint8Array(arrayBuffer2);
1893
+ }
1894
+ /** Does this layout have a field with specified name */
1895
+ has(name2) {
1896
+ return Boolean(this.layout[name2]);
1897
+ }
1898
+ /** Get offset and size for a field with specified name */
1899
+ get(name2) {
1900
+ const layout = this.layout[name2];
1901
+ return layout;
1902
+ }
1903
+ };
1904
+
1905
+ // src/utils/array-equal.ts
1906
+ function arrayEqual(a, b, limit = 16) {
1907
+ if (a !== b) {
1908
+ return false;
1909
+ }
1910
+ const arrayA = isNumberArray(a);
1911
+ if (!arrayA) {
1912
+ return false;
1913
+ }
1914
+ const arrayB = isNumberArray(b);
1915
+ if (arrayB && arrayA.length === arrayB.length) {
1916
+ for (let i = 0; i < arrayA.length; ++i) {
1917
+ if (arrayB[i] !== arrayA[i]) {
1918
+ return false;
1919
+ }
1920
+ }
1921
+ }
1922
+ return true;
1923
+ }
1924
+ function arrayCopy(a) {
1925
+ const numberArray = isNumberArray(a);
1926
+ if (numberArray) {
1927
+ return numberArray.slice();
1928
+ }
1929
+ return a;
1930
+ }
1931
+
1932
+ // src/lib/uniforms/uniform-block.ts
1933
+ var UniformBlock = class {
1934
+ name;
1935
+ uniforms = {};
1936
+ modifiedUniforms = {};
1937
+ modified = true;
1938
+ bindingLayout = {};
1939
+ needsRedraw = "initialized";
1940
+ constructor(props) {
1941
+ var _a;
1942
+ this.name = props == null ? void 0 : props.name;
1943
+ if ((props == null ? void 0 : props.name) && (props == null ? void 0 : props.shaderLayout)) {
1944
+ const binding = (_a = props == null ? void 0 : props.shaderLayout.bindings) == null ? void 0 : _a.find(
1945
+ (binding2) => binding2.type === "uniform" && binding2.name === (props == null ? void 0 : props.name)
1946
+ );
1947
+ if (!binding) {
1948
+ throw new Error(props == null ? void 0 : props.name);
1949
+ }
1950
+ const uniformBlock = binding;
1951
+ for (const uniform of uniformBlock.uniforms || []) {
1952
+ this.bindingLayout[uniform.name] = uniform;
1953
+ }
1954
+ }
1955
+ }
1956
+ /** Set a map of uniforms */
1957
+ setUniforms(uniforms) {
1958
+ for (const [key, value] of Object.entries(uniforms)) {
1959
+ this._setUniform(key, value);
1960
+ if (!this.needsRedraw) {
1961
+ this.setNeedsRedraw(`${this.name}.${key}=${value}`);
1962
+ }
1963
+ }
1964
+ }
1965
+ setNeedsRedraw(reason) {
1966
+ this.needsRedraw = this.needsRedraw || reason;
1967
+ }
1968
+ /** Returns all uniforms */
1969
+ getAllUniforms() {
1970
+ this.modifiedUniforms = {};
1971
+ this.needsRedraw = false;
1972
+ return this.uniforms || {};
1973
+ }
1974
+ /** Set a single uniform */
1975
+ _setUniform(key, value) {
1976
+ if (arrayEqual(this.uniforms[key], value)) {
1977
+ return;
1978
+ }
1979
+ this.uniforms[key] = arrayCopy(value);
1980
+ this.modifiedUniforms[key] = true;
1981
+ this.modified = true;
1982
+ }
1983
+ };
1984
+
1985
+ // src/lib/uniforms/uniform-store.ts
1986
+ var UniformStore = class {
1987
+ /** Stores the uniform values for each uniform block */
1988
+ uniformBlocks = /* @__PURE__ */ new Map();
1989
+ /** Can generate data for a uniform buffer for each block from data */
1990
+ uniformBufferLayouts = /* @__PURE__ */ new Map();
1991
+ /** Actual buffer for the blocks */
1992
+ uniformBuffers = /* @__PURE__ */ new Map();
1993
+ /**
1994
+ * Create a new UniformStore instance
1995
+ * @param blocks
1996
+ */
1997
+ constructor(blocks) {
1998
+ for (const [bufferName, block] of Object.entries(blocks)) {
1999
+ const uniformBufferName = bufferName;
2000
+ const uniformBufferLayout = new UniformBufferLayout(block.uniformTypes || {});
2001
+ this.uniformBufferLayouts.set(uniformBufferName, uniformBufferLayout);
2002
+ const uniformBlock = new UniformBlock({ name: bufferName });
2003
+ uniformBlock.setUniforms(block.defaultUniforms || {});
2004
+ this.uniformBlocks.set(uniformBufferName, uniformBlock);
2005
+ }
2006
+ }
2007
+ /** Destroy any managed uniform buffers */
2008
+ destroy() {
2009
+ for (const uniformBuffer of Object.values(this.uniformBuffers)) {
2010
+ uniformBuffer.destroy();
2011
+ }
2012
+ }
2013
+ /**
2014
+ * Set uniforms
2015
+ * Makes all properties partial
2016
+ */
2017
+ setUniforms(uniforms) {
2018
+ for (const [blockName, uniformValues] of Object.entries(uniforms)) {
2019
+ this.uniformBlocks.get(blockName).setUniforms(uniformValues);
2020
+ }
2021
+ this.updateUniformBuffers();
2022
+ }
2023
+ /** Get the required minimum length of the uniform buffer */
2024
+ getUniformBufferByteLength(uniformBufferName) {
2025
+ return this.uniformBufferLayouts.get(uniformBufferName).byteLength;
2026
+ }
2027
+ /** Get formatted binary memory that can be uploaded to a buffer */
2028
+ getUniformBufferData(uniformBufferName) {
2029
+ const uniformValues = this.uniformBlocks.get(uniformBufferName).getAllUniforms();
2030
+ return this.uniformBufferLayouts.get(uniformBufferName).getData(uniformValues);
2031
+ }
2032
+ /**
2033
+ * Creates an unmanaged uniform buffer (umnanaged means that application is responsible for destroying it)
2034
+ * The new buffer is initialized with current / supplied values
2035
+ */
2036
+ createUniformBuffer(device, uniformBufferName, uniforms) {
2037
+ if (uniforms) {
2038
+ this.setUniforms(uniforms);
2039
+ }
2040
+ const byteLength = this.getUniformBufferByteLength(uniformBufferName);
2041
+ const uniformBuffer = device.createBuffer({
2042
+ usage: Buffer2.UNIFORM | Buffer2.COPY_DST,
2043
+ byteLength
2044
+ });
2045
+ const uniformBufferData = this.getUniformBufferData(uniformBufferName);
2046
+ uniformBuffer.write(uniformBufferData);
2047
+ return uniformBuffer;
2048
+ }
2049
+ /** Get the managed uniform buffer. "managed" resources are destroyed when the uniformStore is destroyed. */
2050
+ getManagedUniformBuffer(device, uniformBufferName) {
2051
+ if (!this.uniformBuffers.get(uniformBufferName)) {
2052
+ const byteLength = this.getUniformBufferByteLength(uniformBufferName);
2053
+ const uniformBuffer = device.createBuffer({
2054
+ usage: Buffer2.UNIFORM | Buffer2.COPY_DST,
2055
+ byteLength
2056
+ });
2057
+ this.uniformBuffers.set(uniformBufferName, uniformBuffer);
2058
+ }
2059
+ return this.uniformBuffers.get(uniformBufferName);
2060
+ }
2061
+ /** Updates all uniform buffers where values have changed */
2062
+ updateUniformBuffers() {
2063
+ let reason = false;
2064
+ for (const uniformBufferName of this.uniformBlocks.keys()) {
2065
+ const bufferReason = this.updateUniformBuffer(uniformBufferName);
2066
+ reason ||= bufferReason;
2067
+ }
2068
+ if (reason) {
2069
+ log.log(3, `UniformStore.updateUniformBuffers(): ${reason}`)();
2070
+ }
2071
+ return reason;
2072
+ }
2073
+ /** Update one uniform buffer. Only updates if values have changed */
2074
+ updateUniformBuffer(uniformBufferName) {
2075
+ const uniformBlock = this.uniformBlocks.get(uniformBufferName);
2076
+ const uniformBuffer = this.uniformBuffers.get(uniformBufferName);
2077
+ let reason = false;
2078
+ if (uniformBuffer && uniformBlock.needsRedraw) {
2079
+ reason ||= uniformBlock.needsRedraw;
2080
+ const uniformBufferData = this.getUniformBufferData(uniformBufferName);
2081
+ const uniformBuffer2 = this.uniformBuffers.get(uniformBufferName);
2082
+ uniformBuffer2.write(uniformBufferData);
2083
+ const uniformValues = this.uniformBlocks.get(uniformBufferName).getAllUniforms();
2084
+ log.log(
2085
+ 4,
2086
+ `Writing to uniform buffer ${String(uniformBufferName)}`,
2087
+ uniformBufferData,
2088
+ uniformValues
2089
+ )();
2090
+ }
2091
+ return reason;
2092
+ }
2093
+ };
2094
+
2095
+ // src/adapter/type-utils/decode-texture-format.ts
2096
+ var REGEX = /^(rg?b?a?)([0-9]*)([a-z]*)(-srgb)?(-webgl|-unsized)?$/;
2097
+ function decodeTextureFormat(format) {
2098
+ const matches = REGEX.exec(format);
2099
+ if (matches) {
2100
+ const [, format2, length, type, srgb, suffix] = matches;
2101
+ if (format2) {
2102
+ const dataType = `${type}${length}`;
2103
+ const decodedType = decodeVertexType(dataType);
2104
+ return {
2105
+ format: format2,
2106
+ components: format2.length,
2107
+ // dataType - overwritten by decodedType
2108
+ srgb: srgb === "-srgb",
2109
+ unsized: suffix === "-unsized",
2110
+ webgl: suffix === "-webgl",
2111
+ ...decodedType
2112
+ };
2113
+ }
2114
+ }
2115
+ return decodeNonStandardFormat(format);
2116
+ }
2117
+ var EXCEPTIONS = {
2118
+ // Packed 16 bit formats
2119
+ "rgba4unorm-webgl": { format: "rgba", bpp: 2 },
2120
+ "rgb565unorm-webgl": { format: "rgb", bpp: 2 },
2121
+ "rgb5a1unorm-webgl": { format: "rgba", bbp: 2 },
2122
+ // Packed 32 bit formats
2123
+ "rgb9e5ufloat": { format: "rgb", bbp: 4 },
2124
+ "rg11b10ufloat": { format: "rgb", bbp: 4 },
2125
+ "rgb10a2unorm": { format: "rgba", bbp: 4 },
2126
+ "rgb10a2unorm-webgl": { format: "rgba", bbp: 4 },
2127
+ // Depth/stencil
2128
+ "stencil8": { components: 1, bpp: 1, a: "stencil" },
2129
+ "depth16unorm": { components: 1, bpp: 2, a: "depth" },
2130
+ "depth24plus": { components: 1, bpp: 3, a: "depth" },
2131
+ "depth32float": { components: 1, bpp: 4, a: "depth" },
2132
+ "depth24plus-stencil8": { components: 2, bpp: 4, a: "depth-stencil" },
2133
+ // "depth24unorm-stencil8" feature
2134
+ "depth24unorm-stencil8": { components: 2, bpp: 4, a: "depth-stencil" },
2135
+ // "depth32float-stencil8" feature
2136
+ "depth32float-stencil8": { components: 2, bpp: 4, a: "depth-stencil" }
2137
+ };
2138
+ function decodeNonStandardFormat(format) {
2139
+ var _a;
2140
+ const data = EXCEPTIONS[format];
2141
+ if (!data) {
2142
+ throw new Error(`Unknown format ${format}`);
2143
+ }
2144
+ return {
2145
+ format: data.format || "",
2146
+ components: data.components || ((_a = data.format) == null ? void 0 : _a.length) || 1,
2147
+ byteLength: data.bpp || 1,
2148
+ srgb: false,
2149
+ unsized: false
2150
+ };
2151
+ }
2152
+
2153
+ // src/adapter/type-utils/vertex-format-from-attribute.ts
2154
+ function getDataTypeFromTypedArray(arrayOrType) {
2155
+ const type = ArrayBuffer.isView(arrayOrType) ? arrayOrType.constructor : arrayOrType;
2156
+ switch (type) {
2157
+ case Float32Array:
2158
+ return "float32";
2159
+ case Uint16Array:
2160
+ return "uint16";
2161
+ case Uint32Array:
2162
+ return "uint32";
2163
+ case Uint8Array:
2164
+ case Uint8ClampedArray:
2165
+ return "uint8";
2166
+ case Int8Array:
2167
+ return "sint8";
2168
+ case Int16Array:
2169
+ return "sint16";
2170
+ case Int32Array:
2171
+ return "sint32";
2172
+ default:
2173
+ throw new Error(type.constructor.name);
2174
+ }
2175
+ }
2176
+ function getTypedArrayFromDataType(dataType) {
2177
+ switch (dataType) {
2178
+ case "float32":
2179
+ return Float32Array;
2180
+ case "uint32":
2181
+ return Uint32Array;
2182
+ case "sint32":
2183
+ return Int32Array;
2184
+ case "uint16":
2185
+ case "unorm16":
2186
+ return Uint16Array;
2187
+ case "sint16":
2188
+ case "snorm16":
2189
+ return Int16Array;
2190
+ case "uint8":
2191
+ case "unorm8":
2192
+ return Uint8Array;
2193
+ case "sint8":
2194
+ case "snorm8":
2195
+ return Int8Array;
2196
+ default:
2197
+ throw new Error(dataType);
2198
+ }
2199
+ }
2200
+ function getVertexFormatFromAttribute(typedArray, size, normalized) {
2201
+ if (!size || size > 4) {
2202
+ throw new Error(`size ${size}`);
2203
+ }
2204
+ const components = size;
2205
+ let dataType = getDataTypeFromTypedArray(typedArray);
2206
+ if (dataType === "uint8" || dataType === "sint8") {
2207
+ if (components === 1 || components === 3) {
2208
+ throw new Error(`size: ${size}`);
2209
+ }
2210
+ if (normalized) {
2211
+ dataType = dataType.replace("int", "norm");
2212
+ }
2213
+ return `${dataType}x${components}`;
2214
+ }
2215
+ if (dataType === "uint16" || dataType === "sint16") {
2216
+ if (components === 1 || components === 3) {
2217
+ throw new Error(`size: ${size}`);
2218
+ }
2219
+ if (normalized) {
2220
+ dataType = dataType.replace("int", "norm");
2221
+ }
2222
+ return `${dataType}x${components}`;
2223
+ }
2224
+ if (components === 1) {
2225
+ return dataType;
2226
+ }
2227
+ return `${dataType}x${components}`;
2228
+ }
2229
+
2230
+ // src/utils/cast.ts
2231
+ function cast(value) {
2232
+ return value;
2233
+ }
2234
+
2235
+ // src/lib/uniforms/uniform.ts
2236
+ function isUniformValue(value) {
2237
+ return isNumberArray(value) !== null || typeof value === "number" || typeof value === "boolean";
2238
+ }
2239
+ function splitUniformsAndBindings(uniforms) {
2240
+ const result = { bindings: {}, uniforms: {} };
2241
+ Object.keys(uniforms).forEach((name2) => {
2242
+ const uniform = uniforms[name2];
2243
+ if (isUniformValue(uniform)) {
2244
+ result.uniforms[name2] = uniform;
2245
+ } else {
2246
+ result.bindings[name2] = uniform;
2247
+ }
2248
+ });
2249
+ return result;
2250
+ }
2251
+
2252
+ // src/utils/format-value.ts
2253
+ function formatArrayValue(v, opts = {}) {
2254
+ const { maxElts = 16, size = 1 } = opts;
2255
+ let string = "[";
2256
+ for (let i = 0; i < v.length && i < maxElts; ++i) {
2257
+ if (i > 0) {
2258
+ string += `,${i % size === 0 ? " " : ""}`;
2259
+ }
2260
+ string += formatValue(v[i], opts);
2261
+ }
2262
+ const terminator = v.length > maxElts ? "..." : "]";
2263
+ return `${string}${terminator}`;
2264
+ }
2265
+ function formatValue(v, opts = {}) {
2266
+ const EPSILON = 1e-16;
2267
+ const { isInteger = false } = opts;
2268
+ if (Array.isArray(v) || ArrayBuffer.isView(v)) {
2269
+ return formatArrayValue(v, opts);
2270
+ }
2271
+ if (typeof v !== "number") {
2272
+ return String(v);
2273
+ }
2274
+ if (Math.abs(v) < EPSILON) {
2275
+ return isInteger ? "0" : "0.";
2276
+ }
2277
+ if (isInteger) {
2278
+ return v.toFixed(0);
2279
+ }
2280
+ if (Math.abs(v) > 100 && Math.abs(v) < 1e4) {
2281
+ return v.toFixed(0);
2282
+ }
2283
+ const string = v.toPrecision(2);
2284
+ const decimal = string.indexOf(".0");
2285
+ return decimal === string.length - 2 ? string.slice(0, -1) : string;
2286
+ }
2287
+
2288
+ // src/utils/stub-methods.ts
2289
+ function stubRemovedMethods(instance, className, version, methodNames) {
2290
+ const upgradeMessage = `See luma.gl ${version} Upgrade Guide at https://luma.gl/docs/upgrade-guide`;
2291
+ const prototype = Object.getPrototypeOf(instance);
2292
+ methodNames.forEach((methodName) => {
2293
+ if (prototype.methodName) {
2294
+ return;
2295
+ }
2296
+ prototype[methodName] = () => {
2297
+ log.removed(`Calling removed method ${className}.${methodName}: `, upgradeMessage)();
2298
+ throw new Error(methodName);
2299
+ };
2300
+ });
2301
+ }
2302
+
2303
+ // src/utils/check-props.ts
2304
+ function checkProps(className, props, propChecks) {
2305
+ const { removedProps = {}, deprecatedProps = {}, replacedProps = {} } = propChecks;
2306
+ for (const propName in removedProps) {
2307
+ if (propName in props) {
2308
+ const replacementProp = removedProps[propName];
2309
+ const replacement = replacementProp ? `${className}.${removedProps[propName]}` : "N/A";
2310
+ log.removed(`${className}.${propName}`, replacement)();
2311
+ }
2312
+ }
2313
+ for (const propName in deprecatedProps) {
2314
+ if (propName in props) {
2315
+ const replacementProp = deprecatedProps[propName];
2316
+ log.deprecated(`${className}.${propName}`, `${className}.${replacementProp}`)();
2317
+ }
2318
+ }
2319
+ let newProps = null;
2320
+ for (const [propName, replacementProp] of Object.entries(replacedProps)) {
2321
+ if (propName in props) {
2322
+ log.deprecated(`${className}.${propName}`, `${className}.${replacementProp}`)();
2323
+ newProps = newProps || Object.assign({}, props);
2324
+ newProps[replacementProp] = props[propName];
2325
+ delete newProps[propName];
2326
+ }
2327
+ }
2328
+ return newProps || props;
2329
+ }
2330
+
2331
+ // src/utils/load-file.ts
2332
+ var pathPrefix = "";
2333
+ function setPathPrefix(prefix) {
2334
+ pathPrefix = prefix;
2335
+ }
2336
+ async function loadFile(url, options) {
2337
+ url = url.startsWith("http") ? url : pathPrefix + url;
2338
+ const dataType = (options == null ? void 0 : options.dataType) || "text";
2339
+ const response = await fetch(url, options);
2340
+ return await response[dataType]();
2341
+ }
2342
+ async function loadImageBitmap(url, opts) {
2343
+ const image = new Image();
2344
+ image.crossOrigin = (opts == null ? void 0 : opts.crossOrigin) || "anonymous";
2345
+ image.src = url.startsWith("http") ? url : pathPrefix + url;
2346
+ await image.decode();
2347
+ return await createImageBitmap(image);
2348
+ }
2349
+ async function loadImage(url, opts) {
2350
+ return new Promise((resolve, reject) => {
2351
+ try {
2352
+ const image = new Image();
2353
+ image.onload = () => resolve(image);
2354
+ image.onerror = () => reject(new Error(`Could not load image ${url}.`));
2355
+ image.crossOrigin = (opts == null ? void 0 : opts.crossOrigin) || "anonymous";
2356
+ image.src = url.startsWith("http") ? url : pathPrefix + url;
2357
+ } catch (error) {
2358
+ reject(error);
2359
+ }
2360
+ });
2361
+ }
2362
+ async function loadScript(scriptUrl, scriptId) {
2363
+ const head = document.getElementsByTagName("head")[0];
2364
+ if (!head) {
2365
+ throw new Error("loadScript");
2366
+ }
2367
+ const script = document.createElement("script");
2368
+ script.setAttribute("type", "text/javascript");
2369
+ script.setAttribute("src", scriptUrl);
2370
+ if (scriptId) {
2371
+ script.id = scriptId;
2372
+ }
2373
+ return new Promise((resolve, reject) => {
2374
+ script.onload = resolve;
2375
+ script.onerror = (error) => reject(new Error(`Unable to load script '${scriptUrl}': ${error}`));
2376
+ head.appendChild(script);
2377
+ });
2378
+ }
2379
+
2380
+ // src/utils/random.ts
2381
+ function makeRandomNumberGenerator() {
2382
+ let s = 1;
2383
+ let c = 1;
2384
+ return () => {
2385
+ s = Math.sin(c * 17.23);
2386
+ c = Math.cos(s * 27.92);
2387
+ return fract(Math.abs(s * c) * 1432.71);
2388
+ };
2389
+ }
2390
+ function fract(n) {
2391
+ return n - Math.floor(n);
2392
+ }
2393
+ var random = makeRandomNumberGenerator();
2394
+
2395
+ // src/utils/deep-equal.ts
2396
+ function deepEqual(a, b, depth) {
2397
+ if (a === b) {
2398
+ return true;
2399
+ }
2400
+ if (!depth || !a || !b) {
2401
+ return false;
2402
+ }
2403
+ if (Array.isArray(a)) {
2404
+ if (!Array.isArray(b) || a.length !== b.length) {
2405
+ return false;
2406
+ }
2407
+ for (let i = 0; i < a.length; i++) {
2408
+ if (!deepEqual(a[i], b[i], depth - 1)) {
2409
+ return false;
2410
+ }
2411
+ }
2412
+ return true;
2413
+ }
2414
+ if (Array.isArray(b)) {
2415
+ return false;
2416
+ }
2417
+ if (typeof a === "object" && typeof b === "object") {
2418
+ const aKeys = Object.keys(a);
2419
+ const bKeys = Object.keys(b);
2420
+ if (aKeys.length !== bKeys.length) {
2421
+ return false;
2422
+ }
2423
+ for (const key of aKeys) {
2424
+ if (!b.hasOwnProperty(key)) {
2425
+ return false;
2426
+ }
2427
+ if (!deepEqual(a[key], b[key], depth - 1)) {
2428
+ return false;
2429
+ }
2430
+ }
2431
+ return true;
2432
+ }
2433
+ return false;
2434
+ }
2435
+
2436
+ // src/utils/request-animation-frame.ts
2437
+ function requestAnimationFrame(callback) {
2438
+ return typeof window !== "undefined" && window.requestAnimationFrame ? window.requestAnimationFrame(callback) : setTimeout(callback, 1e3 / 60);
2439
+ }
2440
+ function cancelAnimationFrame(timerId) {
2441
+ return typeof window !== "undefined" && window.cancelAnimationFrame ? window.cancelAnimationFrame(timerId) : clearTimeout(timerId);
2442
+ }
2443
+
2444
+ // src/index.ts
2445
+ var glsl = (x) => `${x}`;