@luma.gl/test-utils 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 (74) hide show
  1. package/dist/create-test-device.d.ts +19 -0
  2. package/dist/create-test-device.d.ts.map +1 -1
  3. package/dist/create-test-device.js +85 -18
  4. package/dist/create-test-device.js.map +1 -1
  5. package/dist/deprecated/classic-animation-loop.d.ts.map +1 -1
  6. package/dist/deprecated/classic-animation-loop.js +2 -10
  7. package/dist/deprecated/classic-animation-loop.js.map +1 -1
  8. package/dist/deprecated/sync-test-device.d.ts +0 -5
  9. package/dist/deprecated/sync-test-device.d.ts.map +1 -1
  10. package/dist/deprecated/sync-test-device.js +11 -1
  11. package/dist/deprecated/sync-test-device.js.map +1 -1
  12. package/dist/index.cjs +232 -103
  13. package/dist/index.cjs.map +4 -4
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +1 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/null-device/null-canvas-context.d.ts +2 -2
  19. package/dist/null-device/null-canvas-context.d.ts.map +1 -1
  20. package/dist/null-device/null-canvas-context.js +4 -3
  21. package/dist/null-device/null-canvas-context.js.map +1 -1
  22. package/dist/null-device/null-device.d.ts +7 -4
  23. package/dist/null-device/null-device.d.ts.map +1 -1
  24. package/dist/null-device/null-device.js +20 -7
  25. package/dist/null-device/null-device.js.map +1 -1
  26. package/dist/null-device/resources/null-command-buffer.d.ts +8 -8
  27. package/dist/null-device/resources/null-command-buffer.d.ts.map +1 -1
  28. package/dist/null-device/resources/null-command-buffer.js +16 -6
  29. package/dist/null-device/resources/null-command-buffer.js.map +1 -1
  30. package/dist/null-device/resources/null-command-encoder.d.ts +8 -7
  31. package/dist/null-device/resources/null-command-encoder.d.ts.map +1 -1
  32. package/dist/null-device/resources/null-command-encoder.js +24 -9
  33. package/dist/null-device/resources/null-command-encoder.js.map +1 -1
  34. package/dist/null-device/resources/null-fence.d.ts +12 -0
  35. package/dist/null-device/resources/null-fence.d.ts.map +1 -0
  36. package/dist/null-device/resources/null-fence.js +19 -0
  37. package/dist/null-device/resources/null-fence.js.map +1 -0
  38. package/dist/null-device/resources/null-query-set.d.ts +6 -0
  39. package/dist/null-device/resources/null-query-set.d.ts.map +1 -1
  40. package/dist/null-device/resources/null-query-set.js +11 -0
  41. package/dist/null-device/resources/null-query-set.js.map +1 -1
  42. package/dist/null-device/resources/null-render-pass.d.ts.map +1 -1
  43. package/dist/null-device/resources/null-render-pass.js +6 -1
  44. package/dist/null-device/resources/null-render-pass.js.map +1 -1
  45. package/dist/null-device/resources/null-render-pipeline.d.ts +3 -4
  46. package/dist/null-device/resources/null-render-pipeline.d.ts.map +1 -1
  47. package/dist/null-device/resources/null-render-pipeline.js +0 -5
  48. package/dist/null-device/resources/null-render-pipeline.js.map +1 -1
  49. package/dist/null-device/resources/null-texture.d.ts +5 -3
  50. package/dist/null-device/resources/null-texture.d.ts.map +1 -1
  51. package/dist/null-device/resources/null-texture.js +16 -15
  52. package/dist/null-device/resources/null-texture.js.map +1 -1
  53. package/dist/test-runner.d.ts +1 -1
  54. package/dist/test-runner.d.ts.map +1 -1
  55. package/dist/test-runner.js +2 -1
  56. package/dist/test-runner.js.map +1 -1
  57. package/dist/utils/resource-tracker.js +1 -1
  58. package/dist/utils/resource-tracker.js.map +1 -1
  59. package/package.json +9 -9
  60. package/src/create-test-device.ts +115 -18
  61. package/src/deprecated/classic-animation-loop.ts +2 -10
  62. package/src/deprecated/sync-test-device.ts +16 -1
  63. package/src/index.ts +1 -0
  64. package/src/null-device/null-canvas-context.ts +4 -3
  65. package/src/null-device/null-device.ts +26 -8
  66. package/src/null-device/resources/null-command-buffer.ts +18 -8
  67. package/src/null-device/resources/null-command-encoder.ts +25 -9
  68. package/src/null-device/resources/null-fence.ts +24 -0
  69. package/src/null-device/resources/null-query-set.ts +14 -0
  70. package/src/null-device/resources/null-render-pass.ts +6 -1
  71. package/src/null-device/resources/null-render-pipeline.ts +3 -14
  72. package/src/null-device/resources/null-texture.ts +36 -29
  73. package/src/test-runner.ts +2 -1
  74. package/src/utils/resource-tracker.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"test-runner.js","sourceRoot":"","sources":["../src/test-runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"test-runner.js","sourceRoot":"","sources":["../src/test-runner.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /* global luma */
2
2
  export function getResourceCounts() {
3
3
  // @ts-ignore
4
- const resourceStats = luma.stats.get('Resource Counts');
4
+ const resourceStats = luma.stats.get('GPU Resource Counts');
5
5
  return {
6
6
  Texture2D: resourceStats.get('Texture2Ds Active').count,
7
7
  Buffer: resourceStats.get('Buffers Active').count
@@ -1 +1 @@
1
- {"version":3,"file":"resource-tracker.js","sourceRoot":"","sources":["../../src/utils/resource-tracker.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,MAAM,UAAU,iBAAiB;IAC/B,aAAa;IACb,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACxD,OAAO;QACL,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,KAAK;QACvD,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,KAAK;KAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,WAAmC,EACnC,SAAiC;IAEjC,IAAI,eAAe,GAAG,IAAI,CAAC;IAC3B,MAAM,IAAI,GAAG,WAAW,CAAC;IACzB,KAAK,MAAM,YAAY,IAAI,SAAS,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;QACtE,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YACpB,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,eAAe,EAAE;gBACnD,CAAC,YAAY,CAAC,EAAE,SAAS;gBACzB,IAAI,EAAE,GAAG,IAAI,IAAI,YAAY,KAAK,SAAS,IAAI;aAChD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"resource-tracker.js","sourceRoot":"","sources":["../../src/utils/resource-tracker.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,MAAM,UAAU,iBAAiB;IAC/B,aAAa;IACb,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAC5D,OAAO;QACL,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,KAAK;QACvD,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,KAAK;KAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,WAAmC,EACnC,SAAiC;IAEjC,IAAI,eAAe,GAAG,IAAI,CAAC;IAC3B,MAAM,IAAI,GAAG,WAAW,CAAC;IACzB,KAAK,MAAM,YAAY,IAAI,SAAS,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;QACtE,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YACpB,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,eAAe,EAAE;gBACnD,CAAC,YAAY,CAAC,EAAE,SAAS;gBACzB,IAAI,EAAE,GAAG,IAAI,IAAI,YAAY,KAAK,SAAS,IAAI;aAChD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luma.gl/test-utils",
3
- "version": "9.2.6",
3
+ "version": "9.3.0-alpha.10",
4
4
  "description": "Automated WebGL testing utilities with Puppeteer and image diffing",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -36,15 +36,15 @@
36
36
  "pre-build": "echo test utils has no bundle"
37
37
  },
38
38
  "peerDependencies": {
39
- "@luma.gl/core": "~9.2.0",
40
- "@luma.gl/engine": "~9.2.0",
41
- "@luma.gl/shadertools": "~9.2.0",
42
- "@luma.gl/webgl": "~9.2.0",
43
- "@luma.gl/webgpu": "~9.2.0"
39
+ "@luma.gl/core": "9.3.0-alpha.6",
40
+ "@luma.gl/engine": "9.3.0-alpha.6",
41
+ "@luma.gl/shadertools": "9.3.0-alpha.6",
42
+ "@luma.gl/webgl": "9.3.0-alpha.6",
43
+ "@luma.gl/webgpu": "9.3.0-alpha.6"
44
44
  },
45
45
  "dependencies": {
46
- "@probe.gl/env": "^4.0.8",
47
- "@probe.gl/stats": "^4.0.8"
46
+ "@probe.gl/env": "^4.1.1",
47
+ "@probe.gl/stats": "^4.1.1"
48
48
  },
49
- "gitHead": "9c7a3adc09c7b23800df3f916762445ebc1fa924"
49
+ "gitHead": "ca3a841517106f8608ce392440fa7f324863a84f"
50
50
  }
@@ -10,13 +10,26 @@ import {nullAdapter} from './null-device/null-adapter';
10
10
  import {NullDevice} from './null-device/null-device';
11
11
 
12
12
  const DEFAULT_CANVAS_CONTEXT_PROPS: CanvasContextProps = {width: 1, height: 1};
13
+ const TEST_DEVICE_CACHE_KEY = '__lumaTestDeviceCache';
13
14
 
14
- /** A null device intended for testing - @note Only available after getTestDevices() has completed */
15
- let nullDevicePromise = makeNullTestDevice();
16
- /** This WebGL Device can be used directly but will not have WebGL debugging initialized */
17
- const webglDevicePromise = makeWebGLTestDevice();
18
- /** A WebGL 2 Device intended for testing - @note Only available after getTestDevices() has completed */
19
- const webgpuDevicePromise = makeWebGPUTestDevice();
15
+ type TestDeviceCache = {
16
+ /** A null device intended for testing - @note Only available after getTestDevices() has completed */
17
+ nullDevicePromise: Promise<NullDevice> | null;
18
+ /** This WebGL Device can be used directly but will not have WebGL debugging initialized */
19
+ webglDevicePromise: Promise<WebGLDevice> | null;
20
+ /** A shared offscreen WebGL device for presentation-context tests */
21
+ presentationWebglDevicePromise: Promise<WebGLDevice | null> | null;
22
+ /** A WebGL 2 Device intended for testing - @note Only available after getTestDevices() has completed */
23
+ webgpuDevicePromise: Promise<WebGPUDevice | null> | null;
24
+ };
25
+
26
+ declare global {
27
+ interface Window {
28
+ [TEST_DEVICE_CACHE_KEY]?: TestDeviceCache;
29
+ }
30
+ }
31
+
32
+ const testDeviceCache = getOrCreateTestDeviceCache();
20
33
 
21
34
  /** Includes WebGPU device if available */
22
35
  export async function getTestDevices(
@@ -32,29 +45,61 @@ export async function getTestDevice(
32
45
  ): Promise<Device | null> {
33
46
  switch (type) {
34
47
  case 'webgl':
35
- return webglDevicePromise;
48
+ return getOrCreateWebGLTestDevicePromise();
36
49
  case 'webgpu':
37
- return webgpuDevicePromise;
50
+ return getWebGPUTestDevice();
38
51
  case 'null':
39
- return nullDevicePromise;
52
+ return getOrCreateNullTestDevicePromise();
40
53
  case 'unknown':
41
54
  return null;
42
55
  }
43
56
  }
44
57
 
45
58
  /** returns WebGPU device promise, if available */
46
- export function getWebGPUTestDevice(): Promise<WebGPUDevice | null> {
47
- return webgpuDevicePromise;
59
+ export async function getWebGPUTestDevice(): Promise<WebGPUDevice | null> {
60
+ const webgpuDevice = await getOrCreateWebGPUTestDevicePromise();
61
+ if (webgpuDevice?.isLost) {
62
+ if (testDeviceCache.webgpuDevicePromise) {
63
+ testDeviceCache.webgpuDevicePromise = null;
64
+ }
65
+ return getOrCreateWebGPUTestDevicePromise();
66
+ }
67
+ return webgpuDevice;
48
68
  }
49
69
 
50
70
  /** returns WebGL device promise, if available */
51
71
  export async function getWebGLTestDevice(): Promise<WebGLDevice> {
52
- return webglDevicePromise;
72
+ return getOrCreateWebGLTestDevicePromise();
73
+ }
74
+
75
+ /** returns an offscreen WebGL device promise for presentation-context tests, if available */
76
+ export async function getPresentationWebGLTestDevice(): Promise<WebGLDevice | null> {
77
+ return getOrCreatePresentationWebGLTestDevicePromise();
53
78
  }
54
79
 
55
80
  /** returns null device promise, if available */
56
81
  export async function getNullTestDevice(): Promise<NullDevice> {
57
- return nullDevicePromise;
82
+ return getOrCreateNullTestDevicePromise();
83
+ }
84
+
85
+ function getOrCreateWebGPUTestDevicePromise(): Promise<WebGPUDevice | null> {
86
+ testDeviceCache.webgpuDevicePromise ||= makeWebGPUTestDevice();
87
+ return testDeviceCache.webgpuDevicePromise;
88
+ }
89
+
90
+ function getOrCreateWebGLTestDevicePromise(): Promise<WebGLDevice> {
91
+ testDeviceCache.webglDevicePromise ||= makeWebGLTestDevice();
92
+ return testDeviceCache.webglDevicePromise;
93
+ }
94
+
95
+ function getOrCreatePresentationWebGLTestDevicePromise(): Promise<WebGLDevice | null> {
96
+ testDeviceCache.presentationWebglDevicePromise ||= makePresentationWebGLTestDevice();
97
+ return testDeviceCache.presentationWebglDevicePromise;
98
+ }
99
+
100
+ function getOrCreateNullTestDevicePromise(): Promise<NullDevice> {
101
+ testDeviceCache.nullDevicePromise ||= makeNullTestDevice();
102
+ return testDeviceCache.nullDevicePromise;
58
103
  }
59
104
 
60
105
  async function makeWebGPUTestDevice(): Promise<WebGPUDevice | null> {
@@ -67,6 +112,11 @@ async function makeWebGPUTestDevice(): Promise<WebGPUDevice | null> {
67
112
  createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
68
113
  debug: true
69
114
  })) as unknown as WebGPUDevice;
115
+ webgpuDevice.lost.finally(() => {
116
+ if (testDeviceCache.webgpuDevicePromise === webgpuDeviceResolvers.promise) {
117
+ testDeviceCache.webgpuDevicePromise = null;
118
+ }
119
+ });
70
120
  webgpuDeviceResolvers.resolve(webgpuDevice);
71
121
  } catch (error) {
72
122
  log.error(String(error))();
@@ -85,9 +135,13 @@ async function makeWebGLTestDevice(): Promise<WebGLDevice> {
85
135
  type: 'webgl',
86
136
  adapters: [webgl2Adapter],
87
137
  createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
88
- debug: true,
89
- debugWebGL: true
138
+ debug: true
90
139
  })) as unknown as WebGLDevice;
140
+ webglDevice.lost.finally(() => {
141
+ if (testDeviceCache.webglDevicePromise === webglDeviceResolvers.promise) {
142
+ testDeviceCache.webglDevicePromise = null;
143
+ }
144
+ });
91
145
  webglDeviceResolvers.resolve(webglDevice);
92
146
  } catch (error) {
93
147
  log.error(String(error))();
@@ -97,6 +151,35 @@ async function makeWebGLTestDevice(): Promise<WebGLDevice> {
97
151
  return webglDeviceResolvers.promise;
98
152
  }
99
153
 
154
+ async function makePresentationWebGLTestDevice(): Promise<WebGLDevice | null> {
155
+ if (typeof OffscreenCanvas === 'undefined') {
156
+ return null;
157
+ }
158
+
159
+ const presentationWebGLDeviceResolvers = withResolvers<WebGLDevice | null>();
160
+ try {
161
+ const webglDevice = (await luma.createDevice({
162
+ id: 'webgl-presentation-context-test-device',
163
+ type: 'webgl',
164
+ adapters: [webgl2Adapter],
165
+ createCanvasContext: {canvas: new OffscreenCanvas(4, 4)},
166
+ debug: true
167
+ })) as unknown as WebGLDevice;
168
+ webglDevice.lost.finally(() => {
169
+ if (
170
+ testDeviceCache.presentationWebglDevicePromise === presentationWebGLDeviceResolvers.promise
171
+ ) {
172
+ testDeviceCache.presentationWebglDevicePromise = null;
173
+ }
174
+ });
175
+ presentationWebGLDeviceResolvers.resolve(webglDevice);
176
+ } catch (error) {
177
+ log.error(String(error))();
178
+ presentationWebGLDeviceResolvers.resolve(null);
179
+ }
180
+ return presentationWebGLDeviceResolvers.promise;
181
+ }
182
+
100
183
  /** returns null device promise, if available */
101
184
  async function makeNullTestDevice(): Promise<NullDevice> {
102
185
  const nullDeviceResolvers = withResolvers<NullDevice>();
@@ -106,20 +189,34 @@ async function makeNullTestDevice(): Promise<NullDevice> {
106
189
  type: 'null',
107
190
  adapters: [nullAdapter],
108
191
  createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
109
- debug: true,
110
- debugWebGL: true
192
+ debug: true
111
193
  })) as unknown as NullDevice;
112
194
  nullDeviceResolvers.resolve(nullDevice);
113
195
  } catch (error) {
114
196
  log.error(String(error))();
115
197
  // @ts-ignore TODO
116
- nullDevicePromise = Promise.resolve(null);
198
+ testDeviceCache.nullDevicePromise = Promise.resolve(null);
117
199
  }
