@luma.gl/webgl 9.3.0-alpha.6 → 9.3.0-alpha.8

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 (202) hide show
  1. package/dist/adapter/converters/device-parameters.d.ts +1 -1
  2. package/dist/adapter/converters/device-parameters.d.ts.map +1 -1
  3. package/dist/adapter/converters/device-parameters.js +4 -1
  4. package/dist/adapter/converters/device-parameters.js.map +1 -1
  5. package/dist/adapter/converters/sampler-parameters.d.ts +1 -1
  6. package/dist/adapter/converters/sampler-parameters.d.ts.map +1 -1
  7. package/dist/adapter/converters/sampler-parameters.js +1 -1
  8. package/dist/adapter/converters/sampler-parameters.js.map +1 -1
  9. package/dist/adapter/converters/shader-formats.d.ts +1 -64
  10. package/dist/adapter/converters/shader-formats.d.ts.map +1 -1
  11. package/dist/adapter/converters/shader-formats.js +1 -64
  12. package/dist/adapter/converters/shader-formats.js.map +1 -1
  13. package/dist/adapter/converters/webgl-shadertypes.d.ts +1 -3
  14. package/dist/adapter/converters/webgl-shadertypes.d.ts.map +1 -1
  15. package/dist/adapter/converters/webgl-shadertypes.js +1 -6
  16. package/dist/adapter/converters/webgl-shadertypes.js.map +1 -1
  17. package/dist/adapter/converters/webgl-texture-table.d.ts +1 -3
  18. package/dist/adapter/converters/webgl-texture-table.d.ts.map +1 -1
  19. package/dist/adapter/converters/webgl-texture-table.js +1 -15
  20. package/dist/adapter/converters/webgl-texture-table.js.map +1 -1
  21. package/dist/adapter/converters/webgl-vertex-formats.d.ts +1 -1
  22. package/dist/adapter/converters/webgl-vertex-formats.d.ts.map +1 -1
  23. package/dist/adapter/converters/webgl-vertex-formats.js +1 -1
  24. package/dist/adapter/converters/webgl-vertex-formats.js.map +1 -1
  25. package/dist/adapter/device-helpers/webgl-device-features.d.ts +1 -1
  26. package/dist/adapter/device-helpers/webgl-device-features.d.ts.map +1 -1
  27. package/dist/adapter/device-helpers/webgl-device-info.d.ts +1 -1
  28. package/dist/adapter/device-helpers/webgl-device-info.d.ts.map +1 -1
  29. package/dist/adapter/device-helpers/webgl-device-info.js +1 -1
  30. package/dist/adapter/device-helpers/webgl-device-info.js.map +1 -1
  31. package/dist/adapter/device-helpers/webgl-device-limits.d.ts +1 -1
  32. package/dist/adapter/device-helpers/webgl-device-limits.d.ts.map +1 -1
  33. package/dist/adapter/device-helpers/webgl-device-limits.js +1 -1
  34. package/dist/adapter/device-helpers/webgl-device-limits.js.map +1 -1
  35. package/dist/adapter/helpers/format-utils.d.ts +1 -1
  36. package/dist/adapter/helpers/format-utils.d.ts.map +1 -1
  37. package/dist/adapter/helpers/format-utils.js +1 -1
  38. package/dist/adapter/helpers/format-utils.js.map +1 -1
  39. package/dist/adapter/helpers/get-shader-layout-from-glsl.js +14 -2
  40. package/dist/adapter/helpers/get-shader-layout-from-glsl.js.map +1 -1
  41. package/dist/adapter/helpers/set-uniform.d.ts +1 -1
  42. package/dist/adapter/helpers/set-uniform.d.ts.map +1 -1
  43. package/dist/adapter/helpers/set-uniform.js +1 -1
  44. package/dist/adapter/helpers/set-uniform.js.map +1 -1
  45. package/dist/adapter/helpers/webgl-texture-utils.d.ts +1 -1
  46. package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
  47. package/dist/adapter/helpers/webgl-texture-utils.js +4 -4
  48. package/dist/adapter/helpers/webgl-texture-utils.js.map +1 -1
  49. package/dist/adapter/helpers/webgl-topology-utils.d.ts +1 -1
  50. package/dist/adapter/helpers/webgl-topology-utils.d.ts.map +1 -1
  51. package/dist/adapter/helpers/webgl-topology-utils.js +1 -1
  52. package/dist/adapter/helpers/webgl-topology-utils.js.map +1 -1
  53. package/dist/adapter/resources/webgl-buffer.d.ts +1 -1
  54. package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
  55. package/dist/adapter/resources/webgl-buffer.js +1 -1
  56. package/dist/adapter/resources/webgl-buffer.js.map +1 -1
  57. package/dist/adapter/resources/webgl-command-buffer.d.ts +1 -1
  58. package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
  59. package/dist/adapter/resources/webgl-command-buffer.js +20 -34
  60. package/dist/adapter/resources/webgl-command-buffer.js.map +1 -1
  61. package/dist/adapter/resources/webgl-command-encoder.d.ts +1 -1
  62. package/dist/adapter/resources/webgl-command-encoder.d.ts.map +1 -1
  63. package/dist/adapter/resources/webgl-command-encoder.js +3 -1
  64. package/dist/adapter/resources/webgl-command-encoder.js.map +1 -1
  65. package/dist/adapter/resources/webgl-framebuffer.d.ts +3 -1
  66. package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
  67. package/dist/adapter/resources/webgl-framebuffer.js +10 -1
  68. package/dist/adapter/resources/webgl-framebuffer.js.map +1 -1
  69. package/dist/adapter/resources/webgl-query-set.d.ts +8 -0
  70. package/dist/adapter/resources/webgl-query-set.d.ts.map +1 -1
  71. package/dist/adapter/resources/webgl-query-set.js +59 -4
  72. package/dist/adapter/resources/webgl-query-set.js.map +1 -1
  73. package/dist/adapter/resources/webgl-render-pass.d.ts +1 -1
  74. package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
  75. package/dist/adapter/resources/webgl-render-pass.js +13 -11
  76. package/dist/adapter/resources/webgl-render-pass.js.map +1 -1
  77. package/dist/adapter/resources/webgl-render-pipeline.d.ts +8 -6
  78. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  79. package/dist/adapter/resources/webgl-render-pipeline.js +39 -20
  80. package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -1
  81. package/dist/adapter/resources/webgl-sampler.d.ts +1 -1
  82. package/dist/adapter/resources/webgl-sampler.d.ts.map +1 -1
  83. package/dist/adapter/resources/webgl-sampler.js +1 -1
  84. package/dist/adapter/resources/webgl-sampler.js.map +1 -1
  85. package/dist/adapter/resources/webgl-shader.d.ts +1 -1
  86. package/dist/adapter/resources/webgl-shader.d.ts.map +1 -1
  87. package/dist/adapter/resources/webgl-shader.js +15 -8
  88. package/dist/adapter/resources/webgl-shader.js.map +1 -1
  89. package/dist/adapter/resources/webgl-shared-render-pipeline.d.ts.map +1 -1
  90. package/dist/adapter/resources/webgl-shared-render-pipeline.js +4 -1
  91. package/dist/adapter/resources/webgl-shared-render-pipeline.js.map +1 -1
  92. package/dist/adapter/resources/webgl-texture.d.ts +4 -2
  93. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  94. package/dist/adapter/resources/webgl-texture.js +12 -17
  95. package/dist/adapter/resources/webgl-texture.js.map +1 -1
  96. package/dist/adapter/resources/webgl-transform-feedback.js +1 -1
  97. package/dist/adapter/resources/webgl-transform-feedback.js.map +1 -1
  98. package/dist/adapter/resources/webgl-vertex-array.d.ts +2 -2
  99. package/dist/adapter/resources/webgl-vertex-array.d.ts.map +1 -1
  100. package/dist/adapter/resources/webgl-vertex-array.js +1 -1
  101. package/dist/adapter/resources/webgl-vertex-array.js.map +1 -1
  102. package/dist/adapter/webgl-device.d.ts +2 -1
  103. package/dist/adapter/webgl-device.d.ts.map +1 -1
  104. package/dist/adapter/webgl-device.js +11 -7
  105. package/dist/adapter/webgl-device.js.map +1 -1
  106. package/dist/constants/index.d.ts +3 -0
  107. package/dist/constants/index.d.ts.map +1 -0
  108. package/dist/constants/index.js +5 -0
  109. package/dist/constants/index.js.map +1 -0
  110. package/dist/constants/webgl-constants.d.ts +822 -0
  111. package/dist/constants/webgl-constants.d.ts.map +1 -0
  112. package/dist/constants/webgl-constants.js +928 -0
  113. package/dist/constants/webgl-constants.js.map +1 -0
  114. package/dist/constants/webgl-types.d.ts +480 -0
  115. package/dist/constants/webgl-types.d.ts.map +1 -0
  116. package/dist/constants/webgl-types.js +6 -0
  117. package/dist/constants/webgl-types.js.map +1 -0
  118. package/dist/context/debug/webgl-developer-tools.js +1 -1
  119. package/dist/context/debug/webgl-developer-tools.js.map +1 -1
  120. package/dist/context/helpers/webgl-context-data.d.ts +1 -1
  121. package/dist/context/helpers/webgl-context-data.d.ts.map +1 -1
  122. package/dist/context/helpers/webgl-extensions.d.ts +1 -1
  123. package/dist/context/helpers/webgl-extensions.d.ts.map +1 -1
  124. package/dist/context/parameters/unified-parameter-api.d.ts +1 -1
  125. package/dist/context/parameters/unified-parameter-api.d.ts.map +1 -1
  126. package/dist/context/parameters/webgl-parameter-tables.d.ts +1 -1
  127. package/dist/context/parameters/webgl-parameter-tables.d.ts.map +1 -1
  128. package/dist/context/parameters/webgl-parameter-tables.js +1 -1
  129. package/dist/context/parameters/webgl-parameter-tables.js.map +1 -1
  130. package/dist/context/polyfills/polyfill-webgl1-extensions.js +1 -1
  131. package/dist/context/polyfills/polyfill-webgl1-extensions.js.map +1 -1
  132. package/dist/dist.dev.js +267 -162
  133. package/dist/dist.min.js +2 -2
  134. package/dist/index.cjs +3 -5941
  135. package/dist/index.cjs.map +4 -4
  136. package/dist/index.d.ts +2 -0
  137. package/dist/index.d.ts.map +1 -1
  138. package/dist/index.js +1 -0
  139. package/dist/index.js.map +1 -1
  140. package/dist/webgl-constants.d.ts +2 -0
  141. package/dist/webgl-constants.d.ts.map +1 -0
  142. package/dist/webgl-constants.js +5 -0
  143. package/dist/webgl-constants.js.map +1 -0
  144. package/dist/webgl-types.d.ts +2 -0
  145. package/dist/webgl-types.d.ts.map +1 -0
  146. package/dist/{types.js → webgl-types.js} +1 -1
  147. package/dist/webgl-types.js.map +1 -0
  148. package/package.json +18 -4
  149. package/src/adapter/converters/device-parameters.ts +6 -2
  150. package/src/adapter/converters/sampler-parameters.ts +1 -1
  151. package/src/adapter/converters/shader-formats.ts +1 -66
  152. package/src/adapter/converters/webgl-shadertypes.ts +1 -9
  153. package/src/adapter/converters/webgl-texture-table.ts +1 -21
  154. package/src/adapter/converters/webgl-vertex-formats.ts +1 -1
  155. package/src/adapter/device-helpers/webgl-device-features.ts +1 -1
  156. package/src/adapter/device-helpers/webgl-device-info.ts +1 -1
  157. package/src/adapter/device-helpers/webgl-device-limits.ts +1 -1
  158. package/src/adapter/helpers/format-utils.ts +1 -1
  159. package/src/adapter/helpers/get-shader-layout-from-glsl.ts +21 -2
  160. package/src/adapter/helpers/set-uniform.ts +1 -1
  161. package/src/adapter/helpers/webgl-texture-utils.ts +4 -4
  162. package/src/adapter/helpers/webgl-topology-utils.ts +1 -1
  163. package/src/adapter/resources/webgl-buffer.ts +1 -1
  164. package/src/adapter/resources/webgl-command-buffer.ts +25 -26
  165. package/src/adapter/resources/webgl-command-encoder.ts +6 -4
  166. package/src/adapter/resources/webgl-framebuffer.ts +12 -1
  167. package/src/adapter/resources/webgl-query-set.ts +71 -4
  168. package/src/adapter/resources/webgl-render-pass.ts +13 -13
  169. package/src/adapter/resources/webgl-render-pipeline.ts +65 -26
  170. package/src/adapter/resources/webgl-sampler.ts +1 -1
  171. package/src/adapter/resources/webgl-shader.ts +15 -8
  172. package/src/adapter/resources/webgl-shared-render-pipeline.ts +4 -1
  173. package/src/adapter/resources/webgl-texture.ts +15 -18
  174. package/src/adapter/resources/webgl-transform-feedback.ts +1 -1
  175. package/src/adapter/resources/webgl-vertex-array.ts +1 -1
  176. package/src/adapter/webgl-device.ts +16 -8
  177. package/src/constants/index.d.ts.map +1 -0
  178. package/src/constants/index.js.map +1 -0
  179. package/src/constants/index.ts +31 -0
  180. package/src/constants/webgl-constants.d.ts.map +1 -0
  181. package/src/constants/webgl-constants.js.map +1 -0
  182. package/src/constants/webgl-constants.ts +1051 -0
  183. package/src/constants/webgl-types.d.ts.map +1 -0
  184. package/src/constants/webgl-types.js.map +1 -0
  185. package/src/constants/webgl-types.ts +813 -0
  186. package/src/context/debug/webgl-developer-tools.ts +1 -1
  187. package/src/context/helpers/webgl-context-data.ts +1 -1
  188. package/src/context/helpers/webgl-extensions.ts +1 -1
  189. package/src/context/parameters/unified-parameter-api.ts +1 -1
  190. package/src/context/parameters/webgl-parameter-tables.ts +1 -1
  191. package/src/context/polyfills/polyfill-webgl1-extensions.ts +1 -1
  192. package/src/index.ts +26 -0
  193. package/src/webgl-constants.d.ts.map +1 -0
  194. package/src/webgl-constants.js.map +1 -0
  195. package/src/webgl-constants.ts +5 -0
  196. package/src/webgl-types.d.ts.map +1 -0
  197. package/src/webgl-types.js.map +1 -0
  198. package/src/webgl-types.ts +29 -0
  199. package/dist/types.d.ts +0 -11
  200. package/dist/types.d.ts.map +0 -1
  201. package/dist/types.js.map +0 -1
  202. package/src/types.ts +0 -14
