@luma.gl/test-utils 9.1.0-alpha.2 → 9.1.0-beta.1

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 (100) hide show
  1. package/dist/create-test-device.d.ts +9 -12
  2. package/dist/create-test-device.d.ts.map +1 -1
  3. package/dist/create-test-device.js +90 -48
  4. package/dist/create-test-device.js.map +1 -0
  5. package/dist/deprecated/classic-animation-loop.d.ts.map +1 -0
  6. package/dist/{engine → deprecated}/classic-animation-loop.js +5 -4
  7. package/dist/deprecated/classic-animation-loop.js.map +1 -0
  8. package/dist/deprecated/sync-test-device.d.ts +14 -0
  9. package/dist/deprecated/sync-test-device.d.ts.map +1 -0
  10. package/dist/deprecated/sync-test-device.js +32 -0
  11. package/dist/deprecated/sync-test-device.js.map +1 -0
  12. package/dist/index.cjs +1158 -1120
  13. package/dist/index.cjs.map +4 -4
  14. package/dist/index.d.ts +3 -3
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +6 -3
  17. package/dist/index.js.map +1 -0
  18. package/dist/null-device/null-adapter.d.ts +13 -0
  19. package/dist/null-device/null-adapter.d.ts.map +1 -0
  20. package/dist/null-device/null-adapter.js +26 -0
  21. package/dist/null-device/null-adapter.js.map +1 -0
  22. package/dist/null-device/null-canvas-context.d.ts +4 -5
  23. package/dist/null-device/null-canvas-context.d.ts.map +1 -1
  24. package/dist/null-device/null-canvas-context.js +9 -21
  25. package/dist/null-device/null-canvas-context.js.map +1 -0
  26. package/dist/null-device/null-device-features.js +1 -0
  27. package/dist/null-device/null-device-features.js.map +1 -0
  28. package/dist/null-device/null-device-info.js +1 -0
  29. package/dist/null-device/null-device-info.js.map +1 -0
  30. package/dist/null-device/null-device.d.ts +7 -11
  31. package/dist/null-device/null-device.d.ts.map +1 -1
  32. package/dist/null-device/null-device.js +14 -31
  33. package/dist/null-device/null-device.js.map +1 -0
  34. package/dist/null-device/resources/null-buffer.js +1 -0
  35. package/dist/null-device/resources/null-buffer.js.map +1 -0
  36. package/dist/null-device/resources/null-command-buffer.js +1 -0
  37. package/dist/null-device/resources/null-command-buffer.js.map +1 -0
  38. package/dist/null-device/resources/null-framebuffer.d.ts +1 -0
  39. package/dist/null-device/resources/null-framebuffer.d.ts.map +1 -1
  40. package/dist/null-device/resources/null-framebuffer.js +4 -0
  41. package/dist/null-device/resources/null-framebuffer.js.map +1 -0
  42. package/dist/null-device/resources/null-query-set.js +1 -0
  43. package/dist/null-device/resources/null-query-set.js.map +1 -0
  44. package/dist/null-device/resources/null-render-pass.js +1 -0
  45. package/dist/null-device/resources/null-render-pass.js.map +1 -0
  46. package/dist/null-device/resources/null-render-pipeline.d.ts +1 -2
  47. package/dist/null-device/resources/null-render-pipeline.d.ts.map +1 -1
  48. package/dist/null-device/resources/null-render-pipeline.js +1 -0
  49. package/dist/null-device/resources/null-render-pipeline.js.map +1 -0
  50. package/dist/null-device/resources/null-sampler.js +1 -0
  51. package/dist/null-device/resources/null-sampler.js.map +1 -0
  52. package/dist/null-device/resources/null-shader.d.ts +1 -0
  53. package/dist/null-device/resources/null-shader.d.ts.map +1 -1
  54. package/dist/null-device/resources/null-shader.js +4 -0
  55. package/dist/null-device/resources/null-shader.js.map +1 -0
  56. package/dist/null-device/resources/null-texture-view.js +1 -0
  57. package/dist/null-device/resources/null-texture-view.js.map +1 -0
  58. package/dist/null-device/resources/null-texture.d.ts +5 -14
  59. package/dist/null-device/resources/null-texture.d.ts.map +1 -1
  60. package/dist/null-device/resources/null-texture.js +16 -30
  61. package/dist/null-device/resources/null-texture.js.map +1 -0
  62. package/dist/null-device/resources/null-transform-feedback.js +1 -0
  63. package/dist/null-device/resources/null-transform-feedback.js.map +1 -0
  64. package/dist/null-device/resources/null-vertex-array.js +1 -0
  65. package/dist/null-device/resources/null-vertex-array.js.map +1 -0
  66. package/dist/performance-test-runner.js +1 -0
  67. package/dist/performance-test-runner.js.map +1 -0
  68. package/dist/register-devices.js +4 -3
  69. package/dist/register-devices.js.map +1 -0
  70. package/dist/snapshot-test-runner.js +1 -0
  71. package/dist/snapshot-test-runner.js.map +1 -0
  72. package/dist/test-runner.d.ts +2 -2
  73. package/dist/test-runner.d.ts.map +1 -1
  74. package/dist/test-runner.js +5 -3
  75. package/dist/test-runner.js.map +1 -0
  76. package/dist/utils/check-type.js +1 -0
  77. package/dist/utils/check-type.js.map +1 -0
  78. package/dist/utils/deep-copy.js +1 -0
  79. package/dist/utils/deep-copy.js.map +1 -0
  80. package/dist/utils/get-bounding-box.js +1 -0
  81. package/dist/utils/get-bounding-box.js.map +1 -0
  82. package/dist/utils/resource-tracker.d.ts +2 -2
  83. package/dist/utils/resource-tracker.js +1 -0
  84. package/dist/utils/resource-tracker.js.map +1 -0
  85. package/package.json +7 -7
  86. package/src/create-test-device.ts +100 -52
  87. package/src/{engine → deprecated}/classic-animation-loop.ts +9 -5
  88. package/src/deprecated/sync-test-device.ts +35 -0
  89. package/src/index.ts +12 -3
  90. package/src/null-device/null-adapter.ts +32 -0
  91. package/src/null-device/null-canvas-context.ts +11 -24
  92. package/src/null-device/null-device.ts +17 -43
  93. package/src/null-device/resources/null-framebuffer.ts +4 -0
  94. package/src/null-device/resources/null-render-pipeline.ts +7 -2
  95. package/src/null-device/resources/null-shader.ts +4 -0
  96. package/src/null-device/resources/null-texture.ts +21 -38
  97. package/src/register-devices.ts +3 -3
  98. package/src/test-runner.ts +5 -3
  99. package/dist/engine/classic-animation-loop.d.ts.map +0 -1
  100. /package/dist/{engine → deprecated}/classic-animation-loop.d.ts +0 -0
