@luma.gl/core 9.2.6 → 9.3.0-alpha.10

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 (280) hide show
  1. package/dist/adapter/canvas-context.d.ts +6 -162
  2. package/dist/adapter/canvas-context.d.ts.map +1 -1
  3. package/dist/adapter/canvas-context.js +5 -419
  4. package/dist/adapter/canvas-context.js.map +1 -1
  5. package/dist/adapter/canvas-observer.d.ts +32 -0
  6. package/dist/adapter/canvas-observer.d.ts.map +1 -0
  7. package/dist/adapter/canvas-observer.js +90 -0
  8. package/dist/adapter/canvas-observer.js.map +1 -0
  9. package/dist/adapter/canvas-surface.d.ts +150 -0
  10. package/dist/adapter/canvas-surface.d.ts.map +1 -0
  11. package/dist/adapter/canvas-surface.js +392 -0
  12. package/dist/adapter/canvas-surface.js.map +1 -0
  13. package/dist/adapter/device.d.ts +81 -16
  14. package/dist/adapter/device.d.ts.map +1 -1
  15. package/dist/adapter/device.js +191 -10
  16. package/dist/adapter/device.js.map +1 -1
  17. package/dist/adapter/luma.js +1 -1
  18. package/dist/adapter/luma.js.map +1 -1
  19. package/dist/adapter/presentation-context.d.ts +11 -0
  20. package/dist/adapter/presentation-context.d.ts.map +1 -0
  21. package/dist/adapter/presentation-context.js +12 -0
  22. package/dist/adapter/presentation-context.js.map +1 -0
  23. package/dist/adapter/resources/buffer.d.ts +1 -1
  24. package/dist/adapter/resources/buffer.d.ts.map +1 -1
  25. package/dist/adapter/resources/buffer.js +14 -6
  26. package/dist/adapter/resources/buffer.js.map +1 -1
  27. package/dist/adapter/resources/command-buffer.d.ts +3 -1
  28. package/dist/adapter/resources/command-buffer.d.ts.map +1 -1
  29. package/dist/adapter/resources/command-buffer.js +3 -1
  30. package/dist/adapter/resources/command-buffer.js.map +1 -1
  31. package/dist/adapter/resources/command-encoder.d.ts +30 -7
  32. package/dist/adapter/resources/command-encoder.d.ts.map +1 -1
  33. package/dist/adapter/resources/command-encoder.js +68 -2
  34. package/dist/adapter/resources/command-encoder.js.map +1 -1
  35. package/dist/adapter/resources/compute-pipeline.d.ts +2 -2
  36. package/dist/adapter/resources/compute-pipeline.d.ts.map +1 -1
  37. package/dist/adapter/resources/fence.d.ts +16 -0
  38. package/dist/adapter/resources/fence.d.ts.map +1 -0
  39. package/dist/adapter/resources/fence.js +17 -0
  40. package/dist/adapter/resources/fence.js.map +1 -0
  41. package/dist/adapter/resources/framebuffer.d.ts +1 -1
  42. package/dist/adapter/resources/framebuffer.d.ts.map +1 -1
  43. package/dist/adapter/resources/framebuffer.js +15 -12
  44. package/dist/adapter/resources/framebuffer.js.map +1 -1
  45. package/dist/adapter/resources/query-set.d.ts +17 -1
  46. package/dist/adapter/resources/query-set.d.ts.map +1 -1
  47. package/dist/adapter/resources/query-set.js.map +1 -1
  48. package/dist/adapter/resources/render-pipeline.d.ts +28 -10
  49. package/dist/adapter/resources/render-pipeline.d.ts.map +1 -1
  50. package/dist/adapter/resources/render-pipeline.js +21 -2
  51. package/dist/adapter/resources/render-pipeline.js.map +1 -1
  52. package/dist/adapter/resources/resource.d.ts +13 -0
  53. package/dist/adapter/resources/resource.d.ts.map +1 -1
  54. package/dist/adapter/resources/resource.js +243 -14
  55. package/dist/adapter/resources/resource.js.map +1 -1
  56. package/dist/adapter/resources/shader.js +27 -25
  57. package/dist/adapter/resources/shader.js.map +1 -1
  58. package/dist/adapter/resources/shared-render-pipeline.d.ts +22 -0
  59. package/dist/adapter/resources/shared-render-pipeline.d.ts.map +1 -0
  60. package/dist/adapter/resources/shared-render-pipeline.js +25 -0
  61. package/dist/adapter/resources/shared-render-pipeline.js.map +1 -0
  62. package/dist/adapter/resources/texture-view.d.ts +1 -1
  63. package/dist/adapter/resources/texture-view.d.ts.map +1 -1
  64. package/dist/adapter/resources/texture.d.ts +168 -28
  65. package/dist/adapter/resources/texture.d.ts.map +1 -1
  66. package/dist/adapter/resources/texture.js +284 -25
  67. package/dist/adapter/resources/texture.js.map +1 -1
  68. package/dist/adapter/types/attachments.d.ts +1 -1
  69. package/dist/adapter/types/attachments.d.ts.map +1 -1
  70. package/dist/adapter/types/buffer-layout.d.ts +1 -1
  71. package/dist/adapter/types/buffer-layout.d.ts.map +1 -1
  72. package/dist/adapter/types/parameters.d.ts +3 -1
  73. package/dist/adapter/types/parameters.d.ts.map +1 -1
  74. package/dist/adapter/types/parameters.js +1 -0
  75. package/dist/adapter/types/parameters.js.map +1 -1
  76. package/dist/adapter/types/shader-layout.d.ts +10 -6
  77. package/dist/adapter/types/shader-layout.d.ts.map +1 -1
  78. package/dist/adapter/types/uniforms.d.ts +6 -0
  79. package/dist/adapter/types/uniforms.d.ts.map +1 -1
  80. package/dist/adapter-utils/bind-groups.d.ts +9 -0
  81. package/dist/adapter-utils/bind-groups.d.ts.map +1 -0
  82. package/dist/adapter-utils/bind-groups.js +41 -0
  83. package/dist/adapter-utils/bind-groups.js.map +1 -0
  84. package/dist/adapter-utils/format-compiler-log.d.ts.map +1 -1
  85. package/dist/adapter-utils/format-compiler-log.js +23 -15
  86. package/dist/adapter-utils/format-compiler-log.js.map +1 -1
  87. package/dist/adapter-utils/get-attribute-from-layouts.d.ts +2 -2
  88. package/dist/adapter-utils/get-attribute-from-layouts.d.ts.map +1 -1
  89. package/dist/adapter-utils/get-attribute-from-layouts.js +6 -6
  90. package/dist/adapter-utils/get-attribute-from-layouts.js.map +1 -1
  91. package/dist/dist.dev.js +2686 -644
  92. package/dist/dist.min.js +10 -9
  93. package/dist/factories/bind-group-factory.d.ts +20 -0
  94. package/dist/factories/bind-group-factory.d.ts.map +1 -0
  95. package/dist/factories/bind-group-factory.js +79 -0
  96. package/dist/factories/bind-group-factory.js.map +1 -0
  97. package/dist/factories/core-module-state.d.ts +7 -0
  98. package/dist/factories/core-module-state.d.ts.map +1 -0
  99. package/dist/{shadertypes/data-types/shader-types.js → factories/core-module-state.js} +1 -1
  100. package/dist/factories/core-module-state.js.map +1 -0
  101. package/dist/factories/pipeline-factory.d.ts +54 -0
  102. package/dist/factories/pipeline-factory.d.ts.map +1 -0
  103. package/dist/factories/pipeline-factory.js +270 -0
  104. package/dist/factories/pipeline-factory.js.map +1 -0
  105. package/dist/factories/shader-factory.d.ts +20 -0
  106. package/dist/factories/shader-factory.d.ts.map +1 -0
  107. package/dist/factories/shader-factory.js +84 -0
  108. package/dist/factories/shader-factory.js.map +1 -0
  109. package/dist/index.cjs +2422 -554
  110. package/dist/index.cjs.map +4 -4
  111. package/dist/index.d.ts +30 -14
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +19 -7
  114. package/dist/index.js.map +1 -1
  115. package/dist/portable/shader-block-writer.d.ts +51 -0
  116. package/dist/portable/shader-block-writer.d.ts.map +1 -0
  117. package/dist/portable/shader-block-writer.js +185 -0
  118. package/dist/portable/shader-block-writer.js.map +1 -0
  119. package/dist/portable/uniform-block.d.ts +1 -1
  120. package/dist/portable/uniform-block.d.ts.map +1 -1
  121. package/dist/portable/uniform-store.d.ts +55 -24
  122. package/dist/portable/uniform-store.d.ts.map +1 -1
  123. package/dist/portable/uniform-store.js +73 -25
  124. package/dist/portable/uniform-store.js.map +1 -1
  125. package/dist/shadertypes/data-types/data-type-decoder.d.ts +20 -0
  126. package/dist/shadertypes/data-types/data-type-decoder.d.ts.map +1 -0
  127. package/dist/shadertypes/data-types/data-type-decoder.js +79 -0
  128. package/dist/shadertypes/data-types/data-type-decoder.js.map +1 -0
  129. package/dist/shadertypes/data-types/data-types.d.ts +31 -12
  130. package/dist/shadertypes/data-types/data-types.d.ts.map +1 -1
  131. package/dist/shadertypes/data-types/decode-data-types.d.ts.map +1 -1
  132. package/dist/shadertypes/data-types/decode-data-types.js +2 -1
  133. package/dist/shadertypes/data-types/decode-data-types.js.map +1 -1
  134. package/dist/{image-utils → shadertypes/image-types}/image-types.d.ts +0 -6
  135. package/dist/shadertypes/image-types/image-types.d.ts.map +1 -0
  136. package/dist/shadertypes/image-types/image-types.js.map +1 -0
  137. package/dist/shadertypes/shader-types/shader-block-layout.d.ts +72 -0
  138. package/dist/shadertypes/shader-types/shader-block-layout.d.ts.map +1 -0
  139. package/dist/shadertypes/shader-types/shader-block-layout.js +209 -0
  140. package/dist/shadertypes/shader-types/shader-block-layout.js.map +1 -0
  141. package/dist/shadertypes/shader-types/shader-type-decoder.d.ts +41 -0
  142. package/dist/shadertypes/shader-types/shader-type-decoder.d.ts.map +1 -0
  143. package/dist/shadertypes/{data-types/decode-shader-types.js → shader-types/shader-type-decoder.js} +43 -4
  144. package/dist/shadertypes/shader-types/shader-type-decoder.js.map +1 -0
  145. package/dist/shadertypes/shader-types/shader-types.d.ts +101 -0
  146. package/dist/shadertypes/shader-types/shader-types.d.ts.map +1 -0
  147. package/dist/shadertypes/shader-types/shader-types.js +30 -0
  148. package/dist/shadertypes/shader-types/shader-types.js.map +1 -0
  149. package/dist/shadertypes/texture-types/pixel-utils.d.ts.map +1 -0
  150. package/dist/shadertypes/{textures → texture-types}/pixel-utils.js +4 -4
  151. package/dist/shadertypes/texture-types/pixel-utils.js.map +1 -0
  152. package/dist/shadertypes/texture-types/texture-format-decoder.d.ts +36 -0
  153. package/dist/shadertypes/texture-types/texture-format-decoder.d.ts.map +1 -0
  154. package/dist/shadertypes/{textures → texture-types}/texture-format-decoder.js +109 -37
  155. package/dist/shadertypes/texture-types/texture-format-decoder.js.map +1 -0
  156. package/dist/shadertypes/texture-types/texture-format-generics.d.ts +34 -0
  157. package/dist/shadertypes/texture-types/texture-format-generics.d.ts.map +1 -0
  158. package/dist/shadertypes/texture-types/texture-format-generics.js.map +1 -0
  159. package/dist/shadertypes/texture-types/texture-format-table.d.ts.map +1 -0
  160. package/dist/shadertypes/{textures → texture-types}/texture-format-table.js +10 -9
  161. package/dist/shadertypes/texture-types/texture-format-table.js.map +1 -0
  162. package/dist/shadertypes/{textures → texture-types}/texture-formats.d.ts +51 -17
  163. package/dist/shadertypes/texture-types/texture-formats.d.ts.map +1 -0
  164. package/dist/shadertypes/{textures → texture-types}/texture-formats.js +1 -0
  165. package/dist/shadertypes/texture-types/texture-formats.js.map +1 -0
  166. package/dist/shadertypes/texture-types/texture-layout.d.ts +5 -0
  167. package/dist/shadertypes/texture-types/texture-layout.d.ts.map +1 -0
  168. package/dist/shadertypes/texture-types/texture-layout.js +41 -0
  169. package/dist/shadertypes/texture-types/texture-layout.js.map +1 -0
  170. package/dist/shadertypes/vertex-types/vertex-format-decoder.d.ts +24 -0
  171. package/dist/shadertypes/vertex-types/vertex-format-decoder.d.ts.map +1 -0
  172. package/dist/shadertypes/vertex-types/vertex-format-decoder.js +106 -0
  173. package/dist/shadertypes/vertex-types/vertex-format-decoder.js.map +1 -0
  174. package/dist/shadertypes/vertex-types/vertex-formats.d.ts +50 -0
  175. package/dist/shadertypes/vertex-types/vertex-formats.d.ts.map +1 -0
  176. package/dist/shadertypes/vertex-types/vertex-formats.js.map +1 -0
  177. package/dist/utils/array-equal.d.ts +1 -1
  178. package/dist/utils/array-equal.d.ts.map +1 -1
  179. package/dist/utils/array-equal.js +15 -9
  180. package/dist/utils/array-equal.js.map +1 -1
  181. package/dist/utils/assert.d.ts +5 -0
  182. package/dist/utils/assert.d.ts.map +1 -0
  183. package/dist/utils/assert.js +17 -0
  184. package/dist/utils/assert.js.map +1 -0
  185. package/dist/utils/stats-manager.d.ts.map +1 -1
  186. package/dist/utils/stats-manager.js +61 -1
  187. package/dist/utils/stats-manager.js.map +1 -1
  188. package/package.json +6 -6
  189. package/src/adapter/canvas-context.ts +7 -556
  190. package/src/adapter/canvas-observer.ts +130 -0
  191. package/src/adapter/canvas-surface.ts +521 -0
  192. package/src/adapter/device.ts +308 -24
  193. package/src/adapter/presentation-context.ts +16 -0
  194. package/src/adapter/resources/buffer.ts +13 -5
  195. package/src/adapter/resources/command-buffer.ts +4 -2
  196. package/src/adapter/resources/command-encoder.ts +101 -10
  197. package/src/adapter/resources/compute-pipeline.ts +2 -2
  198. package/src/adapter/resources/fence.ts +32 -0
  199. package/src/adapter/resources/framebuffer.ts +16 -13
  200. package/src/adapter/resources/query-set.ts +17 -1
  201. package/src/adapter/resources/render-pipeline.ts +52 -16
  202. package/src/adapter/resources/resource.ts +289 -14
  203. package/src/adapter/resources/shader.ts +28 -28
  204. package/src/adapter/resources/shared-render-pipeline.ts +40 -0
  205. package/src/adapter/resources/texture-view.ts +1 -1
  206. package/src/adapter/resources/texture.ts +427 -49
  207. package/src/adapter/types/attachments.ts +1 -1
  208. package/src/adapter/types/buffer-layout.ts +1 -1
  209. package/src/adapter/types/parameters.ts +4 -1
  210. package/src/adapter/types/shader-layout.ts +15 -9
  211. package/src/adapter/types/uniforms.ts +12 -0
  212. package/src/adapter-utils/bind-groups.ts +71 -0
  213. package/src/adapter-utils/format-compiler-log.ts +23 -15
  214. package/src/adapter-utils/get-attribute-from-layouts.ts +8 -11
  215. package/src/factories/bind-group-factory.ts +139 -0
  216. package/src/factories/core-module-state.ts +11 -0
  217. package/src/factories/pipeline-factory.ts +328 -0
  218. package/src/factories/shader-factory.ts +103 -0
  219. package/src/index.ts +70 -26
  220. package/src/portable/shader-block-writer.ts +254 -0
  221. package/src/portable/uniform-block.ts +1 -1
  222. package/src/portable/uniform-store.ts +98 -40
  223. package/src/shadertypes/data-types/data-type-decoder.ts +105 -0
  224. package/src/shadertypes/data-types/data-types.ts +100 -48
  225. package/src/shadertypes/data-types/decode-data-types.ts +2 -1
  226. package/src/{image-utils → shadertypes/image-types}/image-types.ts +0 -7
  227. package/src/shadertypes/shader-types/shader-block-layout.ts +340 -0
  228. package/src/shadertypes/{data-types/decode-shader-types.ts → shader-types/shader-type-decoder.ts} +88 -14
  229. package/src/shadertypes/shader-types/shader-types.ts +207 -0
  230. package/src/shadertypes/{textures → texture-types}/pixel-utils.ts +4 -4
  231. package/src/shadertypes/{textures → texture-types}/texture-format-decoder.ts +166 -45
  232. package/src/shadertypes/{textures → texture-types}/texture-format-generics.ts +42 -48
  233. package/src/shadertypes/{textures → texture-types}/texture-format-table.ts +10 -9
  234. package/src/shadertypes/{textures → texture-types}/texture-formats.ts +73 -17
  235. package/src/shadertypes/texture-types/texture-layout.ts +60 -0
  236. package/src/shadertypes/vertex-types/vertex-format-decoder.ts +131 -0
  237. package/src/shadertypes/vertex-types/vertex-formats.ts +183 -0
  238. package/src/utils/array-equal.ts +21 -9
  239. package/src/utils/assert.ts +18 -0
  240. package/src/utils/stats-manager.ts +76 -2
  241. package/dist/image-utils/image-types.d.ts.map +0 -1
  242. package/dist/image-utils/image-types.js.map +0 -1
  243. package/dist/portable/uniform-buffer-layout.d.ts +0 -28
  244. package/dist/portable/uniform-buffer-layout.d.ts.map +0 -1
  245. package/dist/portable/uniform-buffer-layout.js +0 -96
  246. package/dist/portable/uniform-buffer-layout.js.map +0 -1
  247. package/dist/shadertypes/data-types/decode-shader-types.d.ts +0 -17
  248. package/dist/shadertypes/data-types/decode-shader-types.d.ts.map +0 -1
  249. package/dist/shadertypes/data-types/decode-shader-types.js.map +0 -1
  250. package/dist/shadertypes/data-types/shader-types.d.ts +0 -45
  251. package/dist/shadertypes/data-types/shader-types.d.ts.map +0 -1
  252. package/dist/shadertypes/data-types/shader-types.js.map +0 -1
  253. package/dist/shadertypes/textures/pixel-utils.d.ts.map +0 -1
  254. package/dist/shadertypes/textures/pixel-utils.js.map +0 -1
  255. package/dist/shadertypes/textures/texture-format-decoder.d.ts +0 -18
  256. package/dist/shadertypes/textures/texture-format-decoder.d.ts.map +0 -1
  257. package/dist/shadertypes/textures/texture-format-decoder.js.map +0 -1
  258. package/dist/shadertypes/textures/texture-format-generics.d.ts +0 -33
  259. package/dist/shadertypes/textures/texture-format-generics.d.ts.map +0 -1
  260. package/dist/shadertypes/textures/texture-format-generics.js.map +0 -1
  261. package/dist/shadertypes/textures/texture-format-table.d.ts.map +0 -1
  262. package/dist/shadertypes/textures/texture-format-table.js.map +0 -1
  263. package/dist/shadertypes/textures/texture-formats.d.ts.map +0 -1
  264. package/dist/shadertypes/textures/texture-formats.js.map +0 -1
  265. package/dist/shadertypes/vertex-arrays/decode-vertex-format.d.ts +0 -18
  266. package/dist/shadertypes/vertex-arrays/decode-vertex-format.d.ts.map +0 -1
  267. package/dist/shadertypes/vertex-arrays/decode-vertex-format.js +0 -100
  268. package/dist/shadertypes/vertex-arrays/decode-vertex-format.js.map +0 -1
  269. package/dist/shadertypes/vertex-arrays/vertex-formats.d.ts +0 -27
  270. package/dist/shadertypes/vertex-arrays/vertex-formats.d.ts.map +0 -1
  271. package/dist/shadertypes/vertex-arrays/vertex-formats.js.map +0 -1
  272. package/src/portable/uniform-buffer-layout.ts +0 -118
  273. package/src/shadertypes/data-types/shader-types.ts +0 -87
  274. package/src/shadertypes/vertex-arrays/decode-vertex-format.ts +0 -124
  275. package/src/shadertypes/vertex-arrays/vertex-formats.ts +0 -91
  276. /package/dist/{image-utils → shadertypes/image-types}/image-types.js +0 -0
  277. /package/dist/shadertypes/{textures → texture-types}/pixel-utils.d.ts +0 -0
  278. /package/dist/shadertypes/{textures → texture-types}/texture-format-generics.js +0 -0
  279. /package/dist/shadertypes/{textures → texture-types}/texture-format-table.d.ts +0 -0
  280. /package/dist/shadertypes/{vertex-arrays → vertex-types}/vertex-formats.js +0 -0
