@luma.gl/engine 9.3.0-alpha.4 → 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 (177) hide show
  1. package/dist/animation-loop/animation-loop.d.ts +8 -4
  2. package/dist/animation-loop/animation-loop.d.ts.map +1 -1
  3. package/dist/animation-loop/animation-loop.js +73 -43
  4. package/dist/animation-loop/animation-loop.js.map +1 -1
  5. package/dist/animation-loop/make-animation-loop.js +7 -1
  6. package/dist/animation-loop/make-animation-loop.js.map +1 -1
  7. package/dist/animation-loop/request-animation-frame.d.ts.map +1 -1
  8. package/dist/animation-loop/request-animation-frame.js +23 -6
  9. package/dist/animation-loop/request-animation-frame.js.map +1 -1
  10. package/dist/compute/computation.d.ts +3 -7
  11. package/dist/compute/computation.d.ts.map +1 -1
  12. package/dist/compute/computation.js +14 -12
  13. package/dist/compute/computation.js.map +1 -1
  14. package/dist/dist.dev.js +2310 -1638
  15. package/dist/dist.min.js +307 -360
  16. package/dist/dynamic-texture/dynamic-texture.d.ts +12 -5
  17. package/dist/dynamic-texture/dynamic-texture.d.ts.map +1 -1
  18. package/dist/dynamic-texture/dynamic-texture.js +222 -55
  19. package/dist/dynamic-texture/dynamic-texture.js.map +1 -1
  20. package/dist/dynamic-texture/texture-data.d.ts +8 -1
  21. package/dist/dynamic-texture/texture-data.d.ts.map +1 -1
  22. package/dist/dynamic-texture/texture-data.js +27 -2
  23. package/dist/dynamic-texture/texture-data.js.map +1 -1
  24. package/dist/geometries/cone-geometry.d.ts +3 -1
  25. package/dist/geometries/cone-geometry.d.ts.map +1 -1
  26. package/dist/geometries/cone-geometry.js.map +1 -1
  27. package/dist/geometries/cylinder-geometry.d.ts +2 -1
  28. package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
  29. package/dist/geometries/cylinder-geometry.js.map +1 -1
  30. package/dist/geometry/gpu-geometry.d.ts.map +1 -1
  31. package/dist/geometry/gpu-geometry.js +8 -3
  32. package/dist/geometry/gpu-geometry.js.map +1 -1
  33. package/dist/index.cjs +2897 -2272
  34. package/dist/index.cjs.map +4 -4
  35. package/dist/index.d.ts +12 -3
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +8 -3
  38. package/dist/index.js.map +1 -1
  39. package/dist/material/material-factory.d.ts +73 -0
  40. package/dist/material/material-factory.d.ts.map +1 -0
  41. package/dist/material/material-factory.js +111 -0
  42. package/dist/material/material-factory.js.map +1 -0
  43. package/dist/material/material.d.ts +84 -0
  44. package/dist/material/material.d.ts.map +1 -0
  45. package/dist/material/material.js +176 -0
  46. package/dist/material/material.js.map +1 -0
  47. package/dist/model/model.d.ts +17 -7
  48. package/dist/model/model.d.ts.map +1 -1
  49. package/dist/model/model.js +80 -34
  50. package/dist/model/model.js.map +1 -1
  51. package/dist/model/split-uniforms-and-bindings.d.ts +4 -3
  52. package/dist/model/split-uniforms-and-bindings.d.ts.map +1 -1
  53. package/dist/model/split-uniforms-and-bindings.js +2 -2
  54. package/dist/model/split-uniforms-and-bindings.js.map +1 -1
  55. package/dist/models/billboard-texture-model.d.ts.map +1 -1
  56. package/dist/models/billboard-texture-model.js +10 -8
  57. package/dist/models/billboard-texture-model.js.map +1 -1
  58. package/dist/models/clip-space.js +7 -7
  59. package/dist/models/directional-light-model.d.ts +7 -0
  60. package/dist/models/directional-light-model.d.ts.map +1 -0
  61. package/dist/models/directional-light-model.js +23 -0
  62. package/dist/models/directional-light-model.js.map +1 -0
  63. package/dist/models/light-model-utils.d.ts +69 -0
  64. package/dist/models/light-model-utils.d.ts.map +1 -0
  65. package/dist/models/light-model-utils.js +395 -0
  66. package/dist/models/light-model-utils.js.map +1 -0
  67. package/dist/models/point-light-model.d.ts +7 -0
  68. package/dist/models/point-light-model.d.ts.map +1 -0
  69. package/dist/models/point-light-model.js +22 -0
  70. package/dist/models/point-light-model.js.map +1 -0
  71. package/dist/models/spot-light-model.d.ts +7 -0
  72. package/dist/models/spot-light-model.d.ts.map +1 -0
  73. package/dist/models/spot-light-model.js +23 -0
  74. package/dist/models/spot-light-model.js.map +1 -0
  75. package/dist/modules/picking/color-picking.d.ts +5 -9
  76. package/dist/modules/picking/color-picking.d.ts.map +1 -1
  77. package/dist/modules/picking/color-picking.js +122 -115
  78. package/dist/modules/picking/color-picking.js.map +1 -1
  79. package/dist/modules/picking/index-picking.d.ts +2 -2
  80. package/dist/modules/picking/index-picking.d.ts.map +1 -1
  81. package/dist/modules/picking/index-picking.js +36 -16
  82. package/dist/modules/picking/index-picking.js.map +1 -1
  83. package/dist/modules/picking/legacy-color-picking.d.ts +26 -0
  84. package/dist/modules/picking/legacy-color-picking.d.ts.map +1 -0
  85. package/dist/modules/picking/legacy-color-picking.js +7 -0
  86. package/dist/modules/picking/legacy-color-picking.js.map +1 -0
  87. package/dist/modules/picking/picking-manager.d.ts +29 -3
  88. package/dist/modules/picking/picking-manager.d.ts.map +1 -1
  89. package/dist/modules/picking/picking-manager.js +188 -41
  90. package/dist/modules/picking/picking-manager.js.map +1 -1
  91. package/dist/modules/picking/picking-uniforms.d.ts +12 -11
  92. package/dist/modules/picking/picking-uniforms.d.ts.map +1 -1
  93. package/dist/modules/picking/picking-uniforms.js +26 -13
  94. package/dist/modules/picking/picking-uniforms.js.map +1 -1
  95. package/dist/modules/picking/picking.d.ts +25 -0
  96. package/dist/modules/picking/picking.d.ts.map +1 -0
  97. package/dist/modules/picking/picking.js +18 -0
  98. package/dist/modules/picking/picking.js.map +1 -0
  99. package/dist/passes/get-fragment-shader.js +11 -30
  100. package/dist/passes/get-fragment-shader.js.map +1 -1
  101. package/dist/passes/shader-pass-renderer.d.ts +0 -2
  102. package/dist/passes/shader-pass-renderer.d.ts.map +1 -1
  103. package/dist/passes/shader-pass-renderer.js +4 -31
  104. package/dist/passes/shader-pass-renderer.js.map +1 -1
  105. package/dist/scenegraph/group-node.d.ts +5 -0
  106. package/dist/scenegraph/group-node.d.ts.map +1 -1
  107. package/dist/scenegraph/group-node.js +12 -0
  108. package/dist/scenegraph/group-node.js.map +1 -1
  109. package/dist/scenegraph/model-node.d.ts +2 -2
  110. package/dist/scenegraph/model-node.d.ts.map +1 -1
  111. package/dist/scenegraph/model-node.js.map +1 -1
  112. package/dist/scenegraph/scenegraph-node.d.ts +1 -1
  113. package/dist/scenegraph/scenegraph-node.d.ts.map +1 -1
  114. package/dist/scenegraph/scenegraph-node.js +23 -15
  115. package/dist/scenegraph/scenegraph-node.js.map +1 -1
  116. package/dist/shader-inputs.d.ts +9 -7
  117. package/dist/shader-inputs.d.ts.map +1 -1
  118. package/dist/shader-inputs.js +84 -4
  119. package/dist/shader-inputs.js.map +1 -1
  120. package/dist/utils/shader-module-utils.d.ts +7 -0
  121. package/dist/utils/shader-module-utils.d.ts.map +1 -0
  122. package/dist/utils/shader-module-utils.js +46 -0
  123. package/dist/utils/shader-module-utils.js.map +1 -0
  124. package/package.json +4 -4
  125. package/src/animation-loop/animation-loop.ts +78 -46
  126. package/src/animation-loop/make-animation-loop.ts +13 -5
  127. package/src/animation-loop/request-animation-frame.ts +32 -6
  128. package/src/compute/computation.ts +31 -17
  129. package/src/dynamic-texture/dynamic-texture.ts +301 -68
  130. package/src/dynamic-texture/texture-data.ts +39 -4
  131. package/src/geometries/cone-geometry.ts +6 -1
  132. package/src/geometries/cylinder-geometry.ts +5 -1
  133. package/src/geometry/gpu-geometry.ts +8 -3
  134. package/src/index.ts +29 -4
  135. package/src/material/material-factory.ts +157 -0
  136. package/src/material/material.ts +254 -0
  137. package/src/model/model.ts +122 -50
  138. package/src/model/split-uniforms-and-bindings.ts +8 -6
  139. package/src/models/billboard-texture-model.ts +10 -8
  140. package/src/models/clip-space.ts +7 -7
  141. package/src/models/directional-light-model.ts +32 -0
  142. package/src/models/light-model-utils.ts +587 -0
  143. package/src/models/point-light-model.ts +31 -0
  144. package/src/models/spot-light-model.ts +32 -0
  145. package/src/modules/picking/color-picking.ts +123 -122
  146. package/src/modules/picking/index-picking.ts +36 -16
  147. package/src/modules/picking/legacy-color-picking.ts +8 -0
  148. package/src/modules/picking/picking-manager.ts +252 -50
  149. package/src/modules/picking/picking-uniforms.ts +38 -23
  150. package/src/modules/picking/picking.ts +22 -0
  151. package/src/passes/get-fragment-shader.ts +11 -30
  152. package/src/passes/shader-pass-renderer.ts +4 -33
  153. package/src/scenegraph/group-node.ts +16 -0
  154. package/src/scenegraph/model-node.ts +2 -2
  155. package/src/scenegraph/scenegraph-node.ts +27 -16
  156. package/src/shader-inputs.ts +165 -15
  157. package/src/utils/shader-module-utils.ts +65 -0
  158. package/dist/dynamic-texture/mipmaps.d.ts +0 -6
  159. package/dist/dynamic-texture/mipmaps.d.ts.map +0 -1
  160. package/dist/dynamic-texture/mipmaps.js +0 -441
  161. package/dist/dynamic-texture/mipmaps.js.map +0 -1
  162. package/dist/factories/pipeline-factory.d.ts +0 -37
  163. package/dist/factories/pipeline-factory.d.ts.map +0 -1
  164. package/dist/factories/pipeline-factory.js +0 -181
  165. package/dist/factories/pipeline-factory.js.map +0 -1
  166. package/dist/factories/shader-factory.d.ts +0 -22
  167. package/dist/factories/shader-factory.d.ts.map +0 -1
  168. package/dist/factories/shader-factory.js +0 -89
  169. package/dist/factories/shader-factory.js.map +0 -1
  170. package/dist/types.d.ts +0 -7
  171. package/dist/types.d.ts.map +0 -1
  172. package/dist/types.js +0 -5
  173. package/dist/types.js.map +0 -1
  174. package/src/dynamic-texture/mipmaps.ts +0 -517
  175. package/src/factories/pipeline-factory.ts +0 -225
  176. package/src/factories/shader-factory.ts +0 -105
  177. package/src/types.ts +0 -11
