@luma.gl/test-utils 9.3.0-alpha.4 → 9.3.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/create-test-device.d.ts +19 -0
- package/dist/create-test-device.d.ts.map +1 -1
- package/dist/create-test-device.js +83 -14
- package/dist/create-test-device.js.map +1 -1
- package/dist/deprecated/classic-animation-loop.d.ts.map +1 -1
- package/dist/deprecated/classic-animation-loop.js +2 -10
- package/dist/deprecated/classic-animation-loop.js.map +1 -1
- package/dist/deprecated/sync-test-device.d.ts +0 -5
- package/dist/deprecated/sync-test-device.d.ts.map +1 -1
- package/dist/deprecated/sync-test-device.js +11 -1
- package/dist/deprecated/sync-test-device.js.map +1 -1
- package/dist/index.cjs +185 -74
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/null-device/null-canvas-context.d.ts.map +1 -1
- package/dist/null-device/null-canvas-context.js +1 -0
- package/dist/null-device/null-canvas-context.js.map +1 -1
- package/dist/null-device/null-device.d.ts +5 -3
- package/dist/null-device/null-device.d.ts.map +1 -1
- package/dist/null-device/null-device.js +16 -4
- package/dist/null-device/null-device.js.map +1 -1
- package/dist/null-device/resources/null-command-buffer.d.ts +8 -8
- package/dist/null-device/resources/null-command-buffer.d.ts.map +1 -1
- package/dist/null-device/resources/null-command-buffer.js +16 -6
- package/dist/null-device/resources/null-command-buffer.js.map +1 -1
- package/dist/null-device/resources/null-command-encoder.d.ts +8 -7
- package/dist/null-device/resources/null-command-encoder.d.ts.map +1 -1
- package/dist/null-device/resources/null-command-encoder.js +24 -9
- package/dist/null-device/resources/null-command-encoder.js.map +1 -1
- package/dist/null-device/resources/null-query-set.d.ts +6 -0
- package/dist/null-device/resources/null-query-set.d.ts.map +1 -1
- package/dist/null-device/resources/null-query-set.js +11 -0
- package/dist/null-device/resources/null-query-set.js.map +1 -1
- package/dist/null-device/resources/null-render-pass.d.ts.map +1 -1
- package/dist/null-device/resources/null-render-pass.js +6 -1
- package/dist/null-device/resources/null-render-pass.js.map +1 -1
- package/dist/null-device/resources/null-render-pipeline.d.ts +3 -4
- package/dist/null-device/resources/null-render-pipeline.d.ts.map +1 -1
- package/dist/null-device/resources/null-render-pipeline.js +0 -5
- package/dist/null-device/resources/null-render-pipeline.js.map +1 -1
- package/dist/null-device/resources/null-texture.d.ts +3 -3
- package/dist/null-device/resources/null-texture.d.ts.map +1 -1
- package/dist/null-device/resources/null-texture.js +9 -13
- package/dist/null-device/resources/null-texture.js.map +1 -1
- package/dist/test-runner.d.ts +1 -1
- package/dist/test-runner.d.ts.map +1 -1
- package/dist/test-runner.js +2 -1
- package/dist/test-runner.js.map +1 -1
- package/dist/utils/resource-tracker.js +1 -1
- package/dist/utils/resource-tracker.js.map +1 -1
- package/package.json +7 -7
- package/src/create-test-device.ts +113 -14
- package/src/deprecated/classic-animation-loop.ts +2 -10
- package/src/deprecated/sync-test-device.ts +16 -1
- package/src/index.ts +1 -0
- package/src/null-device/null-canvas-context.ts +1 -0
- package/src/null-device/null-device.ts +21 -4
- package/src/null-device/resources/null-command-buffer.ts +18 -8
- package/src/null-device/resources/null-command-encoder.ts +25 -9
- package/src/null-device/resources/null-query-set.ts +14 -0
- package/src/null-device/resources/null-render-pass.ts +6 -1
- package/src/null-device/resources/null-render-pipeline.ts +3 -14
- package/src/null-device/resources/null-texture.ts +17 -17
- package/src/test-runner.ts +2 -1
- package/src/utils/resource-tracker.ts +1 -1
|
@@ -10,13 +10,26 @@ import {nullAdapter} from './null-device/null-adapter';
|
|
|
10
10
|
import {NullDevice} from './null-device/null-device';
|
|
11
11
|
|
|
12
12
|
const DEFAULT_CANVAS_CONTEXT_PROPS: CanvasContextProps = {width: 1, height: 1};
|
|
13
|
+
const TEST_DEVICE_CACHE_KEY = '__lumaTestDeviceCache';
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
type TestDeviceCache = {
|
|
16
|
+
/** A null device intended for testing - @note Only available after getTestDevices() has completed */
|
|
17
|
+
nullDevicePromise: Promise<NullDevice> | null;
|
|
18
|
+
/** This WebGL Device can be used directly but will not have WebGL debugging initialized */
|
|
19
|
+
webglDevicePromise: Promise<WebGLDevice> | null;
|
|
20
|
+
/** A shared offscreen WebGL device for presentation-context tests */
|
|
21
|
+
presentationWebglDevicePromise: Promise<WebGLDevice | null> | null;
|
|
22
|
+
/** A WebGL 2 Device intended for testing - @note Only available after getTestDevices() has completed */
|
|
23
|
+
webgpuDevicePromise: Promise<WebGPUDevice | null> | null;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
declare global {
|
|
27
|
+
interface Window {
|
|
28
|
+
[TEST_DEVICE_CACHE_KEY]?: TestDeviceCache;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const testDeviceCache = getOrCreateTestDeviceCache();
|
|
20
33
|
|
|
21
34
|
/** Includes WebGPU device if available */
|
|
22
35
|
export async function getTestDevices(
|
|
@@ -32,29 +45,61 @@ export async function getTestDevice(
|
|
|
32
45
|
): Promise<Device | null> {
|
|
33
46
|
switch (type) {
|
|
34
47
|
case 'webgl':
|
|
35
|
-
return
|
|
48
|
+
return getOrCreateWebGLTestDevicePromise();
|
|
36
49
|
case 'webgpu':
|
|
37
|
-
return
|
|
50
|
+
return getWebGPUTestDevice();
|
|
38
51
|
case 'null':
|
|
39
|
-
return
|
|
52
|
+
return getOrCreateNullTestDevicePromise();
|
|
40
53
|
case 'unknown':
|
|
41
54
|
return null;
|
|
42
55
|
}
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
/** returns WebGPU device promise, if available */
|
|
46
|
-
export function getWebGPUTestDevice(): Promise<WebGPUDevice | null> {
|
|
47
|
-
|
|
59
|
+
export async function getWebGPUTestDevice(): Promise<WebGPUDevice | null> {
|
|
60
|
+
const webgpuDevice = await getOrCreateWebGPUTestDevicePromise();
|
|
61
|
+
if (webgpuDevice?.isLost) {
|
|
62
|
+
if (testDeviceCache.webgpuDevicePromise) {
|
|
63
|
+
testDeviceCache.webgpuDevicePromise = null;
|
|
64
|
+
}
|
|
65
|
+
return getOrCreateWebGPUTestDevicePromise();
|
|
66
|
+
}
|
|
67
|
+
return webgpuDevice;
|
|
48
68
|
}
|
|
49
69
|
|
|
50
70
|
/** returns WebGL device promise, if available */
|
|
51
71
|
export async function getWebGLTestDevice(): Promise<WebGLDevice> {
|
|
52
|
-
return
|
|
72
|
+
return getOrCreateWebGLTestDevicePromise();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** returns an offscreen WebGL device promise for presentation-context tests, if available */
|
|
76
|
+
export async function getPresentationWebGLTestDevice(): Promise<WebGLDevice | null> {
|
|
77
|
+
return getOrCreatePresentationWebGLTestDevicePromise();
|
|
53
78
|
}
|
|
54
79
|
|
|
55
80
|
/** returns null device promise, if available */
|
|
56
81
|
export async function getNullTestDevice(): Promise<NullDevice> {
|
|
57
|
-
return
|
|
82
|
+
return getOrCreateNullTestDevicePromise();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function getOrCreateWebGPUTestDevicePromise(): Promise<WebGPUDevice | null> {
|
|
86
|
+
testDeviceCache.webgpuDevicePromise ||= makeWebGPUTestDevice();
|
|
87
|
+
return testDeviceCache.webgpuDevicePromise;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function getOrCreateWebGLTestDevicePromise(): Promise<WebGLDevice> {
|
|
91
|
+
testDeviceCache.webglDevicePromise ||= makeWebGLTestDevice();
|
|
92
|
+
return testDeviceCache.webglDevicePromise;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function getOrCreatePresentationWebGLTestDevicePromise(): Promise<WebGLDevice | null> {
|
|
96
|
+
testDeviceCache.presentationWebglDevicePromise ||= makePresentationWebGLTestDevice();
|
|
97
|
+
return testDeviceCache.presentationWebglDevicePromise;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function getOrCreateNullTestDevicePromise(): Promise<NullDevice> {
|
|
101
|
+
testDeviceCache.nullDevicePromise ||= makeNullTestDevice();
|
|
102
|
+
return testDeviceCache.nullDevicePromise;
|
|
58
103
|
}
|
|
59
104
|
|
|
60
105
|
async function makeWebGPUTestDevice(): Promise<WebGPUDevice | null> {
|
|
@@ -67,6 +112,11 @@ async function makeWebGPUTestDevice(): Promise<WebGPUDevice | null> {
|
|
|
67
112
|
createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
|
|
68
113
|
debug: true
|
|
69
114
|
})) as unknown as WebGPUDevice;
|
|
115
|
+
webgpuDevice.lost.finally(() => {
|
|
116
|
+
if (testDeviceCache.webgpuDevicePromise === webgpuDeviceResolvers.promise) {
|
|
117
|
+
testDeviceCache.webgpuDevicePromise = null;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
70
120
|
webgpuDeviceResolvers.resolve(webgpuDevice);
|
|
71
121
|
} catch (error) {
|
|
72
122
|
log.error(String(error))();
|
|
@@ -87,6 +137,11 @@ async function makeWebGLTestDevice(): Promise<WebGLDevice> {
|
|
|
87
137
|
createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS,
|
|
88
138
|
debug: true
|
|
89
139
|
})) as unknown as WebGLDevice;
|
|
140
|
+
webglDevice.lost.finally(() => {
|
|
141
|
+
if (testDeviceCache.webglDevicePromise === webglDeviceResolvers.promise) {
|
|
142
|
+
testDeviceCache.webglDevicePromise = null;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
90
145
|
webglDeviceResolvers.resolve(webglDevice);
|
|
91
146
|
} catch (error) {
|
|
92
147
|
log.error(String(error))();
|
|
@@ -96,6 +151,35 @@ async function makeWebGLTestDevice(): Promise<WebGLDevice> {
|
|
|
96
151
|
return webglDeviceResolvers.promise;
|
|
97
152
|
}
|
|
98
153
|
|
|
154
|
+
async function makePresentationWebGLTestDevice(): Promise<WebGLDevice | null> {
|
|
155
|
+
if (typeof OffscreenCanvas === 'undefined') {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const presentationWebGLDeviceResolvers = withResolvers<WebGLDevice | null>();
|
|
160
|
+
try {
|
|
161
|
+
const webglDevice = (await luma.createDevice({
|
|
162
|
+
id: 'webgl-presentation-context-test-device',
|
|
163
|
+
type: 'webgl',
|
|
164
|
+
adapters: [webgl2Adapter],
|
|
165
|
+
createCanvasContext: {canvas: new OffscreenCanvas(4, 4)},
|
|
166
|
+
debug: true
|
|
167
|
+
})) as unknown as WebGLDevice;
|
|
168
|
+
webglDevice.lost.finally(() => {
|
|
169
|
+
if (
|
|
170
|
+
testDeviceCache.presentationWebglDevicePromise === presentationWebGLDeviceResolvers.promise
|
|
171
|
+
) {
|
|
172
|
+
testDeviceCache.presentationWebglDevicePromise = null;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
presentationWebGLDeviceResolvers.resolve(webglDevice);
|
|
176
|
+
} catch (error) {
|
|
177
|
+
log.error(String(error))();
|
|
178
|
+
presentationWebGLDeviceResolvers.resolve(null);
|
|
179
|
+
}
|
|
180
|
+
return presentationWebGLDeviceResolvers.promise;
|
|
181
|
+
}
|
|
182
|
+
|
|
99
183
|
/** returns null device promise, if available */
|
|
100
184
|
async function makeNullTestDevice(): Promise<NullDevice> {
|
|
101
185
|
const nullDeviceResolvers = withResolvers<NullDevice>();
|
|
@@ -111,13 +195,28 @@ async function makeNullTestDevice(): Promise<NullDevice> {
|
|
|
111
195
|
} catch (error) {
|
|
112
196
|
log.error(String(error))();
|
|
113
197
|
// @ts-ignore TODO
|
|
114
|
-
nullDevicePromise = Promise.resolve(null);
|
|
198
|
+
testDeviceCache.nullDevicePromise = Promise.resolve(null);
|
|
115
199
|
}
|
|
116
200
|
return nullDeviceResolvers.promise;
|
|
117
201
|
}
|
|
118
202
|
|
|
119
203
|
// HELPERS
|
|
120
204
|
|
|
205
|
+
function getOrCreateTestDeviceCache(): TestDeviceCache {
|
|
206
|
+
const rootObject = globalThis as typeof globalThis & {
|
|
207
|
+
[TEST_DEVICE_CACHE_KEY]?: TestDeviceCache;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
rootObject[TEST_DEVICE_CACHE_KEY] ||= {
|
|
211
|
+
nullDevicePromise: null,
|
|
212
|
+
webglDevicePromise: null,
|
|
213
|
+
presentationWebglDevicePromise: null,
|
|
214
|
+
webgpuDevicePromise: null
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
return rootObject[TEST_DEVICE_CACHE_KEY];
|
|
218
|
+
}
|
|
219
|
+
|
|
121
220
|
// TODO - replace with Promise.withResolvers once we upgrade TS baseline
|
|
122
221
|
function withResolvers<T>(): {
|
|
123
222
|
promise: Promise<T>;
|
|
@@ -163,9 +163,9 @@ export class ClassicAnimationLoop {
|
|
|
163
163
|
this.gl = (this.device && this.device.gl) || props.gl;
|
|
164
164
|
|
|
165
165
|
this.stats = props.stats;
|
|
166
|
+
this.frameRate = this.stats.get('Frame Rate');
|
|
166
167
|
this.cpuTime = this.stats.get('CPU Time');
|
|
167
168
|
this.gpuTime = this.stats.get('GPU Time');
|
|
168
|
-
this.frameRate = this.stats.get('Frame Rate');
|
|
169
169
|
|
|
170
170
|
this.setProps({
|
|
171
171
|
autoResizeViewport: props.autoResizeViewport,
|
|
@@ -613,15 +613,7 @@ export class ClassicAnimationLoop {
|
|
|
613
613
|
const width = this.gl.drawingBufferWidth;
|
|
614
614
|
const height = this.gl.drawingBufferHeight;
|
|
615
615
|
|
|
616
|
-
|
|
617
|
-
let aspect = 1;
|
|
618
|
-
|
|
619
|
-
const canvas = getHTMLCanvasElement(this.gl.canvas);
|
|
620
|
-
if (canvas && canvas.clientHeight) {
|
|
621
|
-
aspect = canvas.clientWidth / canvas.clientHeight;
|
|
622
|
-
} else if (width > 0 && height > 0) {
|
|
623
|
-
aspect = width / height;
|
|
624
|
-
}
|
|
616
|
+
const aspect = width > 0 && height > 0 ? width / height : 1;
|
|
625
617
|
|
|
626
618
|
return {width, height, aspect};
|
|
627
619
|
}
|
|
@@ -16,9 +16,22 @@ const DEFAULT_CANVAS_CONTEXT_PROPS: CanvasContextProps = {
|
|
|
16
16
|
* @deprecated Use getWebGLTestDevice().
|
|
17
17
|
*/
|
|
18
18
|
export function createTestDevice(): WebGLDevice | null {
|
|
19
|
+
if (cachedWebglDevice) {
|
|
20
|
+
return cachedWebglDevice;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (
|
|
24
|
+
typeof navigator === 'undefined' ||
|
|
25
|
+
typeof document === 'undefined' ||
|
|
26
|
+
typeof HTMLCanvasElement === 'undefined'
|
|
27
|
+
) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
19
31
|
try {
|
|
20
32
|
// TODO - We do not use luma.createDevice since createTestDevice currently expect WebGL context to be created synchronously
|
|
21
|
-
|
|
33
|
+
cachedWebglDevice = new WebGLDevice({createCanvasContext: DEFAULT_CANVAS_CONTEXT_PROPS});
|
|
34
|
+
return cachedWebglDevice;
|
|
22
35
|
} catch (error) {
|
|
23
36
|
// eslint-disable-next-line no-console
|
|
24
37
|
console.error(`Failed to created device: ${(error as Error).message}`);
|
|
@@ -32,4 +45,6 @@ export function createTestDevice(): WebGLDevice | null {
|
|
|
32
45
|
* @note This WebGL Device is create synchronously and can be used directly but will not have WebGL debugging initialized
|
|
33
46
|
* @deprecated Use getWebGLTestDevice().
|
|
34
47
|
*/
|
|
48
|
+
let cachedWebglDevice: WebGLDevice | null = null;
|
|
49
|
+
|
|
35
50
|
export const webglDevice = createTestDevice();
|
package/src/index.ts
CHANGED
|
@@ -29,6 +29,7 @@ export class NullCanvasContext extends CanvasContext {
|
|
|
29
29
|
// Base class constructor cannot access derived methods/fields, so we need to call these functions in the subclass constructor
|
|
30
30
|
this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
|
|
31
31
|
this._configureDevice();
|
|
32
|
+
this._startObservers();
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
_getCurrentFramebuffer(): NullFramebuffer {
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
import type {
|
|
6
6
|
DeviceProps,
|
|
7
7
|
CanvasContextProps,
|
|
8
|
+
PresentationContextProps,
|
|
9
|
+
PresentationContext,
|
|
8
10
|
VertexArray,
|
|
9
11
|
VertexArrayProps,
|
|
10
12
|
BufferProps,
|
|
@@ -22,6 +24,7 @@ import type {
|
|
|
22
24
|
QuerySetProps
|
|
23
25
|
} from '@luma.gl/core';
|
|
24
26
|
import {Device, DeviceFeatures} from '@luma.gl/core';
|
|
27
|
+
import type {NullCommandBuffer} from './resources/null-command-buffer';
|
|
25
28
|
|
|
26
29
|
import {NullDeviceInfo} from './null-device-info';
|
|
27
30
|
import {NullDeviceLimits} from './null-device-features';
|
|
@@ -72,7 +75,9 @@ export class NullDevice extends Device {
|
|
|
72
75
|
* Destroys the context
|
|
73
76
|
* @note Has no effect for null contexts
|
|
74
77
|
*/
|
|
75
|
-
destroy(): void {
|
|
78
|
+
destroy(): void {
|
|
79
|
+
this.commandEncoder?.destroy();
|
|
80
|
+
}
|
|
76
81
|
|
|
77
82
|
get isLost(): boolean {
|
|
78
83
|
return false;
|
|
@@ -84,6 +89,10 @@ export class NullDevice extends Device {
|
|
|
84
89
|
return new NullCanvasContext(this, props);
|
|
85
90
|
}
|
|
86
91
|
|
|
92
|
+
createPresentationContext(_props?: PresentationContextProps): PresentationContext {
|
|
93
|
+
throw new Error('PresentationContext is not supported on NullDevice');
|
|
94
|
+
}
|
|
95
|
+
|
|
87
96
|
createBuffer(props: BufferProps | ArrayBuffer | ArrayBufferView): NullBuffer {
|
|
88
97
|
const newProps = this._normalizeBufferProps(props);
|
|
89
98
|
return new NullBuffer(this, newProps);
|
|
@@ -133,15 +142,23 @@ export class NullDevice extends Device {
|
|
|
133
142
|
return new NullRenderPipeline(this, props);
|
|
134
143
|
}
|
|
135
144
|
|
|
136
|
-
createComputePipeline(
|
|
137
|
-
throw new Error('ComputePipeline not supported
|
|
145
|
+
createComputePipeline(_props?: ComputePipelineProps): ComputePipeline {
|
|
146
|
+
throw new Error('ComputePipeline is not supported on NullDevice');
|
|
138
147
|
}
|
|
139
148
|
|
|
140
149
|
override createCommandEncoder(props: CommandEncoderProps = {}): NullCommandEncoder {
|
|
141
150
|
return new NullCommandEncoder(this, props);
|
|
142
151
|
}
|
|
143
152
|
|
|
144
|
-
submit(): void {
|
|
153
|
+
submit(commandBuffer?: NullCommandBuffer): void {
|
|
154
|
+
if (!commandBuffer) {
|
|
155
|
+
commandBuffer = this.commandEncoder.finish({id: `${this.id}-default-command-buffer`});
|
|
156
|
+
this.commandEncoder.destroy();
|
|
157
|
+
this.commandEncoder = this.createCommandEncoder({id: `${this.id}-default-command-encoder`});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
commandBuffer.destroy();
|
|
161
|
+
}
|
|
145
162
|
|
|
146
163
|
override setParametersWebGL(parameters: any): void {}
|
|
147
164
|
|
|
@@ -14,25 +14,35 @@ import {CommandBuffer} from '@luma.gl/core';
|
|
|
14
14
|
import type {NullDevice} from '../null-device';
|
|
15
15
|
|
|
16
16
|
export class NullCommandBuffer extends CommandBuffer {
|
|
17
|
-
device: NullDevice;
|
|
18
|
-
handle: null = null;
|
|
17
|
+
readonly device: NullDevice;
|
|
18
|
+
readonly handle: null = null;
|
|
19
19
|
|
|
20
20
|
constructor(device: NullDevice, props: CommandBufferProps) {
|
|
21
21
|
super(device, props);
|
|
22
22
|
this.device = device;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
copyBufferToBuffer(
|
|
25
|
+
copyBufferToBuffer(_options: CopyBufferToBufferOptions): void {
|
|
26
|
+
throw new Error('copyBufferToBuffer is not supported on NullDevice');
|
|
27
|
+
}
|
|
26
28
|
|
|
27
|
-
copyBufferToTexture(
|
|
29
|
+
copyBufferToTexture(_options: CopyBufferToTextureOptions) {
|
|
30
|
+
throw new Error('copyBufferToTexture is not supported on NullDevice');
|
|
31
|
+
}
|
|
28
32
|
|
|
29
|
-
copyTextureToBuffer(
|
|
33
|
+
copyTextureToBuffer(_options: CopyTextureToBufferOptions): void {
|
|
34
|
+
throw new Error('copyTextureToBuffer is not supported on NullDevice');
|
|
35
|
+
}
|
|
30
36
|
|
|
31
|
-
copyTextureToTexture(
|
|
37
|
+
copyTextureToTexture(_options: CopyTextureToTextureOptions): void {
|
|
38
|
+
throw new Error('copyTextureToTexture is not supported on NullDevice');
|
|
39
|
+
}
|
|
32
40
|
|
|
33
41
|
pushDebugGroup(groupLabel: string): void {}
|
|
34
42
|
popDebugGroup() {}
|
|
35
43
|
|
|
36
|
-
insertDebugMarker(
|
|
37
|
-
resolveQuerySet(
|
|
44
|
+
insertDebugMarker(_markerLabel: string): void {}
|
|
45
|
+
resolveQuerySet(_querySet: QuerySet): void {
|
|
46
|
+
throw new Error('resolveQuerySet is not supported on NullDevice');
|
|
47
|
+
}
|
|
38
48
|
}
|
|
@@ -27,27 +27,43 @@ export class NullCommandEncoder extends CommandEncoder {
|
|
|
27
27
|
this.device = device;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
override destroy(): void {
|
|
31
|
+
this.destroyResource();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
finish(props: CommandBufferProps = {}): NullCommandBuffer {
|
|
35
|
+
const commandBuffer = new NullCommandBuffer(this.device, props);
|
|
36
|
+
this.destroy();
|
|
37
|
+
return commandBuffer;
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
beginRenderPass(props: RenderPassProps): NullRenderPass {
|
|
35
41
|
return new NullRenderPass(this.device, props);
|
|
36
42
|
}
|
|
37
43
|
|
|
38
|
-
beginComputePass(
|
|
39
|
-
throw new Error('ComputePass not supported
|
|
44
|
+
beginComputePass(_props: ComputePassProps): ComputePass {
|
|
45
|
+
throw new Error('ComputePass is not supported on NullDevice');
|
|
40
46
|
}
|
|
41
47
|
|
|
42
|
-
copyBufferToBuffer(
|
|
48
|
+
copyBufferToBuffer(_options: CopyBufferToBufferOptions): void {
|
|
49
|
+
throw new Error('copyBufferToBuffer is not supported on NullDevice');
|
|
50
|
+
}
|
|
43
51
|
|
|
44
|
-
copyBufferToTexture(
|
|
52
|
+
copyBufferToTexture(_options: CopyBufferToTextureOptions) {
|
|
53
|
+
throw new Error('copyBufferToTexture is not supported on NullDevice');
|
|
54
|
+
}
|
|
45
55
|
|
|
46
|
-
copyTextureToBuffer(
|
|
56
|
+
copyTextureToBuffer(_options: CopyTextureToBufferOptions): void {
|
|
57
|
+
throw new Error('copyTextureToBuffer is not supported on NullDevice');
|
|
58
|
+
}
|
|
47
59
|
|
|
48
|
-
copyTextureToTexture(
|
|
60
|
+
copyTextureToTexture(_options: CopyTextureToTextureOptions): void {
|
|
61
|
+
throw new Error('copyTextureToTexture is not supported on NullDevice');
|
|
62
|
+
}
|
|
49
63
|
|
|
50
|
-
resolveQuerySet(
|
|
64
|
+
resolveQuerySet(_querySet: QuerySet): void {
|
|
65
|
+
throw new Error('resolveQuerySet is not supported on NullDevice');
|
|
66
|
+
}
|
|
51
67
|
|
|
52
68
|
pushDebugGroup(groupLabel: string): void {}
|
|
53
69
|
popDebugGroup() {}
|
|
@@ -13,4 +13,18 @@ export class NullQuerySet extends QuerySet {
|
|
|
13
13
|
super(device, props);
|
|
14
14
|
this.device = device;
|
|
15
15
|
}
|
|
16
|
+
|
|
17
|
+
isResultAvailable(_queryIndex?: number): boolean {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async readResults(options?: {firstQuery?: number; queryCount?: number}): Promise<bigint[]> {
|
|
22
|
+
const firstQuery = options?.firstQuery || 0;
|
|
23
|
+
const queryCount = options?.queryCount || this.props.count - firstQuery;
|
|
24
|
+
return new Array(queryCount).fill(0n);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async readTimestampDuration(_beginIndex: number, _endIndex: number): Promise<number> {
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
16
30
|
}
|
|
@@ -14,7 +14,12 @@ export class NullRenderPass extends RenderPass {
|
|
|
14
14
|
this.device = device;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
end(): void {
|
|
17
|
+
end(): void {
|
|
18
|
+
if (this.destroyed) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
this.destroy();
|
|
22
|
+
}
|
|
18
23
|
|
|
19
24
|
pushDebugGroup(groupLabel: string): void {}
|
|
20
25
|
popDebugGroup(): void {}
|
|
@@ -2,13 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import type {
|
|
6
|
-
UniformValue,
|
|
7
|
-
RenderPipelineProps,
|
|
8
|
-
Binding,
|
|
9
|
-
RenderPass,
|
|
10
|
-
VertexArray
|
|
11
|
-
} from '@luma.gl/core';
|
|
5
|
+
import type {RenderPipelineProps, Binding, RenderPass, VertexArray} from '@luma.gl/core';
|
|
12
6
|
import {RenderPipeline} from '@luma.gl/core';
|
|
13
7
|
|
|
14
8
|
import type {NullDevice} from '../null-device';
|
|
@@ -22,9 +16,6 @@ export class NullRenderPipeline extends RenderPipeline {
|
|
|
22
16
|
vs: NullShader;
|
|
23
17
|
fs: NullShader;
|
|
24
18
|
|
|
25
|
-
uniforms: Record<string, UniformValue> = {};
|
|
26
|
-
bindings: Record<string, Binding> = {};
|
|
27
|
-
|
|
28
19
|
constructor(device: NullDevice, props: RenderPipelineProps) {
|
|
29
20
|
super(device, props);
|
|
30
21
|
this.device = device;
|
|
@@ -39,15 +30,13 @@ export class NullRenderPipeline extends RenderPipeline {
|
|
|
39
30
|
};
|
|
40
31
|
}
|
|
41
32
|
|
|
42
|
-
setBindings(bindings: Record<string, Binding>): void {
|
|
43
|
-
Object.assign(this.bindings, bindings);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
33
|
draw(options: {
|
|
47
34
|
renderPass: RenderPass;
|
|
48
35
|
vertexArray: VertexArray;
|
|
49
36
|
vertexCount?: number;
|
|
50
37
|
instanceCount?: number;
|
|
38
|
+
bindings?: Record<string, Binding>;
|
|
39
|
+
uniforms?: Record<string, unknown>;
|
|
51
40
|
}): boolean {
|
|
52
41
|
const {renderPass, vertexArray} = options;
|
|
53
42
|
vertexArray.bindBeforeRender(renderPass);
|
|
@@ -46,6 +46,8 @@ export class NullTexture extends Texture {
|
|
|
46
46
|
arrayLayerCount: 1
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
+
this.trackAllocatedMemory(this.getAllocatedByteLength(), 'Texture');
|
|
50
|
+
|
|
49
51
|
Object.seal(this);
|
|
50
52
|
}
|
|
51
53
|
|
|
@@ -61,16 +63,6 @@ export class NullTexture extends Texture {
|
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
copyExternalImage(options: CopyExternalImageOptions): {width: number; height: number} {
|
|
64
|
-
this.trackDeallocatedMemory('Texture');
|
|
65
|
-
|
|
66
|
-
// const {image: data} = options;
|
|
67
|
-
// if (data && data.byteLength) {
|
|
68
|
-
// this.trackAllocatedMemory(data.byteLength, 'Texture');
|
|
69
|
-
// } else {
|
|
70
|
-
const bytesPerPixel = 4;
|
|
71
|
-
this.trackAllocatedMemory(this.width * this.height * bytesPerPixel, 'Texture');
|
|
72
|
-
// }
|
|
73
|
-
|
|
74
66
|
return {width: this.width, height: this.height};
|
|
75
67
|
}
|
|
76
68
|
|
|
@@ -78,23 +70,31 @@ export class NullTexture extends Texture {
|
|
|
78
70
|
// ignore
|
|
79
71
|
}
|
|
80
72
|
|
|
81
|
-
copyImageData(options: CopyImageDataOptions): void {
|
|
82
|
-
|
|
73
|
+
override copyImageData(options: CopyImageDataOptions): void {
|
|
74
|
+
super.copyImageData(options);
|
|
83
75
|
}
|
|
84
76
|
|
|
85
|
-
override readBuffer(
|
|
86
|
-
|
|
77
|
+
override readBuffer(_options: TextureReadOptions = {}, buffer?: Buffer): Buffer {
|
|
78
|
+
if (!buffer) {
|
|
79
|
+
throw new Error('buffer required');
|
|
80
|
+
}
|
|
81
|
+
return buffer;
|
|
87
82
|
}
|
|
88
83
|
|
|
89
|
-
override async readDataAsync(
|
|
90
|
-
|
|
84
|
+
override async readDataAsync(_options: TextureReadOptions = {}): Promise<ArrayBuffer> {
|
|
85
|
+
throw new Error(
|
|
86
|
+
`${this} readDataAsync is deprecated; use readBuffer() with an explicit destination buffer or DynamicTexture.readAsync()`
|
|
87
|
+
);
|
|
91
88
|
}
|
|
92
89
|
|
|
93
90
|
override writeBuffer(buffer: Buffer, options: TextureWriteOptions = {}) {
|
|
94
91
|
// ignore
|
|
95
92
|
}
|
|
96
93
|
|
|
97
|
-
override writeData(
|
|
94
|
+
override writeData(
|
|
95
|
+
data: ArrayBuffer | SharedArrayBuffer | ArrayBufferView,
|
|
96
|
+
options: TextureWriteOptions = {}
|
|
97
|
+
): void {
|
|
98
98
|
// ignore
|
|
99
99
|
}
|
|
100
100
|
}
|
package/src/test-runner.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import {AnimationProps} from '@luma.gl/engine';
|
|
9
9
|
import {getWebGLTestDevice} from './create-test-device';
|
|
10
|
+
import {createTestDevice} from './deprecated/sync-test-device';
|
|
10
11
|
|
|
11
12
|
// TODO - Replace with new AnimationLoop from `@luma.gl/engine`
|
|
12
13
|
import {ClassicAnimationLoop as AnimationLoop} from './deprecated/classic-animation-loop';
|
|
@@ -65,7 +66,7 @@ const DEFAULT_TEST_PROPS: Required<TestRunnerProps> = {
|
|
|
65
66
|
|
|
66
67
|
/** Runs an array of test cases */
|
|
67
68
|
export class TestRunner {
|
|
68
|
-
device =
|
|
69
|
+
device = createTestDevice();
|
|
69
70
|
props: Record<string, any>;
|
|
70
71
|
isRunning: boolean = false;
|
|
71
72
|
testOptions: Required<TestRunnerProps> = {...DEFAULT_TEST_PROPS};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* global luma */
|
|
2
2
|
export function getResourceCounts() {
|
|
3
3
|
// @ts-ignore
|
|
4
|
-
const resourceStats = luma.stats.get('Resource Counts');
|
|
4
|
+
const resourceStats = luma.stats.get('GPU Resource Counts');
|
|
5
5
|
return {
|
|
6
6
|
Texture2D: resourceStats.get('Texture2Ds Active').count,
|
|
7
7
|
Buffer: resourceStats.get('Buffers Active').count
|