@luma.gl/webgl 9.3.0-alpha.2 → 9.3.0-alpha.6
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/adapter/converters/webgl-texture-table.d.ts +7 -1
- package/dist/adapter/converters/webgl-texture-table.d.ts.map +1 -1
- package/dist/adapter/converters/webgl-texture-table.js +121 -43
- package/dist/adapter/converters/webgl-texture-table.js.map +1 -1
- package/dist/adapter/device-helpers/webgl-device-features.d.ts.map +1 -1
- package/dist/adapter/device-helpers/webgl-device-features.js +1 -2
- package/dist/adapter/device-helpers/webgl-device-features.js.map +1 -1
- package/dist/adapter/device-helpers/webgl-device-info.js +5 -0
- package/dist/adapter/device-helpers/webgl-device-info.js.map +1 -1
- package/dist/adapter/helpers/get-shader-layout-from-glsl.js +23 -21
- package/dist/adapter/helpers/get-shader-layout-from-glsl.js.map +1 -1
- package/dist/adapter/helpers/parse-shader-compiler-log.d.ts +1 -1
- package/dist/adapter/helpers/parse-shader-compiler-log.d.ts.map +1 -1
- package/dist/adapter/helpers/parse-shader-compiler-log.js +20 -0
- package/dist/adapter/helpers/parse-shader-compiler-log.js.map +1 -1
- package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-buffer.js +19 -4
- package/dist/adapter/resources/webgl-buffer.js.map +1 -1
- package/dist/adapter/resources/webgl-command-buffer.d.ts +3 -4
- package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-command-buffer.js +11 -7
- package/dist/adapter/resources/webgl-command-buffer.js.map +1 -1
- package/dist/adapter/resources/webgl-command-encoder.d.ts +5 -4
- package/dist/adapter/resources/webgl-command-encoder.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-command-encoder.js +20 -7
- package/dist/adapter/resources/webgl-command-encoder.js.map +1 -1
- package/dist/adapter/resources/webgl-query-set.d.ts +29 -31
- package/dist/adapter/resources/webgl-query-set.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-query-set.js +193 -97
- package/dist/adapter/resources/webgl-query-set.js.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.js +17 -0
- package/dist/adapter/resources/webgl-render-pass.js.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.d.ts +13 -19
- package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.js +36 -154
- package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -1
- package/dist/adapter/resources/webgl-shared-render-pipeline.d.ts +24 -0
- package/dist/adapter/resources/webgl-shared-render-pipeline.d.ts.map +1 -0
- package/dist/adapter/resources/webgl-shared-render-pipeline.js +152 -0
- package/dist/adapter/resources/webgl-shared-render-pipeline.js.map +1 -0
- package/dist/adapter/resources/webgl-texture.d.ts +23 -4
- package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-texture.js +203 -100
- package/dist/adapter/resources/webgl-texture.js.map +1 -1
- package/dist/adapter/resources/webgl-transform-feedback.js +5 -5
- package/dist/adapter/resources/webgl-transform-feedback.js.map +1 -1
- package/dist/adapter/webgl-adapter.d.ts.map +1 -1
- package/dist/adapter/webgl-adapter.js +3 -4
- package/dist/adapter/webgl-adapter.js.map +1 -1
- package/dist/adapter/webgl-device.d.ts +6 -3
- package/dist/adapter/webgl-device.d.ts.map +1 -1
- package/dist/adapter/webgl-device.js +56 -14
- package/dist/adapter/webgl-device.js.map +1 -1
- package/dist/adapter/webgl-presentation-context.d.ts +21 -0
- package/dist/adapter/webgl-presentation-context.d.ts.map +1 -0
- package/dist/adapter/webgl-presentation-context.js +64 -0
- package/dist/adapter/webgl-presentation-context.js.map +1 -0
- package/dist/context/debug/spector.d.ts.map +1 -1
- package/dist/context/debug/spector.js +4 -4
- package/dist/context/debug/spector.js.map +1 -1
- package/dist/context/debug/webgl-developer-tools.js +2 -0
- package/dist/context/debug/webgl-developer-tools.js.map +1 -1
- package/dist/context/helpers/create-browser-context.d.ts.map +1 -1
- package/dist/context/helpers/create-browser-context.js +6 -8
- package/dist/context/helpers/create-browser-context.js.map +1 -1
- package/dist/context/helpers/webgl-context-data.d.ts +5 -1
- package/dist/context/helpers/webgl-context-data.d.ts.map +1 -1
- package/dist/context/helpers/webgl-context-data.js +9 -10
- package/dist/context/helpers/webgl-context-data.js.map +1 -1
- package/dist/context/parameters/unified-parameter-api.d.ts +1 -1
- package/dist/context/parameters/unified-parameter-api.js +2 -2
- package/dist/context/parameters/unified-parameter-api.js.map +1 -1
- package/dist/context/state-tracker/webgl-state-tracker.js +2 -2
- package/dist/context/state-tracker/webgl-state-tracker.js.map +1 -1
- package/dist/dist.dev.js +1427 -828
- package/dist/dist.min.js +2 -2
- package/dist/index.cjs +1325 -811
- package/dist/index.cjs.map +4 -4
- package/dist/utils/fill-array.js +1 -1
- package/dist/utils/fill-array.js.map +1 -1
- package/package.json +4 -4
- package/src/adapter/converters/webgl-texture-table.ts +159 -47
- package/src/adapter/device-helpers/webgl-device-features.ts +1 -2
- package/src/adapter/device-helpers/webgl-device-info.ts +6 -0
- package/src/adapter/helpers/get-shader-layout-from-glsl.ts +25 -24
- package/src/adapter/helpers/parse-shader-compiler-log.ts +23 -1
- package/src/adapter/resources/webgl-buffer.ts +16 -4
- package/src/adapter/resources/webgl-command-buffer.ts +21 -24
- package/src/adapter/resources/webgl-command-encoder.ts +22 -7
- package/src/adapter/resources/webgl-query-set.ts +229 -102
- package/src/adapter/resources/webgl-render-pass.ts +19 -0
- package/src/adapter/resources/webgl-render-pipeline.ts +46 -181
- package/src/adapter/resources/webgl-shared-render-pipeline.ts +208 -0
- package/src/adapter/resources/webgl-texture.ts +326 -121
- package/src/adapter/resources/webgl-transform-feedback.ts +5 -5
- package/src/adapter/webgl-adapter.ts +3 -4
- package/src/adapter/webgl-device.ts +66 -19
- package/src/adapter/webgl-presentation-context.ts +93 -0
- package/src/context/debug/spector.ts +4 -4
- package/src/context/debug/webgl-developer-tools.ts +2 -0
- package/src/context/helpers/create-browser-context.ts +8 -8
- package/src/context/helpers/webgl-context-data.ts +17 -11
- package/src/context/parameters/unified-parameter-api.ts +2 -2
- package/src/context/state-tracker/webgl-state-tracker.ts +2 -2
- package/src/utils/fill-array.ts +1 -1
|
@@ -8,6 +8,8 @@ import type {
|
|
|
8
8
|
DeviceInfo,
|
|
9
9
|
DeviceTextureFormatCapabilities,
|
|
10
10
|
CanvasContextProps,
|
|
11
|
+
PresentationContextProps,
|
|
12
|
+
PresentationContext,
|
|
11
13
|
Buffer,
|
|
12
14
|
Texture,
|
|
13
15
|
Framebuffer,
|
|
@@ -23,6 +25,7 @@ import type {
|
|
|
23
25
|
FramebufferProps,
|
|
24
26
|
// RenderPipeline,
|
|
25
27
|
RenderPipelineProps,
|
|
28
|
+
SharedRenderPipeline,
|
|
26
29
|
ComputePipeline,
|
|
27
30
|
ComputePipelineProps,
|
|
28
31
|
// CommandEncoder,
|
|
@@ -36,10 +39,12 @@ import {Device, CanvasContext, log} from '@luma.gl/core';
|
|
|
36
39
|
import type {GLExtensions} from '@luma.gl/constants';
|
|
37
40
|
import {WebGLStateTracker} from '../context/state-tracker/webgl-state-tracker';
|
|
38
41
|
import {createBrowserContext} from '../context/helpers/create-browser-context';
|
|
42
|
+
import {getWebGLContextData} from '../context/helpers/webgl-context-data';
|
|
39
43
|
import {getDeviceInfo} from './device-helpers/webgl-device-info';
|
|
40
44
|
import {WebGLDeviceFeatures} from './device-helpers/webgl-device-features';
|
|
41
45
|
import {WebGLDeviceLimits} from './device-helpers/webgl-device-limits';
|
|
42
46
|
import {WebGLCanvasContext} from './webgl-canvas-context';
|
|
47
|
+
import {WebGLPresentationContext} from './webgl-presentation-context';
|
|
43
48
|
import type {Spector} from '../context/debug/spector-types';
|
|
44
49
|
import {initializeSpectorJS} from '../context/debug/spector';
|
|
45
50
|
import {makeDebugContext} from '../context/debug/webgl-developer-tools';
|
|
@@ -52,6 +57,7 @@ import {WEBGLSampler} from './resources/webgl-sampler';
|
|
|
52
57
|
import {WEBGLTexture} from './resources/webgl-texture';
|
|
53
58
|
import {WEBGLFramebuffer} from './resources/webgl-framebuffer';
|
|
54
59
|
import {WEBGLRenderPipeline} from './resources/webgl-render-pipeline';
|
|
60
|
+
import {WEBGLSharedRenderPipeline} from './resources/webgl-shared-render-pipeline';
|
|
55
61
|
import {WEBGLCommandEncoder} from './resources/webgl-command-encoder';
|
|
56
62
|
import {WEBGLCommandBuffer} from './resources/webgl-command-buffer';
|
|
57
63
|
import {WEBGLVertexArray} from './resources/webgl-vertex-array';
|
|
@@ -70,6 +76,13 @@ import {getWebGLExtension} from '../context/helpers/webgl-extensions';
|
|
|
70
76
|
|
|
71
77
|
/** WebGPU style Device API for a WebGL context */
|
|
72
78
|
export class WebGLDevice extends Device {
|
|
79
|
+
static getDeviceFromContext(gl: WebGL2RenderingContext | null): WebGLDevice | null {
|
|
80
|
+
if (!gl) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
// @ts-expect-error Ingore WebGL2RenderingContext type
|
|
84
|
+
return gl.luma?.device ?? null;
|
|
85
|
+
}
|
|
73
86
|
// Public `Device` API
|
|
74
87
|
|
|
75
88
|
/** type of this device */
|
|
@@ -100,7 +113,7 @@ export class WebGLDevice extends Device {
|
|
|
100
113
|
_constants: (TypedArray | null)[];
|
|
101
114
|
|
|
102
115
|
/** State used by luma.gl classes - TODO - not used? */
|
|
103
|
-
readonly
|
|
116
|
+
readonly extensions!: GLExtensions;
|
|
104
117
|
_polyfilled: boolean = false;
|
|
105
118
|
|
|
106
119
|
/** Instance of Spector.js (if initialized) */
|
|
@@ -141,7 +154,8 @@ export class WebGLDevice extends Device {
|
|
|
141
154
|
// Note that this can be avoided in webgl2adapter.create() if
|
|
142
155
|
// DeviceProps._reuseDevices is set.
|
|
143
156
|
// @ts-expect-error device is attached to context
|
|
144
|
-
|
|
157
|
+
const existingContext = canvasContextProps.canvas?.gl ?? null;
|
|
158
|
+
let device: WebGLDevice | null = WebGLDevice.getDeviceFromContext(existingContext);
|
|
145
159
|
if (device) {
|
|
146
160
|
throw new Error(`WebGL context already attached to device ${device.id}`);
|
|
147
161
|
}
|
|
@@ -190,8 +204,7 @@ export class WebGLDevice extends Device {
|
|
|
190
204
|
|
|
191
205
|
// Note that the browser will only create one WebGL context per canvas.
|
|
192
206
|
// This means that a newly created gl context may already have a device attached to it.
|
|
193
|
-
|
|
194
|
-
device = gl.device;
|
|
207
|
+
device = WebGLDevice.getDeviceFromContext(gl);
|
|
195
208
|
if (device) {
|
|
196
209
|
if (props._reuseDevices) {
|
|
197
210
|
log.log(
|
|
@@ -199,6 +212,9 @@ export class WebGLDevice extends Device {
|
|
|
199
212
|
`Not creating a new Device, instead returning a reference to Device ${device.id} already attached to WebGL context`,
|
|
200
213
|
device
|
|
201
214
|
)();
|
|
215
|
+
// Destroy the orphaned canvas context that was created above (line 149)
|
|
216
|
+
// to prevent its ResizeObserver from firing callbacks with undefined device
|
|
217
|
+
this.canvasContext.destroy();
|
|
202
218
|
device._reused = true;
|
|
203
219
|
return device;
|
|
204
220
|
}
|
|
@@ -214,16 +230,15 @@ export class WebGLDevice extends Device {
|
|
|
214
230
|
this.spectorJS = initializeSpectorJS({...this.props, gl: this.handle});
|
|
215
231
|
|
|
216
232
|
// Instrument context
|
|
217
|
-
|
|
233
|
+
const contextData = getWebGLContextData(this.handle);
|
|
234
|
+
contextData.device = this; // Update GL context: Link webgl context back to device
|
|
235
|
+
|
|
236
|
+
this.extensions = contextData.extensions || (contextData.extensions = {});
|
|
218
237
|
|
|
219
238
|
// initialize luma Device fields
|
|
220
|
-
this.info = getDeviceInfo(this.gl, this.
|
|
239
|
+
this.info = getDeviceInfo(this.gl, this.extensions);
|
|
221
240
|
this.limits = new WebGLDeviceLimits(this.gl);
|
|
222
|
-
this.features = new WebGLDeviceFeatures(
|
|
223
|
-
this.gl,
|
|
224
|
-
this._extensions,
|
|
225
|
-
this.props._disabledFeatures
|
|
226
|
-
);
|
|
241
|
+
this.features = new WebGLDeviceFeatures(this.gl, this.extensions, this.props._disabledFeatures);
|
|
227
242
|
if (this.props._initializeFeatures) {
|
|
228
243
|
this.features.initializeFeatures();
|
|
229
244
|
}
|
|
@@ -245,6 +260,7 @@ export class WebGLDevice extends Device {
|
|
|
245
260
|
}
|
|
246
261
|
|
|
247
262
|
this.commandEncoder = new WEBGLCommandEncoder(this, {id: `${this}-command-encoder`});
|
|
263
|
+
this.canvasContext._startObservers();
|
|
248
264
|
}
|
|
249
265
|
|
|
250
266
|
/**
|
|
@@ -258,6 +274,7 @@ export class WebGLDevice extends Device {
|
|
|
258
274
|
* browser API for destroying WebGL contexts.
|
|
259
275
|
*/
|
|
260
276
|
destroy(): void {
|
|
277
|
+
this.commandEncoder?.destroy();
|
|
261
278
|
// Note that deck.gl (especially in React strict mode) depends on being able
|
|
262
279
|
// to asynchronously create a Device against the same canvas (i.e. WebGL context)
|
|
263
280
|
// multiple times and getting the same device back. Since deck.gl is not aware
|
|
@@ -265,7 +282,8 @@ export class WebGLDevice extends Device {
|
|
|
265
282
|
// Therefore we must do nothing in destroy() if props._reuseDevices is true
|
|
266
283
|
if (!this.props._reuseDevices && !this._reused) {
|
|
267
284
|
// Delete the reference to the device that we store on the WebGL context
|
|
268
|
-
|
|
285
|
+
const contextData = getWebGLContextData(this.handle);
|
|
286
|
+
contextData.device = null;
|
|
269
287
|
}
|
|
270
288
|
}
|
|
271
289
|
|
|
@@ -279,6 +297,10 @@ export class WebGLDevice extends Device {
|
|
|
279
297
|
throw new Error('WebGL only supports a single canvas');
|
|
280
298
|
}
|
|
281
299
|
|
|
300
|
+
createPresentationContext(props?: PresentationContextProps): PresentationContext {
|
|
301
|
+
return new WebGLPresentationContext(this, props || {});
|
|
302
|
+
}
|
|
303
|
+
|
|
282
304
|
createBuffer(props: BufferProps | ArrayBuffer | ArrayBufferView): WEBGLBuffer {
|
|
283
305
|
const newProps = this._normalizeBufferProps(props);
|
|
284
306
|
return new WEBGLBuffer(this, newProps);
|
|
@@ -324,6 +346,13 @@ export class WebGLDevice extends Device {
|
|
|
324
346
|
return new WEBGLRenderPipeline(this, props);
|
|
325
347
|
}
|
|
326
348
|
|
|
349
|
+
override _createSharedRenderPipelineWebGL(props: RenderPipelineProps): SharedRenderPipeline {
|
|
350
|
+
return new WEBGLSharedRenderPipeline(
|
|
351
|
+
this,
|
|
352
|
+
props as RenderPipelineProps & {vs: WEBGLShader; fs: WEBGLShader}
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
|
|
327
356
|
createComputePipeline(props?: ComputePipelineProps): ComputePipeline {
|
|
328
357
|
throw new Error('ComputePipeline not supported in WebGL');
|
|
329
358
|
}
|
|
@@ -337,14 +366,32 @@ export class WebGLDevice extends Device {
|
|
|
337
366
|
* https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/commit
|
|
338
367
|
* Chrome's offscreen canvas does not require gl.commit
|
|
339
368
|
*/
|
|
340
|
-
submit(commandBuffer
|
|
369
|
+
submit(commandBuffer?: WEBGLCommandBuffer): void {
|
|
370
|
+
let submittedCommandEncoder: WEBGLCommandEncoder | null = null;
|
|
341
371
|
if (!commandBuffer) {
|
|
342
|
-
|
|
372
|
+
submittedCommandEncoder = this.commandEncoder;
|
|
373
|
+
commandBuffer = submittedCommandEncoder.finish();
|
|
343
374
|
this.commandEncoder.destroy();
|
|
344
|
-
this.commandEncoder = this.createCommandEncoder({
|
|
375
|
+
this.commandEncoder = this.createCommandEncoder({
|
|
376
|
+
id: submittedCommandEncoder.props.id,
|
|
377
|
+
timeProfilingQuerySet: submittedCommandEncoder.getTimeProfilingQuerySet()
|
|
378
|
+
});
|
|
345
379
|
}
|
|
346
380
|
|
|
347
|
-
|
|
381
|
+
try {
|
|
382
|
+
commandBuffer._executeCommands();
|
|
383
|
+
|
|
384
|
+
if (submittedCommandEncoder) {
|
|
385
|
+
submittedCommandEncoder
|
|
386
|
+
.resolveTimeProfilingQuerySet()
|
|
387
|
+
.then(() => {
|
|
388
|
+
this.commandEncoder._gpuTimeMs = submittedCommandEncoder._gpuTimeMs;
|
|
389
|
+
})
|
|
390
|
+
.catch(() => {});
|
|
391
|
+
}
|
|
392
|
+
} finally {
|
|
393
|
+
commandBuffer.destroy();
|
|
394
|
+
}
|
|
348
395
|
}
|
|
349
396
|
|
|
350
397
|
//
|
|
@@ -407,7 +454,7 @@ export class WebGLDevice extends Device {
|
|
|
407
454
|
override _getDeviceSpecificTextureFormatCapabilities(
|
|
408
455
|
capabilities: DeviceTextureFormatCapabilities
|
|
409
456
|
): DeviceTextureFormatCapabilities {
|
|
410
|
-
return getTextureFormatCapabilitiesWebGL(this.gl, capabilities, this.
|
|
457
|
+
return getTextureFormatCapabilitiesWebGL(this.gl, capabilities, this.extensions);
|
|
411
458
|
}
|
|
412
459
|
|
|
413
460
|
//
|
|
@@ -510,8 +557,8 @@ export class WebGLDevice extends Device {
|
|
|
510
557
|
|
|
511
558
|
/** Ensure extensions are only requested once */
|
|
512
559
|
getExtension(name: keyof GLExtensions): GLExtensions {
|
|
513
|
-
getWebGLExtension(this.gl, name, this.
|
|
514
|
-
return this.
|
|
560
|
+
getWebGLExtension(this.gl, name, this.extensions);
|
|
561
|
+
return this.extensions;
|
|
515
562
|
}
|
|
516
563
|
|
|
517
564
|
// INTERNAL SUPPORT METHODS FOR WEBGL RESOURCES
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {PresentationContextProps, TextureFormatDepthStencil, Framebuffer} from '@luma.gl/core';
|
|
6
|
+
import {PresentationContext} from '@luma.gl/core';
|
|
7
|
+
import type {WebGLDevice} from './webgl-device';
|
|
8
|
+
|
|
9
|
+
type PresentationCanvasRenderingContext2D =
|
|
10
|
+
| CanvasRenderingContext2D
|
|
11
|
+
| OffscreenCanvasRenderingContext2D;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Tracks a non-WebGL destination canvas while rendering into the device's default canvas context.
|
|
15
|
+
*/
|
|
16
|
+
export class WebGLPresentationContext extends PresentationContext {
|
|
17
|
+
readonly device: WebGLDevice;
|
|
18
|
+
readonly handle = null;
|
|
19
|
+
readonly context2d: PresentationCanvasRenderingContext2D;
|
|
20
|
+
|
|
21
|
+
get [Symbol.toStringTag](): string {
|
|
22
|
+
return 'WebGLPresentationContext';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
constructor(device: WebGLDevice, props: PresentationContextProps = {}) {
|
|
26
|
+
super(props);
|
|
27
|
+
this.device = device;
|
|
28
|
+
const contextLabel = `${this[Symbol.toStringTag]}(${this.id})`;
|
|
29
|
+
|
|
30
|
+
const defaultCanvasContext = this.device.getDefaultCanvasContext();
|
|
31
|
+
if (!defaultCanvasContext.offscreenCanvas) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
`${contextLabel}: WebGL PresentationContext requires the default CanvasContext canvas to be an OffscreenCanvas`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const context2d = this.canvas.getContext('2d');
|
|
38
|
+
if (!context2d) {
|
|
39
|
+
throw new Error(`${contextLabel}: Failed to create 2d presentation context`);
|
|
40
|
+
}
|
|
41
|
+
this.context2d = context2d;
|
|
42
|
+
|
|
43
|
+
this._setAutoCreatedCanvasId(`${this.device.id}-presentation-canvas`);
|
|
44
|
+
this._configureDevice();
|
|
45
|
+
this._startObservers();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
present(): void {
|
|
49
|
+
this._resizeDrawingBufferIfNeeded();
|
|
50
|
+
this.device.submit();
|
|
51
|
+
|
|
52
|
+
const defaultCanvasContext = this.device.getDefaultCanvasContext();
|
|
53
|
+
const [sourceWidth, sourceHeight] = defaultCanvasContext.getDrawingBufferSize();
|
|
54
|
+
|
|
55
|
+
// Responsive layouts can transiently collapse presentation canvases to 0x0 during reflow.
|
|
56
|
+
// In that case WebGL has nothing meaningful to present, and drawImage() would throw when the
|
|
57
|
+
// offscreen source canvas has zero width or height.
|
|
58
|
+
if (
|
|
59
|
+
this.drawingBufferWidth === 0 ||
|
|
60
|
+
this.drawingBufferHeight === 0 ||
|
|
61
|
+
sourceWidth === 0 ||
|
|
62
|
+
sourceHeight === 0 ||
|
|
63
|
+
defaultCanvasContext.canvas.width === 0 ||
|
|
64
|
+
defaultCanvasContext.canvas.height === 0
|
|
65
|
+
) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (
|
|
70
|
+
sourceWidth !== this.drawingBufferWidth ||
|
|
71
|
+
sourceHeight !== this.drawingBufferHeight ||
|
|
72
|
+
defaultCanvasContext.canvas.width !== this.drawingBufferWidth ||
|
|
73
|
+
defaultCanvasContext.canvas.height !== this.drawingBufferHeight
|
|
74
|
+
) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`${this[Symbol.toStringTag]}(${this.id}): Default canvas context size ${sourceWidth}x${sourceHeight} does not match presentation size ${this.drawingBufferWidth}x${this.drawingBufferHeight}`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
this.context2d.clearRect(0, 0, this.drawingBufferWidth, this.drawingBufferHeight);
|
|
81
|
+
this.context2d.drawImage(defaultCanvasContext.canvas, 0, 0);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
protected override _configureDevice(): void {}
|
|
85
|
+
|
|
86
|
+
protected override _getCurrentFramebuffer(options?: {
|
|
87
|
+
depthStencilFormat?: TextureFormatDepthStencil | false;
|
|
88
|
+
}): Framebuffer {
|
|
89
|
+
const defaultCanvasContext = this.device.getDefaultCanvasContext();
|
|
90
|
+
defaultCanvasContext.setDrawingBufferSize(this.drawingBufferWidth, this.drawingBufferHeight);
|
|
91
|
+
return defaultCanvasContext.getCurrentFramebuffer(options);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import {log} from '@luma.gl/core';
|
|
6
6
|
import {loadScript} from '../../utils/load-script';
|
|
7
|
+
import {getWebGLContextData} from '../helpers/webgl-context-data';
|
|
7
8
|
|
|
8
9
|
import type {Spector} from './spector-types';
|
|
9
10
|
|
|
@@ -91,11 +92,10 @@ export function initializeSpectorJS(props: SpectorProps): Spector | null {
|
|
|
91
92
|
if (props.gl) {
|
|
92
93
|
// capture startup
|
|
93
94
|
const gl = props.gl;
|
|
94
|
-
|
|
95
|
-
const device =
|
|
95
|
+
const contextData = getWebGLContextData(gl);
|
|
96
|
+
const device = contextData.device;
|
|
96
97
|
spector?.startCapture(props.gl, 500); // 500 commands
|
|
97
|
-
|
|
98
|
-
gl.device = device;
|
|
98
|
+
contextData.device = device;
|
|
99
99
|
|
|
100
100
|
new Promise(resolve => setTimeout(resolve, 2000)).then(_ => {
|
|
101
101
|
log.info('Spector capture stopped after 2 seconds')();
|
|
@@ -104,6 +104,8 @@ function getDebugContext(
|
|
|
104
104
|
// Store the debug context
|
|
105
105
|
data.realContext = gl;
|
|
106
106
|
data.debugContext = debugContext;
|
|
107
|
+
// Share the context metadata object with the debug context so lookups stay consistent.
|
|
108
|
+
(debugContext as {luma?: unknown}).luma = data;
|
|
107
109
|
debugContext.debug = true;
|
|
108
110
|
|
|
109
111
|
// Return it
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
+
import {getWebGLContextData} from './webgl-context-data';
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
8
|
* ContextProps
|
|
7
9
|
* @param onContextLost
|
|
@@ -55,15 +57,11 @@ export function createBrowserContext(
|
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
// Creation failed with failIfMajorPerformanceCaveat - Try a Software GPU
|
|
60
|
+
let softwareRenderer = false;
|
|
58
61
|
if (!gl && allowSoftwareRenderer) {
|
|
59
62
|
webglProps.failIfMajorPerformanceCaveat = false;
|
|
60
63
|
gl = canvas.getContext('webgl2', webglProps);
|
|
61
|
-
|
|
62
|
-
// @ts-expect-error
|
|
63
|
-
gl.luma ||= {};
|
|
64
|
-
// @ts-expect-error
|
|
65
|
-
gl.luma.softwareRenderer = true;
|
|
66
|
-
}
|
|
64
|
+
softwareRenderer = true;
|
|
67
65
|
}
|
|
68
66
|
|
|
69
67
|
if (!gl) {
|
|
@@ -79,6 +77,10 @@ export function createBrowserContext(
|
|
|
79
77
|
throw new Error(`Failed to create WebGL context: ${errorMessage}`);
|
|
80
78
|
}
|
|
81
79
|
|
|
80
|
+
// Initialize luma.gl specific context data
|
|
81
|
+
const luma = getWebGLContextData(gl);
|
|
82
|
+
luma.softwareRenderer = softwareRenderer;
|
|
83
|
+
|
|
82
84
|
// Carefully extract and wrap callbacks to prevent addEventListener from rebinding them.
|
|
83
85
|
const {onContextLost, onContextRestored} = props;
|
|
84
86
|
canvas.addEventListener('webglcontextlost', (event: Event) => onContextLost(event), false);
|
|
@@ -88,8 +90,6 @@ export function createBrowserContext(
|
|
|
88
90
|
false
|
|
89
91
|
);
|
|
90
92
|
|
|
91
|
-
// @ts-expect-error
|
|
92
|
-
gl.luma ||= {};
|
|
93
93
|
return gl;
|
|
94
94
|
} finally {
|
|
95
95
|
canvas.removeEventListener('webglcontextcreationerror', onCreateError, false);
|
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
+
import type {GLExtensions} from '@luma.gl/constants';
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
8
|
* Stores luma.gl specific state associated with a context
|
|
7
9
|
*/
|
|
8
10
|
export interface WebGLContextData {
|
|
11
|
+
/** This type is used by lower level code that is not aware of the Device type */
|
|
12
|
+
device?: unknown;
|
|
9
13
|
_polyfilled: boolean;
|
|
10
|
-
|
|
14
|
+
extensions: GLExtensions;
|
|
15
|
+
softwareRenderer?: boolean;
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
/**
|
|
@@ -16,16 +21,17 @@ export interface WebGLContextData {
|
|
|
16
21
|
*/
|
|
17
22
|
export function getWebGLContextData(gl: WebGL2RenderingContext): WebGLContextData {
|
|
18
23
|
// @ts-expect-error
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
24
|
+
const contextData = (gl.luma as WebGLContextData | null) || {
|
|
25
|
+
_polyfilled: false,
|
|
26
|
+
extensions: {},
|
|
27
|
+
softwareRenderer: false
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
contextData._polyfilled ??= false;
|
|
31
|
+
contextData.extensions ||= {};
|
|
28
32
|
|
|
29
33
|
// @ts-expect-error
|
|
30
|
-
|
|
34
|
+
gl.luma = contextData;
|
|
35
|
+
|
|
36
|
+
return contextData;
|
|
31
37
|
}
|
|
@@ -18,7 +18,7 @@ export type {GLParameters};
|
|
|
18
18
|
/**
|
|
19
19
|
* Sets any GL parameter regardless of function (gl.blendMode, ...)
|
|
20
20
|
*
|
|
21
|
-
* @note requires a `cache` object to be set on the context (
|
|
21
|
+
* @note requires a `cache` object to be set on the context (lumaState.cache)
|
|
22
22
|
* This object is used to fill in any missing values for composite setter functions
|
|
23
23
|
*/
|
|
24
24
|
export function setGLParameters(gl: WebGL2RenderingContext, parameters: GLParameters): void {
|
|
@@ -58,7 +58,7 @@ export function setGLParameters(gl: WebGL2RenderingContext, parameters: GLParame
|
|
|
58
58
|
// But it is too inconvenient to always require a cache parameter here.
|
|
59
59
|
// This is the ONLY external dependency in this module/
|
|
60
60
|
// @ts-expect-error
|
|
61
|
-
const cache = gl.
|
|
61
|
+
const cache = gl.lumaState?.cache;
|
|
62
62
|
if (cache) {
|
|
63
63
|
for (const key in compositeSetters) {
|
|
64
64
|
// TODO - avoid calling composite setters if values have not changed.
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
export class WebGLStateTracker {
|
|
22
22
|
static get(gl: WebGL2RenderingContext): WebGLStateTracker {
|
|
23
23
|
// @ts-expect-error
|
|
24
|
-
return gl.
|
|
24
|
+
return gl.lumaState as WebGLStateTracker;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
gl: WebGL2RenderingContext;
|
|
@@ -78,7 +78,7 @@ export class WebGLStateTracker {
|
|
|
78
78
|
this.initialized = true;
|
|
79
79
|
|
|
80
80
|
// @ts-expect-error
|
|
81
|
-
this.gl.
|
|
81
|
+
this.gl.lumaState = this;
|
|
82
82
|
|
|
83
83
|
installProgramSpy(gl);
|
|
84
84
|
|
package/src/utils/fill-array.ts
CHANGED