118
200
  return nullDeviceResolvers.promise;
119
201
  }
120
202
 
121
203
  // HELPERS
122
204
 
205
+ function getOrCreateTestDeviceCache(): TestDeviceCache {
206
+ const rootObject = globalThis as typeof globalThis & {
207
+ [TEST_DEVICE_CACHE_KEY]?: TestDeviceCache;
208
+ };
209
+
210
+ rootObject[TEST_DEVICE_CACHE_KEY] ||= {
211
+ nullDevicePromise: null,
212
+ webglDevicePromise: null,
213
+ presentationWebglDevicePromise: null,
214
+ webgpuDevicePromise: null
215
+ };
216
+
217
+ return rootObject[TEST_DEVICE_CACHE_KEY];
218
+ }
219
+
123
220
  // TODO - replace with Promise.withResolvers once we upgrade TS baseline
124
221
  function withResolvers<T>(): {
125
222
  promise: Promise<T>;
@@ -163,9 +163,9 @@ export class ClassicAnimationLoop {
163
163
  this.gl = (this.device && this.device.gl) || props.gl;
164
164
 
165
165
  this.stats = props.stats;
166
+ this.frameRate = this.stats.get('Frame Rate');
166
167
  this.cpuTime = this.stats.get('CPU Time');
167
168
  this.gpuTime = this.stats.get('GPU Time');
168
- this.frameRate = this.stats.get('Frame Rate');
169
169
 
170
170
  this.setProps({
171
171
  autoResizeViewport: props.autoResizeViewport,
@@ -613,15 +613,7 @@ export class ClassicAnimationLoop {
613
613
  const width = this.gl.drawingBufferWidth;
614
614
  const height = this.gl.drawingBufferHeight;
615
615
 
616
- // https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
617
- let aspect = 1;
618
-
619
- const canvas = getHTMLCanvasElement(this.gl.canvas);
620
- if (canvas && canvas.clientHeight) {
621
- aspect = canvas.clientWidth / canvas.clientHeight;
622
- } else if (width > 0 && height > 0) {
623
- aspect = width / height;
624
- }
616
+ const aspect = width > 0 && height > 0 ? width / height : 1;
625
617
 
626
618
  return {width, height, aspect};
627
619
  }
@@ -16,9 +16,22 @@ const DEFAULT_CANVAS_CONTEXT_PROPS: CanvasContextProps = {
16
16
  * @deprecated Use getWebGLTestDevice().
17
17
  */
18
18
  export function createTestDevice(): WebGLDevice | null {
19
+ if (cachedWebglDevice) {
20
+ return cachedWebglDevice;
21
+ }
22
+
23
+ if (
24
+ typeof navigator === 'undefined' ||
25
+ typeof document === 'undefined' ||
26
+ typeof HTMLCanvasElement === 'undefined'
27
+ ) {
28
+ return null;
29
+ }
30
+
19
31
  try {
20
32
  // TODO - We do not use luma.createDevice since createTestDevice currently expect WebGL context to be created synchronously
21
- return new WebGLDevice({createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS});
33
+ cachedWebglDevice = new WebGLDevice({createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS});
34
+ return cachedWebglDevice;
22
35
  } catch (error) {
23
36
  // eslint-disable-next-line no-console
24
37
  console.error(`Failed to created device: ${(error as Error).message}`);
@@ -32,4 +45,6 @@ export function createTestDevice(): WebGLDevice | null {
32
45
  * @note This WebGL Device is create synchronously and can be used directly but will not have WebGL debugging initialized
33
46
  * @deprecated Use getWebGLTestDevice().
34
47
  */
48
+ let cachedWebglDevice: WebGLDevice | null = null;
49
+
35
50
  export const webglDevice = createTestDevice();
package/src/index.ts CHANGED
@@ -12,6 +12,7 @@ export {
12
12
  getTestDevices,
13
13
  getTestDevice,
14
14
  getWebGLTestDevice,
15
+ getPresentationWebGLTestDevice,
15
16
  getWebGPUTestDevice,
16
17
  getNullTestDevice
17
18
  } from './create-test-device';
@@ -28,14 +28,15 @@ export class NullCanvasContext extends CanvasContext {
28
28
 
29
29
  // Base class constructor cannot access derived methods/fields, so we need to call these functions in the subclass constructor
30
30
  this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
31
- this._updateDevice();
31
+ this._configureDevice();
32
+ this._startObservers();
32
33
  }
33
34
 
34
- getCurrentFramebuffer(): NullFramebuffer {
35
+ _getCurrentFramebuffer(): NullFramebuffer {
35
36
  // Setting handle to null returns a reference to the default framebuffer
36
37
  this._framebuffer = this._framebuffer || new NullFramebuffer(this.device, {handle: null});
37
38
  return this._framebuffer;
38
39
  }
39
40
 
40
- _updateDevice() {}
41
+ _configureDevice() {}
41
42
  }
@@ -5,6 +5,8 @@
5
5
  import type {
6
6
  DeviceProps,
7
7
  CanvasContextProps,
8
+ PresentationContextProps,
9
+ PresentationContext,
8
10
  VertexArray,
9
11
  VertexArrayProps,
10
12
  BufferProps,
@@ -22,6 +24,7 @@ import type {
22
24
  QuerySetProps
23
25
  } from '@luma.gl/core';
24
26
  import {Device, DeviceFeatures} from '@luma.gl/core';
27
+ import type {NullCommandBuffer} from './resources/null-command-buffer';
25
28
 
26
29
  import {NullDeviceInfo} from './null-device-info';
27
30
  import {NullDeviceLimits} from './null-device-features';
@@ -37,6 +40,7 @@ import {NullRenderPipeline} from './resources/null-render-pipeline';
37
40
  import {NullVertexArray} from './resources/null-vertex-array';
38
41
  import {NullTransformFeedback} from './resources/null-transform-feedback';
39
42
  import {NullQuerySet} from './resources/null-query-set';
43
+ import {NullFence} from './resources/null-fence';
40
44
 
41
45
  /** Do-nothing device implementation for testing */
42
46
  export class NullDevice extends Device {
@@ -71,7 +75,9 @@ export class NullDevice extends Device {
71
75
  * Destroys the context
72
76
  * @note Has no effect for null contexts
73
77
  */
74
- destroy(): void {}
78
+ destroy(): void {
79
+ this.commandEncoder?.destroy();
80
+ }
75
81
 
76
82
  get isLost(): boolean {
77
83
  return false;
@@ -79,14 +85,14 @@ export class NullDevice extends Device {
79
85
 
80
86
  // IMPLEMENTATION OF ABSTRACT DEVICE
81
87
 
82
- getTextureByteAlignment(): number {
83
- return 1;
84
- }
85
-
86
88
  createCanvasContext(props: CanvasContextProps): NullCanvasContext {
87
89
  return new NullCanvasContext(this, props);
88
90
  }
89
91
 
92
+ createPresentationContext(_props?: PresentationContextProps): PresentationContext {
93
+ throw new Error('PresentationContext is not supported on NullDevice');
94
+ }
95
+
90
96
  createBuffer(props: BufferProps | ArrayBuffer | ArrayBufferView): NullBuffer {
91
97
  const newProps = this._normalizeBufferProps(props);
92
98
  return new NullBuffer(this, newProps);
@@ -128,19 +134,31 @@ export class NullDevice extends Device {
128
134
  return new NullQuerySet(this, props);
129
135
  }
130
136
 
137
+ override createFence(): NullFence {
138
+ return new NullFence(this);
139
+ }
140
+
131
141
  createRenderPipeline(props: RenderPipelineProps): NullRenderPipeline {
132
142
  return new NullRenderPipeline(this, props);
133
143
  }
134
144
 
135
- createComputePipeline(props?: ComputePipelineProps): ComputePipeline {
136
- throw new Error('ComputePipeline not supported in WebGL');
145
+ createComputePipeline(_props?: ComputePipelineProps): ComputePipeline {
146
+ throw new Error('ComputePipeline is not supported on NullDevice');
137
147
  }
138
148
 
139
149
  override createCommandEncoder(props: CommandEncoderProps = {}): NullCommandEncoder {
140
150
  return new NullCommandEncoder(this, props);
141
151
  }
142
152
 
143
- submit(): void {}
153
+ submit(commandBuffer?: NullCommandBuffer): void {
154
+ if (!commandBuffer) {
155
+ commandBuffer = this.commandEncoder.finish({id: `${this.id}-default-command-buffer`});
156
+ this.commandEncoder.destroy();
157
+ this.commandEncoder = this.createCommandEncoder({id: `${this.id}-default-command-encoder`});
158
+ }
159
+
160
+ commandBuffer.destroy();
161
+ }
144
162
 
145
163
  override setParametersWebGL(parameters: any): void {}
146
164
 
@@ -14,25 +14,35 @@ import {CommandBuffer} from '@luma.gl/core';
14
14
  import type {NullDevice} from '../null-device';
15
15
 
16
16
  export class NullCommandBuffer extends CommandBuffer {
17
- device: NullDevice;
18
- handle: null = null;
17
+ readonly device: NullDevice;
18
+ readonly handle: null = null;
19
19
 
20
20
  constructor(device: NullDevice, props: CommandBufferProps) {
21
21
  super(device, props);
22
22
  this.device = device;
23
23
  }
24
24
 
25
- copyBufferToBuffer(options: CopyBufferToBufferOptions): void {}
25
+ copyBufferToBuffer(_options: CopyBufferToBufferOptions): void {
26
+ throw new Error('copyBufferToBuffer is not supported on NullDevice');
27
+ }
26
28
 
27
- copyBufferToTexture(options: CopyBufferToTextureOptions) {}
29
+ copyBufferToTexture(_options: CopyBufferToTextureOptions) {
30
+ throw new Error('copyBufferToTexture is not supported on NullDevice');
31
+ }
28
32
 
29
- copyTextureToBuffer(options: CopyTextureToBufferOptions): void {}
33
+ copyTextureToBuffer(_options: CopyTextureToBufferOptions): void {
34
+ throw new Error('copyTextureToBuffer is not supported on NullDevice');
35
+ }
30
36
 
31
- copyTextureToTexture(options: CopyTextureToTextureOptions): void {}
37
+ copyTextureToTexture(_options: CopyTextureToTextureOptions): void {
38
+ throw new Error('copyTextureToTexture is not supported on NullDevice');
39
+ }
32
40
 
33
41
  pushDebugGroup(groupLabel: string): void {}
34
42
  popDebugGroup() {}
35
43
 
36
- insertDebugMarker(markerLabel: string): void {}
37
- resolveQuerySet(querySet: QuerySet): void {}
44
+ insertDebugMarker(_markerLabel: string): void {}
45
+ resolveQuerySet(_querySet: QuerySet): void {
46
+ throw new Error('resolveQuerySet is not supported on NullDevice');
47
+ }
38
48
  }
@@ -27,27 +27,43 @@ export class NullCommandEncoder extends CommandEncoder {
27
27
  this.device = device;
28
28
  }
29
29
 
30
- finish(props: CommandBufferProps): NullCommandBuffer {
31
- return new NullCommandBuffer(this.device, props);
30
+ override destroy(): void {
31
+ this.destroyResource();
32
+ }
33
+
34
+ finish(props: CommandBufferProps = {}): NullCommandBuffer {
35
+ const commandBuffer = new NullCommandBuffer(this.device, props);
36
+ this.destroy();
37
+ return commandBuffer;
32
38
  }
33
39
 
34
40
  beginRenderPass(props: RenderPassProps): NullRenderPass {
35
41
  return new NullRenderPass(this.device, props);
36
42
  }
37
43
 
38
- beginComputePass(props: ComputePassProps): ComputePass {
39
- throw new Error('ComputePass not supported in WebGL');
44
+ beginComputePass(_props: ComputePassProps): ComputePass {
45
+ throw new Error('ComputePass is not supported on NullDevice');
40
46
  }
41
47
 
42
- copyBufferToBuffer(options: CopyBufferToBufferOptions): void {}
48
+ copyBufferToBuffer(_options: CopyBufferToBufferOptions): void {
49
+ throw new Error('copyBufferToBuffer is not supported on NullDevice');
50
+ }
43
51
 
44
- copyBufferToTexture(options: CopyBufferToTextureOptions) {}
52
+ copyBufferToTexture(_options: CopyBufferToTextureOptions) {
53
+ throw new Error('copyBufferToTexture is not supported on NullDevice');
54
+ }
45
55
 
46
- copyTextureToBuffer(options: CopyTextureToBufferOptions): void {}
56
+ copyTextureToBuffer(_options: CopyTextureToBufferOptions): void {
57
+ throw new Error('copyTextureToBuffer is not supported on NullDevice');
58
+ }
47
59
 
48
- copyTextureToTexture(options: CopyTextureToTextureOptions): void {}
60
+ copyTextureToTexture(_options: CopyTextureToTextureOptions): void {
61
+ throw new Error('copyTextureToTexture is not supported on NullDevice');
62
+ }
49
63
 
50
- resolveQuerySet(querySet: QuerySet): void {}
64
+ resolveQuerySet(_querySet: QuerySet): void {
65
+ throw new Error('resolveQuerySet is not supported on NullDevice');
66
+ }
51
67
 
52
68
  pushDebugGroup(groupLabel: string): void {}
53
69
  popDebugGroup() {}
@@ -0,0 +1,24 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {Fence, type FenceProps} from '@luma.gl/core';
6
+ import type {NullDevice} from '../null-device';
7
+
8
+ /** Null fence that is always signaled */
9
+ export class NullFence extends Fence {
10
+ readonly device: NullDevice;
11
+ readonly handle = null;
12
+ readonly signaled: Promise<void> = Promise.resolve();
13
+
14
+ constructor(device: NullDevice, props: FenceProps = {}) {
15
+ super(device, props);
16
+ this.device = device;
17
+ }
18
+
19
+ override destroy(): void {}
20
+
21
+ isSignaled(): boolean {
22
+ return true;
23
+ }
24
+ }
@@ -13,4 +13,18 @@ export class NullQuerySet extends QuerySet {
13
13
  super(device, props);
14
14
  this.device = device;
15
15
  }
16
+
17
+ isResultAvailable(_queryIndex?: number): boolean {
18
+ return false;
19
+ }
20
+
21
+ async readResults(options?: {firstQuery?: number; queryCount?: number}): Promise<bigint[]> {
22
+ const firstQuery = options?.firstQuery || 0;
23
+ const queryCount = options?.queryCount || this.props.count - firstQuery;
24
+ return new Array(queryCount).fill(0n);
25
+ }
26
+
27
+ async readTimestampDuration(_beginIndex: number, _endIndex: number): Promise<number> {
28
+ return 0;
29
+ }
16
30
  }
@@ -14,7 +14,12 @@ export class NullRenderPass extends RenderPass {
14
14
  this.device = device;
15
15
  }
16
16
 
17
- end(): void {}
17
+ end(): void {
18
+ if (this.destroyed) {
19
+ return;
20
+ }
21
+ this.destroy();
22
+ }
18
23
 
19
24
  pushDebugGroup(groupLabel: string): void {}
20
25
  popDebugGroup(): void {}
@@ -2,13 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import type {
6
- UniformValue,
7
- RenderPipelineProps,
8
- Binding,
9
- RenderPass,
10
- VertexArray
11
- } from '@luma.gl/core';
5
+ import type {RenderPipelineProps, Binding, RenderPass, VertexArray} from '@luma.gl/core';
12
6
  import {RenderPipeline} from '@luma.gl/core';
13
7
 
14
8
  import type {NullDevice} from '../null-device';
@@ -22,9 +16,6 @@ export class NullRenderPipeline extends RenderPipeline {
22
16
  vs: NullShader;
23
17
  fs: NullShader;
24
18
 
25
- uniforms: Record<string, UniformValue> = {};
26
- bindings: Record<string, Binding> = {};
27
-
28
19
  constructor(device: NullDevice, props: RenderPipelineProps) {
29
20
  super(device, props);
30
21
  this.device = device;
@@ -39,15 +30,13 @@ export class NullRenderPipeline extends RenderPipeline {
39
30
  };
40
31
  }
41
32
 
42
- setBindings(bindings: Record<string, Binding>): void {
43
- Object.assign(this.bindings, bindings);
44
- }
45
-
46
33
  draw(options: {
47
34
  renderPass: RenderPass;
48
35
  vertexArray: VertexArray;
49
36
  vertexCount?: number;
50
37
  instanceCount?: number;
38
+ bindings?: Record<string, Binding>;
39
+ uniforms?: Record<string, unknown>;
51
40
  }): boolean {
52
41
  const {renderPass, vertexArray} = options;
53
42
  vertexArray.bindBeforeRender(renderPass);