@@ -3,8 +3,76 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import type {Device} from '../device';
6
+ import type {Stat, Stats} from '@probe.gl/stats';
6
7
  import {uid} from '../../utils/uid';
7
8
 
9
+ const CPU_HOTSPOT_PROFILER_MODULE = 'cpu-hotspot-profiler';
10
+ const RESOURCE_COUNTS_STATS = 'GPU Resource Counts';
11
+ const LEGACY_RESOURCE_COUNTS_STATS = 'Resource Counts';
12
+ const GPU_TIME_AND_MEMORY_STATS = 'GPU Time and Memory';
13
+ const BASE_RESOURCE_COUNT_ORDER = [
14
+ 'Resources',
15
+ 'Buffers',
16
+ 'Textures',
17
+ 'Samplers',
18
+ 'TextureViews',
19
+ 'Framebuffers',
20
+ 'QuerySets',
21
+ 'Shaders',
22
+ 'RenderPipelines',
23
+ 'ComputePipelines',
24
+ 'PipelineLayouts',
25
+ 'VertexArrays',
26
+ 'RenderPasss',
27
+ 'ComputePasss',
28
+ 'CommandEncoders',
29
+ 'CommandBuffers'
30
+ ] as const;
31
+ const WEBGL_RESOURCE_COUNT_ORDER = [
32
+ 'Resources',
33
+ 'Buffers',
34
+ 'Textures',
35
+ 'Samplers',
36
+ 'TextureViews',
37
+ 'Framebuffers',
38
+ 'QuerySets',
39
+ 'Shaders',
40
+ 'RenderPipelines',
41
+ 'SharedRenderPipelines',
42
+ 'ComputePipelines',
43
+ 'PipelineLayouts',
44
+ 'VertexArrays',
45
+ 'RenderPasss',
46
+ 'ComputePasss',
47
+ 'CommandEncoders',
48
+ 'CommandBuffers'
49
+ ] as const;
50
+ const BASE_RESOURCE_COUNT_STAT_ORDER = BASE_RESOURCE_COUNT_ORDER.flatMap(resourceType => [
51
+ `${resourceType} Created`,
52
+ `${resourceType} Active`
53
+ ]);
54
+ const WEBGL_RESOURCE_COUNT_STAT_ORDER = WEBGL_RESOURCE_COUNT_ORDER.flatMap(resourceType => [
55
+ `${resourceType} Created`,
56
+ `${resourceType} Active`
57
+ ]);
58
+ const ORDERED_STATS_CACHE = new WeakMap<
59
+ Stats,
60
+ {orderedStatNames: readonly string[]; statCount: number}
61
+ >();
62
+ const ORDERED_STAT_NAME_SET_CACHE = new WeakMap<readonly string[], Set<string>>();
63
+
64
+ type CpuHotspotProfiler = {
65
+ enabled?: boolean;
66
+ activeDefaultFramebufferAcquireDepth?: number;
67
+ statsBookkeepingTimeMs?: number;
68
+ statsBookkeepingCalls?: number;
69
+ transientCanvasResourceCreates?: number;
70
+ transientCanvasTextureCreates?: number;
71
+ transientCanvasTextureViewCreates?: number;
72
+ transientCanvasSamplerCreates?: number;
73
+ transientCanvasFramebufferCreates?: number;
74
+ };
75
+
8
76
  export type ResourceProps = {
9
77
  /** Name of resource, mainly for debugging purposes. A unique name will be assigned if not provided */
10
78
  id?: string;
@@ -33,16 +101,23 @@ export abstract class Resource<Props extends ResourceProps> {
33
101
 
34
102
  /** props.id, for debugging. */
35
103
  id: string;
104
+ /** The props that this resource was created with */
36
105
  readonly props: Required<Props>;
106
+ /** User data object, reserved for the application */
37
107
  readonly userData: Record<string, unknown> = {};
108
+ /** The device that this resource is associated with */
38
109
  abstract readonly device: Device;
110
+ /** The handle for the underlying resource, e.g. WebGL object or WebGPU handle */
39
111
  abstract readonly handle: unknown;
112
+ /** The device that this resource is associated with - TODO can we remove this dup? */
40
113
  private _device: Device;
41
114
 
42
115
  /** Whether this resource has been destroyed */
43
116
  destroyed: boolean = false;
44
117
  /** For resources that allocate GPU memory */
45
118
  private allocatedBytes: number = 0;
119
+ /** Stats bucket currently holding the tracked allocation */
120
+ private allocatedBytesName: string | null = null;
46
121
  /** Attached resources will be destroyed when this resource is destroyed. Tracks auto-created "sub" resources. */
47
122
  private _attachedResources = new Set<Resource<ResourceProps>>();
48
123
 
@@ -69,6 +144,9 @@ export abstract class Resource<Props extends ResourceProps> {
69
144
  * destroy can be called on any resource to release it before it is garbage collected.
70
145
  */
71
146
  destroy(): void {
147
+ if (this.destroyed) {
148
+ return;
149
+ }
72
150
  this.destroyResource();
73
151
  }
74
152
 
@@ -114,7 +192,7 @@ export abstract class Resource<Props extends ResourceProps> {
114
192
 
115
193
  /** Destroy all owned resources. Make sure the resources are no longer needed before calling. */
116
194
  destroyAttachedResources(): void {
117
- for (const resource of Object.values(this._attachedResources)) {
195
+ for (const resource of this._attachedResources) {
118
196
  resource.destroy();
119
197
  }
120
198
  // don't remove while we are iterating
@@ -125,6 +203,9 @@ export abstract class Resource<Props extends ResourceProps> {
125
203
 
126
204
  /** Perform all destroy steps. Can be called by derived resources when overriding destroy() */
127
205
  protected destroyResource(): void {
206
+ if (this.destroyed) {
207
+ return;
208
+ }
128
209
  this.destroyAttachedResources();
129
210
  this.removeStats();
130
211
  this.destroyed = true;
@@ -132,34 +213,111 @@ export abstract class Resource<Props extends ResourceProps> {
132
213
 
133
214
  /** Called by .destroy() to track object destruction. Subclass must call if overriding destroy() */
134
215
  protected removeStats(): void {
135
- const stats = this._device.statsManager.getStats('Resource Counts');
136
- const name = this[Symbol.toStringTag];
137
- stats.get(`${name}s Active`).decrementCount();
216
+ const profiler = getCpuHotspotProfiler(this._device);
217
+ const startTime = profiler ? getTimestamp() : 0;
218
+ const statsObjects = [
219
+ this._device.statsManager.getStats(RESOURCE_COUNTS_STATS),
220
+ this._device.statsManager.getStats(LEGACY_RESOURCE_COUNTS_STATS)
221
+ ];
222
+ const orderedStatNames = getResourceCountStatOrder(this._device);
223
+ for (const stats of statsObjects) {
224
+ initializeStats(stats, orderedStatNames);
225
+ }
226
+ const name = this.getStatsName();
227
+ for (const stats of statsObjects) {
228
+ stats.get('Resources Active').decrementCount();
229
+ stats.get(`${name}s Active`).decrementCount();
230
+ }
231
+ if (profiler) {
232
+ profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
233
+ profiler.statsBookkeepingTimeMs =
234
+ (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
235
+ }
138
236
  }
139
237
 
140
238
  /** Called by subclass to track memory allocations */
141
- protected trackAllocatedMemory(bytes: number, name = this[Symbol.toStringTag]): void {
142
- const stats = this._device.statsManager.getStats('Resource Counts');
239
+ protected trackAllocatedMemory(bytes: number, name = this.getStatsName()): void {
240
+ const profiler = getCpuHotspotProfiler(this._device);
241
+ const startTime = profiler ? getTimestamp() : 0;
242
+ const stats = this._device.statsManager.getStats(GPU_TIME_AND_MEMORY_STATS);
243
+
244
+ if (this.allocatedBytes > 0 && this.allocatedBytesName) {
245
+ stats.get('GPU Memory').subtractCount(this.allocatedBytes);
246
+ stats.get(`${this.allocatedBytesName} Memory`).subtractCount(this.allocatedBytes);
247
+ }
248
+
143
249
  stats.get('GPU Memory').addCount(bytes);
144
250
  stats.get(`${name} Memory`).addCount(bytes);
251
+ if (profiler) {
252
+ profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
253
+ profiler.statsBookkeepingTimeMs =
254
+ (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
255
+ }
145
256
  this.allocatedBytes = bytes;
257
+ this.allocatedBytesName = name;
258
+ }
259
+
260
+ /** Called by subclass to track handle-backed memory allocations separately from owned allocations */
261
+ protected trackReferencedMemory(bytes: number, name = this.getStatsName()): void {
262
+ this.trackAllocatedMemory(bytes, `Referenced ${name}`);
146
263
  }
147
264
 
148
265
  /** Called by subclass to track memory deallocations */
149
- protected trackDeallocatedMemory(name = this[Symbol.toStringTag]): void {
150
- const stats = this._device.statsManager.getStats('Resource Counts');
266
+ protected trackDeallocatedMemory(name = this.getStatsName()): void {
267
+ if (this.allocatedBytes === 0) {
268
+ this.allocatedBytesName = null;
269
+ return;
270
+ }
271
+
272
+ const profiler = getCpuHotspotProfiler(this._device);
273
+ const startTime = profiler ? getTimestamp() : 0;
274
+ const stats = this._device.statsManager.getStats(GPU_TIME_AND_MEMORY_STATS);
151
275
  stats.get('GPU Memory').subtractCount(this.allocatedBytes);
152
- stats.get(`${name} Memory`).subtractCount(this.allocatedBytes);
276
+ stats.get(`${this.allocatedBytesName || name} Memory`).subtractCount(this.allocatedBytes);
277
+ if (profiler) {
278
+ profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
279
+ profiler.statsBookkeepingTimeMs =
280
+ (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
281
+ }
153
282
  this.allocatedBytes = 0;
283
+ this.allocatedBytesName = null;
284
+ }
285
+
286
+ /** Called by subclass to deallocate handle-backed memory tracked via trackReferencedMemory() */
287
+ protected trackDeallocatedReferencedMemory(name = this.getStatsName()): void {
288
+ this.trackDeallocatedMemory(`Referenced ${name}`);
154
289
  }
155
290
 
156
291
  /** Called by resource constructor to track object creation */
157
292
  private addStats(): void {
158
- const stats = this._device.statsManager.getStats('Resource Counts');
159
- const name = this[Symbol.toStringTag];
160
- stats.get('Resources Created').incrementCount();
161
- stats.get(`${name}s Created`).incrementCount();
162
- stats.get(`${name}s Active`).incrementCount();
293
+ const name = this.getStatsName();
294
+ const profiler = getCpuHotspotProfiler(this._device);
295
+ const startTime = profiler ? getTimestamp() : 0;
296
+ const statsObjects = [
297
+ this._device.statsManager.getStats(RESOURCE_COUNTS_STATS),
298
+ this._device.statsManager.getStats(LEGACY_RESOURCE_COUNTS_STATS)
299
+ ];
300
+ const orderedStatNames = getResourceCountStatOrder(this._device);
301
+ for (const stats of statsObjects) {
302
+ initializeStats(stats, orderedStatNames);
303
+ }
304
+ for (const stats of statsObjects) {
305
+ stats.get('Resources Created').incrementCount();
306
+ stats.get('Resources Active').incrementCount();
307
+ stats.get(`${name}s Created`).incrementCount();
308
+ stats.get(`${name}s Active`).incrementCount();
309
+ }
310
+ if (profiler) {
311
+ profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
312
+ profiler.statsBookkeepingTimeMs =
313
+ (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
314
+ }
315
+ recordTransientCanvasResourceCreate(this._device, name);
316
+ }
317
+
318
+ /** Canonical resource name used for stats buckets. */
319
+ protected getStatsName(): string {
320
+ return getCanonicalResourceName(this);
163
321
  }
164
322
  }
165
323
 
@@ -178,3 +336,120 @@ function selectivelyMerge<Props>(props: Props, defaultProps: Required<Props>): R
178
336
  }
179
337
  return mergedProps;
180
338
  }
339
+
340
+ function initializeStats(stats: Stats, orderedStatNames: readonly string[]): void {
341
+ const statsMap = stats.stats;
342
+ let addedOrderedStat = false;
343
+ for (const statName of orderedStatNames) {
344
+ if (!statsMap[statName]) {
345
+ stats.get(statName);
346
+ addedOrderedStat = true;
347
+ }
348
+ }
349
+
350
+ const statCount = Object.keys(statsMap).length;
351
+ const cachedStats = ORDERED_STATS_CACHE.get(stats);
352
+ if (
353
+ !addedOrderedStat &&
354
+ cachedStats?.orderedStatNames === orderedStatNames &&
355
+ cachedStats.statCount === statCount
356
+ ) {
357
+ return;
358
+ }
359
+
360
+ const reorderedStats: Record<string, Stat> = {};
361
+ let orderedStatNamesSet = ORDERED_STAT_NAME_SET_CACHE.get(orderedStatNames);
362
+ if (!orderedStatNamesSet) {
363
+ orderedStatNamesSet = new Set(orderedStatNames);
364
+ ORDERED_STAT_NAME_SET_CACHE.set(orderedStatNames, orderedStatNamesSet);
365
+ }
366
+
367
+ for (const statName of orderedStatNames) {
368
+ if (statsMap[statName]) {
369
+ reorderedStats[statName] = statsMap[statName];
370
+ }
371
+ }
372
+
373
+ for (const [statName, stat] of Object.entries(statsMap)) {
374
+ if (!orderedStatNamesSet.has(statName)) {
375
+ reorderedStats[statName] = stat;
376
+ }
377
+ }
378
+
379
+ for (const statName of Object.keys(statsMap)) {
380
+ delete statsMap[statName];
381
+ }
382
+
383
+ Object.assign(statsMap, reorderedStats);
384
+ ORDERED_STATS_CACHE.set(stats, {orderedStatNames, statCount});
385
+ }
386
+
387
+ function getResourceCountStatOrder(device: Device): readonly string[] {
388
+ return device.type === 'webgl' ? WEBGL_RESOURCE_COUNT_STAT_ORDER : BASE_RESOURCE_COUNT_STAT_ORDER;
389
+ }
390
+
391
+ function getCpuHotspotProfiler(device: Device): CpuHotspotProfiler | null {
392
+ const profiler = device.userData[CPU_HOTSPOT_PROFILER_MODULE] as CpuHotspotProfiler | undefined;
393
+ return profiler?.enabled ? profiler : null;
394
+ }
395
+
396
+ function getTimestamp(): number {
397
+ return globalThis.performance?.now?.() ?? Date.now();
398
+ }
399
+
400
+ function recordTransientCanvasResourceCreate(device: Device, name: string): void {
401
+ const profiler = getCpuHotspotProfiler(device);
402
+ if (!profiler || !profiler.activeDefaultFramebufferAcquireDepth) {
403
+ return;
404
+ }
405
+
406
+ profiler.transientCanvasResourceCreates = (profiler.transientCanvasResourceCreates || 0) + 1;
407
+
408
+ switch (name) {
409
+ case 'Texture':
410
+ profiler.transientCanvasTextureCreates = (profiler.transientCanvasTextureCreates || 0) + 1;
411
+ break;
412
+ case 'TextureView':
413
+ profiler.transientCanvasTextureViewCreates =
414
+ (profiler.transientCanvasTextureViewCreates || 0) + 1;
415
+ break;
416
+ case 'Sampler':
417
+ profiler.transientCanvasSamplerCreates = (profiler.transientCanvasSamplerCreates || 0) + 1;
418
+ break;
419
+ case 'Framebuffer':
420
+ profiler.transientCanvasFramebufferCreates =
421
+ (profiler.transientCanvasFramebufferCreates || 0) + 1;
422
+ break;
423
+ default:
424
+ break;
425
+ }
426
+ }
427
+
428
+ function getCanonicalResourceName(resource: Resource<any>): string {
429
+ let prototype = Object.getPrototypeOf(resource);
430
+
431
+ while (prototype) {
432
+ const parentPrototype = Object.getPrototypeOf(prototype);
433
+ if (!parentPrototype || parentPrototype === Resource.prototype) {
434
+ return (
435
+ getPrototypeToStringTag(prototype) ||
436
+ resource[Symbol.toStringTag] ||
437
+ resource.constructor.name
438
+ );
439
+ }
440
+ prototype = parentPrototype;
441
+ }
442
+
443
+ return resource[Symbol.toStringTag] || resource.constructor.name;
444
+ }
445
+
446
+ function getPrototypeToStringTag(prototype: object): string | null {
447
+ const descriptor = Object.getOwnPropertyDescriptor(prototype, Symbol.toStringTag);
448
+ if (typeof descriptor?.get === 'function') {
449
+ return descriptor.get.call(prototype);
450
+ }
451
+ if (typeof descriptor?.value === 'string') {
452
+ return descriptor.value;
453
+ }
454
+ return null;
455
+ }
@@ -106,38 +106,38 @@ export abstract class Shader extends Resource<ShaderProps> {
106
106
 
107
107
  const shaderName: string = shaderId; // getShaderName(this.source) || ;
108
108
  const shaderTitle: string = `${this.stage} shader "${shaderName}"`;
109
- let htmlLog = formatCompilerLog(messages, this.source, {showSourceCode: 'all', html: true});
109
+ const htmlLog = formatCompilerLog(messages, this.source, {showSourceCode: 'all', html: true});
110
110
  // Show translated source if available
111
111
  const translatedSource = this.getTranslatedSource();
112
+
113
+ const container = document.createElement('div');
114
+ container.innerHTML = `\
115
+ <h1>Compilation error in ${shaderTitle}</h1>
116
+ <div style="display:flex;position:fixed;top:10px;right:20px;gap:2px;">
117
+ <button id="copy">Copy source</button><br/>
118
+ <button id="close">Close</button>
119
+ </div>
120
+ <code><pre>${htmlLog}</pre></code>`;
112
121
  if (translatedSource) {
113
- htmlLog += `<br /><br /><h1>Translated Source</h1><br /><br /><code style="user-select:text;"><pre>${translatedSource}</pre></code>`;
122
+ container.innerHTML += `<br /><h1>Translated Source</h1><br /><br /><code><pre>${translatedSource}</pre></code>`;
114
123
  }
115
- // Make it clickable so we can copy to clipboard
116
- const button = document.createElement('Button');
117
- button.innerHTML = `
118
- <h1>Compilation error in ${shaderTitle}</h1><br /><br />
119
- <code style="user-select:text;"><pre>
120
- ${htmlLog}
121
- </pre></code>`;
122
- button.style.top = '10px';
123
- button.style.left = '10px';
124
- button.style.position = 'absolute';
125
- button.style.zIndex = '9999';
126
- button.style.width = '100%';
127
- button.style.textAlign = 'left';
128
- document.body.appendChild(button);
129
-
130
- const errors = document.getElementsByClassName('luma-compiler-log-error');
131
- errors[0]?.scrollIntoView();
132
-
133
- // TODO - add a small embedded copy button (instead of main button)
134
- button.onclick = () => {
135
- // const source = this.source.replaceAll('\n', '<br />');
136
- const dataURI = `data:text/plain,${encodeURIComponent(this.source)}`;
137
- navigator.clipboard.writeText(dataURI);
124
+ container.style.top = '0';
125
+ container.style.left = '0';
126
+ container.style.background = 'white';
127
+ container.style.position = 'fixed';
128
+ container.style.zIndex = '9999';
129
+ container.style.maxWidth = '100vw';
130
+ container.style.maxHeight = '100vh';
131
+ container.style.overflowY = 'auto';
132
+ document.body.appendChild(container);
133
+ const error = container.querySelector('.luma-compiler-log-error');
134
+ error?.scrollIntoView();
135
+ (container.querySelector('button#close') as HTMLButtonElement).onclick = () => {
136
+ container.remove();
137
+ };
138
+ (container.querySelector('button#copy') as HTMLButtonElement).onclick = () => {
139
+ navigator.clipboard.writeText(this.source);
138
140
  };
139
-
140
- // TODO - add a small embedded close button
141
141
  }
142
142
 
143
143
  static override defaultProps: Required<ShaderProps> = {
@@ -162,5 +162,5 @@ function getShaderIdFromProps(props: ShaderProps): string {
162
162
  function getShaderName(shader: string, defaultName: string = 'unnamed'): string {
163
163
  const SHADER_NAME_REGEXP = /#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/;
164
164
  const match = SHADER_NAME_REGEXP.exec(shader);
165
- return match ? match[1] : defaultName;
165
+ return match?.[1] ?? defaultName;
166
166
  }
@@ -0,0 +1,40 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {Device} from '../device';
6
+ import type {Shader} from './shader';
7
+ import {Resource, type ResourceProps} from './resource';
8
+
9
+ export type SharedRenderPipelineProps = ResourceProps & {
10
+ handle?: unknown;
11
+ vs: Shader;
12
+ fs: Shader;
13
+ varyings?: string[];
14
+ bufferMode?: number;
15
+ };
16
+
17
+ /**
18
+ * Internal base class for backend-specific shared render-pipeline implementations.
19
+ * Backends may use this to share expensive linked/program state across multiple
20
+ * `RenderPipeline` wrappers.
21
+ */
22
+ export abstract class SharedRenderPipeline extends Resource<SharedRenderPipelineProps> {
23
+ override get [Symbol.toStringTag](): string {
24
+ return 'SharedRenderPipeline';
25
+ }
26
+
27
+ abstract override readonly device: Device;
28
+ abstract override readonly handle: unknown;
29
+
30
+ constructor(device: Device, props: SharedRenderPipelineProps) {
31
+ super(device, props, {
32
+ ...Resource.defaultProps,
33
+ handle: undefined!,
34
+ vs: undefined!,
35
+ fs: undefined!,
36
+ varyings: undefined!,
37
+ bufferMode: undefined!
38
+ });
39
+ }
40
+ }
@@ -4,7 +4,7 @@
4
4
 
5
5
  import type {Device} from '../device';
6
6
  import type {Texture} from './texture';
7
- import type {TextureFormat} from '../../shadertypes/textures/texture-formats';
7
+ import type {TextureFormat} from '../../shadertypes/texture-types/texture-formats';
8
8
  import {Resource, ResourceProps} from './resource';
9
9
 
10
10
  /** Properties for initializing a texture view */