@luma.gl/webgl 9.2.5 → 9.3.0-alpha.2
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/resources/webgl-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-buffer.js +1 -0
- package/dist/adapter/resources/webgl-buffer.js.map +1 -1
- package/dist/adapter/resources/webgl-fence.d.ts +14 -0
- package/dist/adapter/resources/webgl-fence.d.ts.map +1 -0
- package/dist/adapter/resources/webgl-fence.js +49 -0
- package/dist/adapter/resources/webgl-fence.js.map +1 -0
- package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.js +4 -6
- package/dist/adapter/resources/webgl-render-pass.js.map +1 -1
- package/dist/adapter/resources/webgl-texture.d.ts +21 -4
- package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-texture.js +148 -22
- package/dist/adapter/resources/webgl-texture.js.map +1 -1
- package/dist/adapter/webgl-adapter.d.ts.map +1 -1
- package/dist/adapter/webgl-adapter.js +19 -19
- package/dist/adapter/webgl-adapter.js.map +1 -1
- package/dist/adapter/webgl-canvas-context.d.ts +2 -2
- package/dist/adapter/webgl-canvas-context.d.ts.map +1 -1
- package/dist/adapter/webgl-canvas-context.js +16 -6
- package/dist/adapter/webgl-canvas-context.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 +14 -13
- package/dist/adapter/webgl-device.js.map +1 -1
- package/dist/context/debug/webgl-developer-tools.js +4 -6
- 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 +47 -35
- package/dist/context/helpers/create-browser-context.js.map +1 -1
- package/dist/dist.dev.js +468 -274
- package/dist/dist.min.js +2 -2
- package/dist/index.cjs +447 -275
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/adapter/resources/webgl-buffer.ts +1 -0
- package/src/adapter/resources/webgl-fence.ts +55 -0
- package/src/adapter/resources/webgl-render-pass.ts +4 -6
- package/src/adapter/resources/webgl-texture.ts +209 -37
- package/src/adapter/webgl-adapter.ts +23 -20
- package/src/adapter/webgl-canvas-context.ts +19 -8
- package/src/adapter/webgl-device.ts +15 -14
- package/src/context/debug/webgl-developer-tools.ts +13 -6
- package/src/context/helpers/create-browser-context.ts +54 -43
- package/src/index.ts +1 -0
|
@@ -57,6 +57,7 @@ import {WEBGLCommandBuffer} from './resources/webgl-command-buffer';
|
|
|
57
57
|
import {WEBGLVertexArray} from './resources/webgl-vertex-array';
|
|
58
58
|
import {WEBGLTransformFeedback} from './resources/webgl-transform-feedback';
|
|
59
59
|
import {WEBGLQuerySet} from './resources/webgl-query-set';
|
|
60
|
+
import {WEBGLFence} from './resources/webgl-fence';
|
|
60
61
|
|
|
61
62
|
import {readPixelsToArray, readPixelsToBuffer} from './helpers/webgl-texture-utils';
|
|
62
63
|
import {
|
|
@@ -160,6 +161,9 @@ export class WebGLDevice extends Device {
|
|
|
160
161
|
if (props.powerPreference !== undefined) {
|
|
161
162
|
webglContextAttributes.powerPreference = props.powerPreference;
|
|
162
163
|
}
|
|
164
|
+
if (props.failIfMajorPerformanceCaveat !== undefined) {
|
|
165
|
+
webglContextAttributes.failIfMajorPerformanceCaveat = props.failIfMajorPerformanceCaveat;
|
|
166
|
+
}
|
|
163
167
|
|
|
164
168
|
// Check if we should attach to an externally created context or create a new context
|
|
165
169
|
const externalGLContext = this.props._handle as WebGL2RenderingContext | null;
|
|
@@ -211,8 +215,6 @@ export class WebGLDevice extends Device {
|
|
|
211
215
|
|
|
212
216
|
// Instrument context
|
|
213
217
|
(this.gl as any).device = this; // Update GL context: Link webgl context back to device
|
|
214
|
-
// TODO - remove, this is only used to detect debug contexts.
|
|
215
|
-
(this.gl as any)._version = 2; // Update GL context: Store WebGL version field on gl context (HACK to identify debug contexts)
|
|
216
218
|
|
|
217
219
|
// initialize luma Device fields
|
|
218
220
|
this.info = getDeviceInfo(this.gl, this._extensions);
|
|
@@ -232,15 +234,14 @@ export class WebGLDevice extends Device {
|
|
|
232
234
|
});
|
|
233
235
|
glState.trackState(this.gl, {copyState: false});
|
|
234
236
|
|
|
235
|
-
//
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
this.gl = makeDebugContext(this.gl, {debugWebGL, traceWebGL});
|
|
237
|
+
// props.debug - instrument the WebGL context with Khronos debug tools
|
|
238
|
+
// props.debugWebGL - activate WebGL context tracing, force log level to at least 1
|
|
239
|
+
if (props.debug || props.debugWebGL) {
|
|
240
|
+
this.gl = makeDebugContext(this.gl, {debugWebGL: true, traceWebGL: props.debugWebGL});
|
|
240
241
|
log.warn('WebGL debug mode activated. Performance reduced.')();
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
}
|
|
243
|
+
if (props.debugWebGL) {
|
|
244
|
+
log.level = Math.max(log.level, 1);
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
this.commandEncoder = new WEBGLCommandEncoder(this, {id: `${this}-command-encoder`});
|
|
@@ -274,10 +275,6 @@ export class WebGLDevice extends Device {
|
|
|
274
275
|
|
|
275
276
|
// IMPLEMENTATION OF ABSTRACT DEVICE
|
|
276
277
|
|
|
277
|
-
getTextureByteAlignment(): number {
|
|
278
|
-
return 4;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
278
|
createCanvasContext(props?: CanvasContextProps): CanvasContext {
|
|
282
279
|
throw new Error('WebGL only supports a single canvas');
|
|
283
280
|
}
|
|
@@ -319,6 +316,10 @@ export class WebGLDevice extends Device {
|
|
|
319
316
|
return new WEBGLQuerySet(this, props);
|
|
320
317
|
}
|
|
321
318
|
|
|
319
|
+
override createFence(): WEBGLFence {
|
|
320
|
+
return new WEBGLFence(this);
|
|
321
|
+
}
|
|
322
|
+
|
|
322
323
|
createRenderPipeline(props: RenderPipelineProps): WEBGLRenderPipeline {
|
|
323
324
|
return new WEBGLRenderPipeline(this, props);
|
|
324
325
|
}
|
|
@@ -132,9 +132,13 @@ function onGLError(
|
|
|
132
132
|
const functionArgs = globalThis.WebGLDebugUtils.glFunctionArgsToString(functionName, args);
|
|
133
133
|
const message = `${errorMessage} in gl.${functionName}(${functionArgs})`;
|
|
134
134
|
// TODO - call device.reportError
|
|
135
|
-
log.error(
|
|
135
|
+
log.error(
|
|
136
|
+
'%cWebGL',
|
|
137
|
+
'color: white; background: red; padding: 2px 6px; border-radius: 3px;',
|
|
138
|
+
message
|
|
139
|
+
)();
|
|
136
140
|
debugger; // eslint-disable-line
|
|
137
|
-
|
|
141
|
+
throw new Error(message);
|
|
138
142
|
}
|
|
139
143
|
|
|
140
144
|
// Don't generate function string until it is needed
|
|
@@ -144,11 +148,14 @@ function onValidateGLFunc(
|
|
|
144
148
|
functionArgs: unknown[]
|
|
145
149
|
): void {
|
|
146
150
|
let functionString: string = '';
|
|
147
|
-
if (log.level >= 1) {
|
|
151
|
+
if (props.traceWebGL && log.level >= 1) {
|
|
148
152
|
functionString = getFunctionString(functionName, functionArgs);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
153
|
+
log.info(
|
|
154
|
+
1,
|
|
155
|
+
'%cWebGL',
|
|
156
|
+
'color: white; background: blue; padding: 2px 6px; border-radius: 3px;',
|
|
157
|
+
functionString
|
|
158
|
+
)();
|
|
152
159
|
}
|
|
153
160
|
|
|
154
161
|
for (const arg of functionArgs) {
|
|
@@ -26,63 +26,74 @@ export function createBrowserContext(
|
|
|
26
26
|
): WebGL2RenderingContext {
|
|
27
27
|
// Try to extract any extra information about why context creation failed
|
|
28
28
|
let errorMessage = '';
|
|
29
|
-
|
|
29
|
+
const onCreateError = (event: Event) => {
|
|
30
|
+
const statusMessage = (event as WebGLContextEvent).statusMessage;
|
|
31
|
+
if (statusMessage) {
|
|
32
|
+
errorMessage ||= statusMessage;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
canvas.addEventListener('webglcontextcreationerror', onCreateError, false);
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
// canvas.removeEventListener('webglcontextcreationerror', onCreateError, false);
|
|
33
|
-
// canvas.addEventListener('webglcontextcreationerror', onCreateError, false);
|
|
37
|
+
const allowSoftwareRenderer = webglContextAttributes.failIfMajorPerformanceCaveat !== true;
|
|
34
38
|
|
|
35
39
|
const webglProps: WebGLContextAttributes = {
|
|
36
40
|
preserveDrawingBuffer: true,
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
...webglContextAttributes,
|
|
42
|
+
// Always start by requesting a high-performance context.
|
|
43
|
+
failIfMajorPerformanceCaveat: true
|
|
39
44
|
};
|
|
40
45
|
|
|
41
46
|
// Create the desired context
|
|
42
47
|
let gl: WebGL2RenderingContext | null = null;
|
|
43
48
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
try {
|
|
50
|
+
// Create a webgl2 context
|
|
51
|
+
gl ||= canvas.getContext('webgl2', webglProps);
|
|
52
|
+
if (!gl && webglProps.failIfMajorPerformanceCaveat) {
|
|
53
|
+
errorMessage ||=
|
|
54
|
+
'Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow.';
|
|
55
|
+
}
|
|
50
56
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
// Creation failed with failIfMajorPerformanceCaveat - Try a Software GPU
|
|
58
|
+
if (!gl && allowSoftwareRenderer) {
|
|
59
|
+
webglProps.failIfMajorPerformanceCaveat = false;
|
|
60
|
+
gl = canvas.getContext('webgl2', webglProps);
|
|
61
|
+
if (gl) {
|
|
62
|
+
// @ts-expect-error
|
|
63
|
+
gl.luma ||= {};
|
|
64
|
+
// @ts-expect-error
|
|
65
|
+
gl.luma.softwareRenderer = true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
60
68
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
if (!gl) {
|
|
70
|
+
gl = canvas.getContext('webgl', {}) as WebGL2RenderingContext;
|
|
71
|
+
if (gl) {
|
|
72
|
+
gl = null;
|
|
73
|
+
errorMessage ||= 'Your browser only supports WebGL1';
|
|
74
|
+
}
|
|
66
75
|
}
|
|
67
|
-
}
|
|
68
76
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
77
|
+
if (!gl) {
|
|
78
|
+
errorMessage ||= 'Your browser does not support WebGL';
|
|
79
|
+
throw new Error(`Failed to create WebGL context: ${errorMessage}`);
|
|
80
|
+
}
|
|
73
81
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
// Carefully extract and wrap callbacks to prevent addEventListener from rebinding them.
|
|
83
|
+
const {onContextLost, onContextRestored} = props;
|
|
84
|
+
canvas.addEventListener('webglcontextlost', (event: Event) => onContextLost(event), false);
|
|
85
|
+
canvas.addEventListener(
|
|
86
|
+
'webglcontextrestored',
|
|
87
|
+
(event: Event) => onContextRestored(event),
|
|
88
|
+
false
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// @ts-expect-error
|
|
92
|
+
gl.luma ||= {};
|
|
93
|
+
return gl;
|
|
94
|
+
} finally {
|
|
95
|
+
canvas.removeEventListener('webglcontextcreationerror', onCreateError, false);
|
|
96
|
+
}
|
|
86
97
|
}
|
|
87
98
|
|
|
88
99
|
/* TODO - can we call this asynchronously to catch the error events?
|
package/src/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ export {WEBGLTexture} from './adapter/resources/webgl-texture';
|
|
|
26
26
|
export {WEBGLShader} from './adapter/resources/webgl-shader';
|
|
27
27
|
export {WEBGLSampler} from './adapter/resources/webgl-sampler';
|
|
28
28
|
export {WEBGLFramebuffer} from './adapter/resources/webgl-framebuffer';
|
|
29
|
+
export {WEBGLFence} from './adapter/resources/webgl-fence';
|
|
29
30
|
|
|
30
31
|
export {WEBGLRenderPipeline} from './adapter/resources/webgl-render-pipeline';
|
|
31
32
|
// export {WEBGLComputePipeline} from './adapter/resources/webgl-compute-pipeline';
|