@@ -1,6 +1,6 @@
1
1
  // WebGL2 QuerySet (also handles disjoint timer extensions)
2
2
  import {QuerySet, QuerySetProps} from '@luma.gl/core';
3
- import {GL} from '@luma.gl/constants';
3
+ import {GL} from '@luma.gl/webgl/constants';
4
4
  import {WebGLDevice} from '../webgl-device';
5
5
 
6
6
  type WebGLPendingQuery = {
@@ -8,6 +8,10 @@ type WebGLPendingQuery = {
8
8
  promise: Promise<bigint> | null;
9
9
  result: bigint | null;
10
10
  disjoint: boolean;
11
+ cancelled: boolean;
12
+ pollRequestId: number | null;
13
+ resolve: ((value: bigint) => void) | null;
14
+ reject: ((error: Error) => void) | null;
11
15
  };
12
16
 
13
17
  type WebGLTimestampPair = {
@@ -23,6 +27,7 @@ export class WEBGLQuerySet extends QuerySet {
23
27
  readonly handle: WebGLQuery | null;
24
28
 
25
29
  protected _timestampPairs: WebGLTimestampPair[] = [];
30
+ protected _pendingReads: Set<WebGLPendingQuery> = new Set();
26
31
  protected _occlusionQuery: WebGLPendingQuery | null = null;
27
32
  protected _occlusionActive = false;
28
33
 
@@ -67,17 +72,24 @@ export class WEBGLQuerySet extends QuerySet {
67
72
 
68
73
  for (const pair of this._timestampPairs) {
69
74
  if (pair.activeQuery) {
75
+ this._cancelPendingQuery(pair.activeQuery);
70
76
  this.device.gl.deleteQuery(pair.activeQuery.handle);
71
77
  }
72
78
  for (const query of pair.completedQueries) {
79
+ this._cancelPendingQuery(query);
73
80
  this.device.gl.deleteQuery(query.handle);
74
81
  }
75
82
  }
76
83
 
77
84
  if (this._occlusionQuery) {
85
+ this._cancelPendingQuery(this._occlusionQuery);
78
86
  this.device.gl.deleteQuery(this._occlusionQuery.handle);
79
87
  }
80
88
 
89
+ for (const query of Array.from(this._pendingReads)) {
90
+ this._cancelPendingQuery(query);
91
+ }
92
+
81
93
  this.destroyResource();
82
94
  }
83
95
 
@@ -162,7 +174,11 @@ export class WEBGLQuerySet extends QuerySet {
162
174
  handle: this.handle,
163
175
  promise: null,
164
176
  result: null,
165
- disjoint: false
177
+ disjoint: false,
178
+ cancelled: false,
179
+ pollRequestId: null,
180
+ resolve: null,
181
+ reject: null
166
182
  };
167
183
  this._occlusionActive = true;
168
184
  }
@@ -198,7 +214,11 @@ export class WEBGLQuerySet extends QuerySet {
198
214
  handle,
199
215
  promise: null,
200
216
  result: null,
201
- disjoint: false
217
+ disjoint: false,
218
+ cancelled: false,
219
+ pollRequestId: null,
220
+ resolve: null,
221
+ reject: null
202
222
  };
203
223
 
204
224
  this.device.gl.beginQuery(GL.TIME_ELAPSED_EXT, handle);
@@ -239,6 +259,11 @@ export class WEBGLQuerySet extends QuerySet {
239
259
  }
240
260
 
241
261
  protected _pollQueryAvailability(query: WebGLPendingQuery): boolean {
262
+ if (query.cancelled || this.destroyed) {
263
+ query.result = 0n;
264
+ return true;
265
+ }
266
+
242
267
  if (query.result !== null || query.disjoint) {
243
268
  return true;
244
269
  }
@@ -279,14 +304,32 @@ export class WEBGLQuerySet extends QuerySet {
279
304
  return query.promise;
280
305
  }
281
306
 
307
+ this._pendingReads.add(query);
282
308
  query.promise = new Promise((resolve, reject) => {
309
+ query.resolve = resolve;
310
+ query.reject = reject;
311
+
283
312
  const poll = () => {
313
+ query.pollRequestId = null;
314
+
315
+ if (query.cancelled || this.destroyed) {
316
+ this._pendingReads.delete(query);
317
+ query.promise = null;
318
+ query.resolve = null;
319
+ query.reject = null;
320
+ resolve(0n);
321
+ return;
322
+ }
323
+
284
324
  if (!this._pollQueryAvailability(query)) {
285
- requestAnimationFrame(poll);
325
+ query.pollRequestId = this._requestAnimationFrame(poll);
286
326
  return;
287
327
  }
288
328
 
329
+ this._pendingReads.delete(query);
289
330
  query.promise = null;
331
+ query.resolve = null;
332
+ query.reject = null;
290
333
  if (query.disjoint) {
291
334
  reject(new Error('GPU timestamp query was invalidated by a disjoint event'));
292
335
  } else {
@@ -299,4 +342,28 @@ export class WEBGLQuerySet extends QuerySet {
299
342
 
300
343
  return query.promise;
301
344
  }
345
+
346
+ protected _cancelPendingQuery(query: WebGLPendingQuery): void {
347
+ this._pendingReads.delete(query);
348
+ query.cancelled = true;
349
+ if (query.pollRequestId !== null) {
350
+ this._cancelAnimationFrame(query.pollRequestId);
351
+ query.pollRequestId = null;
352
+ }
353
+ if (query.resolve) {
354
+ const resolve = query.resolve;
355
+ query.promise = null;
356
+ query.resolve = null;
357
+ query.reject = null;
358
+ resolve(0n);
359
+ }
360
+ }
361
+
362
+ protected _requestAnimationFrame(callback: FrameRequestCallback): number {
363
+ return requestAnimationFrame(callback);
364
+ }
365
+
366
+ protected _cancelAnimationFrame(requestId: number): void {
367
+ cancelAnimationFrame(requestId);
368
+ }
302
369
  }
@@ -5,7 +5,7 @@
5
5
  import {NumericArray, NumberArray4} from '@math.gl/types';
6
6
  import {RenderPass, RenderPassProps, RenderPassParameters} from '@luma.gl/core';
7
7
  import {WebGLDevice} from '../webgl-device';
8
- import {GL, GLParameters} from '@luma.gl/constants';
8
+ import {GL, GLParameters} from '@luma.gl/webgl/constants';
9
9
  import {withGLParameters} from '../../context/state-tracker/with-parameters';
10
10
  import {setGLParameters} from '../../context/parameters/unified-parameter-api';
11
11
  import {WEBGLQuerySet} from './webgl-query-set';
@@ -23,19 +23,21 @@ export class WEBGLRenderPass extends RenderPass {
23
23
  constructor(device: WebGLDevice, props: RenderPassProps) {
24
24
  super(device, props);
25
25
  this.device = device;
26
+ const webglFramebuffer = this.props.framebuffer as WEBGLFramebuffer | null;
27
+ const isDefaultFramebuffer = !webglFramebuffer || webglFramebuffer.handle === null;
26
28
 
27
- if (!props?.framebuffer) {
28
- // Default-framebuffer rendering bypasses CanvasContext.getCurrentFramebuffer(),
29
- // so flush any deferred canvas resize before deriving viewport state.
29
+ if (isDefaultFramebuffer) {
30
+ // Treat an explicit wrapper around the default framebuffer the same as the
31
+ // implicit default path so draw buffer and viewport state stay valid.
30
32
  device.getDefaultCanvasContext()._resizeDrawingBufferIfNeeded();
31
33
  }
32
34
 
33
35
  // If no viewport is provided, apply reasonably defaults
34
36
  let viewport: NumberArray4 | undefined;
35
37
  if (!props?.parameters?.viewport) {
36
- if (props?.framebuffer) {
38
+ if (!isDefaultFramebuffer) {
37
39
  // Set the viewport to the size of the framebuffer
38
- const {width, height} = props.framebuffer;
40
+ const {width, height} = webglFramebuffer;
39
41
  viewport = [0, 0, width, height];
40
42
  } else {
41
43
  // Instead of using our own book-keeping, we can just read the values from the WebGL context
@@ -49,15 +51,13 @@ export class WEBGLRenderPass extends RenderPass {
49
51
  this.setParameters({viewport, ...this.props.parameters});
50
52
 
51
53
  // Specify mapping of draw buffer locations to color attachments
52
- const webglFramebuffer = this.props.framebuffer as WEBGLFramebuffer;
53
54
  // Default framebuffers can only be set to GL.BACK or GL.NONE
54
- if (this.props.framebuffer && webglFramebuffer?.handle) {
55
- const drawBuffers = this.props.framebuffer.colorAttachments.map(
56
- (_, i) => GL.COLOR_ATTACHMENT0 + i
57
- );
55
+ if (!isDefaultFramebuffer) {
56
+ const drawBuffers = webglFramebuffer.colorAttachments.map((_, i) => GL.COLOR_ATTACHMENT0 + i);
58
57
  this.device.gl.drawBuffers(drawBuffers);
59
- } else if (!this.props.framebuffer) {
60
- // Default framebuffer only supports GL.BACK/GL.NONE draw buffers
58
+ } else {
59
+ // Default framebuffer only supports GL.BACK/GL.NONE draw buffers, even when
60
+ // passed through an explicit framebuffer wrapper.
61
61
  this.device.gl.drawBuffers([GL.BACK]);
62
62
  }
63
63
 
@@ -8,13 +8,14 @@ import type {
8
8
  PrimitiveTopology,
9
9
  ShaderLayout,
10
10
  UniformValue,
11
- Binding,
11
+ Bindings,
12
+ BindingsByGroup,
12
13
  RenderPass,
13
14
  VertexArray
14
15
  } from '@luma.gl/core';
15
- import {RenderPipeline, log} from '@luma.gl/core';
16
+ import {RenderPipeline, flattenBindingsByGroup, log, normalizeBindingsByGroup} from '@luma.gl/core';
16
17
  // import {getAttributeInfosFromLayouts} from '@luma.gl/core';
17
- import {GL} from '@luma.gl/constants';
18
+ import {GL} from '@luma.gl/webgl/constants';
18
19
 
19
20
  import {withDeviceAndGLParameters} from '../converters/device-parameters';
20
21
  import {setUniform} from '../helpers/set-uniform';
@@ -45,7 +46,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
45
46
  introspectedLayout: ShaderLayout;
46
47
 
47
48
  /** Compatibility path for direct pipeline.setBindings() usage */
48
- bindings: Record<string, Binding> = {};
49
+ bindings: Bindings = {};
49
50
  /** Compatibility path for direct pipeline.uniforms usage */
50
51
  uniforms: Record<string, UniformValue> = {};
51
52
  /** WebGL varyings */
@@ -73,7 +74,10 @@ export class WEBGLRenderPipeline extends RenderPipeline {
73
74
  this.introspectedLayout = webglSharedRenderPipeline.introspectedLayout;
74
75
  this.device._setWebGLDebugMetadata(this.handle, this, {spector: {id: this.props.id}});
75
76
 
76
- // Merge provided layout with introspected layout
77
+ // WebGL only honors shaderLayout overrides for attributes that already exist in the
78
+ // linked program, and only the `type` / `stepMode` fields participate in the merge.
79
+ // Bindings and unknown attributes are ignored. If WebGL cache keys ever depend on
80
+ // `shaderLayout`, they need to match these merge semantics rather than the raw prop.
77
81
  this.shaderLayout = props.shaderLayout
78
82
  ? mergeShaderLayout(this.introspectedLayout, props.shaderLayout)
79
83
  : this.introspectedLayout;
@@ -93,11 +97,12 @@ export class WEBGLRenderPipeline extends RenderPipeline {
93
97
  * Compatibility shim for code paths that still set bindings on the pipeline.
94
98
  * Shared-model draws pass bindings per draw and do not rely on this state.
95
99
  */
96
- setBindings(bindings: Record<string, Binding>, options?: {disableWarnings?: boolean}): void {
97
- for (const [name, value] of Object.entries(bindings)) {
98
- const binding =
99
- this.shaderLayout.bindings.find(binding_ => binding_.name === name) ||
100
- this.shaderLayout.bindings.find(binding_ => binding_.name === `${name}Uniforms`);
100
+ setBindings(bindings: Bindings | BindingsByGroup, options?: {disableWarnings?: boolean}): void {
101
+ const flatBindings = flattenBindingsByGroup(
102
+ normalizeBindingsByGroup(this.shaderLayout, bindings)
103
+ );
104
+ for (const [name, value] of Object.entries(flatBindings)) {
105
+ const binding = getShaderLayoutBindingByName(this.shaderLayout, name);
101
106
 
102
107
  if (!binding) {
103
108
  const validBindings = this.shaderLayout.bindings
@@ -161,10 +166,15 @@ export class WEBGLRenderPipeline extends RenderPipeline {
161
166
  firstInstance?: number;
162
167
  baseVertex?: number;
163
168
  transformFeedback?: WEBGLTransformFeedback;
164
- bindings?: Record<string, Binding>;
169
+ bindings?: Bindings;
170
+ bindGroups?: BindingsByGroup;
171
+ _bindGroupCacheKeys?: Partial<Record<number, object>>;
165
172
  uniforms?: Record<string, UniformValue>;
166
173
  }): boolean {
167
174
  this._syncLinkStatus();
175
+ const drawBindings = options.bindGroups
176
+ ? flattenBindingsByGroup(options.bindGroups)
177
+ : options.bindings || this.bindings;
168
178
 
169
179
  const {
170
180
  renderPass,
@@ -180,7 +190,6 @@ export class WEBGLRenderPipeline extends RenderPipeline {
180
190
  // firstInstance,
181
191
  // baseVertex,
182
192
  transformFeedback,
183
- bindings = this.bindings,
184
193
  uniforms = this.uniforms
185
194
  } = options;
186
195
 
@@ -199,7 +208,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
199
208
  // Note: async textures set as uniforms might still be loading.
200
209
  // Now that all uniforms have been updated, check if any texture
201
210
  // in the uniforms is not yet initialized, then we don't draw
202
- if (!this._areTexturesRenderable(bindings)) {
211
+ if (!this._areTexturesRenderable(drawBindings)) {
203
212
  log.info(2, `RenderPipeline:${this.id}.draw() aborted - textures not yet loaded`)();
204
213
  // Note: false means that the app needs to redraw the pipeline again.
205
214
  return false;
@@ -222,7 +231,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
222
231
  }
223
232
 
224
233
  // We have to apply bindings before every draw call since other draw calls will overwrite
225
- this._applyBindings(bindings, {disableWarnings: this.props.disableWarnings});
234
+ this._applyBindings(drawBindings, {disableWarnings: this.props.disableWarnings});
226
235
  this._applyUniforms(uniforms);
227
236
 
228
237
  const webglRenderPass = renderPass as WEBGLRenderPass;
@@ -266,11 +275,11 @@ export class WEBGLRenderPipeline extends RenderPipeline {
266
275
  * Update a texture if needed (e.g. from video)
267
276
  * Note: This is currently done before every draw call
268
277
  */
269
- _areTexturesRenderable(bindings: Record<string, Binding>) {
278
+ _areTexturesRenderable(bindings: Bindings) {
270
279
  let texturesRenderable = true;
271
280
 
272
281
  for (const bindingInfo of this.shaderLayout.bindings) {
273
- if (!bindings[bindingInfo.name] && !bindings[bindingInfo.name.replace(/Uniforms$/, '')]) {
282
+ if (!getBindingValueForLayoutBinding(bindings, bindingInfo.name)) {
274
283
  log.warn(`Binding ${bindingInfo.name} not found in ${this.id}`)();
275
284
  texturesRenderable = false;
276
285
  }
@@ -287,7 +296,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
287
296
  }
288
297
 
289
298
  /** Apply any bindings (before each draw call) */
290
- _applyBindings(bindings: Record<string, Binding>, _options?: {disableWarnings?: boolean}) {
299
+ _applyBindings(bindings: Bindings, _options?: {disableWarnings?: boolean}) {
291
300
  this._syncLinkStatus();
292
301
 
293
302
  // If we are using async linking, we need to wait until linking completes
@@ -301,8 +310,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
301
310
  let textureUnit = 0;
302
311
  let uniformBufferIndex = 0;
303
312
  for (const binding of this.shaderLayout.bindings) {
304
- // Accept both `xyz` and `xyzUniforms` as valid names for `xyzUniforms` uniform block
305
- const value = bindings[binding.name] || bindings[binding.name.replace(/Uniforms$/, '')];
313
+ const value = getBindingValueForLayoutBinding(bindings, binding.name);
306
314
  if (!value) {
307
315
  throw new Error(`No value for binding ${binding.name} in ${this.id}`);
308
316
  }
@@ -318,15 +326,13 @@ export class WEBGLRenderPipeline extends RenderPipeline {
318
326
  if (value instanceof WEBGLBuffer) {
319
327
  gl.bindBufferBase(GL.UNIFORM_BUFFER, uniformBufferIndex, value.handle);
320
328
  } else {
329
+ const bufferBinding = value as {buffer: WEBGLBuffer; offset?: number; size?: number};
321
330
  gl.bindBufferRange(
322
331
  GL.UNIFORM_BUFFER,
323
332
  uniformBufferIndex,
324
- // @ts-expect-error
325
- value.buffer.handle,
326
- // @ts-expect-error
327
- value.offset || 0,
328
- // @ts-expect-error
329
- value.size || value.buffer.byteLength - value.offset
333
+ bufferBinding.buffer.handle,
334
+ bufferBinding.offset || 0,
335
+ bufferBinding.size || bufferBinding.buffer.byteLength - (bufferBinding.offset || 0)
330
336
  );
331
337
  }
332
338
  uniformBufferIndex += 1;
@@ -405,7 +411,8 @@ function mergeShaderLayout(baseLayout: ShaderLayout, overrideLayout: ShaderLayou
405
411
  // Deep clone the base layout
406
412
  const mergedLayout: ShaderLayout = {
407
413
  ...baseLayout,
408
- attributes: baseLayout.attributes.map(attribute => ({...attribute}))
414
+ attributes: baseLayout.attributes.map(attribute => ({...attribute})),
415
+ bindings: baseLayout.bindings.map(binding => ({...binding}))
409
416
  };
410
417
  // Merge the attributes
411
418
  for (const attribute of overrideLayout?.attributes || []) {
@@ -417,5 +424,37 @@ function mergeShaderLayout(baseLayout: ShaderLayout, overrideLayout: ShaderLayou
417
424
  baseAttribute.stepMode = attribute.stepMode || baseAttribute.stepMode;
418
425
  }
419
426
  }
427
+
428
+ for (const binding of overrideLayout?.bindings || []) {
429
+ const baseBinding = getShaderLayoutBindingByName(mergedLayout, binding.name);
430
+ if (!baseBinding) {
431
+ log.warn(`shader layout binding ${binding.name} not present in shader`);
432
+ continue;
433
+ }
434
+ Object.assign(baseBinding, binding);
435
+ }
420
436
  return mergedLayout;
421
437
  }
438
+
439
+ function getShaderLayoutBindingByName(
440
+ shaderLayout: ShaderLayout,
441
+ bindingName: string
442
+ ): ShaderLayout['bindings'][number] | undefined {
443
+ return shaderLayout.bindings.find(
444
+ binding =>
445
+ binding.name === bindingName ||
446
+ binding.name === `${bindingName}Uniforms` ||
447
+ `${binding.name}Uniforms` === bindingName
448
+ );
449
+ }
450
+
451
+ function getBindingValueForLayoutBinding(
452
+ bindings: Bindings,
453
+ bindingName: string
454
+ ): Bindings[string] | undefined {
455
+ return (
456
+ bindings[bindingName] ||
457
+ bindings[`${bindingName}Uniforms`] ||
458
+ bindings[bindingName.replace(/Uniforms$/, '')]
459
+ );
460
+ }
@@ -3,7 +3,7 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import {Sampler, SamplerProps} from '@luma.gl/core';
6
- import {GL, GLSamplerParameters} from '@luma.gl/constants';
6
+ import {GL, GLSamplerParameters} from '@luma.gl/webgl/constants';
7
7
  import {convertSamplerParametersToWebGL} from '../converters/sampler-parameters';
8
8
  import type {WebGLDevice} from '../webgl-device';
9
9
 
@@ -3,7 +3,7 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import {Shader, ShaderProps, CompilerMessage, log} from '@luma.gl/core';
6
- import {GL} from '@luma.gl/constants';
6
+ import {GL} from '@luma.gl/webgl/constants';
7
7
  import {parseShaderCompilerLog} from '../helpers/parse-shader-compiler-log';
8
8
  import {WebGLDevice} from '../webgl-device';
9
9
 
@@ -31,7 +31,13 @@ export class WEBGLShader extends Shader {
31
31
  // default framebuffer handle is null, so we can't set spector metadata...
32
32
  device._setWebGLDebugMetadata(this.handle, this, {spector: this.props});
33
33
 
34
- this._compile(this.source);
34
+ const compilationStatus = this._compile(this.source);
35
+ if (compilationStatus && typeof compilationStatus.catch === 'function') {
36
+ compilationStatus.catch(() => {
37
+ // Ensure any async compile status errors are consumed.
38
+ this.compilationStatus = 'error';
39
+ });
40
+ }
35
41
  }
36
42
 
37
43
  override destroy(): void {
@@ -71,7 +77,7 @@ export class WEBGLShader extends Shader {
71
77
  // PRIVATE METHODS
72
78
 
73
79
  /** Compile a shader and get compilation status */
74
- protected async _compile(source: string): Promise<void> {
80
+ protected _compile(source: string): void | Promise<void> {
75
81
  source = source.startsWith('#version ') ? source : `#version 300 es\n${source}`;
76
82
 
77
83
  const {gl} = this.device;
@@ -97,12 +103,13 @@ export class WEBGLShader extends Shader {
97
103
 
98
104
  // async case
99
105
  log.once(1, 'Shader compilation is asynchronous')();
100
- await this._waitForCompilationComplete();
101
- log.info(2, `Shader ${this.id} - async compilation complete: ${this.compilationStatus}`)();
102
- this._getCompilationStatus();
106
+ return this._waitForCompilationComplete().then(() => {
107
+ log.info(2, `Shader ${this.id} - async compilation complete: ${this.compilationStatus}`)();
108
+ this._getCompilationStatus();
103
109
 
104
- // The `Shader` base class will determine if debug window should be opened based on this.compilationStatus
105
- this.debugShader();
110
+ // The `Shader` base class will determine if debug window should be opened based on this.compilationStatus
111
+ this.debugShader();
112
+ });
106
113
  }
107
114
 
108
115
  /** Use KHR_parallel_shader_compile extension if available */
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {GL} from '@luma.gl/constants';
5
+ import {GL} from '@luma.gl/webgl/constants';
6
6
  import {
7
7
  SharedRenderPipeline,
8
8
  log,
@@ -48,6 +48,9 @@ export class WEBGLSharedRenderPipeline extends SharedRenderPipeline {
48
48
  }
49
49
 
50
50
  this._linkShaders();
51
+ // Introspection happens after linking to build wrapper-facing layout metadata.
52
+ // It is not a prerequisite for deciding whether a shared `WebGLProgram` can be
53
+ // reused; that decision must remain based on the shared-pipeline cache key alone.
51
54
  log.time(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
52
55
  this.introspectedLayout = getShaderLayoutFromGLSL(this.device.gl, this.handle);
53
56
  log.timeEnd(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
@@ -15,6 +15,7 @@ import {
15
15
  type TextureWriteOptions,
16
16
  type TextureFormat,
17
17
  Buffer,
18
+ getTypedArrayConstructor,
18
19
  Texture,
19
20
  log
20
21
  } from '@luma.gl/core';
@@ -27,7 +28,7 @@ import {
27
28
  GLTextureCubeMapTarget,
28
29
  GLTexelDataFormat,
29
30
  GLPixelType
30
- } from '@luma.gl/constants';
31
+ } from '@luma.gl/webgl/constants';
31
32
 
32
33
  import {getTextureFormatWebGL} from '../converters/webgl-texture-table';
33
34
  import {convertSamplerParametersToWebGL} from '../converters/sampler-parameters';
@@ -38,7 +39,6 @@ import {WEBGLFramebuffer} from './webgl-framebuffer';
38
39
  import {WEBGLSampler} from './webgl-sampler';
39
40
  import {WEBGLTextureView} from './webgl-texture-view';
40
41
  import {convertGLDataTypeToDataType} from '../converters/shader-formats';
41
- import {getTypedArrayConstructor} from '@luma.gl/core';
42
42
 
43
43
  /**
44
44
  * WebGL... the texture API from hell... hopefully made simpler
@@ -219,23 +219,21 @@ export class WEBGLTexture extends Texture {
219
219
  * @note Only first-pass color readback is supported. Unsupported formats and aspects throw
220
220
  * before any WebGL calls are issued.
221
221
  */
222
- readBuffer(options: TextureReadOptions = {}, buffer?: Buffer): Buffer {
222
+ readBuffer(options: TextureReadOptions & {byteOffset?: number} = {}, buffer?: Buffer): Buffer {
223
+ if (!buffer) {
224
+ throw new Error(`${this} readBuffer requires a destination buffer`);
225
+ }
223
226
  const normalizedOptions = this._getSupportedColorReadOptions(options);
227
+ const byteOffset = options.byteOffset ?? 0;
224
228
  const memoryLayout = this.computeMemoryLayout(normalizedOptions);
225
- const readBuffer =
226
- buffer ||
227
- this.device.createBuffer({
228
- byteLength: memoryLayout.byteLength,
229
- usage: Buffer.COPY_DST | Buffer.MAP_READ
230
- });
231
229
 
232
- if (readBuffer.byteLength < memoryLayout.byteLength) {
230
+ if (buffer.byteLength < byteOffset + memoryLayout.byteLength) {
233
231
  throw new Error(
234
- `${this} readBuffer target is too small (${readBuffer.byteLength} < ${memoryLayout.byteLength})`
232
+ `${this} readBuffer target is too small (${buffer.byteLength} < ${byteOffset + memoryLayout.byteLength})`
235
233
  );
236
234
  }
237
235
 
238
- const webglBuffer = readBuffer as WEBGLBuffer;
236
+ const webglBuffer = buffer as WEBGLBuffer;
239
237
  this.gl.bindBuffer(GL.PIXEL_PACK_BUFFER, webglBuffer.handle);
240
238
  try {
241
239
  this._readColorTextureLayers(normalizedOptions, memoryLayout, destinationByteOffset => {
@@ -246,21 +244,20 @@ export class WEBGLTexture extends Texture {
246
244
  normalizedOptions.height,
247
245
  this.glFormat,
248
246
  this.glType,
249
- destinationByteOffset
247
+ byteOffset + destinationByteOffset
250
248
  );
251
249
  });
252
250
  } finally {
253
251
  this.gl.bindBuffer(GL.PIXEL_PACK_BUFFER, null);
254
252
  }
255
253
 
256
- return readBuffer;
254
+ return buffer;
257
255
  }
258
256
 
259
257
  async readDataAsync(options: TextureReadOptions = {}): Promise<ArrayBuffer> {
260
- const buffer = this.readBuffer(options);
261
- const data = await buffer.readAsync();
262
- buffer.destroy();
263
- return data.buffer as ArrayBuffer;
258
+ throw new Error(
259
+ `${this} readDataAsync is deprecated; use readBuffer() with an explicit destination buffer or DynamicTexture.readAsync()`
260
+ );
264
261
  }
265
262
 
266
263
  writeBuffer(buffer: Buffer, options_: TextureWriteOptions = {}) {
@@ -1,6 +1,6 @@
1
1
  import type {PrimitiveTopology, ShaderLayout, TransformFeedbackProps} from '@luma.gl/core';
2
2
  import {log, TransformFeedback, Buffer, BufferRange} from '@luma.gl/core';
3
- import {GL} from '@luma.gl/constants';
3
+ import {GL} from '@luma.gl/webgl/constants';
4
4
  import {WebGLDevice} from '../webgl-device';
5
5
  import {WEBGLBuffer} from '../../index';
6
6
  import {getGLPrimitive} from '../helpers/webgl-topology-utils';
@@ -5,7 +5,7 @@
5
5
  import type {TypedArray, NumericArray} from '@math.gl/types';
6
6
  import type {Device, Buffer, VertexArrayProps} from '@luma.gl/core';
7
7
  import {VertexArray, getScratchArray} from '@luma.gl/core';
8
- import {GL} from '@luma.gl/constants';
8
+ import {GL} from '@luma.gl/webgl/constants';
9
9
  import {getBrowser} from '@probe.gl/env';
10
10
 
11
11
  import {WebGLDevice} from '../webgl-device';
@@ -36,7 +36,7 @@ import type {
36
36
  VertexFormat
37
37
  } from '@luma.gl/core';
38
38
  import {Device, CanvasContext, log} from '@luma.gl/core';
39
- import type {GLExtensions} from '@luma.gl/constants';
39
+ import type {GLExtensions} from '@luma.gl/webgl/constants';
40
40
  import {WebGLStateTracker} from '../context/state-tracker/webgl-state-tracker';
41
41
  import {createBrowserContext} from '../context/helpers/create-browser-context';
42
42
  import {getWebGLContextData} from '../context/helpers/webgl-context-data';
@@ -369,13 +369,7 @@ export class WebGLDevice extends Device {
369
369
  submit(commandBuffer?: WEBGLCommandBuffer): void {
370
370
  let submittedCommandEncoder: WEBGLCommandEncoder | null = null;
371
371
  if (!commandBuffer) {
372
- submittedCommandEncoder = this.commandEncoder;
373
- commandBuffer = submittedCommandEncoder.finish();
374
- this.commandEncoder.destroy();
375
- this.commandEncoder = this.createCommandEncoder({
376
- id: submittedCommandEncoder.props.id,
377
- timeProfilingQuerySet: submittedCommandEncoder.getTimeProfilingQuerySet()
378
- });
372
+ ({submittedCommandEncoder, commandBuffer} = this._finalizeDefaultCommandEncoderForSubmit());
379
373
  }
380
374
 
381
375
  try {
@@ -394,6 +388,20 @@ export class WebGLDevice extends Device {
394
388
  }
395
389
  }
396
390
 
391
+ private _finalizeDefaultCommandEncoderForSubmit(): {
392
+ submittedCommandEncoder: WEBGLCommandEncoder;
393
+ commandBuffer: WEBGLCommandBuffer;
394
+ } {
395
+ const submittedCommandEncoder = this.commandEncoder;
396
+ const commandBuffer = submittedCommandEncoder.finish();
397
+ this.commandEncoder.destroy();
398
+ this.commandEncoder = this.createCommandEncoder({
399
+ id: submittedCommandEncoder.props.id,
400
+ timeProfilingQuerySet: submittedCommandEncoder.getTimeProfilingQuerySet()
401
+ });
402
+ return {submittedCommandEncoder, commandBuffer};
403
+ }
404
+
397
405
  //
398
406
  // TEMPORARY HACKS - will be removed in v9.1
399
407
  //
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,EAAE,EAAC,6BAA0B;AAErC,YAAY,EACV,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,WAAW,EACX,aAAa,EACb,aAAa,EACb,UAAU,EACV,eAAe,EACf,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,iBAAiB,EAClB,yBAAsB"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAEpC,OAAO,EAAC,EAAE,EAAC,6BAA0B"}
@@ -0,0 +1,31 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ export {GL} from './webgl-constants';
6
+
7
+ export type {
8
+ GLTextureTarget,
9
+ GLTextureCubeMapTarget,
10
+ GLTexelDataFormat,
11
+ GLPrimitiveTopology,
12
+ GLPrimitive,
13
+ GLDataType,
14
+ GLPixelType,
15
+ GLUniformType,
16
+ GLSamplerType,
17
+ GLFunction,
18
+ GLBlendEquation,
19
+ GLBlendFunction,
20
+ GLStencilOp,
21
+ GLSamplerParameters,
22
+ GLValueParameters,
23
+ GLPackParameters,
24
+ GLUnpackParameters,
25
+ GLFunctionParameters,
26
+ GLParameters,
27
+ GLLimits,
28
+ GLExtensions,
29
+ GLPolygonMode,
30
+ GLProvokingVertex
31
+ } from './webgl-types';