@luma.gl/webgl 9.3.0-alpha.2 → 9.3.0-alpha.4
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/helpers/get-shader-layout-from-glsl.js +11 -8
- 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-command-buffer.d.ts +2 -3
- package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-command-buffer.js +9 -5
- package/dist/adapter/resources/webgl-command-buffer.js.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.js +5 -0
- package/dist/adapter/resources/webgl-render-pass.js.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.js +1 -2
- package/dist/adapter/resources/webgl-render-pipeline.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 +2 -1
- package/dist/adapter/webgl-device.d.ts.map +1 -1
- package/dist/adapter/webgl-device.js +25 -11
- package/dist/adapter/webgl-device.js.map +1 -1
- 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 +104 -49
- package/dist/dist.min.js +2 -2
- package/dist/index.cjs +108 -44
- 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/helpers/get-shader-layout-from-glsl.ts +11 -9
- package/src/adapter/helpers/parse-shader-compiler-log.ts +23 -1
- package/src/adapter/resources/webgl-command-buffer.ts +18 -22
- package/src/adapter/resources/webgl-render-pass.ts +6 -0
- package/src/adapter/resources/webgl-render-pipeline.ts +1 -2
- package/src/adapter/resources/webgl-transform-feedback.ts +5 -5
- package/src/adapter/webgl-adapter.ts +3 -4
- package/src/adapter/webgl-device.ts +26 -15
- 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
package/dist/utils/fill-array.js
CHANGED
|
@@ -8,7 +8,7 @@ export function fillArray(options) {
|
|
|
8
8
|
const total = count * length;
|
|
9
9
|
let copied = 0;
|
|
10
10
|
for (let i = start; copied < length; copied++) {
|
|
11
|
-
target[i++] = source[copied];
|
|
11
|
+
target[i++] = source[copied] ?? 0;
|
|
12
12
|
}
|
|
13
13
|
while (copied < total) {
|
|
14
14
|
// If we have copied less than half, copy everything we got
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fill-array.js","sourceRoot":"","sources":["../../src/utils/fill-array.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAIpC,sEAAsE;AACtE,MAAM,UAAU,SAAS,CAAC,OAKzB;IACC,MAAM,EAAC,MAAM,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAC,GAAG,OAAO,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC7B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;QAC9C,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"fill-array.js","sourceRoot":"","sources":["../../src/utils/fill-array.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAIpC,sEAAsE;AACtE,MAAM,UAAU,SAAS,CAAC,OAKzB;IACC,MAAM,EAAC,MAAM,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAC,GAAG,OAAO,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC7B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;QAC9C,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,MAAM,GAAG,KAAK,EAAE,CAAC;QACtB,2DAA2D;QAC3D,uCAAuC;QACvC,IAAI,MAAM,GAAG,KAAK,GAAG,MAAM,EAAE,CAAC;YAC5B,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC;YACzD,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC,CAAC;YACjE,MAAM,GAAG,KAAK,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC;AACxB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luma.gl/webgl",
|
|
3
|
-
"version": "9.3.0-alpha.
|
|
3
|
+
"version": "9.3.0-alpha.4",
|
|
4
4
|
"description": "WebGL2 adapter for the luma.gl core API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
"@luma.gl/core": "9.2.0-alpha.6"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@luma.gl/constants": "9.3.0-alpha.
|
|
46
|
+
"@luma.gl/constants": "9.3.0-alpha.4",
|
|
47
47
|
"@math.gl/types": "^4.1.0",
|
|
48
|
-
"@probe.gl/env": "^4.
|
|
48
|
+
"@probe.gl/env": "^4.1.1"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "7486e7b0377fb6ab961b4499828681bede60f3b1"
|
|
51
51
|
}
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
VaryingBinding,
|
|
11
11
|
AttributeShaderType
|
|
12
12
|
} from '@luma.gl/core';
|
|
13
|
-
import {getVariableShaderTypeInfo} from '@luma.gl/core';
|
|
13
|
+
import {getVariableShaderTypeInfo, assertDefined} from '@luma.gl/core';
|
|
14
14
|
|
|
15
15
|
import {GL, GLUniformType} from '@luma.gl/constants';
|
|
16
16
|
import {
|
|
@@ -252,7 +252,11 @@ function readUniformBlocks(
|
|
|
252
252
|
// ); // Array of GLint indicating the strides between columns of a column-major matrix or a row-major matrix.
|
|
253
253
|
// const uniformRowMajor = gl.getActiveUniforms(program, uniformIndices, GL.UNIFORM_IS_ROW_MAJOR);
|
|
254
254
|
for (let i = 0; i < blockInfo.uniformCount; ++i) {
|
|
255
|
-
const
|
|
255
|
+
const uniformIndex = uniformIndices[i];
|
|
256
|
+
if (uniformIndex === undefined) {
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
const activeInfo = gl.getActiveUniform(program, uniformIndex);
|
|
256
260
|
if (!activeInfo) {
|
|
257
261
|
throw new Error('activeInfo');
|
|
258
262
|
}
|
|
@@ -314,13 +318,11 @@ function parseUniformName(name: string): {name: string; length: number; isArray:
|
|
|
314
318
|
// if array name then clean the array brackets
|
|
315
319
|
const UNIFORM_NAME_REGEXP = /([^[]*)(\[[0-9]+\])?/;
|
|
316
320
|
const matches = UNIFORM_NAME_REGEXP.exec(name);
|
|
317
|
-
|
|
318
|
-
throw new Error(`Failed to parse GLSL uniform name ${name}`);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
+
const uniformName = assertDefined(matches?.[1], `Failed to parse GLSL uniform name ${name}`);
|
|
321
322
|
return {
|
|
322
|
-
name:
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
name: uniformName,
|
|
324
|
+
// TODO - is this a bug, shouldn't we return the value?
|
|
325
|
+
length: matches?.[2] ? 1 : 0,
|
|
326
|
+
isArray: Boolean(matches?.[2])
|
|
325
327
|
};
|
|
326
328
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import type
|
|
5
|
+
import {type CompilerMessage} from '@luma.gl/core';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Parse a WebGL-format GLSL compilation log into an array of WebGPU style message records.
|
|
@@ -20,21 +20,43 @@ export function parseShaderCompilerLog(errLog: string): readonly CompilerMessage
|
|
|
20
20
|
continue; // eslint-disable-line no-continue
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
const lineWithTrimmedWhitespace = line.trim();
|
|
24
|
+
|
|
23
25
|
const segments: string[] = line.split(':');
|
|
26
|
+
const trimmedMessageType = segments[0]?.trim();
|
|
24
27
|
|
|
25
28
|
// Check for messages with no line information `ERROR: unsupported shader version`
|
|
26
29
|
if (segments.length === 2) {
|
|
27
30
|
const [messageType, message] = segments;
|
|
31
|
+
if (!messageType || !message) {
|
|
32
|
+
messages.push({
|
|
33
|
+
message: lineWithTrimmedWhitespace,
|
|
34
|
+
type: getMessageType(trimmedMessageType || 'info'),
|
|
35
|
+
lineNum: 0,
|
|
36
|
+
linePos: 0
|
|
37
|
+
});
|
|
38
|
+
continue; // eslint-disable-line no-continue
|
|
39
|
+
}
|
|
28
40
|
messages.push({
|
|
29
41
|
message: message.trim(),
|
|
30
42
|
type: getMessageType(messageType),
|
|
31
43
|
lineNum: 0,
|
|
32
44
|
linePos: 0
|
|
33
45
|
});
|
|
46
|
+
|
|
34
47
|
continue; // eslint-disable-line no-continue
|
|
35
48
|
}
|
|
36
49
|
|
|
37
50
|
const [messageType, linePosition, lineNumber, ...rest] = segments;
|
|
51
|
+
if (!messageType || !linePosition || !lineNumber) {
|
|
52
|
+
messages.push({
|
|
53
|
+
message: segments.slice(1).join(':').trim() || lineWithTrimmedWhitespace,
|
|
54
|
+
type: getMessageType(trimmedMessageType || 'info'),
|
|
55
|
+
lineNum: 0,
|
|
56
|
+
linePos: 0
|
|
57
|
+
});
|
|
58
|
+
continue; // eslint-disable-line no-continue
|
|
59
|
+
}
|
|
38
60
|
|
|
39
61
|
let lineNum = parseInt(lineNumber, 10);
|
|
40
62
|
if (isNaN(lineNum)) {
|
|
@@ -2,23 +2,19 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import type {
|
|
6
|
-
CopyBufferToBufferOptions,
|
|
7
|
-
CopyBufferToTextureOptions,
|
|
8
|
-
CopyTextureToBufferOptions,
|
|
9
|
-
CopyTextureToTextureOptions
|
|
10
|
-
// ClearTextureOptions,
|
|
11
|
-
// TextureReadOptions
|
|
12
|
-
} from '@luma.gl/core';
|
|
13
|
-
import {CommandBuffer, Texture, Framebuffer} from '@luma.gl/core';
|
|
14
5
|
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
|
|
6
|
+
type CopyBufferToBufferOptions,
|
|
7
|
+
type CopyBufferToTextureOptions,
|
|
8
|
+
type CopyTextureToBufferOptions,
|
|
9
|
+
type CopyTextureToTextureOptions,
|
|
10
|
+
// type ClearTextureOptions,
|
|
11
|
+
// type TextureReadOptions
|
|
12
|
+
CommandBuffer,
|
|
13
|
+
Texture,
|
|
14
|
+
Framebuffer,
|
|
15
|
+
assertDefined
|
|
16
|
+
} from '@luma.gl/core';
|
|
17
|
+
import {GL, type GLTextureTarget, type GLTextureCubeMapTarget} from '@luma.gl/constants';
|
|
22
18
|
|
|
23
19
|
import {WebGLDevice} from '../webgl-device';
|
|
24
20
|
import {WEBGLBuffer} from './webgl-buffer';
|
|
@@ -145,7 +141,7 @@ function _copyTextureToBuffer(device: WebGLDevice, options: CopyTextureToBufferO
|
|
|
145
141
|
height = options.sourceTexture.height,
|
|
146
142
|
depthOrArrayLayers = 0,
|
|
147
143
|
/** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
|
|
148
|
-
origin = [0, 0],
|
|
144
|
+
origin = [0, 0, 0],
|
|
149
145
|
|
|
150
146
|
/** Destination buffer */
|
|
151
147
|
destinationBuffer,
|
|
@@ -181,9 +177,9 @@ function _copyTextureToBuffer(device: WebGLDevice, options: CopyTextureToBufferO
|
|
|
181
177
|
const webglBuffer = destinationBuffer as WEBGLBuffer;
|
|
182
178
|
const sourceWidth = width || framebuffer.width;
|
|
183
179
|
const sourceHeight = height || framebuffer.height;
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
);
|
|
180
|
+
const colorAttachment0 = assertDefined(framebuffer.colorAttachments[0]);
|
|
181
|
+
|
|
182
|
+
const sourceParams = getTextureFormatWebGL(colorAttachment0.texture.props.format);
|
|
187
183
|
const sourceFormat = sourceParams.format;
|
|
188
184
|
const sourceType = sourceParams.type;
|
|
189
185
|
|
|
@@ -256,7 +252,7 @@ function _copyTextureToTexture(device: WebGLDevice, options: CopyTextureToTextur
|
|
|
256
252
|
origin = [0, 0],
|
|
257
253
|
|
|
258
254
|
/** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to. */
|
|
259
|
-
destinationOrigin = [0, 0],
|
|
255
|
+
destinationOrigin = [0, 0, 0],
|
|
260
256
|
|
|
261
257
|
/** Texture to copy to/from. */
|
|
262
258
|
destinationTexture
|
|
@@ -275,7 +271,7 @@ function _copyTextureToTexture(device: WebGLDevice, options: CopyTextureToTextur
|
|
|
275
271
|
} = options;
|
|
276
272
|
|
|
277
273
|
const {framebuffer, destroyFramebuffer} = getFramebuffer(sourceTexture);
|
|
278
|
-
const [sourceX, sourceY] = origin;
|
|
274
|
+
const [sourceX = 0, sourceY = 0] = origin;
|
|
279
275
|
const [destinationX, destinationY, destinationZ] = destinationOrigin;
|
|
280
276
|
|
|
281
277
|
// @ts-expect-error native bindFramebuffer is overridden by our state tracker
|
|
@@ -24,6 +24,12 @@ export class WEBGLRenderPass extends RenderPass {
|
|
|
24
24
|
super(device, props);
|
|
25
25
|
this.device = device;
|
|
26
26
|
|
|
27
|
+
if (!props?.framebuffer) {
|
|
28
|
+
// Default-framebuffer rendering bypasses CanvasContext.getCurrentFramebuffer(),
|
|
29
|
+
// so flush any deferred canvas resize before deriving viewport state.
|
|
30
|
+
device.getDefaultCanvasContext()._resizeDrawingBufferIfNeeded();
|
|
31
|
+
}
|
|
32
|
+
|
|
27
33
|
// If no viewport is provided, apply reasonably defaults
|
|
28
34
|
let viewport: NumberArray4 | undefined;
|
|
29
35
|
if (!props?.parameters?.viewport) {
|
|
@@ -452,8 +452,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
|
|
|
452
452
|
if ((location as GL) === GL.INVALID_INDEX) {
|
|
453
453
|
throw new Error(`Invalid uniform block name ${name}`);
|
|
454
454
|
}
|
|
455
|
-
gl.uniformBlockBinding(this.handle,
|
|
456
|
-
// console.debug(binding, location);
|
|
455
|
+
gl.uniformBlockBinding(this.handle, location, uniformBufferIndex);
|
|
457
456
|
if (value instanceof WEBGLBuffer) {
|
|
458
457
|
gl.bindBufferBase(GL.UNIFORM_BUFFER, uniformBufferIndex, value.handle);
|
|
459
458
|
} else {
|
|
@@ -69,8 +69,8 @@ export class WEBGLTransformFeedback extends TransformFeedback {
|
|
|
69
69
|
this.unusedBuffers = {};
|
|
70
70
|
|
|
71
71
|
this.bind(() => {
|
|
72
|
-
for (const bufferName
|
|
73
|
-
this.setBuffer(bufferName,
|
|
72
|
+
for (const [bufferName, buffer] of Object.entries(buffers)) {
|
|
73
|
+
this.setBuffer(bufferName, buffer);
|
|
74
74
|
}
|
|
75
75
|
});
|
|
76
76
|
}
|
|
@@ -99,7 +99,7 @@ export class WEBGLTransformFeedback extends TransformFeedback {
|
|
|
99
99
|
return this.buffers[locationOrName] || null;
|
|
100
100
|
}
|
|
101
101
|
const location = this._getVaryingIndex(locationOrName);
|
|
102
|
-
return
|
|
102
|
+
return this.buffers[location] ?? null;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
bind(funcOrHandle: (() => void) | WebGLTransformFeedback | null = this.handle) {
|
|
@@ -162,8 +162,8 @@ export class WEBGLTransformFeedback extends TransformFeedback {
|
|
|
162
162
|
* cannot be bound to 'TRANSFORM_FEEDBACK_BUFFER' target.
|
|
163
163
|
*/
|
|
164
164
|
protected _bindBuffers(): void {
|
|
165
|
-
for (const bufferIndex
|
|
166
|
-
const {buffer, byteLength, byteOffset} = this._getBufferRange(
|
|
165
|
+
for (const [bufferIndex, bufferEntry] of Object.entries(this.buffers)) {
|
|
166
|
+
const {buffer, byteLength, byteOffset} = this._getBufferRange(bufferEntry);
|
|
167
167
|
this._bindBuffer(Number(bufferIndex), buffer, byteOffset, byteLength);
|
|
168
168
|
}
|
|
169
169
|
}
|
|
@@ -55,10 +55,9 @@ export class WebGLAdapter extends Adapter {
|
|
|
55
55
|
if (gl instanceof WebGLDevice) {
|
|
56
56
|
return gl;
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
return gl.device as WebGLDevice;
|
|
58
|
+
const existingDevice = WebGLDevice.getDeviceFromContext(gl as WebGL2RenderingContext | null);
|
|
59
|
+
if (existingDevice) {
|
|
60
|
+
return existingDevice;
|
|
62
61
|
}
|
|
63
62
|
if (!isWebGL(gl)) {
|
|
64
63
|
throw new Error('Invalid WebGL2RenderingContext');
|
|
@@ -36,6 +36,7 @@ import {Device, CanvasContext, log} from '@luma.gl/core';
|
|
|
36
36
|
import type {GLExtensions} from '@luma.gl/constants';
|
|
37
37
|
import {WebGLStateTracker} from '../context/state-tracker/webgl-state-tracker';
|
|
38
38
|
import {createBrowserContext} from '../context/helpers/create-browser-context';
|
|
39
|
+
import {getWebGLContextData} from '../context/helpers/webgl-context-data';
|
|
39
40
|
import {getDeviceInfo} from './device-helpers/webgl-device-info';
|
|
40
41
|
import {WebGLDeviceFeatures} from './device-helpers/webgl-device-features';
|
|
41
42
|
import {WebGLDeviceLimits} from './device-helpers/webgl-device-limits';
|
|
@@ -70,6 +71,13 @@ import {getWebGLExtension} from '../context/helpers/webgl-extensions';
|
|
|
70
71
|
|
|
71
72
|
/** WebGPU style Device API for a WebGL context */
|
|
72
73
|
export class WebGLDevice extends Device {
|
|
74
|
+
static getDeviceFromContext(gl: WebGL2RenderingContext | null): WebGLDevice | null {
|
|
75
|
+
if (!gl) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
// @ts-expect-error Ingore WebGL2RenderingContext type
|
|
79
|
+
return gl.luma?.device ?? null;
|
|
80
|
+
}
|
|
73
81
|
// Public `Device` API
|
|
74
82
|
|
|
75
83
|
/** type of this device */
|
|
@@ -100,7 +108,7 @@ export class WebGLDevice extends Device {
|
|
|
100
108
|
_constants: (TypedArray | null)[];
|
|
101
109
|
|
|
102
110
|
/** State used by luma.gl classes - TODO - not used? */
|
|
103
|
-
readonly
|
|
111
|
+
readonly extensions!: GLExtensions;
|
|
104
112
|
_polyfilled: boolean = false;
|
|
105
113
|
|
|
106
114
|
/** Instance of Spector.js (if initialized) */
|
|
@@ -141,7 +149,8 @@ export class WebGLDevice extends Device {
|
|
|
141
149
|
// Note that this can be avoided in webgl2adapter.create() if
|
|
142
150
|
// DeviceProps._reuseDevices is set.
|
|
143
151
|
// @ts-expect-error device is attached to context
|
|
144
|
-
|
|
152
|
+
const existingContext = canvasContextProps.canvas?.gl ?? null;
|
|
153
|
+
let device: WebGLDevice | null = WebGLDevice.getDeviceFromContext(existingContext);
|
|
145
154
|
if (device) {
|
|
146
155
|
throw new Error(`WebGL context already attached to device ${device.id}`);
|
|
147
156
|
}
|
|
@@ -190,8 +199,7 @@ export class WebGLDevice extends Device {
|
|
|
190
199
|
|
|
191
200
|
// Note that the browser will only create one WebGL context per canvas.
|
|
192
201
|
// This means that a newly created gl context may already have a device attached to it.
|
|
193
|
-
|
|
194
|
-
device = gl.device;
|
|
202
|
+
device = WebGLDevice.getDeviceFromContext(gl);
|
|
195
203
|
if (device) {
|
|
196
204
|
if (props._reuseDevices) {
|
|
197
205
|
log.log(
|
|
@@ -199,6 +207,9 @@ export class WebGLDevice extends Device {
|
|
|
199
207
|
`Not creating a new Device, instead returning a reference to Device ${device.id} already attached to WebGL context`,
|
|
200
208
|
device
|
|
201
209
|
)();
|
|
210
|
+
// Destroy the orphaned canvas context that was created above (line 149)
|
|
211
|
+
// to prevent its ResizeObserver from firing callbacks with undefined device
|
|
212
|
+
this.canvasContext.destroy();
|
|
202
213
|
device._reused = true;
|
|
203
214
|
return device;
|
|
204
215
|
}
|
|
@@ -214,16 +225,15 @@ export class WebGLDevice extends Device {
|
|
|
214
225
|
this.spectorJS = initializeSpectorJS({...this.props, gl: this.handle});
|
|
215
226
|
|
|
216
227
|
// Instrument context
|
|
217
|
-
|
|
228
|
+
const contextData = getWebGLContextData(this.handle);
|
|
229
|
+
contextData.device = this; // Update GL context: Link webgl context back to device
|
|
230
|
+
|
|
231
|
+
this.extensions = contextData.extensions || (contextData.extensions = {});
|
|
218
232
|
|
|
219
233
|
// initialize luma Device fields
|
|
220
|
-
this.info = getDeviceInfo(this.gl, this.
|
|
234
|
+
this.info = getDeviceInfo(this.gl, this.extensions);
|
|
221
235
|
this.limits = new WebGLDeviceLimits(this.gl);
|
|
222
|
-
this.features = new WebGLDeviceFeatures(
|
|
223
|
-
this.gl,
|
|
224
|
-
this._extensions,
|
|
225
|
-
this.props._disabledFeatures
|
|
226
|
-
);
|
|
236
|
+
this.features = new WebGLDeviceFeatures(this.gl, this.extensions, this.props._disabledFeatures);
|
|
227
237
|
if (this.props._initializeFeatures) {
|
|
228
238
|
this.features.initializeFeatures();
|
|
229
239
|
}
|
|
@@ -265,7 +275,8 @@ export class WebGLDevice extends Device {
|
|
|
265
275
|
// Therefore we must do nothing in destroy() if props._reuseDevices is true
|
|
266
276
|
if (!this.props._reuseDevices && !this._reused) {
|
|
267
277
|
// Delete the reference to the device that we store on the WebGL context
|
|
268
|
-
|
|
278
|
+
const contextData = getWebGLContextData(this.handle);
|
|
279
|
+
contextData.device = null;
|
|
269
280
|
}
|
|
270
281
|
}
|
|
271
282
|
|
|
@@ -407,7 +418,7 @@ export class WebGLDevice extends Device {
|
|
|
407
418
|
override _getDeviceSpecificTextureFormatCapabilities(
|
|
408
419
|
capabilities: DeviceTextureFormatCapabilities
|
|
409
420
|
): DeviceTextureFormatCapabilities {
|
|
410
|
-
return getTextureFormatCapabilitiesWebGL(this.gl, capabilities, this.
|
|
421
|
+
return getTextureFormatCapabilitiesWebGL(this.gl, capabilities, this.extensions);
|
|
411
422
|
}
|
|
412
423
|
|
|
413
424
|
//
|
|
@@ -510,8 +521,8 @@ export class WebGLDevice extends Device {
|
|
|
510
521
|
|
|
511
522
|
/** Ensure extensions are only requested once */
|
|
512
523
|
getExtension(name: keyof GLExtensions): GLExtensions {
|
|
513
|
-
getWebGLExtension(this.gl, name, this.
|
|
514
|
-
return this.
|
|
524
|
+
getWebGLExtension(this.gl, name, this.extensions);
|
|
525
|
+
return this.extensions;
|
|
515
526
|
}
|
|
516
527
|
|
|
517
528
|
// INTERNAL SUPPORT METHODS FOR WEBGL RESOURCES
|
|
@@ -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