@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
package/dist/index.cjs CHANGED
@@ -29,13 +29,14 @@ __export(dist_exports, {
29
29
  deepCopy: () => deepCopy,
30
30
  getLeakedResources: () => getLeakedResources,
31
31
  getNullTestDevice: () => getNullTestDevice,
32
+ getPresentationWebGLTestDevice: () => getPresentationWebGLTestDevice,
32
33
  getResourceCounts: () => getResourceCounts,
33
34
  getTestDevice: () => getTestDevice,
34
35
  getTestDevices: () => getTestDevices,
35
36
  getWebGLTestDevice: () => getWebGLTestDevice,
36
37
  getWebGPUTestDevice: () => getWebGPUTestDevice,
37
38
  nullAdapter: () => nullAdapter,
38
- webglDevice: () => webglDevice2
39
+ webglDevice: () => webglDevice
39
40
  });
40
41
  module.exports = __toCommonJS(dist_exports);
41
42
 
@@ -46,15 +47,15 @@ var import_webgpu = require("@luma.gl/webgpu");
46
47
  import_core.luma.registerAdapters([import_webgl.webgl2Adapter, import_webgpu.webgpuAdapter]);
47
48
 
48
49
  // dist/create-test-device.js
49
- var import_core19 = require("@luma.gl/core");
50
+ var import_core20 = require("@luma.gl/core");
50
51
  var import_webgl2 = require("@luma.gl/webgl");
51
52
  var import_webgpu2 = require("@luma.gl/webgpu");
52
53
 
53
54
  // dist/null-device/null-adapter.js
54
- var import_core18 = require("@luma.gl/core");
55
+ var import_core19 = require("@luma.gl/core");
55
56
 
56
57
  // dist/null-device/null-device.js
57
- var import_core17 = require("@luma.gl/core");
58
+ var import_core18 = require("@luma.gl/core");
58
59
 
59
60
  // dist/null-device/null-device-info.js