@@ -12,6 +12,7 @@ import {AnimationProps} from './animation-props';
12
12
  import {Stats, Stat} from '@probe.gl/stats';
13
13
 
14
14
  let statIdCounter = 0;
15
+ const ANIMATION_LOOP_STATS = 'Animation Loop';
15
16
 
16
17
  /** AnimationLoop properties */
17
18
  export type AnimationLoopProps = {
@@ -45,7 +46,7 @@ export class AnimationLoop {
45
46
  onFinalize: () => {},
46
47
  onError: error => console.error(error), // eslint-disable-line no-console
47
48
 
48
- stats: luma.stats.get(`animation-loop-${statIdCounter++}`),
49
+ stats: undefined!,
49
50
 
50
51
  // view parameters
51
52
  autoResizeViewport: false
@@ -58,6 +59,7 @@ export class AnimationLoop {
58
59
  animationProps: AnimationProps | null = null;
59
60
  timeline: Timeline | null = null;
60
61
  stats: Stats;
62
+ sharedStats: Stats;
61
63
  cpuTime: Stat;
62
64
  gpuTime: Stat;
63
65
  frameRate: Stat;
@@ -73,8 +75,7 @@ export class AnimationLoop {
73
75
  _resolveNextFrame: ((animationLoop: AnimationLoop) => void) | null = null;
74
76
  _cpuStartTime: number = 0;
75
77
  _error: Error | null = null;
76
-
77
- // _gpuTimeQuery: Query | null = null;
78
+ _lastFrameTime: number = 0;
78
79
 
79
80
  /*
80
81
  * @param {HTMLCanvasElement} canvas - if provided, width and height will be passed to context
@@ -88,10 +89,12 @@ export class AnimationLoop {
88
89
  }
89
90
 
90
91
  // state
91
- this.stats = props.stats || new Stats({id: 'animation-loop-stats'});
92
+ this.stats = props.stats || new Stats({id: `animation-loop-${statIdCounter++}`});
93
+ this.sharedStats = luma.stats.get(ANIMATION_LOOP_STATS);
94
+ this.frameRate = this.stats.get('Frame Rate');
95
+ this.frameRate.setSampleSize(1);
92
96
  this.cpuTime = this.stats.get('CPU Time');
93
97
  this.gpuTime = this.stats.get('GPU Time');
94
- this.frameRate = this.stats.get('Frame Rate');
95
98
 
96
99
  this.setProps({autoResizeViewport: props.autoResizeViewport});
97
100
 
@@ -106,6 +109,7 @@ export class AnimationLoop {
106
109
  destroy(): void {
107
110
  this.stop();
108
111
  this._setDisplay(null);
112
+ this.device?._disableDebugGPUTime();
109
113
  }
110
114
 
111
115
  /** @deprecated Use .destroy() */
@@ -152,6 +156,9 @@ export class AnimationLoop {
152
156
  // Create the WebGL context
153
157
  await this._initDevice();
154
158
  this._initialize();
159
+ if (!this._running) {
160
+ return null;
161
+ }
155
162
 
156
163
  // Note: onIntialize can return a promise (e.g. in case app needs to load resources)
157
164
  await this.props.onInitialize(this._getAnimationProps());
@@ -192,17 +199,18 @@ export class AnimationLoop {
192
199
  this._nextFramePromise = null;
193
200
  this._resolveNextFrame = null;
194
201
  this._running = false;
202
+ this._lastFrameTime = 0;
195
203
  }
196
204
  return this;
197
205
  }
198
206
 
199
207
  /** Explicitly draw a frame */
200
- redraw(): this {
208
+ redraw(time?: number): this {
201
209
  if (this.device?.isLost || this._error) {
202
210
  return this;
203
211
  }
204
212
 
205
- this._beginFrameTimers();
213
+ this._beginFrameTimers(time);
206
214
 
207
215
  this._setupFrame();
208
216
  this._updateAnimationProps();
@@ -268,7 +276,7 @@ export class AnimationLoop {
268
276
  // Default viewport setup, in case onInitialize wants to render
269
277
  this._resizeViewport();
270
278
 
271
- // this._gpuTimeQuery = Query.isSupported(this.gl, ['timers']) ? new Query(this.gl) : null;
279
+ this.device?._enableDebugGPUTime();
272
280
  }
273
281
 
274
282
  _setDisplay(display: any): void {
@@ -314,11 +322,11 @@ export class AnimationLoop {
314
322
  this._animationFrameId = null;
315
323
  }
316
324
 
317
- _animationFrame(): void {
325
+ _animationFrame(time: number): void {
318
326
  if (!this._running) {
319
327
  return;
320
328
  }
321
- this.redraw();
329
+ this.redraw(time);
322
330
  this._requestAnimationFrame();
323
331
  }
324
332
 
@@ -467,20 +475,10 @@ export class AnimationLoop {
467
475
  if (!this.device) {
468
476
  return {width: 1, height: 1, aspect: 1};
469
477
  }
470
- // https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
471
- const [width, height] = this.device?.getDefaultCanvasContext().getDevicePixelSize() || [1, 1];
472
-
473
- // https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
474
- let aspect = 1;
475
- const canvas = this.device?.getDefaultCanvasContext().canvas;
476
-
477
- // @ts-expect-error
478
- if (canvas && canvas.clientHeight) {
479
- // @ts-expect-error
480
- aspect = canvas.clientWidth / canvas.clientHeight;
481
- } else if (width > 0 && height > 0) {
482
- aspect = width / height;
483
- }
478
+ // Match projection setup to the actual render target dimensions, which may
479
+ // differ from the CSS size when device-pixel scaling or backend clamping applies.
480
+ const [width, height] = this.device.getDefaultCanvasContext().getDrawingBufferSize();
481
+ const aspect = width > 0 && height > 0 ? width / height : 1;
484
482
 
485
483
  return {width, height, aspect};
486
484
  }
@@ -502,36 +500,70 @@ export class AnimationLoop {
502
500
  }
503
501
  }
504
502
 
505
- _beginFrameTimers() {
506
- this.frameRate.timeEnd();
507
- this.frameRate.timeStart();
508
-
509
- // Check if timer for last frame has completed.
510
- // GPU timer results are never available in the same
511
- // frame they are captured.
512
- // if (
513
- // this._gpuTimeQuery &&
514
- // this._gpuTimeQuery.isResultAvailable() &&
515
- // !this._gpuTimeQuery.isTimerDisjoint()
516
- // ) {
517
- // this.stats.get('GPU Time').addTime(this._gpuTimeQuery.getTimerMilliseconds());
518
- // }
503
+ _beginFrameTimers(time?: number) {
504
+ const now = time ?? (typeof performance !== 'undefined' ? performance.now() : Date.now());
505
+ if (this._lastFrameTime) {
506
+ const frameTime = now - this._lastFrameTime;
507
+ if (frameTime > 0) {
508
+ this.frameRate.addTime(frameTime);
509
+ }
510
+ }
511
+ this._lastFrameTime = now;
519
512
 
520
- // if (this._gpuTimeQuery) {
521
- // // GPU time query start
522
- // this._gpuTimeQuery.beginTimeElapsedQuery();
523
- // }
513
+ if (this.device?._isDebugGPUTimeEnabled()) {
514
+ this._consumeEncodedGpuTime();
515
+ }
524
516
 
525
517
  this.cpuTime.timeStart();
526
518
  }
527
519
 
528
520
  _endFrameTimers() {
521
+ if (this.device?._isDebugGPUTimeEnabled()) {
522
+ this._consumeEncodedGpuTime();
523
+ }
524
+
529
525
  this.cpuTime.timeEnd();
526
+ this._updateSharedStats();
527
+ }
530
528
 
531
- // if (this._gpuTimeQuery) {
532
- // // GPU time query end. Results will be available on next frame.
533
- // this._gpuTimeQuery.end();
534
- // }
529
+ _consumeEncodedGpuTime(): void {
530
+ if (!this.device) {
531
+ return;
532
+ }
533
+
534
+ const gpuTimeMs = this.device.commandEncoder._gpuTimeMs;
535
+ if (gpuTimeMs !== undefined) {
536
+ this.gpuTime.addTime(gpuTimeMs);
537
+ this.device.commandEncoder._gpuTimeMs = undefined;
538
+ }
539
+ }
540
+
541
+ _updateSharedStats(): void {
542
+ if (this.stats === this.sharedStats) {
543
+ return;
544
+ }
545
+
546
+ for (const name of Object.keys(this.sharedStats.stats)) {
547
+ if (!this.stats.stats[name]) {
548
+ delete this.sharedStats.stats[name];
549
+ }
550
+ }
551
+
552
+ this.stats.forEach(sourceStat => {
553
+ const targetStat = this.sharedStats.get(sourceStat.name, sourceStat.type);
554
+ targetStat.sampleSize = sourceStat.sampleSize;
555
+ targetStat.time = sourceStat.time;
556
+ targetStat.count = sourceStat.count;
557
+ targetStat.samples = sourceStat.samples;
558
+ targetStat.lastTiming = sourceStat.lastTiming;
559
+ targetStat.lastSampleTime = sourceStat.lastSampleTime;
560
+ targetStat.lastSampleCount = sourceStat.lastSampleCount;
561
+ targetStat._count = sourceStat._count;
562
+ targetStat._time = sourceStat._time;
563
+ targetStat._samples = sourceStat._samples;
564
+ targetStat._startTime = sourceStat._startTime;
565
+ targetStat._timerPending = sourceStat._timerPending;
566
+ });
535
567
  }
536
568
 
537
569
  // Event handling
@@ -36,14 +36,14 @@ export function makeAnimationLoop(
36
36
  device,
37
37
 
38
38
  async onInitialize(animationProps: AnimationProps): Promise<unknown> {
39
- clearError(animationProps.animationLoop.device!);
39
+ clearError(animationProps.animationLoop.device);
40
40
  try {
41
41
  // @ts-expect-error abstract to prevent instantiation
42
42
  renderLoop = new AnimationLoopTemplateCtor(animationProps);
43
43
  // Any async loading can be handled here
44
44
  return await renderLoop?.onInitialize(animationProps);
45
45
  } catch (error) {
46
- setError(animationProps.animationLoop.device!, error as Error);
46
+ setError(animationProps.animationLoop.device, error as Error);
47
47
  return null;
48
48
  }
49
49
  },
@@ -63,8 +63,12 @@ export function makeAnimationLoop(
63
63
  return animationLoop;
64
64
  }
65
65
 
66
- function setError(device: Device, error: Error): void {
67
- const canvas = device?.getDefaultCanvasContext().canvas;
66
+ function setError(device: Device | null, error: Error): void {
67
+ if (!device) {
68
+ return;
69
+ }
70
+
71
+ const canvas = device.getDefaultCanvasContext().canvas;
68
72
  if (canvas instanceof HTMLCanvasElement) {
69
73
  canvas.style.overflow = 'visible';
70
74
  let errorDiv = document.getElementById('animation-loop-error');
@@ -82,7 +86,11 @@ function setError(device: Device, error: Error): void {
82
86
  }
83
87
  }
84
88
 
85
- function clearError(device: Device): void {
89
+ function clearError(device: Device | null): void {
90
+ if (!device) {
91
+ return;
92
+ }
93
+
86
94
  const errorDiv = document.getElementById('animation-loop-error');
87
95
  if (errorDiv) {
88
96
  errorDiv.remove();
@@ -7,14 +7,40 @@
7
7
  /** Node.js polyfill for requestAnimationFrame */
8
8
  // / <reference types="@types/node" />
9
9
  export function requestAnimationFramePolyfill(callback: (time?: any) => void): any {
10
- return typeof window !== 'undefined' && window.requestAnimationFrame
11
- ? window.requestAnimationFrame(callback)
12
- : setTimeout(callback, 1000 / 60);
10
+ const browserRequestAnimationFrame =
11
+ typeof window !== 'undefined'
12
+ ? window.requestAnimationFrame ||
13
+ (window as Window & {webkitRequestAnimationFrame?: (cb: FrameRequestCallback) => number})
14
+ .webkitRequestAnimationFrame ||
15
+ (window as Window & {mozRequestAnimationFrame?: (cb: FrameRequestCallback) => number})
16
+ .mozRequestAnimationFrame
17
+ : null;
18
+
19
+ if (browserRequestAnimationFrame) {
20
+ return browserRequestAnimationFrame.call(window, callback);
21
+ }
22
+
23
+ return setTimeout(
24
+ () => callback(typeof performance !== 'undefined' ? performance.now() : Date.now()),
25
+ 1000 / 60
26
+ );
13
27
  }
14
28
 
15
29
  /** Node.js polyfill for cancelAnimationFrame */
16
30
  export function cancelAnimationFramePolyfill(timerId: any): void {
17
- return typeof window !== 'undefined' && window.cancelAnimationFrame
18
- ? window.cancelAnimationFrame(timerId)
19
- : clearTimeout(timerId);
31
+ const browserCancelAnimationFrame =
32
+ typeof window !== 'undefined'
33
+ ? window.cancelAnimationFrame ||
34
+ (window as Window & {webkitCancelAnimationFrame?: (handle: number) => void})
35
+ .webkitCancelAnimationFrame ||
36
+ (window as Window & {mozCancelAnimationFrame?: (handle: number) => void})
37
+ .mozCancelAnimationFrame
38
+ : null;
39
+
40
+ if (browserCancelAnimationFrame) {
41
+ browserCancelAnimationFrame.call(window, timerId);
42
+ return;
43
+ }
44
+
45
+ clearTimeout(timerId);
20
46
  }
@@ -2,22 +2,28 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import type {DeviceFeature, ComputePipelineProps, Shader, Binding} from '@luma.gl/core';
6
5
  import {
6
+ type DeviceFeature,
7
+ type ComputePipelineProps,
8
+ type Shader,
9
+ type Binding,
7
10
  Device,
8
11
  Buffer,
9
12
  ComputePipeline,
10
13
  ComputePass,
14
+ PipelineFactory,
15
+ ShaderFactory,
11
16
  UniformStore,
12
17
  log,
13
- getTypedArrayConstructor
18
+ dataTypeDecoder
14
19
  } from '@luma.gl/core';
15
- import type {ShaderModule, PlatformInfo} from '@luma.gl/shadertools';
16
- import {ShaderAssembler} from '@luma.gl/shadertools';
17
- import {TypedArray, isNumericArray} from '@math.gl/types';
20
+ import {type ShaderModule, type PlatformInfo, ShaderAssembler} from '@luma.gl/shadertools';
21
+ import {type TypedArray, isNumericArray} from '@math.gl/types';
18
22
  import {ShaderInputs} from '../shader-inputs';
19
- import {PipelineFactory} from '../factories/pipeline-factory';
20
- import {ShaderFactory} from '../factories/shader-factory';
23
+ import {
24
+ mergeShaderModuleBindingsIntoLayout,
25
+ shaderModuleHasUniforms
26
+ } from '../utils/shader-module-utils';
21
27
  import {uid} from '../utils/uid';
22
28
  // import {getDebugTableForShaderLayout} from '../debug/debug-shader-layout';
23
29
 
@@ -131,11 +137,6 @@ export class Computation {
131
137
  this.shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap);
132
138
  this.setShaderInputs(this.shaderInputs);
133
139
 
134
- // Support WGSL shader layout introspection
135
- // TODO - Don't modify props!!
136
- // @ts-expect-error method on WebGPUDevice
137
- this.props.shaderLayout ||= device.getShaderLayout(this.props.source);
138
-
139
140
  // Setup shader assembler
140
141
  const platformInfo = getPlatformInfo(device);
141
142
 
@@ -143,6 +144,9 @@ export class Computation {
143
144
  const modules =
144
145
  (this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || [];
145
146
 
147
+ this.props.shaderLayout =
148
+ mergeShaderModuleBindingsIntoLayout(this.props.shaderLayout, modules) || null;
149
+
146
150
  this.pipelineFactory =
147
151
  props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
148
152
  this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
@@ -156,6 +160,14 @@ export class Computation {
156
160
  this.source = source;
157
161
  // @ts-ignore
158
162
  this._getModuleUniforms = getUniforms;
163
+ const inferredShaderLayout = (
164
+ device as Device & {getShaderLayout?: (source: string) => any}
165
+ ).getShaderLayout?.(this.source);
166
+ this.props.shaderLayout =
167
+ mergeShaderModuleBindingsIntoLayout(
168
+ this.props.shaderLayout || inferredShaderLayout || null,
169
+ modules
170
+ ) || null;
159
171
 
160
172
  // Create the pipeline
161
173
  // @note order is important
@@ -198,7 +210,7 @@ export class Computation {
198
210
  this.pipeline.setBindings(this.bindings);
199
211
  computePass.setPipeline(this.pipeline);
200
212
  // @ts-expect-error
201
- computePass.setBindings([]);
213
+ computePass.setBindings({});
202
214
 
203
215
  computePass.dispatch(x, y, z);
204
216
  } finally {
@@ -230,9 +242,11 @@ export class Computation {
230
242
  this.shaderInputs = shaderInputs;
231
243
  this._uniformStore = new UniformStore(this.shaderInputs.modules);
232
244
  // Create uniform buffer bindings for all modules
233
- for (const moduleName of Object.keys(this.shaderInputs.modules)) {
234
- const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
235
- this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
245
+ for (const [moduleName, module] of Object.entries(this.shaderInputs.modules)) {
246
+ if (shaderModuleHasUniforms(module)) {
247
+ const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
248
+ this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
249
+ }
236
250
  }
237
251
  }
238
252
 
@@ -341,7 +355,7 @@ export class Computation {
341
355
 
342
356
  // TODO - fix typing of luma data types
343
357
  _getBufferOrConstantValues(attribute: Buffer | TypedArray, dataType: any): string {
344
- const TypedArrayConstructor = getTypedArrayConstructor(dataType);
358
+ const TypedArrayConstructor = dataTypeDecoder.getTypedArrayConstructor(dataType);
345
359
  const typedArray =
346
360
  attribute instanceof Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
347
361
  return typedArray.toString();