package/dist/index.cjs CHANGED
@@ -2,7 +2,6 @@ var __defProp = Object.defineProperty;
2
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
5
  var __export = (target, all) => {
7
6
  for (var name in all)
8
7
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -16,26 +15,25 @@ var __copyProps = (to, from, except, desc) => {
16
15
  return to;
17
16
  };
18
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var __publicField = (obj, key, value) => {
20
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
- return value;
22
- };
23
18
 
24
19
  // dist/index.js
25
20
  var dist_exports = {};
26
21
  __export(dist_exports, {
22
+ NullAdapter: () => NullAdapter,
27
23
  NullDevice: () => NullDevice,
28
24
  PerformanceTestRunner: () => PerformanceTestRunner,
29
25
  SnapshotTestRunner: () => SnapshotTestRunner,
30
26
  checkType: () => checkType,
31
- createTestContext: () => createTestContext,
32
27
  createTestDevice: () => createTestDevice,
33
28
  deepCopy: () => deepCopy,
34
29
  getLeakedResources: () => getLeakedResources,
30
+ getNullTestDevice: () => getNullTestDevice,
35
31
  getResourceCounts: () => getResourceCounts,
36
32
  getTestDevices: () => getTestDevices,
37
- webglDevice: () => webglDevice,
38
- webgpuDevice: () => webgpuDevice
33
+ getWebGLTestDevice: () => getWebGLTestDevice,
34
+ getWebGPUTestDevice: () => getWebGPUTestDevice,
35
+ nullAdapter: () => nullAdapter,
36
+ webglDevice: () => webglDevice2
39
37
  });
40
38
  module.exports = __toCommonJS(dist_exports);
41
39
 
@@ -43,1308 +41,1331 @@ module.exports = __toCommonJS(dist_exports);
43
41
  var import_core = require("@luma.gl/core");
44
42
  var import_webgl = require("@luma.gl/webgl");
45
43
  var import_webgpu = require("@luma.gl/webgpu");
46
- import_core.luma.registerDevices([import_webgl.WebGLDevice, import_webgpu.WebGPUDevice]);
44
+ import_core.luma.registerAdapters([import_webgl.webgl2Adapter, import_webgpu.webgpuAdapter]);
47
45
 
48
46
  // dist/create-test-device.js
49
- var import_core2 = require("@luma.gl/core");
47
+ var import_core18 = require("@luma.gl/core");
50
48
  var import_webgl2 = require("@luma.gl/webgl");
51
- var CONTEXT_DEFAULTS = {
52
- width: 1,
53
- height: 1,
54
- debug: true
49
+ var import_webgpu2 = require("@luma.gl/webgpu");
50
+
51
+ // dist/null-device/null-adapter.js
52
+ var import_core17 = require("@luma.gl/core");
53
+
54
+ // dist/null-device/null-device.js
55
+ var import_core16 = require("@luma.gl/core");
56
+
57
+ // dist/null-device/null-device-info.js
58
+ var NullDeviceInfo = {
59
+ type: "unknown",
60
+ gpu: "software",
61
+ gpuType: "unknown",
62
+ gpuBackend: "unknown",
63
+ vendor: "no one",
64
+ renderer: "none",
65
+ version: "1.0",
66
+ shadingLanguage: "glsl",
67
+ shadingLanguageVersion: 300
55
68
  };
56
- function createTestContext(opts = {}) {
57
- const device = createTestDevice(opts);
58
- return device && device.gl;
59
- }
60
- function createTestDevice(props = {}) {
61
- try {
62
- props = { ...CONTEXT_DEFAULTS, ...props, debug: true };
63
- return new import_webgl2.WebGLDevice(props);
64
- } catch (error) {
65
- console.error(`Failed to created device '${props.id}': ${error.message}`);
66
- return null;
67
- }
68
- }
69
- var webglDevice = createTestDevice();
70
- var webglDeviceAsync;
71
- var webgpuDevice;
72
- var devicesCreated = false;
73
- async function getTestDevices(type) {
74
- if (!devicesCreated) {
75
- devicesCreated = true;
76
- try {
77
- webgpuDevice = await import_core2.luma.createDevice({
78
- id: "webgpu-test-device",
79
- type: "webgpu"
80
- });
81
- } catch (error) {
82
- import_core2.log.error(String(error))();
83
- }
84
- try {
85
- webglDeviceAsync = await import_core2.luma.createDevice({
86
- id: "webgl-test-device",
87
- type: "webgl"
88
- });
89
- } catch (error) {
90
- import_core2.log.error(String(error))();
91
- }
92
- }
93
- return [webglDeviceAsync, webgpuDevice].filter(Boolean).filter((device) => !type || type === device.type);
94
- }
95
69
 
96
- // dist/engine/classic-animation-loop.js
70
+ // dist/null-device/null-device-features.js
71
+ var import_core2 = require("@luma.gl/core");
72
+ var NullDeviceLimits = class extends import_core2.DeviceLimits {
73
+ maxTextureDimension1D = 0;
74
+ maxTextureDimension2D = 2048;
75
+ maxTextureDimension3D = 256;
76
+ maxTextureArrayLayers = 256;
77
+ maxBindGroups = 0;
78
+ maxDynamicUniformBuffersPerPipelineLayout = 0;
79
+ maxDynamicStorageBuffersPerPipelineLayout = 0;
80
+ maxSampledTexturesPerShaderStage = 8;
81
+ maxSamplersPerShaderStage = 16;
82
+ maxStorageBuffersPerShaderStage = 0;
83
+ maxStorageTexturesPerShaderStage = 0;
84
+ maxUniformBuffersPerShaderStage = 20;
85
+ maxUniformBufferBindingSize = 16384;
86
+ maxStorageBufferBindingSize = 0;
87
+ minUniformBufferOffsetAlignment = 0;
88
+ minStorageBufferOffsetAlignment = 0;
89
+ maxVertexBuffers = 16;
90
+ maxVertexAttributes = 16;
91
+ maxVertexBufferArrayStride = 2048;
92
+ maxInterStageShaderComponents = 60;
93
+ maxComputeWorkgroupStorageSize = 0;
94
+ maxComputeInvocationsPerWorkgroup = 0;
95
+ maxComputeWorkgroupSizeX = 0;
96
+ maxComputeWorkgroupSizeY = 0;
97
+ maxComputeWorkgroupSizeZ = 0;
98
+ maxComputeWorkgroupsPerDimension = 0;
99
+ };
100
+
101
+ // dist/null-device/null-canvas-context.js
102
+ var import_core4 = require("@luma.gl/core");
103
+
104
+ // dist/null-device/resources/null-framebuffer.js
97
105
  var import_core3 = require("@luma.gl/core");
98
- var import_engine = require("@luma.gl/engine");
99
- var import_env = require("@probe.gl/env");
100
- var import_webgl3 = require("@luma.gl/webgl");
101
- var isPage = (0, import_env.isBrowser)() && typeof document !== "undefined";
102
- function getHTMLCanvasElement(canvas) {
103
- return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement ? canvas : null;
104
- }
105
- var statIdCounter = 0;
106
- var DEFAULT_CLASSIC_ANIMATION_LOOP_PROPS = {
107
- onCreateDevice: (props) => import_core3.luma.createDevice(props),
108
- onCreateContext: void 0,
109
- onAddHTML: void 0,
110
- onInitialize: () => ({}),
111
- onRender: () => {
112
- },
113
- onFinalize: () => {
114
- },
115
- onError: (error) => console.error(error),
116
- // eslint-disable-line no-console
117
- device: null,
118
- // debug: true,
119
- // view parameters
120
- useDevicePixels: true,
121
- autoResizeViewport: true,
122
- autoResizeDrawingBuffer: true,
123
- stats: import_core3.luma.stats.get(`animation-loop-${statIdCounter++}`),
124
- // deprecated
125
- // onCreateContext: (opts) => createGLContext(opts),
126
- gl: void 0,
127
- glOptions: {},
128
- createFramebuffer: false
106
+ var NullFramebuffer = class extends import_core3.Framebuffer {
107
+ device;
108
+ colorAttachments = [];
109
+ depthStencilAttachment = null;
110
+ constructor(device, props) {
111
+ super(device, props);
112
+ this.device = device;
113
+ }
114
+ updateAttachments() {
115
+ }
129
116
  };
130
- var ClassicAnimationLoop = class {
117
+
118
+ // dist/null-device/null-canvas-context.js
119
+ var NullCanvasContext = class extends import_core4.CanvasContext {
131
120
  device;
132
- canvas;
133
- props;
134
- animationProps;
135
- // framebuffer: ClassicFramebuffer = null;
136
- timeline = null;
137
- stats;
138
- cpuTime;
139
- gpuTime;
140
- frameRate;
141
- display;
142
- needsRedraw = "initialized";
143
- _initialized = false;
144
- _running = false;
145
- _animationFrameId = null;
146
- _pageLoadPromise = null;
147
- _nextFramePromise = null;
148
- _resolveNextFrame = null;
149
- _cpuStartTime = 0;
150
- // _gpuTimeQuery: Query | null = null;
151
- /** @deprecated */
152
- gl;
153
- /*
154
- */
155
- constructor(props = {}) {
156
- this.props = { ...DEFAULT_CLASSIC_ANIMATION_LOOP_PROPS, ...props };
157
- props = this.props;
158
- let { useDevicePixels = true } = this.props;
159
- if ("useDevicePixelRatio" in props) {
160
- import_core3.log.deprecated("useDevicePixelRatio", "useDevicePixels")();
161
- useDevicePixels = props.useDevicePixelRatio;
162
- }
163
- this.device = props.device;
164
- this.gl = this.device && this.device.gl || props.gl;
165
- this.stats = props.stats;
166
- this.cpuTime = this.stats.get("CPU Time");
167
- this.gpuTime = this.stats.get("GPU Time");
168
- this.frameRate = this.stats.get("Frame Rate");
169
- this.setProps({
170
- autoResizeViewport: props.autoResizeViewport,
171
- autoResizeDrawingBuffer: props.autoResizeDrawingBuffer,
172
- useDevicePixels
173
- });
174
- this.start = this.start.bind(this);
175
- this.stop = this.stop.bind(this);
176
- this._onMousemove = this._onMousemove.bind(this);
177
- this._onMouseleave = this._onMouseleave.bind(this);
121
+ handle = null;
122
+ presentationSize;
123
+ _framebuffer = null;
124
+ get [Symbol.toStringTag]() {
125
+ return "NullCanvasContext";
178
126
  }
179
- destroy() {
180
- this.stop();
181
- this._setDisplay(null);
127
+ constructor(device, props) {
128
+ super(props);
129
+ this.device = device;
130
+ this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
131
+ this.updateSize([this.drawingBufferWidth, this.drawingBufferHeight]);
182
132
  }
183
- /** @deprecated Use .destroy() */
184
- delete() {
185
- this.destroy();
133
+ getCurrentFramebuffer() {
134
+ this._framebuffer = this._framebuffer || new NullFramebuffer(this.device, { handle: null });
135
+ return this._framebuffer;
186
136
  }
187
- setNeedsRedraw(reason) {
188
- this.needsRedraw = this.needsRedraw || reason;
189
- return this;
137
+ /** Resizes and updates render targets if necessary */
138
+ updateSize(size) {
190
139
  }
191
- setProps(props) {
192
- if ("autoResizeViewport" in props) {
193
- this.props.autoResizeViewport = props.autoResizeViewport;
194
- }
195
- if ("autoResizeDrawingBuffer" in props) {
196
- this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer;
197
- }
198
- if ("useDevicePixels" in props) {
199
- this.props.useDevicePixels = props.useDevicePixels;
200
- }
201
- return this;
140
+ resize(options) {
141
+ throw new Error("not implemented");
202
142
  }
203
- start(opts = {}) {
204
- this._start(opts);
205
- return this;
143
+ commit() {
206
144
  }
207
- /** Starts a render loop if not already running */
208
- async _start(props) {
209
- if (this._running) {
210
- return this;
211
- }
212
- this._running = true;
213
- try {
214
- await this._getPageLoadPromise();
215
- if (!this._running) {
216
- return null;
217
- }
218
- let appContext;
219
- if (!this._initialized) {
220
- this._initialized = true;
221
- await this._createDevice(props);
222
- this._initialize(props);
223
- appContext = await this.onInitialize(this.animationProps);
224
- this._addCallbackData(appContext || {});
225
- }
226
- if (!this._running) {
227
- return null;
228
- }
229
- if (appContext !== false) {
230
- this._cancelAnimationFrame();
231
- this._requestAnimationFrame();
232
- }
233
- return this;
234
- } catch (error) {
235
- this.props.onError(error);
236
- return null;
237
- }
145
+ };
146
+
147
+ // dist/null-device/resources/null-buffer.js
148
+ var import_core5 = require("@luma.gl/core");
149
+ var NullBuffer = class extends import_core5.Buffer {
150
+ device;
151
+ byteLength;
152
+ constructor(device, props = {}) {
153
+ super(device, props);
154
+ this.device = device;
155
+ const byteOffset = props.byteOffset || 0;
156
+ const byteLength = props.byteLength ?? (props.data ? props.data.byteLength + byteOffset : 0);
157
+ this.byteLength = byteLength;
158
+ this.trackAllocatedMemory(byteLength);
238
159
  }
239
- /** Explicitly draw a frame */
240
- redraw() {
241
- if (this.isContextLost()) {
242
- return this;
243
- }
244
- this._beginTimers();
245
- this._setupFrame();
246
- this._updateCallbackData();
247
- this._renderFrame(this.animationProps);
248
- this._clearNeedsRedraw();
249
- if (this._resolveNextFrame) {
250
- this._resolveNextFrame(this);
251
- this._nextFramePromise = null;
252
- this._resolveNextFrame = null;
160
+ destroy() {
161
+ if (!this.destroyed) {
162
+ super.destroy();
163
+ this.trackDeallocatedMemory();
253
164
  }
254
- this._endTimers();
255
- return this;
256
165
  }
257
- // Stops a render loop if already running, finalizing
258
- stop() {
259
- if (this._running) {
260
- this._finalizeCallbackData();
261
- this._cancelAnimationFrame();
262
- this._nextFramePromise = null;
263
- this._resolveNextFrame = null;
264
- this._running = false;
265
- }
266
- return this;
166
+ async readAsync(byteOffset = 0, byteLength) {
167
+ byteLength = byteLength ?? this.byteLength - byteOffset;
168
+ return new Uint8Array(byteLength);
267
169
  }
268
- attachTimeline(timeline) {
269
- this.timeline = timeline;
270
- return this.timeline;
170
+ write(data, byteOffset = 0) {
271
171
  }
272
- detachTimeline() {
273
- this.timeline = null;
172
+ };
173
+
174
+ // dist/null-device/resources/null-shader.js
175
+ var import_core6 = require("@luma.gl/core");
176
+ var NullShader = class extends import_core6.Shader {
177
+ device;
178
+ constructor(device, props) {
179
+ super(device, props);
180
+ this.device = device;
274
181
  }
275
- waitForRender() {
276
- this.setNeedsRedraw("waitForRender");
277
- if (!this._nextFramePromise) {
278
- this._nextFramePromise = new Promise((resolve) => {
279
- this._resolveNextFrame = resolve;
280
- });
281
- }
282
- return this._nextFramePromise;
182
+ get asyncCompilationStatus() {
183
+ return this.getCompilationInfo().then(() => "success");
283
184
  }
284
- async toDataURL() {
285
- var _a;
286
- this.setNeedsRedraw("toDataURL");
287
- await this.waitForRender();
288
- return (_a = getHTMLCanvasElement(this.gl.canvas)) == null ? void 0 : _a.toDataURL();
185
+ async getCompilationInfo() {
186
+ return [];
289
187
  }
290
- isContextLost() {
291
- return this.gl.isContextLost();
188
+ };
189
+
190
+ // dist/null-device/resources/null-command-buffer.js
191
+ var import_core7 = require("@luma.gl/core");
192
+ var NullCommandEncoder = class extends import_core7.CommandEncoder {
193
+ device;
194
+ constructor(device, props) {
195
+ super(device, props);
196
+ this.device = device;
292
197
  }
293
- onCreateDevice(deviceProps) {
294
- const { onCreateDevice } = this.props;
295
- return onCreateDevice(deviceProps);
198
+ finish() {
296
199
  }
297
- onInitialize(animationProps) {
298
- const { onInitialize } = this.props;
299
- return onInitialize(animationProps);
200
+ copyBufferToBuffer(options) {
300
201
  }
301
- onRender(animationProps) {
302
- const { onRender } = this.props;
303
- return onRender(animationProps);
202
+ copyBufferToTexture(options) {
304
203
  }
305
- onFinalize(animationProps) {
306
- const { onFinalize } = this.props;
307
- return onFinalize(animationProps);
204
+ copyTextureToBuffer(options) {
308
205
  }
309
- // DEPRECATED/REMOVED METHODS
310
- /** @deprecated Use .onCreateDevice() */
311
- onCreateContext(props) {
312
- const { onCreateContext } = this.props;
313
- return onCreateContext(props);
206
+ copyTextureToTexture(options) {
314
207
  }
315
- /** @deprecated */
316
- getHTMLControlValue(id, defaultValue = 1) {
317
- const element = document.getElementById(id);
318
- return element ? Number(element.value) : defaultValue;
208
+ pushDebugGroup(groupLabel) {
319
209
  }
320
- // PRIVATE METHODS
321
- _initialize(props) {
322
- this._createFramebuffer();
323
- this._startEventHandling();
324
- this._initializeCallbackData();
325
- this._updateCallbackData();
326
- this._resizeCanvasDrawingBuffer();
327
- this._resizeViewport();
210
+ popDebugGroup() {
328
211
  }
329
- _getPageLoadPromise() {
330
- if (!this._pageLoadPromise) {
331
- this._pageLoadPromise = isPage ? new Promise((resolve, reject) => {
332
- if (isPage && document.readyState === "complete") {
333
- resolve(document);
334
- return;
335
- }
336
- window.addEventListener("load", () => {
337
- resolve(document);
338
- });
339
- }) : Promise.resolve({});
340
- }
341
- return this._pageLoadPromise;
212
+ insertDebugMarker(markerLabel) {
342
213
  }
343
- _setDisplay(display) {
344
- if (this.display) {
345
- this.display.destroy();
346
- this.display.animationLoop = null;
347
- }
348
- if (display) {
349
- display.animationLoop = this;
350
- }
351
- this.display = display;
214
+ resolveQuerySet(querySet) {
352
215
  }
353
- _requestAnimationFrame() {
354
- if (!this._running) {
355
- return;
356
- }
357
- this._animationFrameId = (0, import_engine.requestAnimationFrame)(this._animationFrame.bind(this));
216
+ };
217
+
218
+ // dist/null-device/resources/null-sampler.js
219
+ var import_core8 = require("@luma.gl/core");
220
+ var NullSampler = class extends import_core8.Sampler {
221
+ device;
222
+ constructor(device, props) {
223
+ super(device, props);
224
+ this.device = device;
358
225
  }
359
- _cancelAnimationFrame() {
360
- if (this._animationFrameId !== null) {
361
- return;
362
- }
363
- (0, import_engine.cancelAnimationFrame)(this._animationFrameId);
364
- this._animationFrameId = null;
226
+ };
227
+
228
+ // dist/null-device/resources/null-texture.js
229
+ var import_core10 = require("@luma.gl/core");
230
+
231
+ // dist/null-device/resources/null-texture-view.js
232
+ var import_core9 = require("@luma.gl/core");
233
+ var NullTextureView = class extends import_core9.TextureView {
234
+ device;
235
+ texture;
236
+ constructor(device, props) {
237
+ super(device, { ...import_core9.Texture.defaultProps, ...props });
238
+ this.device = device;
239
+ this.texture = props.texture;
365
240
  }
366
- _animationFrame() {
367
- if (!this._running) {
368
- return;
369
- }
370
- this.redraw();
371
- this._requestAnimationFrame();
241
+ };
242
+
243
+ // dist/null-device/resources/null-texture.js
244
+ var NullTexture = class extends import_core10.Texture {
245
+ device;
246
+ sampler;
247
+ view;
248
+ constructor(device, props) {
249
+ super(device, props);
250
+ const propsWithData = { ...this.props };
251
+ propsWithData.data = props.data;
252
+ this.device = device;
253
+ this.initialize(propsWithData);
254
+ Object.seal(this);
372
255
  }
373
- // Called on each frame, can be overridden to call onRender multiple times
374
- // to support e.g. stereoscopic rendering
375
- _renderFrame(props) {
376
- if (this.display) {
377
- this.display._renderFrame(props);
378
- return;
256
+ destroy() {
257
+ if (!this.destroyed) {
258
+ super.destroy();
259
+ this.trackDeallocatedMemory("Texture");
379
260
  }
380
- this.onRender(props);
381
261
  }
382
- _clearNeedsRedraw() {
383
- this.needsRedraw = null;
262
+ createView(props) {
263
+ return new NullTextureView(this.device, { ...props, texture: this });
384
264
  }
385
- _setupFrame() {
386
- this._resizeCanvasDrawingBuffer();
387
- this._resizeViewport();
388
- this._resizeFramebuffer();
265
+ setTexture1DData(data) {
266
+ throw new Error("not implemented");
389
267
  }
390
- /* eslint-disable @typescript-eslint/unbound-method */
391
- // Initialize the object that will be passed to app callbacks
392
- _initializeCallbackData() {
393
- this.animationProps = {
394
- device: this.device,
395
- gl: this.gl,
396
- stop: this.stop,
397
- canvas: this.gl.canvas,
398
- // Initial values
399
- useDevicePixels: this.props.useDevicePixels,
400
- needsRedraw: null,
401
- // Animation props
402
- startTime: Date.now(),
403
- engineTime: 0,
404
- tick: 0,
405
- tock: 0,
406
- timeline: this.timeline,
407
- // @ts-ignore
408
- animationLoop: this,
409
- // Timeline time for back compatibility
410
- time: 0,
411
- // Experimental
412
- _mousePosition: null,
413
- // Event props
414
- /** @deprecated */
415
- // framebuffer: this.framebuffer,
416
- /** @deprecated */
417
- _timeline: this.timeline,
418
- /** @deprecated */
419
- _loop: this,
420
- /** @deprecated */
421
- _animationLoop: this
422
- };
268
+ setTexture2DData(lodData, depth, target) {
269
+ throw new Error("not implemented");
423
270
  }
424
- // Update the context object that will be passed to app callbacks
425
- _updateCallbackData() {
426
- const { width, height, aspect } = this._getSizeAndAspect();
427
- if (width !== this.animationProps.width || height !== this.animationProps.height) {
428
- this.setNeedsRedraw("drawing buffer resized");
429
- }
430
- if (aspect !== this.animationProps.aspect) {
431
- this.setNeedsRedraw("drawing buffer aspect changed");
432
- }
433
- this.animationProps.width = width;
434
- this.animationProps.height = height;
435
- this.animationProps.aspect = aspect;
436
- this.animationProps.needsRedraw = this.needsRedraw;
437
- this.animationProps.engineTime = Date.now() - this.animationProps.startTime;
438
- if (this.timeline) {
439
- this.timeline.update(this.animationProps.engineTime);
440
- }
441
- this.animationProps.tick = Math.floor(this.animationProps.time / 1e3 * 60);
442
- this.animationProps.tock++;
443
- this.animationProps.time = this.timeline ? this.timeline.getTime() : this.animationProps.engineTime;
271
+ setTexture3DData(lodData, depth, target) {
272
+ throw new Error("not implemented");
444
273
  }
445
- _finalizeCallbackData() {
446
- this.onFinalize(this.animationProps);
274
+ setTextureCubeData(data, depth) {
275
+ throw new Error("not implemented");
447
276
  }
448
- /** Add application's data to the app context object */
449
- _addCallbackData(appContext) {
450
- if (typeof appContext === "object" && appContext !== null) {
451
- this.animationProps = Object.assign({}, this.animationProps, appContext);
452
- }
277
+ setTextureArrayData(data) {
278
+ throw new Error("not implemented");
453
279
  }
454
- /** Either uses supplied or existing context, or calls provided callback to create one */
455
- async _createDevice(props) {
456
- const deviceProps = { ...this.props, ...props, ...this.props.glOptions };
457
- this.device = await this.onCreateDevice(deviceProps);
458
- this.gl = this.device.gl;
459
- (0, import_webgl3.resetGLParameters)(this.gl);
460
- this._createInfoDiv();
280
+ setTextureCubeArrayData(data) {
281
+ throw new Error("not implemented");
461
282
  }
462
- _createInfoDiv() {
463
- const canvas = getHTMLCanvasElement(this.gl.canvas);
464
- if (canvas && this.props.onAddHTML) {
465
- const wrapperDiv = document.createElement("div");
466
- document.body.appendChild(wrapperDiv);
467
- wrapperDiv.style.position = "relative";
468
- const div = document.createElement("div");
469
- div.style.position = "absolute";
470
- div.style.left = "10px";
471
- div.style.bottom = "10px";
472
- div.style.width = "300px";
473
- div.style.background = "white";
474
- if (canvas) {
475
- wrapperDiv.appendChild(canvas);
476
- }
477
- wrapperDiv.appendChild(div);
478
- const html = this.props.onAddHTML(div);
479
- if (html) {
480
- div.innerHTML = html;
481
- }
482
- }
483
- }
484
- _getSizeAndAspect() {
485
- const width = this.gl.drawingBufferWidth;
486
- const height = this.gl.drawingBufferHeight;
487
- let aspect = 1;
488
- const canvas = getHTMLCanvasElement(this.gl.canvas);
489
- if (canvas && canvas.clientHeight) {
490
- aspect = canvas.clientWidth / canvas.clientHeight;
491
- } else if (width > 0 && height > 0) {
492
- aspect = width / height;
493
- }
494
- return { width, height, aspect };
495
- }
496
- /** Default viewport setup */
497
- _resizeViewport() {
498
- if (this.props.autoResizeViewport) {
499
- this.gl.viewport(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight);
500
- }
501
- }
502
- /**
503
- * Resize the render buffer of the canvas to match canvas client size
504
- * Optionally multiplying with devicePixel ratio
505
- */
506
- _resizeCanvasDrawingBuffer() {
507
- if (this.props.autoResizeDrawingBuffer) {
508
- this.device.canvasContext.resize({ useDevicePixels: this.props.useDevicePixels });
509
- }
510
- }
511
- _beginTimers() {
512
- this.frameRate.timeEnd();
513
- this.frameRate.timeStart();
514
- this.cpuTime.timeStart();
515
- }
516
- _endTimers() {
517
- this.cpuTime.timeEnd();
518
- }
519
- // Event handling
520
- _startEventHandling() {
521
- const { canvas } = this.gl;
522
- if (canvas) {
523
- canvas.addEventListener("mousemove", this._onMousemove);
524
- canvas.addEventListener("mouseleave", this._onMouseleave);
525
- }
526
- }
527
- _onMousemove(e) {
528
- this.animationProps._mousePosition = [e.offsetX, e.offsetY];
529
- }
530
- _onMouseleave(e) {
531
- this.animationProps._mousePosition = null;
532
- }
533
- // Deprecated
534
- /** @deprecated */
535
- _createFramebuffer() {
536
- if (this.props.createFramebuffer) {
537
- }
538
- }
539
- /** @deprecated */
540
- _resizeFramebuffer() {
541
- }
542
- };
543
-
544
- // dist/test-runner.js
545
- var DEFAULT_TEST_CASE = {
546
- name: "Unnamed test",
547
- onInitialize: async () => {
548
- },
549
- onRender: ({ done }) => done(),
550
- onFinalize: () => {
551
- }
552
- };
553
- var DEFAULT_TEST_PROPS = {
554
- width: void 0,
555
- height: void 0,
556
- // test lifecycle callback
557
- onTestStart: (testCase) => console.log(`# ${testCase.name}`),
558
- onTestPass: (testCase, result) => console.log(`ok ${testCase.name} passed`),
559
- onTestFail: (testCase, error) => console.log(`not ok ${testCase.name} failed`),
560
- // milliseconds to wait for each test case before aborting
561
- timeout: 2e3,
562
- maxFramesToRender: void 0,
563
- imageDiffOptions: void 0
564
- };
565
- var TestRunner = class {
566
- device = webglDevice;
567
- props;
568
- isRunning = false;
569
- testOptions = { ...DEFAULT_TEST_PROPS };
570
- _animationProps;
571
- _animationLoop;
572
- _testCases = [];
573
- _testCaseData = null;
574
- _currentTestCase;
575
- _currentTestCaseStartTime;
576
- _currentTestCaseStartTick;
577
- // should be defined in snapshot-test-runner
578
- isDiffing = false;
579
- // @ts-expect-error
580
- isHeadless = Boolean(window.browserTestDriver_isHeadless);
581
- /**
582
- * props
583
- * AnimationLoop props
584
- */
585
- constructor(props = {}) {
586
- this.props = props;
587
- }
588
- /**
589
- * Add testCase(s)
590
- */
591
- add(testCases) {
592
- if (!Array.isArray(testCases)) {
593
- testCases = [testCases];
594
- }
595
- for (const testCase of testCases) {
596
- this._testCases.push(testCase);
597
- }
598
- return this;
599
- }
600
- /**
601
- * Returns a promise that resolves when all the test cases are done
602
- */
603
- run(options = {}) {
604
- this.testOptions = { ...this.testOptions, ...options };
605
- return new Promise((resolve, reject) => {
606
- this._animationLoop = new ClassicAnimationLoop({
607
- ...this.props,
608
- device: this.device,
609
- onRender: this._onRender.bind(this),
610
- onFinalize: () => {
611
- this.isRunning = false;
612
- resolve();
613
- }
614
- });
615
- this._animationLoop.start(this.props);
616
- this.isRunning = true;
617
- this.isDiffing = false;
618
- this._currentTestCase = null;
619
- }).catch((error) => {
620
- this._fail({ error: error.message });
283
+ initialize(props = {}) {
284
+ this.setSampler(props.sampler);
285
+ this.view = new NullTextureView(this.device, {
286
+ ...props,
287
+ texture: this,
288
+ mipLevelCount: 1,
289
+ arrayLayerCount: 1
621
290
  });
291
+ return this;
622
292
  }
623
- /* Lifecycle methods for subclassing */
624
- initTestCase(testCase) {
625
- const { animationLoop } = testCase;
626
- if (animationLoop) {
627
- testCase.onInitialize = animationLoop.props.onInitialize.bind(animationLoop);
628
- testCase.onRender = animationLoop.props.onRender.bind(animationLoop);
629
- testCase.onFinalize = animationLoop.props.onFinalize.bind(animationLoop);
630
- }
631
- for (const key in DEFAULT_TEST_CASE) {
632
- testCase[key] = testCase[key] || DEFAULT_TEST_CASE[key];
633
- }
634
- }
635
- shouldRender(animationProps) {
636
- return true;
637
- }
638
- assert(testCase) {
639
- this._pass(testCase);
640
- this._next();
641
- }
642
- /* Utilities */
643
- _pass(result) {
644
- this.testOptions.onTestPass(this._currentTestCase, result);
645
- }
646
- _fail(result) {
647
- this.testOptions.onTestFail(this._currentTestCase, result);
648
- }
649
- _next() {
650
- this._nextTestCase();
651
- }
652
- /* Private methods */
653
- _onRender(animationProps) {
654
- this._animationProps = animationProps;
655
- const testCase = this._currentTestCase || this._nextTestCase();
656
- if (!testCase) {
657
- this._animationLoop.stop();
658
- return;
659
- }
660
- let isDone = false;
661
- const testCaseAnimationProps = {
662
- ...animationProps,
663
- ...this._testCaseData,
664
- // tick/time starts from 0 for each test case
665
- startTime: this._currentTestCaseStartTime,
666
- time: animationProps.time - this._currentTestCaseStartTime,
667
- tick: animationProps.tick - this._currentTestCaseStartTick,
668
- // called by the test case when it is done rendering and ready for capture and diff
669
- done: () => {
670
- isDone = true;
671
- }
672
- };
673
- if (this._testCaseData && this.shouldRender(testCaseAnimationProps)) {
674
- testCase.onRender(testCaseAnimationProps);
675
- }
676
- const timeout = testCase.timeout || this.testOptions.timeout;
677
- if (timeout && testCaseAnimationProps.time > timeout) {
678
- isDone = true;
679
- }
680
- if (isDone) {
681
- this.assert(testCase);
293
+ setSampler(sampler = {}) {
294
+ if (sampler instanceof NullSampler) {
295
+ this.sampler = sampler;
296
+ } else {
297
+ this.sampler = new NullSampler(this.device, sampler);
682
298
  }
299
+ return this;
683
300
  }
684
- _nextTestCase() {
685
- const animationProps = this._animationProps;
686
- if (this._testCaseData) {
687
- for (const key in this._testCaseData) {
688
- const value = this._testCaseData[key];
689
- if (value && value.delete) {
690
- value.destroy();
691
- }
692
- }
693
- this._currentTestCase.onFinalize(Object.assign({}, animationProps, this._testCaseData));
694
- this.device.popState();
695
- this._currentTestCase = null;
696
- this._testCaseData = null;
697
- }
698
- const testCase = this._testCases.shift();
699
- if (testCase) {
700
- this._currentTestCase = testCase;
701
- this._currentTestCaseStartTime = animationProps.time;
702
- this._currentTestCaseStartTick = animationProps.tick;
703
- this.initTestCase(testCase);
704
- this.device.pushState();
705
- const initProps = {
706
- ...animationProps,
707
- // tick/time starts from 0 for each test case
708
- startTime: animationProps.time,
709
- time: 0,
710
- tick: 0
711
- };
712
- Promise.resolve(testCase.onInitialize(initProps)).then((userData) => {
713
- this._testCaseData = userData || {};
714
- });
715
- this.testOptions.onTestStart(testCase);
716
- }
717
- return testCase;
301
+ copyExternalImage(options) {
302
+ this.trackDeallocatedMemory("Texture");
303
+ const { image: data } = options;
304
+ const bytesPerPixel = 4;
305
+ this.trackAllocatedMemory(this.width * this.height * bytesPerPixel, "Texture");
306
+ const width = options.width ?? data.width;
307
+ const height = options.height ?? data.height;
308
+ this.width = width;
309
+ this.height = height;
310
+ return { width, height };
718
311
  }
719
312
  };
720
313
 
721
- // dist/utils/get-bounding-box.js
722
- function getBoundingBoxInPage(domElement) {
723
- const bbox = domElement.getBoundingClientRect();
724
- return {
725
- x: window.scrollX + bbox.x,
726
- y: window.scrollY + bbox.y,
727
- width: bbox.width,
728
- height: bbox.height
729
- };
730
- }
731
-
732
- // dist/snapshot-test-runner.js
733
- var SnapshotTestRunner = class extends TestRunner {
734
- // should be defined here but hack access in TestRunner
735
- // private isDiffing: boolean = false;
736
- constructor(props) {
737
- super(props);
738
- this.testOptions.imageDiffOptions = {};
314
+ // dist/null-device/resources/null-render-pass.js
315
+ var import_core11 = require("@luma.gl/core");
316
+ var NullRenderPass = class extends import_core11.RenderPass {
317
+ device;
318
+ constructor(device, props) {
319
+ super(device, props);
320
+ this.device = device;
739
321
  }
740
- initTestCase(testCase) {
741
- super.initTestCase(testCase);
742
- if (!testCase.goldenImage) {
743
- throw new Error(`Test case ${testCase.name} does not have golden image`);
744
- }
322
+ end() {
745
323
  }
746
- shouldRender() {
747
- return !this.isDiffing;
324
+ pushDebugGroup(groupLabel) {
748
325
  }
749
- async assert(testCase) {
750
- var _a;
751
- if (this.isDiffing) {
752
- return;
753
- }
754
- this.isDiffing = true;
755
- const canvas = (_a = this._animationProps) == null ? void 0 : _a.canvas;
756
- if (!(canvas instanceof HTMLCanvasElement)) {
757
- throw new Error("canvas");
758
- }
759
- const diffOptions = {
760
- ...this.testOptions.imageDiffOptions,
761
- ...testCase.imageDiffOptions,
762
- goldenImage: testCase.goldenImage,
763
- region: getBoundingBoxInPage(canvas)
764
- };
765
- const result = await globalThis.browserTestDriver_captureAndDiffScreen(diffOptions);
766
- if (result.success) {
767
- this._pass(result);
768
- } else {
769
- this._fail(result);
770
- }
771
- this.isDiffing = false;
772
- this._next();
326
+ popDebugGroup() {
773
327
  }
774
- };
775
-
776
- // dist/performance-test-runner.js
777
- var import_stats = require("@probe.gl/stats");
778
- var PerformanceTestRunner = class extends TestRunner {
779
- _stats = null;
780
- _fps = null;
781
- constructor(props) {
782
- super(props);
783
- Object.assign(this.testOptions, {
784
- maxFramesToRender: 60,
785
- targetFPS: 50
786
- });
328
+ insertDebugMarker(markerLabel) {
787
329
  }
788
- initTestCase(testCase) {
789
- super.initTestCase(testCase);
790
- this._stats = new import_stats.Stats({ id: testCase.name });
791
- this._fps = this._stats.get("fps");
330
+ setParameters(parameters = {}) {
792
331
  }
793
- shouldRender(animationProps) {
794
- var _a, _b;
795
- (_a = this._fps) == null ? void 0 : _a.timeEnd();
796
- (_b = this._fps) == null ? void 0 : _b.timeStart();
797
- if (this._fps.count > this.testOptions.maxFramesToRender) {
798
- animationProps.done();
799
- }
800
- return true;
332
+ beginOcclusionQuery(queryIndex) {
801
333
  }
802
- assert(testCase) {
803
- var _a, _b;
804
- const targetFPS = testCase.targetFPS || this.testOptions.targetFPS;
805
- const count = (_a = this._fps) == null ? void 0 : _a.count;
806
- const fps = ((_b = this._fps) == null ? void 0 : _b.getHz()) || 0;
807
- if (fps >= targetFPS) {
808
- this._pass({ fps, framesRendered: count });
809
- } else {
810
- this._fail({ fps, framesRendered: count });
811
- }
812
- this._next();
334
+ endOcclusionQuery() {
813
335
  }
814
336
  };
815
337
 
816
- // dist/null-device/null-device.js
817
- var import_core18 = require("@luma.gl/core");
818
-
819
- // dist/null-device/null-device-info.js
820
- var NullDeviceInfo = {
821
- type: "unknown",
822
- gpu: "software",
823
- gpuType: "unknown",
824
- gpuBackend: "unknown",
825
- vendor: "no one",
826
- renderer: "none",
827
- version: "1.0",
828
- shadingLanguage: "glsl",
829
- shadingLanguageVersion: 300
830
- };
831
-
832
- // dist/null-device/null-device-features.js
833
- var import_core4 = require("@luma.gl/core");
834
- var NullDeviceLimits = class extends import_core4.DeviceLimits {
835
- maxTextureDimension1D = 0;
836
- maxTextureDimension2D = 2048;
837
- maxTextureDimension3D = 256;
838
- maxTextureArrayLayers = 256;
839
- maxBindGroups = 0;
840
- maxDynamicUniformBuffersPerPipelineLayout = 0;
841
- maxDynamicStorageBuffersPerPipelineLayout = 0;
842
- maxSampledTexturesPerShaderStage = 8;
843
- maxSamplersPerShaderStage = 16;
844
- maxStorageBuffersPerShaderStage = 0;
845
- maxStorageTexturesPerShaderStage = 0;
846
- maxUniformBuffersPerShaderStage = 20;
847
- maxUniformBufferBindingSize = 16384;
848
- maxStorageBufferBindingSize = 0;
849
- minUniformBufferOffsetAlignment = 0;
850
- minStorageBufferOffsetAlignment = 0;
851
- maxVertexBuffers = 16;
852
- maxVertexAttributes = 16;
853
- maxVertexBufferArrayStride = 2048;
854
- maxInterStageShaderComponents = 60;
855
- maxComputeWorkgroupStorageSize = 0;
856
- maxComputeInvocationsPerWorkgroup = 0;
857
- maxComputeWorkgroupSizeX = 0;
858
- maxComputeWorkgroupSizeY = 0;
859
- maxComputeWorkgroupSizeZ = 0;
860
- maxComputeWorkgroupsPerDimension = 0;
861
- };
862
-
863
- // dist/null-device/null-canvas-context.js
864
- var import_core6 = require("@luma.gl/core");
865
-
866
- // dist/null-device/resources/null-framebuffer.js
867
- var import_core5 = require("@luma.gl/core");
868
- var NullFramebuffer = class extends import_core5.Framebuffer {
338
+ // dist/null-device/resources/null-render-pipeline.js
339
+ var import_core12 = require("@luma.gl/core");
340
+ var NullRenderPipeline = class extends import_core12.RenderPipeline {
869
341
  device;
870
- colorAttachments = [];
871
- depthStencilAttachment = null;
342
+ vs;
343
+ fs;
344
+ uniforms = {};
345
+ bindings = {};
872
346
  constructor(device, props) {
873
347
  super(device, props);
874
348
  this.device = device;
349
+ this.vs = props.vs;
350
+ this.fs = props.fs;
351
+ this.shaderLayout = props.shaderLayout || {
352
+ attributes: [],
353
+ bindings: [],
354
+ uniforms: []
355
+ };
875
356
  }
876
- };
877
-
878
- // dist/null-device/null-canvas-context.js
879
- var NullCanvasContext = class extends import_core6.CanvasContext {
880
- device;
881
- format = "rgba8unorm";
882
- depthStencilFormat = "depth24plus";
883
- presentationSize;
884
- _framebuffer = null;
885
- constructor(device, props) {
886
- super(props);
887
- this.device = device;
888
- this.presentationSize = [-1, -1];
889
- this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
890
- this.update();
891
- }
892
- getCurrentFramebuffer() {
893
- this.update();
894
- this._framebuffer = this._framebuffer || new NullFramebuffer(this.device, { handle: null });
895
- return this._framebuffer;
896
- }
897
- /** Resizes and updates render targets if necessary */
898
- update() {
899
- const size = this.getPixelSize();
900
- const sizeChanged = size[0] !== this.presentationSize[0] || size[1] !== this.presentationSize[1];
901
- if (sizeChanged) {
902
- this.presentationSize = size;
903
- this.resize();
904
- }
905
- }
906
- resize(options) {
907
- if (this.canvas) {
908
- const devicePixelRatio = this.getDevicePixelRatio(options == null ? void 0 : options.useDevicePixels);
909
- this.setDevicePixelRatio(devicePixelRatio, options);
910
- return;
911
- }
357
+ setBindings(bindings) {
358
+ Object.assign(this.bindings, bindings);
912
359
  }
913
- getDrawingBufferSize() {
914
- return [this.width, this.height];
360
+ setUniformsWebGL(uniforms) {
361
+ Object.assign(this.uniforms, uniforms);
915
362
  }
916
- commit() {
363
+ draw(options) {
364
+ const { renderPass, vertexArray } = options;
365
+ vertexArray.bindBeforeRender(renderPass);
366
+ vertexArray.unbindAfterRender(renderPass);
367
+ return true;
917
368
  }
918
369
  };
919
370
 
920
- // dist/null-device/resources/null-buffer.js
921
- var import_core7 = require("@luma.gl/core");
922
- var NullBuffer = class extends import_core7.Buffer {
371
+ // dist/null-device/resources/null-vertex-array.js
372
+ var import_core13 = require("@luma.gl/core");
373
+ var NullVertexArray = class extends import_core13.VertexArray {
923
374
  device;
924
- byteLength;
925
- constructor(device, props = {}) {
375
+ // Create a VertexArray
376
+ constructor(device, props) {
926
377
  super(device, props);
927
378
  this.device = device;
928
- const byteOffset = props.byteOffset || 0;
929
- const byteLength = props.byteLength ?? (props.data ? props.data.byteLength + byteOffset : 0);
930
- this.byteLength = byteLength;
931
- this.trackAllocatedMemory(byteLength);
932
379
  }
933
- destroy() {
934
- if (!this.destroyed) {
935
- super.destroy();
936
- this.trackDeallocatedMemory();
380
+ setIndexBuffer(indexBuffer) {
381
+ this.indexBuffer = indexBuffer;
382
+ }
383
+ /** Set a location in vertex attributes array to a buffer, enables the location, sets divisor */
384
+ setBuffer(location, attributeBuffer) {
385
+ const attributeInfo = this.attributeInfos[location];
386
+ if (!attributeInfo) {
387
+ throw new Error(`Unknown attribute location ${location}`);
937
388
  }
389
+ this.attributes[location] = attributeBuffer;
390
+ }
391
+ bindBeforeRender() {
938
392
  }
939
- async readAsync(byteOffset = 0, byteLength) {
940
- byteLength = byteLength ?? this.byteLength - byteOffset;
941
- return new Uint8Array(byteLength);
393
+ unbindAfterRender() {
942
394
  }
943
- write(data, byteOffset = 0) {
395
+ setConstantWebGL(location, value) {
944
396
  }
945
397
  };
946
398
 
947
- // dist/null-device/resources/null-shader.js
948
- var import_core8 = require("@luma.gl/core");
949
- var NullShader = class extends import_core8.Shader {
399
+ // dist/null-device/resources/null-transform-feedback.js
400
+ var import_core14 = require("@luma.gl/core");
401
+ var NullTransformFeedback = class extends import_core14.TransformFeedback {
950
402
  device;
403
+ layout;
404
+ buffers = {};
951
405
  constructor(device, props) {
952
406
  super(device, props);
953
407
  this.device = device;
408
+ this.layout = this.props.layout;
409
+ if (props.buffers) {
410
+ this.setBuffers(props.buffers);
411
+ }
412
+ Object.seal(this);
954
413
  }
955
- async getCompilationInfo() {
956
- return [];
414
+ begin(topology = "point-list") {
415
+ }
416
+ end() {
417
+ }
418
+ setBuffers(buffers) {
419
+ this.buffers = {};
420
+ for (const bufferName in buffers) {
421
+ this.setBuffer(bufferName, buffers[bufferName]);
422
+ }
423
+ }
424
+ setBuffer(locationOrName, bufferOrRange) {
425
+ this.buffers[locationOrName] = bufferOrRange;
426
+ }
427
+ getBuffer(locationOrName) {
428
+ return this.buffers[locationOrName] || null;
957
429
  }
958
430
  };
959
431
 
960
- // dist/null-device/resources/null-command-buffer.js
961
- var import_core9 = require("@luma.gl/core");
962
- var NullCommandEncoder = class extends import_core9.CommandEncoder {
432
+ // dist/null-device/resources/null-query-set.js
433
+ var import_core15 = require("@luma.gl/core");
434
+ var NullQuerySet = class extends import_core15.QuerySet {
963
435
  device;
964
436
  constructor(device, props) {
965
437
  super(device, props);
966
438
  this.device = device;
967
439
  }
968
- finish() {
440
+ };
441
+
442
+ // dist/null-device/null-device.js
443
+ var NullDevice = class extends import_core16.Device {
444
+ static isSupported() {
445
+ return true;
969
446
  }
970
- copyBufferToBuffer(options) {
447
+ type = "unknown";
448
+ handle = null;
449
+ preferredColorFormat = "rgba8unorm";
450
+ preferredDepthFormat = "depth24plus";
451
+ features = new import_core16.DeviceFeatures([], this.props._disabledFeatures);
452
+ limits = new NullDeviceLimits();
453
+ info = NullDeviceInfo;
454
+ canvasContext;
455
+ lost;
456
+ constructor(props) {
457
+ super({ ...props, id: props.id || "null-device" });
458
+ const canvasContextProps = props.createCanvasContext === true ? {} : props.createCanvasContext;
459
+ this.canvasContext = new NullCanvasContext(this, canvasContextProps);
460
+ this.lost = new Promise((resolve) => {
461
+ });
971
462
  }
972
- copyBufferToTexture(options) {
463
+ /**
464
+ * Destroys the context
465
+ * @note Has no effect for null contexts
466
+ */
467
+ destroy() {
973
468
  }
974
- copyTextureToBuffer(options) {
469
+ get isLost() {
470
+ return false;
975
471
  }
976
- copyTextureToTexture(options) {
472
+ // IMPLEMENTATION OF ABSTRACT DEVICE
473
+ createCanvasContext(props) {
474
+ return new NullCanvasContext(this, props);
977
475
  }
978
- pushDebugGroup(groupLabel) {
476
+ createBuffer(props) {
477
+ const newProps = this._normalizeBufferProps(props);
478
+ return new NullBuffer(this, newProps);
979
479
  }
980
- popDebugGroup() {
480
+ getDefaultRenderPass() {
481
+ return new NullRenderPass(this, {});
981
482
  }
982
- insertDebugMarker(markerLabel) {
483
+ createTexture(props) {
484
+ return new NullTexture(this, props);
983
485
  }
984
- resolveQuerySet(querySet) {
486
+ createExternalTexture(props) {
487
+ throw new Error("createExternalTexture() not implemented");
488
+ }
489
+ createSampler(props) {
490
+ return new NullSampler(this, props);
491
+ }
492
+ createShader(props) {
493
+ return new NullShader(this, props);
494
+ }
495
+ createFramebuffer(props) {
496
+ return new NullFramebuffer(this, props);
497
+ }
498
+ createVertexArray(props) {
499
+ return new NullVertexArray(this, props);
500
+ }
501
+ createTransformFeedback(props) {
502
+ return new NullTransformFeedback(this, props);
503
+ }
504
+ createQuerySet(props) {
505
+ return new NullQuerySet(this, props);
506
+ }
507
+ createRenderPipeline(props) {
508
+ return new NullRenderPipeline(this, props);
509
+ }
510
+ beginRenderPass(props) {
511
+ return new NullRenderPass(this, props);
512
+ }
513
+ createComputePipeline(props) {
514
+ throw new Error("ComputePipeline not supported in WebGL");
515
+ }
516
+ beginComputePass(props) {
517
+ throw new Error("ComputePass not supported in WebGL");
518
+ }
519
+ createCommandEncoder(props = {}) {
520
+ return new NullCommandEncoder(this, props);
521
+ }
522
+ submit() {
523
+ }
524
+ setParametersWebGL(parameters) {
525
+ }
526
+ getParametersWebGL(parameters) {
527
+ }
528
+ withParametersWebGL(parameters, func) {
529
+ const { nocatch = true } = parameters;
530
+ let value;
531
+ if (nocatch) {
532
+ return func();
533
+ }
534
+ try {
535
+ value = func();
536
+ } catch {
537
+ }
538
+ return value;
539
+ }
540
+ _getDeviceSpecificTextureFormatCapabilities(format) {
541
+ return format;
985
542
  }
986
543
  };
987
544
 
988
- // dist/null-device/resources/null-sampler.js
989
- var import_core10 = require("@luma.gl/core");
990
- var NullSampler = class extends import_core10.Sampler {
991
- device;
992
- constructor(device, props) {
993
- super(device, props);
994
- this.device = device;
545
+ // dist/null-device/null-adapter.js
546
+ var NullAdapter = class extends import_core17.Adapter {
547
+ /** type of device's created by this adapter */
548
+ type = "unknown";
549
+ constructor() {
550
+ super();
551
+ NullDevice.adapter = this;
552
+ }
553
+ /** Check if WebGPU is available */
554
+ isSupported() {
555
+ return true;
556
+ }
557
+ async attach(handle) {
558
+ return new NullDevice({});
559
+ }
560
+ async create(props = {}) {
561
+ return new NullDevice(props);
995
562
  }
996
563
  };
564
+ var nullAdapter = new NullAdapter();
997
565
 
998
- // dist/null-device/resources/null-texture.js
999
- var import_core12 = require("@luma.gl/core");
1000
-
1001
- // dist/null-device/resources/null-texture-view.js
1002
- var import_core11 = require("@luma.gl/core");
1003
- var NullTextureView = class extends import_core11.TextureView {
1004
- device;
1005
- texture;
1006
- constructor(device, props) {
1007
- super(device, { ...import_core11.Texture.defaultProps, ...props });
1008
- this.device = device;
1009
- this.texture = props.texture;
1010
- }
566
+ // dist/create-test-device.js
567
+ var DEFAULT_CANVAS_CONTEXT_PROPS = {
568
+ width: 1,
569
+ height: 1
570
+ };
571
+ var withResolvers = () => {
572
+ let resolve;
573
+ let reject;
574
+ const promise = new Promise((_resolve, _reject) => {
575
+ resolve = _resolve;
576
+ reject = _reject;
577
+ });
578
+ return { promise, resolve, reject };
1011
579
  };
580
+ var nullDevicePromise = makeNullTestDevice();
581
+ var webglDevicePromise = makeWebGLTestDevice();
582
+ var webgpuDevicePromise = makeWebGPUTestDevice();
583
+ async function getTestDevices(types = ["webgl", "webgpu"]) {
584
+ return [await getNullTestDevice(), await getWebGLTestDevice(), await getWebGPUTestDevice()].filter(Boolean).filter((device) => types.includes(device.type));
585
+ }
586
+ function getWebGPUTestDevice() {
587
+ return webgpuDevicePromise;
588
+ }
589
+ async function getWebGLTestDevice() {
590
+ return webglDevicePromise;
591
+ }
592
+ async function getNullTestDevice() {
593
+ return nullDevicePromise;
594
+ }
595
+ async function makeWebGPUTestDevice() {
596
+ const webgpuDeviceResolvers = withResolvers();
597
+ try {
598
+ const webgpuDevice = await import_core18.luma.createDevice({
599
+ id: "webgpu-test-device",
600
+ type: "webgpu",
601
+ adapters: [import_webgpu2.webgpuAdapter],
602
+ createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
603
+ debug: true
604
+ });
605
+ webgpuDeviceResolvers.resolve(webgpuDevice);
606
+ } catch (error) {
607
+ import_core18.log.error(String(error))();
608
+ webgpuDeviceResolvers.resolve(null);
609
+ }
610
+ return webgpuDeviceResolvers.promise;
611
+ }
612
+ async function makeWebGLTestDevice() {
613
+ const webglDeviceResolvers = withResolvers();
614
+ try {
615
+ const webglDevice3 = await import_core18.luma.createDevice({
616
+ id: "webgl-test-device",
617
+ type: "webgl",
618
+ adapters: [import_webgl2.webgl2Adapter],
619
+ createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
620
+ debug: true,
621
+ debugWebGL: true
622
+ });
623
+ webglDeviceResolvers.resolve(webglDevice3);
624
+ } catch (error) {
625
+ import_core18.log.error(String(error))();
626
+ webglDeviceResolvers.resolve(null);
627
+ }
628
+ return webglDeviceResolvers.promise;
629
+ }
630
+ async function makeNullTestDevice() {
631
+ const nullDeviceResolvers = withResolvers();
632
+ try {
633
+ const nullDevice = await import_core18.luma.createDevice({
634
+ id: "null-test-device",
635
+ type: "unknown",
636
+ adapters: [nullAdapter],
637
+ createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
638
+ debug: true,
639
+ debugWebGL: true
640
+ });
641
+ nullDeviceResolvers.resolve(nullDevice);
642
+ } catch (error) {
643
+ import_core18.log.error(String(error))();
644
+ nullDevicePromise = Promise.resolve(null);
645
+ }
646
+ return nullDeviceResolvers.promise;
647
+ }
1012
648
 
1013
- // dist/null-device/resources/null-texture.js
1014
- var NullTexture = class extends import_core12.Texture {
649
+ // dist/deprecated/classic-animation-loop.js
650
+ var import_core19 = require("@luma.gl/core");
651
+ var import_engine = require("@luma.gl/engine");
652
+ var import_env = require("@probe.gl/env");
653
+ var import_webgl3 = require("@luma.gl/webgl");
654
+ var isPage = (0, import_env.isBrowser)() && typeof document !== "undefined";
655
+ function getHTMLCanvasElement(canvas) {
656
+ return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement ? canvas : null;
657
+ }
658
+ var statIdCounter = 0;
659
+ var DEFAULT_CLASSIC_ANIMATION_LOOP_PROPS = {
660
+ onCreateDevice: (props) => import_core19.luma.createDevice({ ...props, debug: true }),
661
+ onCreateContext: void 0,
662
+ onAddHTML: void 0,
663
+ onInitialize: () => ({}),
664
+ onRender: () => {
665
+ },
666
+ onFinalize: () => {
667
+ },
668
+ onError: (error) => console.error(error),
669
+ // eslint-disable-line no-console
670
+ device: null,
671
+ // debug: true,
672
+ // view parameters
673
+ useDevicePixels: true,
674
+ autoResizeViewport: true,
675
+ autoResizeDrawingBuffer: true,
676
+ stats: import_core19.luma.stats.get(`animation-loop-${statIdCounter++}`),
677
+ // deprecated
678
+ // onCreateContext: (opts) => createGLContext(opts),
679
+ gl: void 0,
680
+ glOptions: {},
681
+ createFramebuffer: false
682
+ };
683
+ var ClassicAnimationLoop = class {
1015
684
  device;
1016
- sampler;
1017
- view;
1018
- constructor(device, props) {
1019
- var _a;
1020
- super(device, props);
1021
- this.device = device;
1022
- if (typeof ((_a = this.props) == null ? void 0 : _a.data) === "string") {
1023
- throw new Error("Texture2D: Loading textures from URLs is not supported");
685
+ canvas;
686
+ props;
687
+ animationProps;
688
+ // framebuffer: ClassicFramebuffer = null;
689
+ timeline = null;
690
+ stats;
691
+ cpuTime;
692
+ gpuTime;
693
+ frameRate;
694
+ display;
695
+ needsRedraw = "initialized";
696
+ _initialized = false;
697
+ _running = false;
698
+ _animationFrameId = null;
699
+ _pageLoadPromise = null;
700
+ _nextFramePromise = null;
701
+ _resolveNextFrame = null;
702
+ _cpuStartTime = 0;
703
+ // _gpuTimeQuery: Query | null = null;
704
+ /** @deprecated */
705
+ gl;
706
+ /*
707
+ */
708
+ constructor(props = {}) {
709
+ this.props = { ...DEFAULT_CLASSIC_ANIMATION_LOOP_PROPS, ...props };
710
+ props = this.props;
711
+ let { useDevicePixels = true } = this.props;
712
+ if ("useDevicePixelRatio" in props) {
713
+ import_core19.log.deprecated("useDevicePixelRatio", "useDevicePixels")();
714
+ useDevicePixels = props.useDevicePixelRatio;
1024
715
  }
1025
- this.initialize(this.props);
1026
- Object.seal(this);
716
+ this.device = props.device;
717
+ this.gl = this.device && this.device.gl || props.gl;
718
+ this.stats = props.stats;
719
+ this.cpuTime = this.stats.get("CPU Time");
720
+ this.gpuTime = this.stats.get("GPU Time");
721
+ this.frameRate = this.stats.get("Frame Rate");
722
+ this.setProps({
723
+ autoResizeViewport: props.autoResizeViewport,
724
+ autoResizeDrawingBuffer: props.autoResizeDrawingBuffer,
725
+ useDevicePixels
726
+ });
727
+ this.start = this.start.bind(this);
728
+ this.stop = this.stop.bind(this);
729
+ this._onMousemove = this._onMousemove.bind(this);
730
+ this._onMouseleave = this._onMouseleave.bind(this);
1027
731
  }
1028
732
  destroy() {
1029
- if (!this.destroyed) {
1030
- super.destroy();
1031
- this.trackDeallocatedMemory("Texture");
1032
- }
1033
- }
1034
- createView(props) {
1035
- return new NullTextureView(this.device, { ...props, texture: this });
1036
- }
1037
- setTexture1DData(data) {
1038
- throw new Error("not implemented");
1039
- }
1040
- setTexture2DData(lodData, depth, target) {
1041
- throw new Error("not implemented");
733
+ this.stop();
734
+ this._setDisplay(null);
1042
735
  }
1043
- setTexture3DData(lodData, depth, target) {
1044
- throw new Error("not implemented");
736
+ /** @deprecated Use .destroy() */
737
+ delete() {
738
+ this.destroy();
1045
739
  }
1046
- setTextureCubeData(data, depth) {
1047
- throw new Error("not implemented");
740
+ setNeedsRedraw(reason) {
741
+ this.needsRedraw = this.needsRedraw || reason;
742
+ return this;
1048
743
  }
1049
- setTextureArrayData(data) {
1050
- throw new Error("not implemented");
744
+ setProps(props) {
745
+ if ("autoResizeViewport" in props) {
746
+ this.props.autoResizeViewport = props.autoResizeViewport;
747
+ }
748
+ if ("autoResizeDrawingBuffer" in props) {
749
+ this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer;
750
+ }
751
+ if ("useDevicePixels" in props) {
752
+ this.props.useDevicePixels = props.useDevicePixels;
753
+ }
754
+ return this;
1051
755
  }
1052
- setTextureCubeArrayData(data) {
1053
- throw new Error("not implemented");
756
+ start(opts = {}) {
757
+ this._start(opts);
758
+ return this;
1054
759
  }
1055
- initialize(props = {}) {
1056
- const data = props.data;
1057
- if (data instanceof Promise) {
1058
- data.then((resolvedImageData) => this.initialize(Object.assign({}, props, {
1059
- pixels: resolvedImageData,
1060
- data: resolvedImageData
1061
- })));
760
+ /** Starts a render loop if not already running */
761
+ async _start(props) {
762
+ if (this._running) {
1062
763
  return this;
1063
764
  }
1064
- this.setImageData(props);
1065
- this.setSampler(props.sampler);
1066
- this.view = new NullTextureView(this.device, {
1067
- ...props,
1068
- texture: this,
1069
- mipLevelCount: 1,
1070
- arrayLayerCount: 1
1071
- });
1072
- return this;
765
+ this._running = true;
766
+ try {
767
+ await this._getPageLoadPromise();
768
+ if (!this._running) {
769
+ return null;
770
+ }
771
+ let appContext;
772
+ if (!this._initialized) {
773
+ this._initialized = true;
774
+ await this._createDevice(props);
775
+ this._initialize(props);
776
+ appContext = await this.onInitialize(this.animationProps);
777
+ this._addCallbackData(appContext || {});
778
+ }
779
+ if (!this._running) {
780
+ return null;
781
+ }
782
+ if (appContext !== false) {
783
+ this._cancelAnimationFrame();
784
+ this._requestAnimationFrame();
785
+ }
786
+ return this;
787
+ } catch (error) {
788
+ this.props.onError(error);
789
+ return null;
790
+ }
1073
791
  }
1074
- setSampler(sampler = {}) {
1075
- if (sampler instanceof NullSampler) {
1076
- this.sampler = sampler;
1077
- } else {
1078
- this.sampler = new NullSampler(this.device, sampler);
792
+ /** Explicitly draw a frame */
793
+ redraw() {
794
+ if (this.isContextLost()) {
795
+ return this;
796
+ }
797
+ this._beginTimers();
798
+ this._setupFrame();
799
+ this._updateCallbackData();
800
+ this._renderFrame(this.animationProps);
801
+ this._clearNeedsRedraw();
802
+ if (this._resolveNextFrame) {
803
+ this._resolveNextFrame(this);
804
+ this._nextFramePromise = null;
805
+ this._resolveNextFrame = null;
1079
806
  }
807
+ this._endTimers();
1080
808
  return this;
1081
809
  }
1082
- setImageData(options) {
1083
- this.trackDeallocatedMemory("Texture");
1084
- const { data } = options;
1085
- if (data && data.byteLength) {
1086
- this.trackAllocatedMemory(data.byteLength, "Texture");
1087
- } else {
1088
- const bytesPerPixel = 4;
1089
- this.trackAllocatedMemory(this.width * this.height * bytesPerPixel, "Texture");
810
+ // Stops a render loop if already running, finalizing
811
+ stop() {
812
+ if (this._running) {
813
+ this._finalizeCallbackData();
814
+ this._cancelAnimationFrame();
815
+ this._nextFramePromise = null;
816
+ this._resolveNextFrame = null;
817
+ this._running = false;
1090
818
  }
1091
- const width = options.width ?? data.width;
1092
- const height = options.height ?? data.height;
1093
- this.width = width;
1094
- this.height = height;
1095
819
  return this;
1096
820
  }
1097
- setSubImageData(options) {
1098
- }
1099
- };
1100
-
1101
- // dist/null-device/resources/null-render-pass.js
1102
- var import_core13 = require("@luma.gl/core");
1103
- var NullRenderPass = class extends import_core13.RenderPass {
1104
- device;
1105
- constructor(device, props) {
1106
- super(device, props);
1107
- this.device = device;
1108
- }
1109
- end() {
821
+ attachTimeline(timeline) {
822
+ this.timeline = timeline;
823
+ return this.timeline;
1110
824
  }
1111
- pushDebugGroup(groupLabel) {
825
+ detachTimeline() {
826
+ this.timeline = null;
1112
827
  }
1113
- popDebugGroup() {
828
+ waitForRender() {
829
+ this.setNeedsRedraw("waitForRender");
830
+ if (!this._nextFramePromise) {
831
+ this._nextFramePromise = new Promise((resolve) => {
832
+ this._resolveNextFrame = resolve;
833
+ });
834
+ }
835
+ return this._nextFramePromise;
1114
836
  }
1115
- insertDebugMarker(markerLabel) {
837
+ async toDataURL() {
838
+ var _a;
839
+ this.setNeedsRedraw("toDataURL");
840
+ await this.waitForRender();
841
+ return (_a = getHTMLCanvasElement(this.gl.canvas)) == null ? void 0 : _a.toDataURL();
1116
842
  }
1117
- setParameters(parameters = {}) {
843
+ isContextLost() {
844
+ return this.gl.isContextLost();
1118
845
  }
1119
- beginOcclusionQuery(queryIndex) {
846
+ onCreateDevice(deviceProps) {
847
+ const { onCreateDevice } = this.props;
848
+ return onCreateDevice(deviceProps);
1120
849
  }
1121
- endOcclusionQuery() {
850
+ onInitialize(animationProps) {
851
+ const { onInitialize } = this.props;
852
+ return onInitialize(animationProps);
1122
853
  }
1123
- };
1124
-
1125
- // dist/null-device/resources/null-render-pipeline.js
1126
- var import_core14 = require("@luma.gl/core");
1127
- var NullRenderPipeline = class extends import_core14.RenderPipeline {
1128
- device;
1129
- vs;
1130
- fs;
1131
- uniforms = {};
1132
- bindings = {};
1133
- constructor(device, props) {
1134
- super(device, props);
1135
- this.device = device;
1136
- this.vs = props.vs;
1137
- this.fs = props.fs;
1138
- this.shaderLayout = props.shaderLayout || {
1139
- attributes: [],
1140
- bindings: [],
1141
- uniforms: []
1142
- };
854
+ onRender(animationProps) {
855
+ const { onRender } = this.props;
856
+ return onRender(animationProps);
1143
857
  }
1144
- setBindings(bindings) {
1145
- Object.assign(this.bindings, bindings);
858
+ onFinalize(animationProps) {
859
+ const { onFinalize } = this.props;
860
+ return onFinalize(animationProps);
1146
861
  }
1147
- setUniformsWebGL(uniforms) {
1148
- Object.assign(this.uniforms, uniforms);
862
+ // DEPRECATED/REMOVED METHODS
863
+ /** @deprecated Use .onCreateDevice() */
864
+ onCreateContext(props) {
865
+ const { onCreateContext } = this.props;
866
+ return onCreateContext(props);
1149
867
  }
1150
- draw(options) {
1151
- const { renderPass, vertexArray } = options;
1152
- vertexArray.bindBeforeRender(renderPass);
1153
- vertexArray.unbindAfterRender(renderPass);
1154
- return true;
868
+ /** @deprecated */
869
+ getHTMLControlValue(id, defaultValue = 1) {
870
+ const element = document.getElementById(id);
871
+ return element ? Number(element.value) : defaultValue;
1155
872
  }
1156
- };
1157
-
1158
- // dist/null-device/resources/null-vertex-array.js
1159
- var import_core15 = require("@luma.gl/core");
1160
- var NullVertexArray = class extends import_core15.VertexArray {
1161
- device;
1162
- // Create a VertexArray
1163
- constructor(device, props) {
1164
- super(device, props);
1165
- this.device = device;
873
+ // PRIVATE METHODS
874
+ _initialize(props) {
875
+ this._createFramebuffer();
876
+ this._startEventHandling();
877
+ this._initializeCallbackData();
878
+ this._updateCallbackData();
879
+ this._resizeCanvasDrawingBuffer();
880
+ this._resizeViewport();
1166
881
  }
1167
- setIndexBuffer(indexBuffer) {
1168
- this.indexBuffer = indexBuffer;
882
+ _getPageLoadPromise() {
883
+ if (!this._pageLoadPromise) {
884
+ this._pageLoadPromise = isPage ? new Promise((resolve, reject) => {
885
+ if (isPage && document.readyState === "complete") {
886
+ resolve(document);
887
+ return;
888
+ }
889
+ window.addEventListener("load", () => {
890
+ resolve(document);
891
+ });
892
+ }) : Promise.resolve({});
893
+ }
894
+ return this._pageLoadPromise;
1169
895
  }
1170
- /** Set a location in vertex attributes array to a buffer, enables the location, sets divisor */
1171
- setBuffer(location, attributeBuffer) {
1172
- const attributeInfo = this.attributeInfos[location];
1173
- if (!attributeInfo) {
1174
- throw new Error(`Unknown attribute location ${location}`);
896
+ _setDisplay(display) {
897
+ if (this.display) {
898
+ this.display.destroy();
899
+ this.display.animationLoop = null;
1175
900
  }
1176
- this.attributes[location] = attributeBuffer;
901
+ if (display) {
902
+ display.animationLoop = this;
903
+ }
904
+ this.display = display;
1177
905
  }
1178
- bindBeforeRender() {
906
+ _requestAnimationFrame() {
907
+ if (!this._running) {
908
+ return;
909
+ }
910
+ this._animationFrameId = (0, import_engine.requestAnimationFramePolyfill)(this._animationFrame.bind(this));
1179
911
  }
1180
- unbindAfterRender() {
912
+ _cancelAnimationFrame() {
913
+ if (this._animationFrameId !== null) {
914
+ return;
915
+ }
916
+ (0, import_engine.cancelAnimationFramePolyfill)(this._animationFrameId);
917
+ this._animationFrameId = null;
1181
918
  }
1182
- setConstantWebGL(location, value) {
919
+ _animationFrame() {
920
+ if (!this._running) {
921
+ return;
922
+ }
923
+ this.redraw();
924
+ this._requestAnimationFrame();
1183
925
  }
1184
- };
1185
-
1186
- // dist/null-device/resources/null-transform-feedback.js
1187
- var import_core16 = require("@luma.gl/core");
1188
- var NullTransformFeedback = class extends import_core16.TransformFeedback {
1189
- device;
1190
- layout;
1191
- buffers = {};
1192
- constructor(device, props) {
1193
- super(device, props);
1194
- this.device = device;
1195
- this.layout = this.props.layout;
1196
- if (props.buffers) {
1197
- this.setBuffers(props.buffers);
926
+ // Called on each frame, can be overridden to call onRender multiple times
927
+ // to support e.g. stereoscopic rendering
928
+ _renderFrame(props) {
929
+ if (this.display) {
930
+ this.display._renderFrame(props);
931
+ return;
1198
932
  }
1199
- Object.seal(this);
933
+ this.onRender(props);
1200
934
  }
1201
- begin(topology = "point-list") {
935
+ _clearNeedsRedraw() {
936
+ this.needsRedraw = null;
1202
937
  }
1203
- end() {
938
+ _setupFrame() {
939
+ this._resizeCanvasDrawingBuffer();
940
+ this._resizeViewport();
941
+ this._resizeFramebuffer();
1204
942
  }
1205
- setBuffers(buffers) {
1206
- this.buffers = {};
1207
- for (const bufferName in buffers) {
1208
- this.setBuffer(bufferName, buffers[bufferName]);
1209
- }
943
+ /* eslint-disable @typescript-eslint/unbound-method */
944
+ // Initialize the object that will be passed to app callbacks
945
+ _initializeCallbackData() {
946
+ this.animationProps = {
947
+ device: this.device,
948
+ gl: this.gl,
949
+ stop: this.stop,
950
+ canvas: this.gl.canvas,
951
+ // Initial values
952
+ useDevicePixels: this.props.useDevicePixels,
953
+ needsRedraw: null,
954
+ // Animation props
955
+ startTime: Date.now(),
956
+ engineTime: 0,
957
+ tick: 0,
958
+ tock: 0,
959
+ timeline: this.timeline,
960
+ // @ts-ignore
961
+ animationLoop: this,
962
+ // Timeline time for back compatibility
963
+ time: 0,
964
+ // Experimental
965
+ _mousePosition: null,
966
+ // Event props
967
+ /** @deprecated */
968
+ // framebuffer: this.framebuffer,
969
+ /** @deprecated */
970
+ _timeline: this.timeline,
971
+ /** @deprecated */
972
+ _loop: this,
973
+ /** @deprecated */
974
+ _animationLoop: this
975
+ };
1210
976
  }
1211
- setBuffer(locationOrName, bufferOrRange) {
1212
- this.buffers[locationOrName] = bufferOrRange;
977
+ // Update the context object that will be passed to app callbacks
978
+ _updateCallbackData() {
979
+ const { width, height, aspect } = this._getSizeAndAspect();
980
+ if (width !== this.animationProps.width || height !== this.animationProps.height) {
981
+ this.setNeedsRedraw("drawing buffer resized");
982
+ }
983
+ if (aspect !== this.animationProps.aspect) {
984
+ this.setNeedsRedraw("drawing buffer aspect changed");
985
+ }
986
+ this.animationProps.width = width;
987
+ this.animationProps.height = height;
988
+ this.animationProps.aspect = aspect;
989
+ this.animationProps.needsRedraw = this.needsRedraw;
990
+ this.animationProps.engineTime = Date.now() - this.animationProps.startTime;
991
+ if (this.timeline) {
992
+ this.timeline.update(this.animationProps.engineTime);
993
+ }
994
+ this.animationProps.tick = Math.floor(this.animationProps.time / 1e3 * 60);
995
+ this.animationProps.tock++;
996
+ this.animationProps.time = this.timeline ? this.timeline.getTime() : this.animationProps.engineTime;
1213
997
  }
1214
- getBuffer(locationOrName) {
1215
- return this.buffers[locationOrName] || null;
998
+ _finalizeCallbackData() {
999
+ this.onFinalize(this.animationProps);
1216
1000
  }
1217
- };
1218
-
1219
- // dist/null-device/resources/null-query-set.js
1220
- var import_core17 = require("@luma.gl/core");
1221
- var NullQuerySet = class extends import_core17.QuerySet {
1222
- device;
1223
- constructor(device, props) {
1224
- super(device, props);
1225
- this.device = device;
1001
+ /** Add application's data to the app context object */
1002
+ _addCallbackData(appContext) {
1003
+ if (typeof appContext === "object" && appContext !== null) {
1004
+ this.animationProps = Object.assign({}, this.animationProps, appContext);
1005
+ }
1226
1006
  }
1227
- };
1228
-
1229
- // dist/null-device/null-device.js
1230
- var _NullDevice = class extends import_core18.Device {
1231
- static isSupported() {
1232
- return true;
1007
+ /** Either uses supplied or existing context, or calls provided callback to create one */
1008
+ async _createDevice(props) {
1009
+ const deviceProps = { ...this.props, ...props, ...this.props.glOptions };
1010
+ this.device = await this.onCreateDevice(deviceProps);
1011
+ this.gl = this.device.gl;
1012
+ (0, import_webgl3.resetGLParameters)(this.gl);
1013
+ this._createInfoDiv();
1233
1014
  }
1234
- type = "unknown";
1235
- features = new import_core18.DeviceFeatures([], this.props.disabledFeatures);
1236
- limits = new NullDeviceLimits();
1237
- info = NullDeviceInfo;
1238
- canvasContext;
1239
- lost;
1240
- static attach(handle) {
1241
- return new _NullDevice({});
1015
+ _createInfoDiv() {
1016
+ const canvas = getHTMLCanvasElement(this.gl.canvas);
1017
+ if (canvas && this.props.onAddHTML) {
1018
+ const wrapperDiv = document.createElement("div");
1019
+ document.body.appendChild(wrapperDiv);
1020
+ wrapperDiv.style.position = "relative";
1021
+ const div = document.createElement("div");
1022
+ div.style.position = "absolute";
1023
+ div.style.left = "10px";
1024
+ div.style.bottom = "10px";
1025
+ div.style.width = "300px";
1026
+ div.style.background = "white";
1027
+ if (canvas) {
1028
+ wrapperDiv.appendChild(canvas);
1029
+ }
1030
+ wrapperDiv.appendChild(div);
1031
+ const html = this.props.onAddHTML(div);
1032
+ if (html) {
1033
+ div.innerHTML = html;
1034
+ }
1035
+ }
1242
1036
  }
1243
- static async create(props = {}) {
1244
- if (typeof props.canvas === "string") {
1245
- await import_core18.CanvasContext.pageLoaded;
1037
+ _getSizeAndAspect() {
1038
+ const width = this.gl.drawingBufferWidth;
1039
+ const height = this.gl.drawingBufferHeight;
1040
+ let aspect = 1;
1041
+ const canvas = getHTMLCanvasElement(this.gl.canvas);
1042
+ if (canvas && canvas.clientHeight) {
1043
+ aspect = canvas.clientWidth / canvas.clientHeight;
1044
+ } else if (width > 0 && height > 0) {
1045
+ aspect = width / height;
1246
1046
  }
1247
- return new _NullDevice(props);
1047
+ return { width, height, aspect };
1248
1048
  }
1249
- constructor(props) {
1250
- super({ ...props, id: props.id || "null-device" });
1251
- this.canvasContext = new NullCanvasContext(this, props);
1252
- this.lost = new Promise((resolve) => {
1253
- });
1254
- this.canvasContext.resize();
1049
+ /** Default viewport setup */
1050
+ _resizeViewport() {
1051
+ if (this.props.autoResizeViewport) {
1052
+ this.gl.viewport(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight);
1053
+ }
1255
1054
  }
1256
1055
  /**
1257
- * Destroys the context
1258
- * @note Has no effect for WebGL browser contexts, there is no browser API for destroying contexts
1056
+ * Resize the render buffer of the canvas to match canvas client size
1057
+ * Optionally multiplying with devicePixel ratio
1259
1058
  */
1260
- destroy() {
1059
+ _resizeCanvasDrawingBuffer() {
1060
+ if (this.props.autoResizeDrawingBuffer) {
1061
+ this.device.canvasContext.resize({ useDevicePixels: this.props.useDevicePixels });
1062
+ }
1261
1063
  }
1262
- get isLost() {
1263
- return false;
1064
+ _beginTimers() {
1065
+ this.frameRate.timeEnd();
1066
+ this.frameRate.timeStart();
1067
+ this.cpuTime.timeStart();
1264
1068
  }
1265
- getSize() {
1266
- return [this.canvasContext.width, this.canvasContext.height];
1069
+ _endTimers() {
1070
+ this.cpuTime.timeEnd();
1267
1071
  }
1268
- isTextureFormatSupported(format) {
1269
- return true;
1072
+ // Event handling
1073
+ _startEventHandling() {
1074
+ const { canvas } = this.gl;
1075
+ if (canvas) {
1076
+ canvas.addEventListener("mousemove", this._onMousemove);
1077
+ canvas.addEventListener("mouseleave", this._onMouseleave);
1078
+ }
1270
1079
  }
1271
- isTextureFormatFilterable(format) {
1272
- return true;
1080
+ _onMousemove(e) {
1081
+ this.animationProps._mousePosition = [e.offsetX, e.offsetY];
1273
1082
  }
1274
- isTextureFormatRenderable(format) {
1275
- return true;
1083
+ _onMouseleave(e) {
1084
+ this.animationProps._mousePosition = null;
1276
1085
  }
1277
- // IMPLEMENTATION OF ABSTRACT DEVICE
1278
- createCanvasContext(props) {
1279
- return new NullCanvasContext(this, props);
1086
+ // Deprecated
1087
+ /** @deprecated */
1088
+ _createFramebuffer() {
1089
+ if (this.props.createFramebuffer) {
1090
+ }
1280
1091
  }
1281
- createBuffer(props) {
1282
- const newProps = this._getBufferProps(props);
1283
- return new NullBuffer(this, newProps);
1092
+ /** @deprecated */
1093
+ _resizeFramebuffer() {
1284
1094
  }
1285
- getDefaultRenderPass() {
1286
- return new NullRenderPass(this, {});
1095
+ };
1096
+
1097
+ // dist/test-runner.js
1098
+ var DEFAULT_TEST_CASE = {
1099
+ name: "Unnamed test",
1100
+ onInitialize: async () => {
1101
+ },
1102
+ onRender: ({ done }) => done(),
1103
+ onFinalize: () => {
1104
+ }
1105
+ };
1106
+ var DEFAULT_TEST_PROPS = {
1107
+ width: void 0,
1108
+ height: void 0,
1109
+ // test lifecycle callback
1110
+ onTestStart: (testCase) => console.log(`# ${testCase.name}`),
1111
+ onTestPass: (testCase, result) => console.log(`ok ${testCase.name} passed`),
1112
+ onTestFail: (testCase, error) => console.log(`not ok ${testCase.name} failed`),
1113
+ // milliseconds to wait for each test case before aborting
1114
+ timeout: 2e3,
1115
+ maxFramesToRender: void 0,
1116
+ imageDiffOptions: void 0
1117
+ };
1118
+ var TestRunner = class {
1119
+ device = webglDevice;
1120
+ props;
1121
+ isRunning = false;
1122
+ testOptions = { ...DEFAULT_TEST_PROPS };
1123
+ _animationProps;
1124
+ _animationLoop;
1125
+ _testCases = [];
1126
+ _testCaseData = null;
1127
+ _currentTestCase;
1128
+ _currentTestCaseStartTime;
1129
+ _currentTestCaseStartTick;
1130
+ // should be defined in snapshot-test-runner
1131
+ isDiffing = false;
1132
+ // @ts-expect-error
1133
+ isHeadless = Boolean(window.browserTestDriver_isHeadless);
1134
+ /**
1135
+ * props
1136
+ * AnimationLoop props
1137
+ */
1138
+ constructor(props = {}) {
1139
+ this.props = props;
1287
1140
  }
1288
- _createTexture(props) {
1289
- return new NullTexture(this, props);
1141
+ /**
1142
+ * Add testCase(s)
1143
+ */
1144
+ add(testCases) {
1145
+ if (!Array.isArray(testCases)) {
1146
+ testCases = [testCases];
1147
+ }
1148
+ for (const testCase of testCases) {
1149
+ this._testCases.push(testCase);
1150
+ }
1151
+ return this;
1290
1152
  }
1291
- createExternalTexture(props) {
1292
- throw new Error("createExternalTexture() not implemented");
1153
+ /**
1154
+ * Returns a promise that resolves when all the test cases are done
1155
+ */
1156
+ async run(options = {}) {
1157
+ this.testOptions = { ...this.testOptions, ...options };
1158
+ const device = await getWebGLTestDevice();
1159
+ return new Promise((resolve, reject) => {
1160
+ this._animationLoop = new ClassicAnimationLoop({
1161
+ ...this.props,
1162
+ device: this.device,
1163
+ onRender: this._onRender.bind(this),
1164
+ onFinalize: () => {
1165
+ this.isRunning = false;
1166
+ resolve();
1167
+ }
1168
+ });
1169
+ this._animationLoop.start(this.props);
1170
+ this.isRunning = true;
1171
+ this.isDiffing = false;
1172
+ this._currentTestCase = null;
1173
+ }).catch((error) => {
1174
+ this._fail({ error: error.message });
1175
+ });
1293
1176
  }
1294
- createSampler(props) {
1295
- return new NullSampler(this, props);
1177
+ /* Lifecycle methods for subclassing */
1178
+ initTestCase(testCase) {
1179
+ const { animationLoop } = testCase;
1180
+ if (animationLoop) {
1181
+ testCase.onInitialize = animationLoop.props.onInitialize.bind(animationLoop);
1182
+ testCase.onRender = animationLoop.props.onRender.bind(animationLoop);
1183
+ testCase.onFinalize = animationLoop.props.onFinalize.bind(animationLoop);
1184
+ }
1185
+ for (const key in DEFAULT_TEST_CASE) {
1186
+ testCase[key] = testCase[key] || DEFAULT_TEST_CASE[key];
1187
+ }
1296
1188
  }
1297
- createShader(props) {
1298
- return new NullShader(this, props);
1189
+ shouldRender(animationProps) {
1190
+ return true;
1299
1191
  }
1300
- createFramebuffer(props) {
1301
- return new NullFramebuffer(this, props);
1192
+ assert(testCase) {
1193
+ this._pass(testCase);
1194
+ this._next();
1302
1195
  }
1303
- createVertexArray(props) {
1304
- return new NullVertexArray(this, props);
1196
+ /* Utilities */
1197
+ _pass(result) {
1198
+ this.testOptions.onTestPass(this._currentTestCase, result);
1305
1199
  }
1306
- createTransformFeedback(props) {
1307
- return new NullTransformFeedback(this, props);
1200
+ _fail(result) {
1201
+ this.testOptions.onTestFail(this._currentTestCase, result);
1308
1202
  }
1309
- createQuerySet(props) {
1310
- return new NullQuerySet(this, props);
1203
+ _next() {
1204
+ this._nextTestCase();
1311
1205
  }
1312
- createRenderPipeline(props) {
1313
- return new NullRenderPipeline(this, props);
1206
+ /* Private methods */
1207
+ _onRender(animationProps) {
1208
+ this._animationProps = animationProps;
1209
+ const testCase = this._currentTestCase || this._nextTestCase();
1210
+ if (!testCase) {
1211
+ this._animationLoop.stop();
1212
+ return;
1213
+ }
1214
+ let isDone = false;
1215
+ const testCaseAnimationProps = {
1216
+ ...animationProps,
1217
+ ...this._testCaseData,
1218
+ // tick/time starts from 0 for each test case
1219
+ startTime: this._currentTestCaseStartTime,
1220
+ time: animationProps.time - this._currentTestCaseStartTime,
1221
+ tick: animationProps.tick - this._currentTestCaseStartTick,
1222
+ // called by the test case when it is done rendering and ready for capture and diff
1223
+ done: () => {
1224
+ isDone = true;
1225
+ }
1226
+ };
1227
+ if (this._testCaseData && this.shouldRender(testCaseAnimationProps)) {
1228
+ testCase.onRender(testCaseAnimationProps);
1229
+ }
1230
+ const timeout = testCase.timeout || this.testOptions.timeout;
1231
+ if (timeout && testCaseAnimationProps.time > timeout) {
1232
+ isDone = true;
1233
+ }
1234
+ if (isDone) {
1235
+ this.assert(testCase);
1236
+ }
1314
1237
  }
1315
- beginRenderPass(props) {
1316
- return new NullRenderPass(this, props);
1238
+ _nextTestCase() {
1239
+ const animationProps = this._animationProps;
1240
+ if (this._testCaseData) {
1241
+ for (const key in this._testCaseData) {
1242
+ const value = this._testCaseData[key];
1243
+ if (value && value.delete) {
1244
+ value.destroy();
1245
+ }
1246
+ }
1247
+ this._currentTestCase.onFinalize(Object.assign({}, animationProps, this._testCaseData));
1248
+ this.device.popState();
1249
+ this._currentTestCase = null;
1250
+ this._testCaseData = null;
1251
+ }
1252
+ const testCase = this._testCases.shift();
1253
+ if (testCase) {
1254
+ this._currentTestCase = testCase;
1255
+ this._currentTestCaseStartTime = animationProps.time;
1256
+ this._currentTestCaseStartTick = animationProps.tick;
1257
+ this.initTestCase(testCase);
1258
+ this.device.pushState();
1259
+ const initProps = {
1260
+ ...animationProps,
1261
+ // tick/time starts from 0 for each test case
1262
+ startTime: animationProps.time,
1263
+ time: 0,
1264
+ tick: 0
1265
+ };
1266
+ Promise.resolve(testCase.onInitialize(initProps)).then((userData) => {
1267
+ this._testCaseData = userData || {};
1268
+ });
1269
+ this.testOptions.onTestStart(testCase);
1270
+ }
1271
+ return testCase;
1317
1272
  }
1318
- createComputePipeline(props) {
1319
- throw new Error("ComputePipeline not supported in WebGL");
1273
+ };
1274
+
1275
+ // dist/utils/get-bounding-box.js
1276
+ function getBoundingBoxInPage(domElement) {
1277
+ const bbox = domElement.getBoundingClientRect();
1278
+ return {
1279
+ x: window.scrollX + bbox.x,
1280
+ y: window.scrollY + bbox.y,
1281
+ width: bbox.width,
1282
+ height: bbox.height
1283
+ };
1284
+ }
1285
+
1286
+ // dist/snapshot-test-runner.js
1287
+ var SnapshotTestRunner = class extends TestRunner {
1288
+ // should be defined here but hack access in TestRunner
1289
+ // private isDiffing: boolean = false;
1290
+ constructor(props) {
1291
+ super(props);
1292
+ this.testOptions.imageDiffOptions = {};
1320
1293
  }
1321
- beginComputePass(props) {
1322
- throw new Error("ComputePass not supported in WebGL");
1294
+ initTestCase(testCase) {
1295
+ super.initTestCase(testCase);
1296
+ if (!testCase.goldenImage) {
1297
+ throw new Error(`Test case ${testCase.name} does not have golden image`);
1298
+ }
1323
1299
  }
1324
- createCommandEncoder(props = {}) {
1325
- return new NullCommandEncoder(this, props);
1300
+ shouldRender() {
1301
+ return !this.isDiffing;
1326
1302
  }
1327
- submit() {
1303
+ async assert(testCase) {
1304
+ var _a;
1305
+ if (this.isDiffing) {
1306
+ return;
1307
+ }
1308
+ this.isDiffing = true;
1309
+ const canvas = (_a = this._animationProps) == null ? void 0 : _a.canvas;
1310
+ if (!(canvas instanceof HTMLCanvasElement)) {
1311
+ throw new Error("canvas");
1312
+ }
1313
+ const diffOptions = {
1314
+ ...this.testOptions.imageDiffOptions,
1315
+ ...testCase.imageDiffOptions,
1316
+ goldenImage: testCase.goldenImage,
1317
+ region: getBoundingBoxInPage(canvas)
1318
+ };
1319
+ const result = await globalThis.browserTestDriver_captureAndDiffScreen(diffOptions);
1320
+ if (result.success) {
1321
+ this._pass(result);
1322
+ } else {
1323
+ this._fail(result);
1324
+ }
1325
+ this.isDiffing = false;
1326
+ this._next();
1328
1327
  }
1329
- setParametersWebGL(parameters) {
1328
+ };
1329
+
1330
+ // dist/performance-test-runner.js
1331
+ var import_stats = require("@probe.gl/stats");
1332
+ var PerformanceTestRunner = class extends TestRunner {
1333
+ _stats = null;
1334
+ _fps = null;
1335
+ constructor(props) {
1336
+ super(props);
1337
+ Object.assign(this.testOptions, {
1338
+ maxFramesToRender: 60,
1339
+ targetFPS: 50
1340
+ });
1330
1341
  }
1331
- getParametersWebGL(parameters) {
1342
+ initTestCase(testCase) {
1343
+ super.initTestCase(testCase);
1344
+ this._stats = new import_stats.Stats({ id: testCase.name });
1345
+ this._fps = this._stats.get("fps");
1332
1346
  }
1333
- withParametersWebGL(parameters, func) {
1334
- const { nocatch = true } = parameters;
1335
- let value;
1336
- if (nocatch) {
1337
- return func();
1347
+ shouldRender(animationProps) {
1348
+ var _a, _b;
1349
+ (_a = this._fps) == null ? void 0 : _a.timeEnd();
1350
+ (_b = this._fps) == null ? void 0 : _b.timeStart();
1351
+ if (this._fps.count > this.testOptions.maxFramesToRender) {
1352
+ animationProps.done();
1338
1353
  }
1339
- try {
1340
- value = func();
1341
- } catch {
1354
+ return true;
1355
+ }
1356
+ assert(testCase) {
1357
+ var _a, _b;
1358
+ const targetFPS = testCase.targetFPS || this.testOptions.targetFPS;
1359
+ const count = (_a = this._fps) == null ? void 0 : _a.count;
1360
+ const fps = ((_b = this._fps) == null ? void 0 : _b.getHz()) || 0;
1361
+ if (fps >= targetFPS) {
1362
+ this._pass({ fps, framesRendered: count });
1363
+ } else {
1364
+ this._fail({ fps, framesRendered: count });
1342
1365
  }
1343
- return value;
1366
+ this._next();
1344
1367
  }
1345
1368
  };
1346
- var NullDevice = _NullDevice;
1347
- __publicField(NullDevice, "type", "unknown");
1348
1369
 
1349
1370
  // dist/utils/check-type.js
1350
1371
  function checkType(value) {
@@ -1387,4 +1408,21 @@ function getLeakedResources(startCounts, endCounts) {
1387
1408
  }
1388
1409
  return leakedResources;
1389
1410
  }
1411
+
1412
+ // dist/deprecated/sync-test-device.js
1413
+ var import_webgl4 = require("@luma.gl/webgl");
1414
+ var DEFAULT_CANVAS_CONTEXT_PROPS2 = {
1415
+ width: 1,
1416
+ height: 1
1417
+ };
1418
+ function createTestDevice() {
1419
+ try {
1420
+ return new import_webgl4.WebGLDevice({ createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS2 });
1421
+ } catch (error) {
1422
+ console.error(`Failed to created device: ${error.message}`);
1423
+ debugger;
1424
+ return null;
1425
+ }
1426
+ }
1427
+ var webglDevice2 = createTestDevice();
1390
1428
  //# sourceMappingURL=index.cjs.map