@luma.gl/webgl 9.1.0-alpha.16 → 9.1.0-alpha.18

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 (55) hide show
  1. package/dist/adapter/converters/sampler-parameters.js +6 -4
  2. package/dist/adapter/converters/texture-formats.d.ts +49 -11
  3. package/dist/adapter/converters/texture-formats.d.ts.map +1 -1
  4. package/dist/adapter/converters/texture-formats.js +150 -160
  5. package/dist/adapter/helpers/format-utils.d.ts.map +1 -1
  6. package/dist/adapter/helpers/format-utils.js +6 -0
  7. package/dist/adapter/helpers/webgl-texture-utils.d.ts +10 -8
  8. package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
  9. package/dist/adapter/helpers/webgl-texture-utils.js +46 -32
  10. package/dist/adapter/resources/webgl-command-buffer.d.ts +59 -2
  11. package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
  12. package/dist/adapter/resources/webgl-command-buffer.js +72 -16
  13. package/dist/adapter/resources/webgl-command-encoder.d.ts.map +1 -1
  14. package/dist/adapter/resources/webgl-command-encoder.js +3 -0
  15. package/dist/adapter/resources/webgl-external-texture.js +14 -0
  16. package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
  17. package/dist/adapter/resources/webgl-framebuffer.js +1 -2
  18. package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
  19. package/dist/adapter/resources/webgl-render-pass.js +29 -17
  20. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  21. package/dist/adapter/resources/webgl-render-pipeline.js +6 -5
  22. package/dist/adapter/resources/webgl-shader.js +1 -1
  23. package/dist/adapter/resources/webgl-texture.d.ts +8 -14
  24. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  25. package/dist/adapter/resources/webgl-texture.js +119 -208
  26. package/dist/adapter/webgl-adapter.js +1 -1
  27. package/dist/adapter/webgl-device.d.ts +7 -1
  28. package/dist/adapter/webgl-device.d.ts.map +1 -1
  29. package/dist/adapter/webgl-device.js +22 -10
  30. package/dist/context/debug/webgl-developer-tools.d.ts +1 -0
  31. package/dist/context/debug/webgl-developer-tools.d.ts.map +1 -1
  32. package/dist/context/debug/webgl-developer-tools.js +4 -2
  33. package/dist/context/helpers/create-browser-context.d.ts.map +1 -1
  34. package/dist/context/helpers/create-browser-context.js +17 -3
  35. package/dist/dist.dev.js +219 -269
  36. package/dist/dist.min.js +2 -2
  37. package/dist/index.cjs +213 -266
  38. package/dist/index.cjs.map +3 -3
  39. package/package.json +4 -4
  40. package/src/adapter/converters/sampler-parameters.ts +6 -4
  41. package/src/adapter/converters/texture-formats.ts +171 -177
  42. package/src/adapter/helpers/format-utils.ts +6 -0
  43. package/src/adapter/helpers/webgl-texture-utils.ts +66 -45
  44. package/src/adapter/resources/webgl-command-buffer.ts +108 -24
  45. package/src/adapter/resources/webgl-command-encoder.ts +6 -0
  46. package/src/adapter/resources/webgl-external-texture.ts +14 -0
  47. package/src/adapter/resources/webgl-framebuffer.ts +1 -2
  48. package/src/adapter/resources/webgl-render-pass.ts +33 -20
  49. package/src/adapter/resources/webgl-render-pipeline.ts +6 -5
  50. package/src/adapter/resources/webgl-shader.ts +1 -1
  51. package/src/adapter/resources/webgl-texture.ts +126 -235
  52. package/src/adapter/webgl-adapter.ts +1 -1
  53. package/src/adapter/webgl-device.ts +23 -10
  54. package/src/context/debug/webgl-developer-tools.ts +5 -2
  55. package/src/context/helpers/create-browser-context.ts +18 -3
@@ -19,46 +19,22 @@ import { initializeTextureStorage,
19
19
  copyExternalImageToMipLevel, copyCPUDataToMipLevel,
20
20
  // copyGPUBufferToMipLevel,
21
21
  getWebGLTextureTarget } from "../helpers/webgl-texture-utils.js";