60
61
  var NullDeviceInfo = {
@@ -131,13 +132,14 @@ var NullCanvasContext = class extends import_core4.CanvasContext {
131
132
  super(props);
132
133
  this.device = device;
133
134
  this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
134
- this._updateDevice();
135
+ this._configureDevice();
136
+ this._startObservers();
135
137
  }
136
- getCurrentFramebuffer() {
138
+ _getCurrentFramebuffer() {
137
139
  this._framebuffer = this._framebuffer || new NullFramebuffer(this.device, { handle: null });
138
140
  return this._framebuffer;
139
141
  }
140
- _updateDevice() {
142
+ _configureDevice() {
141
143
  }
142
144
  };
143
145
 
@@ -231,21 +233,26 @@ var NullCommandBuffer = class extends import_core7.CommandBuffer {
231
233
  super(device, props);
232
234
  this.device = device;
233
235
  }
234
- copyBufferToBuffer(options) {
236
+ copyBufferToBuffer(_options) {
237
+ throw new Error("copyBufferToBuffer is not supported on NullDevice");
235
238
  }
236
- copyBufferToTexture(options) {
239
+ copyBufferToTexture(_options) {
240
+ throw new Error("copyBufferToTexture is not supported on NullDevice");
237
241
  }
238
- copyTextureToBuffer(options) {
242
+ copyTextureToBuffer(_options) {
243
+ throw new Error("copyTextureToBuffer is not supported on NullDevice");
239
244
  }
240
- copyTextureToTexture(options) {
245
+ copyTextureToTexture(_options) {
246
+ throw new Error("copyTextureToTexture is not supported on NullDevice");
241
247
  }
242
248
  pushDebugGroup(groupLabel) {
243
249
  }
244
250
  popDebugGroup() {
245
251
  }
246
- insertDebugMarker(markerLabel) {
252
+ insertDebugMarker(_markerLabel) {
247
253
  }
248
- resolveQuerySet(querySet) {
254
+ resolveQuerySet(_querySet) {
255
+ throw new Error("resolveQuerySet is not supported on NullDevice");
249
256
  }
250
257
  };
251
258
 
@@ -259,6 +266,10 @@ var NullRenderPass = class extends import_core8.RenderPass {
259
266
  this.device = device;
260
267
  }
261
268
  end() {
269
+ if (this.destroyed) {
270
+ return;
271
+ }
272
+ this.destroy();
262
273
  }
263
274
  pushDebugGroup(groupLabel) {
264
275
  }
@@ -282,24 +293,34 @@ var NullCommandEncoder = class extends import_core9.CommandEncoder {
282
293
  super(device, props);
283
294
  this.device = device;
284
295
  }
285
- finish(props) {
286
- return new NullCommandBuffer(this.device, props);
296
+ destroy() {
297
+ this.destroyResource();
298
+ }
299
+ finish(props = {}) {
300
+ const commandBuffer = new NullCommandBuffer(this.device, props);
301
+ this.destroy();
302
+ return commandBuffer;
287
303
  }
288
304
  beginRenderPass(props) {
289
305
  return new NullRenderPass(this.device, props);
290
306
  }
291
- beginComputePass(props) {
292
- throw new Error("ComputePass not supported in WebGL");
307
+ beginComputePass(_props) {
308
+ throw new Error("ComputePass is not supported on NullDevice");
293
309
  }
294
- copyBufferToBuffer(options) {
310
+ copyBufferToBuffer(_options) {
311
+ throw new Error("copyBufferToBuffer is not supported on NullDevice");
295
312
  }
296
- copyBufferToTexture(options) {
313
+ copyBufferToTexture(_options) {
314
+ throw new Error("copyBufferToTexture is not supported on NullDevice");
297
315
  }
298
- copyTextureToBuffer(options) {
316
+ copyTextureToBuffer(_options) {
317
+ throw new Error("copyTextureToBuffer is not supported on NullDevice");
299
318
  }
300
- copyTextureToTexture(options) {
319
+ copyTextureToTexture(_options) {
320
+ throw new Error("copyTextureToTexture is not supported on NullDevice");
301
321
  }
302
- resolveQuerySet(querySet) {
322
+ resolveQuerySet(_querySet) {
323
+ throw new Error("resolveQuerySet is not supported on NullDevice");
303
324
  }
304
325
  pushDebugGroup(groupLabel) {
305
326
  }
@@ -355,6 +376,7 @@ var NullTexture = class extends import_core12.Texture {
355
376
  mipLevelCount: 1,
356
377
  arrayLayerCount: 1
357
378
  });
379
+ this.trackAllocatedMemory(this.getAllocatedByteLength(), "Texture");
358
380
  Object.seal(this);
359
381
  }
360
382
  destroy() {
@@ -367,22 +389,25 @@ var NullTexture = class extends import_core12.Texture {
367
389
  return new NullTextureView(this.device, { ...props, texture: this });
368
390
  }
369
391
  copyExternalImage(options) {
370
- this.trackDeallocatedMemory("Texture");
371
- const { image: data } = options;
372
- const bytesPerPixel = 4;
373
- this.trackAllocatedMemory(this.width * this.height * bytesPerPixel, "Texture");
374
- const width = options.width ?? data.width;
375
- const height = options.height ?? data.height;
376
- this.width = width;
377
- this.height = height;
378
- return { width, height };
392
+ return { width: this.width, height: this.height };
379
393
  }
380
394
  setSampler(sampler) {
381
395
  }
382
396
  copyImageData(options) {
383
- throw new Error("copyImageData not implemented");
397
+ super.copyImageData(options);
384
398
  }
385
- generateMipmapsWebGL() {
399
+ readBuffer(_options = {}, buffer) {
400
+ if (!buffer) {
401
+ throw new Error("buffer required");
402
+ }
403
+ return buffer;
404
+ }
405
+ async readDataAsync(_options = {}) {
406
+ throw new Error(`${this} readDataAsync is deprecated; use readBuffer() with an explicit destination buffer or DynamicTexture.readAsync()`);
407
+ }
408
+ writeBuffer(buffer, options = {}) {
409
+ }
410
+ writeData(data, options = {}) {
386
411
  }
387
412
  };
388
413
 
@@ -393,8 +418,6 @@ var NullRenderPipeline = class extends import_core13.RenderPipeline {
393
418
  handle = null;
394
419
  vs;
395
420
  fs;
396
- uniforms = {};
397
- bindings = {};
398
421
  constructor(device, props) {
399
422
  super(device, props);
400
423
  this.device = device;
@@ -406,9 +429,6 @@ var NullRenderPipeline = class extends import_core13.RenderPipeline {
406
429
  uniforms: []
407
430
  };
408
431
  }
409
- setBindings(bindings) {
410
- Object.assign(this.bindings, bindings);
411
- }
412
432
  draw(options) {
413
433
  const { renderPass, vertexArray } = options;
414
434
  vertexArray.bindBeforeRender(renderPass);
@@ -489,10 +509,38 @@ var NullQuerySet = class extends import_core16.QuerySet {
489
509
  super(device, props);
490
510
  this.device = device;
491
511
  }
512
+ isResultAvailable(_queryIndex) {
513
+ return false;
514
+ }
515
+ async readResults(options) {
516
+ const firstQuery = (options == null ? void 0 : options.firstQuery) || 0;
517
+ const queryCount = (options == null ? void 0 : options.queryCount) || this.props.count - firstQuery;
518
+ return new Array(queryCount).fill(0n);
519
+ }
520
+ async readTimestampDuration(_beginIndex, _endIndex) {
521
+ return 0;
522
+ }
523
+ };
524
+
525
+ // dist/null-device/resources/null-fence.js
526
+ var import_core17 = require("@luma.gl/core");
527
+ var NullFence = class extends import_core17.Fence {
528
+ device;
529
+ handle = null;
530
+ signaled = Promise.resolve();
531
+ constructor(device, props = {}) {
532
+ super(device, props);
533
+ this.device = device;
534
+ }
535
+ destroy() {
536
+ }
537
+ isSignaled() {
538
+ return true;
539
+ }
492
540
  };
493
541
 
494
542
  // dist/null-device/null-device.js
495
- var NullDevice = class extends import_core17.Device {
543
+ var NullDevice = class extends import_core18.Device {
496
544
  static isSupported() {
497
545
  return true;
498
546
  }
@@ -500,7 +548,7 @@ var NullDevice = class extends import_core17.Device {
500
548
  handle = null;
501
549
  preferredColorFormat = "rgba8unorm";
502
550
  preferredDepthFormat = "depth24plus";
503
- features = new import_core17.DeviceFeatures([], this.props._disabledFeatures);
551
+ features = new import_core18.DeviceFeatures([], this.props._disabledFeatures);
504
552
  limits = new NullDeviceLimits();
505
553
  info = NullDeviceInfo;
506
554
  canvasContext;
@@ -508,7 +556,7 @@ var NullDevice = class extends import_core17.Device {
508
556
  lost;
509
557
  constructor(props) {
510
558
  super({ ...props, id: props.id || "null-device" });
511
- const canvasContextProps = import_core17.Device._getCanvasContextProps(props);
559
+ const canvasContextProps = import_core18.Device._getCanvasContextProps(props);
512
560
  this.canvasContext = new NullCanvasContext(this, canvasContextProps);
513
561
  this.lost = new Promise((resolve) => {
514
562
  });
@@ -519,17 +567,19 @@ var NullDevice = class extends import_core17.Device {
519
567
  * @note Has no effect for null contexts
520
568
  */
521
569
  destroy() {
570
+ var _a;
571
+ (_a = this.commandEncoder) == null ? void 0 : _a.destroy();
522
572
  }
523
573
  get isLost() {
524
574
  return false;
525
575
  }
526
576
  // IMPLEMENTATION OF ABSTRACT DEVICE
527
- getTextureByteAlignment() {
528
- return 1;
529
- }
530
577
  createCanvasContext(props) {
531
578
  return new NullCanvasContext(this, props);
532
579
  }
580
+ createPresentationContext(_props) {
581
+ throw new Error("PresentationContext is not supported on NullDevice");
582
+ }
533
583
  createBuffer(props) {
534
584
  const newProps = this._normalizeBufferProps(props);
535
585
  return new NullBuffer(this, newProps);
@@ -561,16 +611,25 @@ var NullDevice = class extends import_core17.Device {
561
611
  createQuerySet(props) {
562
612
  return new NullQuerySet(this, props);
563
613
  }
614
+ createFence() {
615
+ return new NullFence(this);
616
+ }
564
617
  createRenderPipeline(props) {
565
618
  return new NullRenderPipeline(this, props);
566
619
  }
567
- createComputePipeline(props) {
568
- throw new Error("ComputePipeline not supported in WebGL");
620
+ createComputePipeline(_props) {
621
+ throw new Error("ComputePipeline is not supported on NullDevice");
569
622
  }
570
623
  createCommandEncoder(props = {}) {
571
624
  return new NullCommandEncoder(this, props);
572
625
  }
573
- submit() {
626
+ submit(commandBuffer) {
627
+ if (!commandBuffer) {
628
+ commandBuffer = this.commandEncoder.finish({ id: `${this.id}-default-command-buffer` });
629
+ this.commandEncoder.destroy();
630
+ this.commandEncoder = this.createCommandEncoder({ id: `${this.id}-default-command-encoder` });
631
+ }
632
+ commandBuffer.destroy();
574
633
  }
575
634
  setParametersWebGL(parameters) {
576
635
  }
@@ -594,7 +653,7 @@ var NullDevice = class extends import_core17.Device {
594
653
  };
595
654
 
596
655
  // dist/null-device/null-adapter.js
597
- var NullAdapter = class extends import_core18.Adapter {
656
+ var NullAdapter = class extends import_core19.Adapter {
598
657
  /** type of device's created by this adapter */
599
658
  type = "null";
600
659
  constructor() {
@@ -618,9 +677,8 @@ var nullAdapter = new NullAdapter();
618
677
 
619
678
  // dist/create-test-device.js
620
679
  var DEFAULT_CANVAS_CONTEXT_PROPS = { width: 1, height: 1 };
621
- var nullDevicePromise = makeNullTestDevice();
622
- var webglDevicePromise = makeWebGLTestDevice();
623
- var webgpuDevicePromise = makeWebGPUTestDevice();
680
+ var TEST_DEVICE_CACHE_KEY = "__lumaTestDeviceCache";
681
+ var testDeviceCache = getOrCreateTestDeviceCache();
624
682
  async function getTestDevices(types = ["webgl", "webgpu"]) {
625
683
  const promises = types.map((type) => getTestDevice(type));
626
684
  const devices = await Promise.all(promises);
@@ -629,37 +687,68 @@ async function getTestDevices(types = ["webgl", "webgpu"]) {
629
687
  async function getTestDevice(type) {
630
688
  switch (type) {
631
689
  case "webgl":
632
- return webglDevicePromise;
690
+ return getOrCreateWebGLTestDevicePromise();
633
691
  case "webgpu":
634
- return webgpuDevicePromise;
692
+ return getWebGPUTestDevice();
635
693
  case "null":
636
- return nullDevicePromise;
694
+ return getOrCreateNullTestDevicePromise();
637
695
  case "unknown":
638
696
  return null;
639
697
  }
640
698
  }
641
- function getWebGPUTestDevice() {
642
- return webgpuDevicePromise;
699
+ async function getWebGPUTestDevice() {
700
+ const webgpuDevice = await getOrCreateWebGPUTestDevicePromise();
701
+ if (webgpuDevice == null ? void 0 : webgpuDevice.isLost) {
702
+ if (testDeviceCache.webgpuDevicePromise) {
703
+ testDeviceCache.webgpuDevicePromise = null;
704
+ }
705
+ return getOrCreateWebGPUTestDevicePromise();
706
+ }
707
+ return webgpuDevice;
643
708
  }
644
709
  async function getWebGLTestDevice() {
645
- return webglDevicePromise;
710
+ return getOrCreateWebGLTestDevicePromise();
711
+ }
712
+ async function getPresentationWebGLTestDevice() {
713
+ return getOrCreatePresentationWebGLTestDevicePromise();
646
714
  }
647
715
  async function getNullTestDevice() {
648
- return nullDevicePromise;
716
+ return getOrCreateNullTestDevicePromise();
717
+ }
718
+ function getOrCreateWebGPUTestDevicePromise() {
719
+ testDeviceCache.webgpuDevicePromise ||= makeWebGPUTestDevice();
720
+ return testDeviceCache.webgpuDevicePromise;
721
+ }
722
+ function getOrCreateWebGLTestDevicePromise() {
723
+ testDeviceCache.webglDevicePromise ||= makeWebGLTestDevice();
724
+ return testDeviceCache.webglDevicePromise;
725
+ }
726
+ function getOrCreatePresentationWebGLTestDevicePromise() {
727
+ testDeviceCache.presentationWebglDevicePromise ||= makePresentationWebGLTestDevice();
728
+ return testDeviceCache.presentationWebglDevicePromise;
729
+ }
730
+ function getOrCreateNullTestDevicePromise() {
731
+ testDeviceCache.nullDevicePromise ||= makeNullTestDevice();
732
+ return testDeviceCache.nullDevicePromise;
649
733
  }
650
734
  async function makeWebGPUTestDevice() {
651
735
  const webgpuDeviceResolvers = withResolvers();
652
736
  try {
653
- const webgpuDevice = await import_core19.luma.createDevice({
737
+ const webgpuDevice = await import_core20.luma.createDevice({
654
738
  id: "webgpu-test-device",
655
739
  type: "webgpu",
656
740
  adapters: [import_webgpu2.webgpuAdapter],
657
741
  createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
658
742
  debug: true
659
743
  });
744
+ webgpuDevice.lost.finally(() => {
745
+ if (testDeviceCache.webgpuDevicePromise === webgpuDeviceResolvers.promise) {
746
+ testDeviceCache.webgpuDevicePromise = null;
747
+ }
748
+ });
660
749
  webgpuDeviceResolvers.resolve(webgpuDevice);
661
750
  } catch (error) {
662
- import_core19.log.error(String(error))();
751
+ import_core20.log.error(String(error))();
663
752
  webgpuDeviceResolvers.resolve(null);
664
753
  }
665
754
  return webgpuDeviceResolvers.promise;
@@ -667,39 +756,77 @@ async function makeWebGPUTestDevice() {
667
756
  async function makeWebGLTestDevice() {
668
757
  const webglDeviceResolvers = withResolvers();
669
758
  try {
670
- const webglDevice3 = await import_core19.luma.createDevice({
759
+ const webglDevice2 = await import_core20.luma.createDevice({
671
760
  id: "webgl-test-device",
672
761
  type: "webgl",
673
762
  adapters: [import_webgl2.webgl2Adapter],
674
763
  createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
675
- debug: true,
676
- debugWebGL: true
764
+ debug: true
765
+ });
766
+ webglDevice2.lost.finally(() => {
767
+ if (testDeviceCache.webglDevicePromise === webglDeviceResolvers.promise) {
768
+ testDeviceCache.webglDevicePromise = null;
769
+ }
677
770
  });
678
- webglDeviceResolvers.resolve(webglDevice3);
771
+ webglDeviceResolvers.resolve(webglDevice2);
679
772
  } catch (error) {
680
- import_core19.log.error(String(error))();
773
+ import_core20.log.error(String(error))();
681
774
  webglDeviceResolvers.resolve(null);
682
775
  }
683
776
  return webglDeviceResolvers.promise;
684
777
  }
778
+ async function makePresentationWebGLTestDevice() {
779
+ if (typeof OffscreenCanvas === "undefined") {
780
+ return null;
781
+ }
782
+ const presentationWebGLDeviceResolvers = withResolvers();
783
+ try {
784
+ const webglDevice2 = await import_core20.luma.createDevice({
785
+ id: "webgl-presentation-context-test-device",
786
+ type: "webgl",
787
+ adapters: [import_webgl2.webgl2Adapter],
788
+ createCanvasContext: { canvas: new OffscreenCanvas(4, 4) },
789
+ debug: true
790
+ });
791
+ webglDevice2.lost.finally(() => {
792
+ if (testDeviceCache.presentationWebglDevicePromise === presentationWebGLDeviceResolvers.promise) {
793
+ testDeviceCache.presentationWebglDevicePromise = null;
794
+ }
795
+ });
796
+ presentationWebGLDeviceResolvers.resolve(webglDevice2);
797
+ } catch (error) {
798
+ import_core20.log.error(String(error))();
799
+ presentationWebGLDeviceResolvers.resolve(null);
800
+ }
801
+ return presentationWebGLDeviceResolvers.promise;
802
+ }
685
803
  async function makeNullTestDevice() {
686
804
  const nullDeviceResolvers = withResolvers();
687
805
  try {
688
- const nullDevice = await import_core19.luma.createDevice({
806
+ const nullDevice = await import_core20.luma.createDevice({
689
807
  id: "null-test-device",
690
808
  type: "null",
691
809
  adapters: [nullAdapter],
692
810
  createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
693
- debug: true,
694
- debugWebGL: true
811
+ debug: true
695
812
  });
696
813
  nullDeviceResolvers.resolve(nullDevice);
697
814
  } catch (error) {
698
- import_core19.log.error(String(error))();
699
- nullDevicePromise = Promise.resolve(null);
815
+ import_core20.log.error(String(error))();
816
+ testDeviceCache.nullDevicePromise = Promise.resolve(null);
700
817
  }
701
818
  return nullDeviceResolvers.promise;
702
819
  }
820
+ function getOrCreateTestDeviceCache() {
821
+ const rootObject = globalThis;
822
+ rootObject[TEST_DEVICE_CACHE_KEY] ||= {
823
+ nullDevicePromise: null,
824
+ webglDevicePromise: null,
825
+ presentationWebglDevicePromise: null,
826
+ webgpuDevicePromise: null
827
+ };
828
+ return rootObject[TEST_DEVICE_CACHE_KEY];
829
+ }
703
830
  function withResolvers() {
704
831
  let resolve;
705
832
  let reject;
@@ -710,18 +837,43 @@ function withResolvers() {
710
837
  return { promise, resolve, reject };
711
838
  }
712
839
 
840
+ // dist/deprecated/sync-test-device.js
841
+ var import_webgl3 = require("@luma.gl/webgl");
842
+ var DEFAULT_CANVAS_CONTEXT_PROPS2 = {
843
+ width: 1,
844
+ height: 1
845
+ };
846
+ function createTestDevice() {
847
+ if (cachedWebglDevice) {
848
+ return cachedWebglDevice;
849
+ }
850
+ if (typeof navigator === "undefined" || typeof document === "undefined" || typeof HTMLCanvasElement === "undefined") {
851
+ return null;
852
+ }
853
+ try {
854
+ cachedWebglDevice = new import_webgl3.WebGLDevice({ createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS2 });
855
+ return cachedWebglDevice;
856
+ } catch (error) {
857
+ console.error(`Failed to created device: ${error.message}`);
858
+ debugger;
859
+ return null;
860
+ }
861
+ }
862
+ var cachedWebglDevice = null;
863
+ var webglDevice = createTestDevice();
864
+
713
865
  // dist/deprecated/classic-animation-loop.js
714
- var import_core20 = require("@luma.gl/core");
866
+ var import_core21 = require("@luma.gl/core");
715
867
  var import_engine = require("@luma.gl/engine");
716
868
  var import_env = require("@probe.gl/env");
717
- var import_webgl3 = require("@luma.gl/webgl");
869
+ var import_webgl4 = require("@luma.gl/webgl");
718
870
  var isPage = (0, import_env.isBrowser)() && typeof document !== "undefined";
719
871
  function getHTMLCanvasElement(canvas) {
720
872
  return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement ? canvas : null;
721
873
  }
722
874
  var statIdCounter = 0;
723
875
  var DEFAULT_CLASSIC_ANIMATION_LOOP_PROPS = {
724
- onCreateDevice: (props) => import_core20.luma.createDevice({ ...props, debug: true }),
876
+ onCreateDevice: (props) => import_core21.luma.createDevice({ ...props, debug: true }),
725
877
  onCreateContext: void 0,
726
878
  onAddHTML: void 0,
727
879
  onInitialize: () => ({}),
@@ -737,7 +889,7 @@ var DEFAULT_CLASSIC_ANIMATION_LOOP_PROPS = {
737
889
  useDevicePixels: true,
738
890
  autoResizeViewport: true,
739
891
  autoResizeDrawingBuffer: true,
740
- stats: import_core20.luma.stats.get(`animation-loop-${statIdCounter++}`),
892
+ stats: import_core21.luma.stats.get(`animation-loop-${statIdCounter++}`),
741
893
  // deprecated
742
894
  // onCreateContext: (opts) => createGLContext(opts),
743
895
  gl: void 0,
@@ -774,15 +926,15 @@ var ClassicAnimationLoop = class {
774
926
  props = this.props;
775
927
  let { useDevicePixels = true } = this.props;
776
928
  if ("useDevicePixelRatio" in props) {
777
- import_core20.log.deprecated("useDevicePixelRatio", "useDevicePixels")();
929
+ import_core21.log.deprecated("useDevicePixelRatio", "useDevicePixels")();
778
930
  useDevicePixels = props.useDevicePixelRatio;
779
931
  }
780
932
  this.device = props.device;
781
933
  this.gl = this.device && this.device.gl || props.gl;
782
934
  this.stats = props.stats;
935
+ this.frameRate = this.stats.get("Frame Rate");
783
936
  this.cpuTime = this.stats.get("CPU Time");
784
937
  this.gpuTime = this.stats.get("GPU Time");
785
- this.frameRate = this.stats.get("Frame Rate");
786
938
  this.setProps({
787
939
  autoResizeViewport: props.autoResizeViewport,
788
940
  autoResizeDrawingBuffer: props.autoResizeDrawingBuffer,
@@ -1073,7 +1225,7 @@ var ClassicAnimationLoop = class {
1073
1225
  const deviceProps = { ...this.props, ...props, ...this.props.glOptions };
1074
1226
  this.device = await this.onCreateDevice(deviceProps);
1075
1227
  this.gl = this.device.gl;
1076
- (0, import_webgl3.resetGLParameters)(this.gl);
1228
+ (0, import_webgl4.resetGLParameters)(this.gl);
1077
1229
  this._createInfoDiv();
1078
1230
  }
1079
1231
  _createInfoDiv() {
@@ -1101,13 +1253,7 @@ var ClassicAnimationLoop = class {
1101
1253
  _getSizeAndAspect() {
1102
1254
  const width = this.gl.drawingBufferWidth;
1103
1255
  const height = this.gl.drawingBufferHeight;
1104
- let aspect = 1;
1105
- const canvas = getHTMLCanvasElement(this.gl.canvas);
1106
- if (canvas && canvas.clientHeight) {
1107
- aspect = canvas.clientWidth / canvas.clientHeight;
1108
- } else if (width > 0 && height > 0) {
1109
- aspect = width / height;
1110
- }
1256
+ const aspect = width > 0 && height > 0 ? width / height : 1;
1111
1257
  return { width, height, aspect };
1112
1258
  }
1113
1259
  /** Default viewport setup */
@@ -1180,7 +1326,7 @@ var DEFAULT_TEST_PROPS = {
1180
1326
  imageDiffOptions: void 0
1181
1327
  };
1182
1328
  var TestRunner = class {
1183
- device = webglDevice;
1329
+ device = createTestDevice();
1184
1330
  props;
1185
1331
  isRunning = false;
1186
1332
  testOptions = { ...DEFAULT_TEST_PROPS };
@@ -1452,7 +1598,7 @@ function deepCopy(object) {
1452
1598
 
1453
1599
  // dist/utils/resource-tracker.js
1454
1600
  function getResourceCounts() {
1455
- const resourceStats = luma.stats.get("Resource Counts");
1601
+ const resourceStats = luma.stats.get("GPU Resource Counts");
1456
1602
  return {
1457
1603
  Texture2D: resourceStats.get("Texture2Ds Active").count,
1458
1604
  Buffer: resourceStats.get("Buffers Active").count
@@ -1472,21 +1618,4 @@ function getLeakedResources(startCounts, endCounts) {
1472
1618
  }
1473
1619
  return leakedResources;
1474
1620
  }
1475
-
1476
- // dist/deprecated/sync-test-device.js
1477
- var import_webgl4 = require("@luma.gl/webgl");
1478
- var DEFAULT_CANVAS_CONTEXT_PROPS2 = {
1479
- width: 1,
1480
- height: 1
1481
- };
1482
- function createTestDevice() {
1483
- try {
1484
- return new import_webgl4.WebGLDevice({ createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS2 });
1485
- } catch (error) {
1486
- console.error(`Failed to created device: ${error.message}`);
1487
- debugger;
1488
- return null;
1489
- }
1490
- }
1491
- var webglDevice2 = createTestDevice();
1492
1621
  //# sourceMappingURL=index.cjs.map