@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.
Files changed (49) hide show
  1. package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
  2. package/dist/adapter/resources/webgl-buffer.js +1 -0
  3. package/dist/adapter/resources/webgl-buffer.js.map +1 -1
  4. package/dist/adapter/resources/webgl-fence.d.ts +14 -0
  5. package/dist/adapter/resources/webgl-fence.d.ts.map +1 -0
  6. package/dist/adapter/resources/webgl-fence.js +49 -0
  7. package/dist/adapter/resources/webgl-fence.js.map +1 -0
  8. package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
  9. package/dist/adapter/resources/webgl-render-pass.js +4 -6
  10. package/dist/adapter/resources/webgl-render-pass.js.map +1 -1
  11. package/dist/adapter/resources/webgl-texture.d.ts +21 -4
  12. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  13. package/dist/adapter/resources/webgl-texture.js +148 -22
  14. package/dist/adapter/resources/webgl-texture.js.map +1 -1
  15. package/dist/adapter/webgl-adapter.d.ts.map +1 -1
  16. package/dist/adapter/webgl-adapter.js +19 -19
  17. package/dist/adapter/webgl-adapter.js.map +1 -1
  18. package/dist/adapter/webgl-canvas-context.d.ts +2 -2
  19. package/dist/adapter/webgl-canvas-context.d.ts.map +1 -1
  20. package/dist/adapter/webgl-canvas-context.js +16 -6
  21. package/dist/adapter/webgl-canvas-context.js.map +1 -1
  22. package/dist/adapter/webgl-device.d.ts +2 -1
  23. package/dist/adapter/webgl-device.d.ts.map +1 -1
  24. package/dist/adapter/webgl-device.js +14 -13
  25. package/dist/adapter/webgl-device.js.map +1 -1
  26. package/dist/context/debug/webgl-developer-tools.js +4 -6
  27. package/dist/context/debug/webgl-developer-tools.js.map +1 -1
  28. package/dist/context/helpers/create-browser-context.d.ts.map +1 -1
  29. package/dist/context/helpers/create-browser-context.js +47 -35
  30. package/dist/context/helpers/create-browser-context.js.map +1 -1
  31. package/dist/dist.dev.js +468 -274
  32. package/dist/dist.min.js +2 -2
  33. package/dist/index.cjs +447 -275
  34. package/dist/index.cjs.map +4 -4
  35. package/dist/index.d.ts +1 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +1 -0
  38. package/dist/index.js.map +1 -1
  39. package/package.json +4 -4
  40. package/src/adapter/resources/webgl-buffer.ts +1 -0
  41. package/src/adapter/resources/webgl-fence.ts +55 -0
  42. package/src/adapter/resources/webgl-render-pass.ts +4 -6
  43. package/src/adapter/resources/webgl-texture.ts +209 -37
  44. package/src/adapter/webgl-adapter.ts +23 -20
  45. package/src/adapter/webgl-canvas-context.ts +19 -8
  46. package/src/adapter/webgl-device.ts +15 -14
  47. package/src/context/debug/webgl-developer-tools.ts +13 -6
  48. package/src/context/helpers/create-browser-context.ts +54 -43
  49. 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
- // DEBUG contexts: Add luma debug instrumentation to the context, force log level to at least 1
236
- const debugWebGL = props.debugWebGL || props.debug;
237
- const traceWebGL = props.debugWebGL;
238
- if (debugWebGL) {
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
- if (props.debugWebGL) {
242
- log.level = Math.max(log.level, 1);
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(message)();
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
- // throw new Error(message);
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
- if (props.traceWebGL) {
150
- log.log(1, functionString)();
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
- // const onCreateError = error => (errorMessage = error.statusMessage || errorMessage);
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
- // Avoid multiple listeners?
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
- // failIfMajorPerformanceCaveat: true,
38
- ...webglContextAttributes
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
- // Create a webgl2 context
45
- gl ||= canvas.getContext('webgl2', webglProps);
46
- if (webglProps.failIfMajorPerformanceCaveat) {
47
- errorMessage ||=
48
- 'Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow.';
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
- // Creation failed with failIfMajorPerformanceCaveat - Try a Software GPU
52
- if (!gl && !webglContextAttributes.failIfMajorPerformanceCaveat) {
53
- webglProps.failIfMajorPerformanceCaveat = false;
54
- gl = canvas.getContext('webgl2', webglProps);
55
- // @ts-expect-error
56
- gl.luma ||= {};
57
- // @ts-expect-error
58
- gl.luma.softwareRenderer = true;
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
- if (!gl) {
62
- gl = canvas.getContext('webgl', {}) as WebGL2RenderingContext;
63
- if (gl) {
64
- gl = null;
65
- errorMessage ||= 'Your browser only supports WebGL1';
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
- if (!gl) {
70
- errorMessage ||= 'Your browser does not support WebGL';
71
- throw new Error(`Failed to create WebGL context: ${errorMessage}`);
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
- // Carefully extract and wrap callbacks to prevent addEventListener from rebinding them.
75
- const {onContextLost, onContextRestored} = props;
76
- canvas.addEventListener('webglcontextlost', (event: Event) => onContextLost(event), false);
77
- canvas.addEventListener(
78
- 'webglcontextrestored',
79
- (event: Event) => onContextRestored(event),
80
- false
81
- );
82
-
83
- // @ts-expect-error
84
- gl.luma ||= {};
85
- return gl;
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';