22
- // PORTABLE HELPERS (Move to methods on Texture?)
23
- /**
24
- * Normalize TextureData to an array of TextureLevelData / ExternalImages
25
- * @param data
26
- * @param options
27
- * @returns array of TextureLevelData / ExternalImages
28
- */
29
- function normalizeTextureData(data, options) {
30
- let lodArray;
31
- if (ArrayBuffer.isView(data)) {
32
- lodArray = [
33
- {
34
- // ts-expect-error does data really need to be Uint8ClampedArray?
35
- data,
36
- width: options.width,
37
- height: options.height
38
- // depth: options.depth
39
- }
40
- ];
41
- }
42
- else if (!Array.isArray(data)) {
43
- lodArray = [data];
44
- }
45
- else {
46
- lodArray = data;
47
- }
48
- return lodArray;
49
- }
50
22
  /**
51
23
  * WebGL... the texture API from hell... hopefully made simpler
52
24
  */
53
25
  export class WEBGLTexture extends Texture {
54
- MAX_ATTRIBUTES;
26
+ // readonly MAX_ATTRIBUTES: number;
55
27
  device;
56
28
  gl;
57
29
  handle;
58
30
  sampler = undefined; // TODO - currently unused in WebGL. Create dummy sampler?
59
31
  view = undefined; // TODO - currently unused in WebGL. Create dummy view?
60
- mipmaps = false;
32
+ mipmaps;
33
+ // Texture type
34
+ /** Whether the internal format is compressed */
35
+ compressed;
61
36
  /**
37
+ * The WebGL target corresponding to the texture type
62
38
  * @note `target` cannot be modified by bind:
63
39
  * textures are special because when you first bind them to a target,
64
40
  * When you first bind a texture as a GL_TEXTURE_2D, you are saying that this texture is a 2D texture.
@@ -67,143 +43,86 @@ export class WEBGLTexture extends Texture {
67
43
  * attempting to bind it as GL_TEXTURE_3D will give rise to a run-time error
68
44
  */
69
45
  glTarget;
70
- // Texture type
71
46
  /** The WebGL format - essentially channel structure */
72
47
  glFormat;
73
48
  /** The WebGL data format - the type of each channel */
74
49
  glType;
75
50
  /** The WebGL constant corresponding to the WebGPU style constant in format */
76
51
  glInternalFormat;
77
- /** Whether the internal format is compressed */
78
- compressed;
79
- // data;
80
- // inherited props
81
- // dimension: ...
82
- // format: GLTextureTarget;
83
- // width: number = undefined;
84
- // height: number = undefined;
85
- // depth: number = undefined;
86
52
  // state
87
- /** Texture binding slot */
53
+ /** Texture binding slot - TODO - move to texture view? */
88
54
  textureUnit = 0;
89
- /** For automatically updating video */
90
- _video = null;
91
55
  constructor(device, props) {
92
- props = Texture._fixProps(props);
93
- // Note: Clear out `props.data` so that we don't hold a reference to any big memory chunks
94
- super(device, { ...Texture.defaultProps, ...props, data: undefined });
56
+ super(device, props);
57
+ // Texture base class strips out the data prop, so we need to add it back in
58
+ const propsWithData = { ...this.props };
59
+ propsWithData.data = props.data;
95
60
  this.device = device;
96
61
  this.gl = this.device.gl;
97
62
  // Note: In WebGL the texture target defines the type of texture on first bind.
98
63
  this.glTarget = getWebGLTextureTarget(this.props.dimension);
99
64
  // The target format of this texture
100
- const format = getTextureFormatWebGL(this.props.format);
101
- this.glInternalFormat = format.internalFormat;
102
- this.glFormat = format.format;
103
- this.glType = format.type;
104
- this.compressed = format.compressed;
105
- if (typeof HTMLVideoElement !== 'undefined' &&
106
- props.data instanceof HTMLVideoElement &&
107
- // @ts-expect-error
108
- props.data.readyState < HTMLVideoElement.HAVE_METADATA) {
109
- const video = props.data;
110
- this._video = null; // Declare member before the object is sealed
111
- video.addEventListener('loadeddata', () => this.initialize(props));
112
- }
113
- // We removed data, we need to add it again.
114
- // @ts-expect-error
115
- this.initialize({ ...this.props, data: props.data });
65
+ const formatInfo = getTextureFormatWebGL(this.props.format);
66
+ this.glInternalFormat = formatInfo.internalFormat;
67
+ this.glFormat = formatInfo.format;
68
+ this.glType = formatInfo.type;
69
+ this.compressed = formatInfo.compressed;
70
+ this.mipmaps = Boolean(this.props.mipmaps);
71
+ this._initialize(propsWithData);
116
72
  Object.seal(this);
117
73
  }
118
74
  /**
119
75
  * Initialize texture with supplied props
120
76
  */
121
77
  // eslint-disable-next-line max-statements
122
- initialize(props = {}) {
78
+ _initialize(propsWithData) {
123
79
  this.handle = this.props.handle || this.gl.createTexture();
124
- this.device.setSpectorMetadata(this.handle, { ...this.props, data: typeof this.props.data });
125
- const data = props.data;
126
- // const {parameters = {} as Record<GL, any>} = props;
127
- let { width, height } = props;
80
+ this.device.setSpectorMetadata(this.handle, { ...this.props, data: propsWithData.data });
81
+ let { width, height } = propsWithData;
128
82
  if (!width || !height) {
129
- const textureSize = Texture.getTextureDataSize(data);
83
+ const textureSize = Texture.getTextureDataSize(propsWithData.data);
130
84
  width = textureSize?.width || 1;
131
85
  height = textureSize?.height || 1;
132
86
  }
133
87
  // Store opts for accessors
134
88
  this.width = width;
135
89
  this.height = height;
136
- this.depth = props.depth;
90
+ this.depth = propsWithData.depth;
137
91
  // Set texture sampler parameters
138
- this.setSampler(props.sampler);
139
- // @ts-ignore
92
+ this.setSampler(propsWithData.sampler);
93
+ // @ts-ignore TODO - fix types
140
94
  this.view = new WEBGLTextureView(this.device, { ...this.props, texture: this });
141
95
  this.bind();
142
- if (!this.props.data) {
143
- initializeTextureStorage(this.gl, this.mipLevels, this);
144
- }
145
- if (props.data) {
96
+ initializeTextureStorage(this.gl, this.mipLevels, this);
97
+ if (propsWithData.data) {
146
98
  // prettier-ignore
147
- switch (props.dimension) {
99
+ switch (propsWithData.dimension) {
148
100
  case '1d':
149
- this.setTexture1DData(props.data);
101
+ this.setTexture1DData(propsWithData.data);
150
102
  break;
151
103
  case '2d':
152
- this.setTexture2DData(props.data);
104
+ this.setTexture2DData(propsWithData.data);
153
105
  break;
154
106
  case '3d':
155
- this.setTexture3DData(props.data);
107
+ this.setTexture3DData(propsWithData.data);
156
108
  break;
157
109
  case 'cube':
158
- this.setTextureCubeData(props.data);
110
+ this.setTextureCubeData(propsWithData.data);
159
111
  break;
160
112
  case '2d-array':
161
- this.setTextureArrayData(props.data);
113
+ this.setTextureArrayData(propsWithData.data);
162
114
  break;
163
115
  case 'cube-array':
164
- this.setTextureCubeArrayData(props.data);
116
+ this.setTextureCubeArrayData(propsWithData.data);
165
117
  break;
166
118
  // @ts-expect-error
167
- default: throw new Error(props.dimension);
119
+ default: throw new Error(propsWithData.dimension);
168
120
  }
169
121
  }
170
- this.mipmaps = Boolean(props.mipmaps);
171
122
  if (this.mipmaps) {
172
123
  this.generateMipmap();
173
124
  }
174
- // if (isVideo) {
175
- // this._video = {
176
- // video: data,
177
- // // TODO - should we be using the sampler parameters here?
178
- // parameters: {},
179
- // // @ts-expect-error HTMLVideoElement.HAVE_CURRENT_DATA is not declared
180
- // lastTime: data.readyState >= HTMLVideoElement.HAVE_CURRENT_DATA ? data.currentTime : -1
181
- // };
182
- // }
183
125
  }
184
- /*
185
- initializeCube(props?: TextureProps): void {
186
- const {mipmaps = true} = props; // , parameters = {} as Record<GL, any>} = props;
187
-
188
- // Store props for accessors
189
- // this.props = props;
190
-
191
- // @ts-expect-error
192
- this.setCubeMapData(props).then(() => {
193
- // TODO - should genMipmap() be called on the cubemap or on the faces?
194
- // TODO - without generateMipmap() cube textures do not work at all!!! Why?
195
- if (mipmaps) {
196
- this.generateMipmap(props);
197
- }
198
-
199
- this.setSampler(props.sampler);
200
-
201
- // v8 compatibility?
202
- // const {parameters = {} as Record<GL, any>} = props;
203
- // this._setSamplerParameters(parameters);
204
- });
205
- }
206
- */
207
126
  destroy() {
208
127
  if (this.handle) {
209
128
  this.gl.deleteTexture(this.handle);
@@ -213,9 +132,6 @@ export class WEBGLTexture extends Texture {
213
132
  this.destroyed = true;
214
133
  }
215
134
  }
216
- toString() {
217
- return `Texture(${this.id},${this.width}x${this.height})`;
218
- }
219
135
  createView(props) {
220
136
  return new WEBGLTextureView(this.device, { ...props, texture: this });
221
137
  }
@@ -232,50 +148,38 @@ export class WEBGLTexture extends Texture {
232
148
  const parameters = convertSamplerParametersToWebGL(samplerProps);
233
149
  this._setSamplerParameters(parameters);
234
150
  }
235
- /** Update external texture (video frame or canvas) */
236
- update() {
237
- log.warn('Texture.update() not implemented');
238
- // if (this._video) {
239
- // const {video, parameters, lastTime} = this._video;
240
- // // @ts-expect-error
241
- // if (lastTime === video.currentTime || video.readyState < HTMLVideoElement.HAVE_CURRENT_DATA) {
242
- // return;
243
- // }
244
- // this.setSubImageData({
245
- // data: video,
246
- // parameters
247
- // });
248
- // if (this.mipmaps) {
249
- // this.generateMipmap();
250
- // }
251
- // this._video.lastTime = video.currentTime;
252
- // }
253
- }
254
151
  // Call to regenerate mipmaps after modifying texture(s)
255
152
  generateMipmap(params = {}) {
256
- if (!this.props.data) {
257
- return;
153
+ if (!this.device.isTextureFormatRenderable(this.props.format) ||
154
+ !this.device.isTextureFormatFilterable(this.props.format)) {
155
+ log.warn(`${this} is not renderable or filterable, may not be able to generate mipmaps`)();
156
+ }
157
+ try {
158
+ this.gl.bindTexture(this.glTarget, this.handle);
159
+ withGLParameters(this.gl, params, () => {
160
+ this.gl.generateMipmap(this.glTarget);
161
+ });
162
+ }
163
+ catch (error) {
164
+ log.warn(`Error generating mipmap for ${this}: ${error.message}`)();
165
+ }
166
+ finally {
167
+ this.gl.bindTexture(this.glTarget, null);
258
168
  }
259
- this.mipmaps = true;
260
- this.gl.bindTexture(this.glTarget, this.handle);
261
- withGLParameters(this.gl, params, () => {
262
- this.gl.generateMipmap(this.glTarget);
263
- });
264
- this.gl.bindTexture(this.glTarget, null);
265
169
  }
266
170
  // Image Data Setters
267
171
  copyExternalImage(options) {
268
172
  const size = Texture.getExternalImageSize(options.image);
269
173
  const opts = { ...Texture.defaultCopyExternalImageOptions, ...size, ...options };
270
- const { image, depth, mipLevel, x, y, z } = opts;
174
+ const { image, depth, mipLevel, x, y, z, flipY } = opts;
271
175
  let { width, height } = opts;
272
176
  const { dimension, glTarget, glFormat, glInternalFormat, glType } = this;
273
177
  // WebGL will error if we try to copy outside the bounds of the texture
274
178
  width = Math.min(width, size.width - x);
275
179
  height = Math.min(height, size.height - y);
276
- // WebGL does not yet support sourceX/sourceY in copyExternalImage; requires copyTexSubImage2D from a framebuffer'
277
180
  if (options.sourceX || options.sourceY) {
278
- throw new Error('WebGL does not yet support sourceX/sourceY in copyExternalImage; requires copyTexSubImage2D from a framebuffer');
181
+ // requires copyTexSubImage2D from a framebuffer'
182
+ throw new Error('WebGL does not support sourceX/sourceY)');
279
183
  }
280
184
  copyExternalImageToMipLevel(this.device.gl, this.handle, image, {
281
185
  dimension,
@@ -289,7 +193,8 @@ export class WEBGLTexture extends Texture {
289
193
  glFormat,
290
194
  glInternalFormat,
291
195
  glType,
292
- glTarget
196
+ glTarget,
197
+ flipY
293
198
  });
294
199
  return { width: opts.width, height: opts.height };
295
200
  }
@@ -299,7 +204,7 @@ export class WEBGLTexture extends Texture {
299
204
  /** Set a simple texture */
300
205
  setTexture2DData(lodData, depth = 0) {
301
206
  this.bind();
302
- const lodArray = normalizeTextureData(lodData, this);
207
+ const lodArray = Texture.normalizeTextureData(lodData, this);
303
208
  // If the user provides multiple LODs, then automatic mipmap
304
209
  // generation generateMipmap() should be disabled to avoid overwriting them.
305
210
  if (lodArray.length > 1 && this.props.mipmaps !== false) {
@@ -366,6 +271,11 @@ export class WEBGLTexture extends Texture {
366
271
  const faceDepth = Texture.CubeFaces.indexOf(face);
367
272
  this.setTexture2DData(lodData, faceDepth);
368
273
  }
274
+ // DEPRECATED METHODS
275
+ /** Update external texture (video frame or canvas) @deprecated Use ExternalTexture */
276
+ update() {
277
+ throw new Error('Texture.update() not implemented. Use ExternalTexture');
278
+ }
369
279
  // INTERNAL METHODS
370
280
  /** @todo update this method to accept LODs */
371
281
  setImageDataForFace(options) {
@@ -404,7 +314,7 @@ export class WEBGLTexture extends Texture {
404
314
  * Sets sampler parameters on texture
405
315
  */
406
316
  _setSamplerParameters(parameters) {
407
- log.log(1, 'texture sampler parameters', parameters)();
317
+ log.log(1, `${this.id} sampler parameters`, this.device.getGLKeys(parameters))();
408
318
  this.gl.bindTexture(this.glTarget, this.handle);
409
319
  for (const [pname, pvalue] of Object.entries(parameters)) {
410
320
  const param = Number(pname);
@@ -436,61 +346,6 @@ export class WEBGLTexture extends Texture {
436
346
  }
437
347
  this.gl.bindTexture(this.glTarget, null);
438
348
  }
439
- // CLASSIC
440
- /*
441
- setCubeMapData(options: {
442
- width: number;
443
- height: number;
444
- data: Record<GL, Texture2DData> | Record<TextureCubeFace, Texture2DData>;
445
- format?: any;
446
- type?: any;
447
- /** @deprecated Use .data *
448
- pixels: any;
449
- }): void {
450
- const {gl} = this;
451
-
452
- const {width, height, pixels, data, format = GL.RGBA, type = GL.UNSIGNED_BYTE} = options;
453
-
454
- // pixel data (imageDataMap) is an Object from Face to Image or Promise.
455
- // For example:
456
- // {
457
- // GL.TEXTURE_CUBE_MAP_POSITIVE_X : Image-or-Promise,
458
- // GL.TEXTURE_CUBE_MAP_NEGATIVE_X : Image-or-Promise,
459
- // ... }
460
- // To provide multiple level-of-details (LODs) this can be Face to Array
461
- // of Image or Promise, like this
462
- // {
463
- // GL.TEXTURE_CUBE_MAP_POSITIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
464
- // GL.TEXTURE_CUBE_MAP_NEGATIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
465
- // ... }
466
-
467
- const imageDataMap = this._getImageDataMap(pixels || data);
468
-
469
- const resolvedFaces = WEBGLTexture.FACES.map(face => {
470
- const facePixels = imageDataMap[face];
471
- return Array.isArray(facePixels) ? facePixels : [facePixels];
472
- });
473
- this.bind();
474
-
475
- WEBGLTexture.FACES.forEach((face, index) => {
476
- if (resolvedFaces[index].length > 1 && this.props.mipmaps !== false) {
477
- // If the user provides multiple LODs, then automatic mipmap
478
- // generation generateMipmap() should be disabled to avoid overwritting them.
479
- log.warn(`${this.id} has mipmap and multiple LODs.`)();
480
- }
481
- resolvedFaces[index].forEach((image, lodLevel) => {
482
- // TODO: adjust width & height for LOD!
483
- if (width && height) {
484
- gl.texImage2D(face, lodLevel, format, width, height, 0 /* border*, format, type, image);
485
- } else {
486
- gl.texImage2D(face, lodLevel, format, format, type, image);
487
- }
488
- });
489
- });
490
-
491
- this.unbind();
492
- }
493
- */
494
349
  // INTERNAL SETTERS
495
350
  /**
496
351
  * Copy a region of data from a CPU memory buffer into this texture.
@@ -506,7 +361,8 @@ export class WEBGLTexture extends Texture {
506
361
  ...this,
507
362
  depth,
508
363
  mipLevel,
509
- glTarget
364
+ glTarget,
365
+ flipY: this.props.flipY
510
366
  });
511
367
  return;
512
368
  }
@@ -545,3 +401,58 @@ export class WEBGLTexture extends Texture {
545
401
  return textureUnit;
546
402
  }
547
403
  }
404
+ // TODO - Remove when texture refactor is complete
405
+ /*
406
+ setCubeMapData(options: {
407
+ width: number;
408
+ height: number;
409
+ data: Record<GL, Texture2DData> | Record<TextureCubeFace, Texture2DData>;
410
+ format?: any;
411
+ type?: any;
412
+ /** @deprecated Use .data *
413
+ pixels: any;
414
+ }): void {
415
+ const {gl} = this;
416
+
417
+ const {width, height, pixels, data, format = GL.RGBA, type = GL.UNSIGNED_BYTE} = options;
418
+
419
+ // pixel data (imageDataMap) is an Object from Face to Image or Promise.
420
+ // For example:
421
+ // {
422
+ // GL.TEXTURE_CUBE_MAP_POSITIVE_X : Image-or-Promise,
423
+ // GL.TEXTURE_CUBE_MAP_NEGATIVE_X : Image-or-Promise,
424
+ // ... }
425
+ // To provide multiple level-of-details (LODs) this can be Face to Array
426
+ // of Image or Promise, like this
427
+ // {
428
+ // GL.TEXTURE_CUBE_MAP_POSITIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
429
+ // GL.TEXTURE_CUBE_MAP_NEGATIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
430
+ // ... }
431
+
432
+ const imageDataMap = this._getImageDataMap(pixels || data);
433
+
434
+ const resolvedFaces = WEBGLTexture.FACES.map(face => {
435
+ const facePixels = imageDataMap[face];
436
+ return Array.isArray(facePixels) ? facePixels : [facePixels];
437
+ });
438
+ this.bind();
439
+
440
+ WEBGLTexture.FACES.forEach((face, index) => {
441
+ if (resolvedFaces[index].length > 1 && this.props.mipmaps !== false) {
442
+ // If the user provides multiple LODs, then automatic mipmap
443
+ // generation generateMipmap() should be disabled to avoid overwritting them.
444
+ log.warn(`${this.id} has mipmap and multiple LODs.`)();
445
+ }
446
+ resolvedFaces[index].forEach((image, lodLevel) => {
447
+ // TODO: adjust width & height for LOD!
448
+ if (width && height) {
449
+ gl.texImage2D(face, lodLevel, format, width, height, 0 /* border*, format, type, image);
450
+ } else {
451
+ gl.texImage2D(face, lodLevel, format, format, type, image);
452
+ }
453
+ });
454
+ });
455
+
456
+ this.unbind();
457
+ }
458
+ */
@@ -49,7 +49,7 @@ export class WebGLAdapter extends Adapter {
49
49
  log.groupCollapsed(LOG_LEVEL, 'WebGLDevice created')();
50
50
  const promises = [];
51
51
  // Load webgl and spector debug scripts from CDN if requested
52
- if (props.debugWebGL) {
52
+ if (props.debugWebGL || props.debug) {
53
53
  promises.push(loadWebGLDeveloperTools());
54
54
  }
55
55
  if (props.debugSpectorJS) {
@@ -128,7 +128,13 @@ export declare class WebGLDevice extends Device {
128
128
  * Be aware that there are some duplicates especially for constants that are 0,
129
129
  * so this isn't guaranteed to return the right key in all cases.
130
130
  */
131
- getGLKey(value: unknown, gl?: WebGL2RenderingContext): string;
131
+ getGLKey(value: unknown, options?: {
132
+ emptyIfUnknown?: boolean;
133
+ }): string;
134
+ /**
135
+ * Returns a map with any GL.<KEY> constants mapped to strings, both for keys and values
136
+ */
137
+ getGLKeys(glParameters: Record<number, unknown>): Record<string, string>;
132
138
  /** Store constants */
133
139
  _constants: (TypedArray | null)[];
134
140
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"webgl-device.d.ts","sourceRoot":"","sources":["../../src/adapter/webgl-device.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webgl-device.d.ts","sourceRoot":"","sources":["../../src/adapter/webgl-device.ts"],"names":[],"mappings":"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"}
@@ -121,11 +121,14 @@ export class WebGLDevice extends Device {
121
121
  });
122
122
  glState.trackState(this.gl, { copyState: false });
123
123
  // DEBUG contexts: Add luma debug instrumentation to the context, force log level to at least 1
124
- if (props.debugWebGL) {
125
- this.gl = makeDebugContext(this.gl, { ...props });
126
- this.debug = true;
127
- log.level = Math.max(log.level, 1);
124
+ const debugWebGL = props.debugWebGL || props.debug;
125
+ const traceWebGL = props.debugWebGL;
126
+ if (debugWebGL) {
127
+ this.gl = makeDebugContext(this.gl, { debugWebGL, traceWebGL });
128
128
  log.warn('WebGL debug mode activated. Performance reduced.')();
129
+ if (props.debugWebGL) {
130
+ log.level = Math.max(log.level, 1);
131
+ }
129
132
  }
130
133
  }
131
134
  /**
@@ -276,18 +279,27 @@ export class WebGLDevice extends Device {
276
279
  * Be aware that there are some duplicates especially for constants that are 0,
277
280
  * so this isn't guaranteed to return the right key in all cases.
278
281
  */
279
- getGLKey(value, gl) {
280
- // @ts-ignore expect-error depends on settings
281
- gl = gl || this.gl2 || this.gl;
282
+ getGLKey(value, options) {
282
283
  const number = Number(value);
283
- for (const key in gl) {
284
+ for (const key in this.gl) {
284
285
  // @ts-ignore expect-error depends on settings
285
- if (gl[key] === number) {
286
+ if (this.gl[key] === number) {
286
287
  return `GL.${key}`;
287
288
  }
288
289
  }
289
290
  // No constant found. Stringify the value and return it.
290
- return String(value);
291
+ return options?.emptyIfUnknown ? '' : String(value);
292
+ }
293
+ /**
294
+ * Returns a map with any GL.<KEY> constants mapped to strings, both for keys and values
295
+ */
296
+ getGLKeys(glParameters) {
297
+ const opts = { emptyIfUnknown: true };
298
+ return Object.entries(glParameters).reduce((keys, [key, value]) => {
299
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
300
+ keys[`${key}:${this.getGLKey(key, opts)}`] = `${value}:${this.getGLKey(value, opts)}`;
301
+ return keys;
302
+ }, {});
291
303
  }
292
304
  /** Store constants */
293
305
  _constants;
@@ -1,5 +1,6 @@
1
1
  type DebugContextProps = {
2
2
  debugWebGL?: boolean;
3
+ traceWebGL?: boolean;
3
4
  };
4
5
  declare global {
5
6
  var WebGLDebugUtils: any;
@@ -1 +1 @@
1
- {"version":3,"file":"webgl-developer-tools.d.ts","sourceRoot":"","sources":["../../../src/context/debug/webgl-developer-tools.ts"],"names":[],"mappings":"AAYA,KAAK,iBAAiB,GAAG;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAaF,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,eAAe,EAAE,GAAG,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAO7D;AAID,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,sBAAsB,EAC1B,KAAK,GAAE,iBAAsB,GAC5B,sBAAsB,CAExB"}
1
+ {"version":3,"file":"webgl-developer-tools.d.ts","sourceRoot":"","sources":["../../../src/context/debug/webgl-developer-tools.ts"],"names":[],"mappings":"AAYA,KAAK,iBAAiB,GAAG;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAaF,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,eAAe,EAAE,GAAG,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAO7D;AAID,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,sBAAsB,EAC1B,KAAK,GAAE,iBAAsB,GAC5B,sBAAsB,CAExB"}
@@ -29,7 +29,7 @@ export async function loadWebGLDeveloperTools() {
29
29
  // Returns (a potentially new) context with debug instrumentation turned off or on.
30
30
  // Note that this actually returns a new context
31
31
  export function makeDebugContext(gl, props = {}) {
32
- return props.debugWebGL ? getDebugContext(gl, props) : getRealContext(gl);
32
+ return props.debugWebGL || props.traceWebGL ? getDebugContext(gl, props) : getRealContext(gl);
33
33
  }
34
34
  // Returns the real context from either of the real/debug contexts
35
35
  function getRealContext(gl) {
@@ -95,7 +95,9 @@ function onValidateGLFunc(props, functionName, functionArgs) {
95
95
  let functionString = '';
96
96
  if (log.level >= 1) {
97
97
  functionString = getFunctionString(functionName, functionArgs);
98
- log.log(1, functionString)();
98
+ if (props.traceWebGL) {
99
+ log.log(1, functionString)();
100
+ }
99
101
  }
100
102
  for (const arg of functionArgs) {
101
103
  if (arg === undefined) {
@@ -1 +1 @@
1
- {"version":3,"file":"create-browser-context.d.ts","sourceRoot":"","sources":["../../../src/context/helpers/create-browser-context.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,KAAK,YAAY,GAAG;IAClB,oCAAoC;IACpC,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACtC,wCAAwC;IACxC,iBAAiB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC3C,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,iBAAiB,GAAG,eAAe,EAC3C,KAAK,EAAE,YAAY,EACnB,sBAAsB,EAAE,sBAAsB,GAC7C,sBAAsB,CA6CxB"}
1
+ {"version":3,"file":"create-browser-context.d.ts","sourceRoot":"","sources":["../../../src/context/helpers/create-browser-context.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,KAAK,YAAY,GAAG;IAClB,oCAAoC;IACpC,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACtC,wCAAwC;IACxC,iBAAiB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC3C,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,iBAAiB,GAAG,eAAe,EAC3C,KAAK,EAAE,YAAY,EACnB,sBAAsB,EAAE,sBAAsB,GAC7C,sBAAsB,CA4DxB"}
@@ -8,7 +8,7 @@
8
8
  */
9
9
  export function createBrowserContext(canvas, props, webglContextAttributes) {
10
10
  // Try to extract any extra information about why context creation failed
11
- const errorMessage = null;
11
+ let errorMessage = '';
12
12
  // const onCreateError = error => (errorMessage = error.statusMessage || errorMessage);
13
13
  // Avoid multiple listeners?
14
14
  // canvas.removeEventListener('webglcontextcreationerror', onCreateError, false);
@@ -22,22 +22,36 @@ export function createBrowserContext(canvas, props, webglContextAttributes) {
22
22
  let gl = null;
23
23
  // Create a webgl2 context
24
24
  gl ||= canvas.getContext('webgl2', webglProps);
25
+ if (webglProps.failIfMajorPerformanceCaveat) {
26
+ errorMessage ||=
27
+ 'Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow.';
28
+ }
25
29
  // Creation failed with failIfMajorPerformanceCaveat - Try a Software GPU
26
30
  if (!gl && !webglContextAttributes.failIfMajorPerformanceCaveat) {
27
31
  webglProps.failIfMajorPerformanceCaveat = false;
28
- gl = canvas.getContext('webgl', webglProps);
32
+ gl = canvas.getContext('webgl2', webglProps);
29
33
  // @ts-expect-error
30
34
  gl.luma ||= {};
31
35
  // @ts-expect-error
32
36
  gl.luma.softwareRenderer = true;
33
37
  }
34
38
  if (!gl) {
35
- throw new Error(`Failed to create WebGL context: ${errorMessage || 'Unknown error'}`);
39
+ gl = canvas.getContext('webgl', {});
40
+ if (gl) {
41
+ gl = null;
42
+ errorMessage ||= 'Your browser only supports WebGL1';
43
+ }
44
+ }
45
+ if (!gl) {
46
+ errorMessage ||= 'Your browser does not support WebGL';
47
+ throw new Error(`Failed to create WebGL context: ${errorMessage}`);
36
48
  }
37
49
  // Carefully extract and wrap callbacks to prevent addEventListener from rebinding them.
38
50
  const { onContextLost, onContextRestored } = props;
39
51
  canvas.addEventListener('webglcontextlost', (event) => onContextLost(event), false);
40
52
  canvas.addEventListener('webglcontextrestored', (event) => onContextRestored(event), false);
53
+ // @ts-expect-error
54
+ gl.luma ||= {};
41
55
  return gl;
42
56
  }
43
57
  /* TODO - can we call this asynchronously to catch the error events?