@luma.gl/webgl 9.1.0-alpha.15 → 9.1.0-alpha.17

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 (69) hide show
  1. package/dist/adapter/converters/device-parameters.d.ts +3 -3
  2. package/dist/adapter/converters/device-parameters.d.ts.map +1 -1
  3. package/dist/adapter/converters/sampler-parameters.js +6 -4
  4. package/dist/adapter/converters/texture-formats.d.ts +49 -11
  5. package/dist/adapter/converters/texture-formats.d.ts.map +1 -1
  6. package/dist/adapter/converters/texture-formats.js +150 -160
  7. package/dist/adapter/helpers/format-utils.d.ts.map +1 -1
  8. package/dist/adapter/helpers/format-utils.js +6 -0
  9. package/dist/adapter/helpers/webgl-texture-utils.d.ts +34 -30
  10. package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
  11. package/dist/adapter/helpers/webgl-texture-utils.js +52 -256
  12. package/dist/adapter/resources/webgl-command-buffer.d.ts +59 -2
  13. package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
  14. package/dist/adapter/resources/webgl-command-buffer.js +87 -31
  15. package/dist/adapter/resources/webgl-command-encoder.d.ts.map +1 -1
  16. package/dist/adapter/resources/webgl-command-encoder.js +3 -0
  17. package/dist/adapter/resources/webgl-external-texture.js +14 -0
  18. package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
  19. package/dist/adapter/resources/webgl-framebuffer.js +1 -2
  20. package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
  21. package/dist/adapter/resources/webgl-render-pass.js +38 -20
  22. package/dist/adapter/resources/webgl-render-pipeline.d.ts +1 -1
  23. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  24. package/dist/adapter/resources/webgl-render-pipeline.js +30 -16
  25. package/dist/adapter/resources/webgl-shader.d.ts +1 -0
  26. package/dist/adapter/resources/webgl-shader.d.ts.map +1 -1
  27. package/dist/adapter/resources/webgl-shader.js +7 -5
  28. package/dist/adapter/resources/webgl-texture.d.ts +8 -14
  29. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  30. package/dist/adapter/resources/webgl-texture.js +119 -208
  31. package/dist/adapter/webgl-adapter.d.ts.map +1 -1
  32. package/dist/adapter/webgl-adapter.js +4 -10
  33. package/dist/adapter/webgl-device.d.ts +8 -3
  34. package/dist/adapter/webgl-device.d.ts.map +1 -1
  35. package/dist/adapter/webgl-device.js +53 -22
  36. package/dist/context/debug/spector-types.js +1 -1
  37. package/dist/context/debug/spector.d.ts +5 -5
  38. package/dist/context/debug/spector.d.ts.map +1 -1
  39. package/dist/context/debug/spector.js +6 -6
  40. package/dist/context/debug/webgl-developer-tools.d.ts +2 -3
  41. package/dist/context/debug/webgl-developer-tools.d.ts.map +1 -1
  42. package/dist/context/debug/webgl-developer-tools.js +6 -19
  43. package/dist/context/helpers/create-browser-context.d.ts +6 -22
  44. package/dist/context/helpers/create-browser-context.d.ts.map +1 -1
  45. package/dist/context/helpers/create-browser-context.js +40 -32
  46. package/dist/dist.dev.js +366 -400
  47. package/dist/dist.min.js +2 -2
  48. package/dist/index.cjs +341 -384
  49. package/dist/index.cjs.map +3 -3
  50. package/package.json +4 -4
  51. package/src/adapter/converters/device-parameters.ts +3 -3
  52. package/src/adapter/converters/sampler-parameters.ts +6 -4
  53. package/src/adapter/converters/texture-formats.ts +171 -177
  54. package/src/adapter/helpers/format-utils.ts +6 -0
  55. package/src/adapter/helpers/webgl-texture-utils.ts +99 -75
  56. package/src/adapter/resources/webgl-command-buffer.ts +124 -40
  57. package/src/adapter/resources/webgl-command-encoder.ts +6 -0
  58. package/src/adapter/resources/webgl-external-texture.ts +14 -0
  59. package/src/adapter/resources/webgl-framebuffer.ts +1 -2
  60. package/src/adapter/resources/webgl-render-pass.ts +44 -23
  61. package/src/adapter/resources/webgl-render-pipeline.ts +32 -16
  62. package/src/adapter/resources/webgl-shader.ts +8 -6
  63. package/src/adapter/resources/webgl-texture.ts +126 -235
  64. package/src/adapter/webgl-adapter.ts +4 -12
  65. package/src/adapter/webgl-device.ts +88 -48
  66. package/src/context/debug/spector-types.ts +1 -1
  67. package/src/context/debug/spector.ts +11 -11
  68. package/src/context/debug/webgl-developer-tools.ts +8 -31
  69. package/src/context/helpers/create-browser-context.ts +53 -63
package/dist/dist.dev.js CHANGED
@@ -14,9 +14,9 @@ var __exports__ = (() => {
14
14
  var __commonJS = (cb, mod) => function __require() {
15
15
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
16
16
  };
17
- var __export = (target, all) => {
17
+ var __export = (target2, all) => {
18
18
  for (var name in all)
19
- __defProp(target, name, { get: all[name], enumerable: true });
19
+ __defProp(target2, name, { get: all[name], enumerable: true });
20
20
  };
21
21
  var __copyProps = (to, from, except, desc) => {
22
22
  if (from && typeof from === "object" || typeof from === "function") {
@@ -26,13 +26,13 @@ var __exports__ = (() => {
26
26
  }
27
27
  return to;
28
28
  };
29
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
30
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ var __reExport = (target2, mod, secondTarget) => (__copyProps(target2, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
30
+ var __toESM = (mod, isNodeMode, target2) => (target2 = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
31
31
  // If the importer is in node compatibility mode or this is not an ESM
32
32
  // file that has been converted to a CommonJS file using a Babel-
33
33
  // compatible transform (i.e. "__esModule" has not been set), then set
34
34
  // "default" to the CommonJS "module.exports" for node compatibility.
35
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
35
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target2, "default", { value: mod, enumerable: true }) : target2,
36
36
  mod
37
37
  ));
38
38
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
@@ -815,8 +815,8 @@ var __exports__ = (() => {
815
815
  var hint = (gl, value, key) => gl.hint(key, value);
816
816
  var pixelStorei = (gl, value, key) => gl.pixelStorei(key, value);
817
817
  var bindFramebuffer = (gl, value, key) => {
818
- const target = key === 36006 /* FRAMEBUFFER_BINDING */ ? 36009 /* DRAW_FRAMEBUFFER */ : 36008 /* READ_FRAMEBUFFER */;
819
- return gl.bindFramebuffer(target, value);
818
+ const target2 = key === 36006 /* FRAMEBUFFER_BINDING */ ? 36009 /* DRAW_FRAMEBUFFER */ : 36008 /* READ_FRAMEBUFFER */;
819
+ return gl.bindFramebuffer(target2, value);
820
820
  };
821
821
  var bindBuffer = (gl, value, key) => {
822
822
  const bindingMap = {
@@ -1049,17 +1049,17 @@ var __exports__ = (() => {
1049
1049
  useProgram: (update, value) => update({
1050
1050
  [35725 /* CURRENT_PROGRAM */]: value
1051
1051
  }),
1052
- bindRenderbuffer: (update, target, value) => update({
1052
+ bindRenderbuffer: (update, target2, value) => update({
1053
1053
  [36007 /* RENDERBUFFER_BINDING */]: value
1054
1054
  }),
1055
- bindTransformFeedback: (update, target, value) => update({
1055
+ bindTransformFeedback: (update, target2, value) => update({
1056
1056
  [36389 /* TRANSFORM_FEEDBACK_BINDING */]: value
1057
1057
  }),
1058
1058
  bindVertexArray: (update, value) => update({
1059
1059
  [34229 /* VERTEX_ARRAY_BINDING */]: value
1060
1060
  }),
1061
- bindFramebuffer: (update, target, framebuffer) => {
1062
- switch (target) {
1061
+ bindFramebuffer: (update, target2, framebuffer) => {
1062
+ switch (target2) {
1063
1063
  case 36160 /* FRAMEBUFFER */:
1064
1064
  return update({
1065
1065
  [36006 /* DRAW_FRAMEBUFFER_BINDING */]: framebuffer,
@@ -1073,14 +1073,14 @@ var __exports__ = (() => {
1073
1073
  return null;
1074
1074
  }
1075
1075
  },
1076
- bindBuffer: (update, target, buffer) => {
1076
+ bindBuffer: (update, target2, buffer) => {
1077
1077
  const pname = {
1078
1078
  [34962 /* ARRAY_BUFFER */]: [34964 /* ARRAY_BUFFER_BINDING */],
1079
1079
  [36662 /* COPY_READ_BUFFER */]: [36662 /* COPY_READ_BUFFER_BINDING */],
1080
1080
  [36663 /* COPY_WRITE_BUFFER */]: [36663 /* COPY_WRITE_BUFFER_BINDING */],
1081
1081
  [35051 /* PIXEL_PACK_BUFFER */]: [35053 /* PIXEL_PACK_BUFFER_BINDING */],
1082
1082
  [35052 /* PIXEL_UNPACK_BUFFER */]: [35055 /* PIXEL_UNPACK_BUFFER_BINDING */]
1083
- }[target];
1083
+ }[target2];
1084
1084
  if (pname) {
1085
1085
  return update({ [pname]: buffer });
1086
1086
  }
@@ -1434,37 +1434,43 @@ var __exports__ = (() => {
1434
1434
  }
1435
1435
 
1436
1436
  // src/context/helpers/create-browser-context.ts
1437
- var DEFAULT_CONTEXT_PROPS = {
1438
- powerPreference: "high-performance",
1439
- // After all, most apps are using WebGL for performance reasons
1440
- // eslint-disable-next-line no-console
1441
- onContextLost: () => console.error("WebGL context lost"),
1442
- // eslint-disable-next-line no-console
1443
- onContextRestored: () => console.info("WebGL context restored")
1444
- };
1445
- function createBrowserContext(canvas, props) {
1446
- props = { ...DEFAULT_CONTEXT_PROPS, ...props };
1447
- let errorMessage = null;
1448
- const onCreateError = (error) => errorMessage = error.statusMessage || errorMessage;
1449
- canvas.addEventListener("webglcontextcreationerror", onCreateError, false);
1437
+ function createBrowserContext(canvas, props, webglContextAttributes) {
1438
+ let errorMessage = "";
1439
+ const webglProps = {
1440
+ preserveDrawingBuffer: true,
1441
+ // failIfMajorPerformanceCaveat: true,
1442
+ ...webglContextAttributes
1443
+ };
1450
1444
  let gl = null;
1451
- gl ||= canvas.getContext("webgl2", props);
1452
- canvas.removeEventListener("webglcontextcreationerror", onCreateError, false);
1445
+ gl ||= canvas.getContext("webgl2", webglProps);
1446
+ if (webglProps.failIfMajorPerformanceCaveat) {
1447
+ errorMessage ||= "Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow.";
1448
+ }
1449
+ if (!gl && !webglContextAttributes.failIfMajorPerformanceCaveat) {
1450
+ webglProps.failIfMajorPerformanceCaveat = false;
1451
+ gl = canvas.getContext("webgl2", webglProps);
1452
+ gl.luma ||= {};
1453
+ gl.luma.softwareRenderer = true;
1454
+ }
1453
1455
  if (!gl) {
1454
- throw new Error(`Failed to create WebGL context: ${errorMessage || "Unknown error"}`);
1455
- }
1456
- if (props.onContextLost) {
1457
- const { onContextLost } = props;
1458
- canvas.addEventListener("webglcontextlost", (event) => onContextLost(event), false);
1459
- }
1460
- if (props.onContextRestored) {
1461
- const { onContextRestored } = props;
1462
- canvas.addEventListener(
1463
- "webglcontextrestored",
1464
- (event) => onContextRestored(event),
1465
- false
1466
- );
1456
+ gl = canvas.getContext("webgl", {});
1457
+ if (gl) {
1458
+ gl = null;
1459
+ errorMessage ||= "Your browser only supports WebGL1";
1460
+ }
1467
1461
  }
1462
+ if (!gl) {
1463
+ errorMessage ||= "Your browser does not support WebGL";
1464
+ throw new Error(`Failed to create WebGL context: ${errorMessage}`);
1465
+ }
1466
+ const { onContextLost, onContextRestored } = props;
1467
+ canvas.addEventListener("webglcontextlost", (event) => onContextLost(event), false);
1468
+ canvas.addEventListener(
1469
+ "webglcontextrestored",
1470
+ (event) => onContextRestored(event),
1471
+ false
1472
+ );
1473
+ gl.luma ||= {};
1468
1474
  return gl;
1469
1475
  }
1470
1476
 
@@ -1695,7 +1701,7 @@ var __exports__ = (() => {
1695
1701
  // 64-bit formats
1696
1702
  "rg32uint": { gl: 33340 /* RG32UI */, b: 8, c: 2, rb: true },
1697
1703
  "rg32sint": { gl: 33339 /* RG32I */, b: 8, c: 2, rb: true },
1698
- "rg32float": { gl: 33328 /* RG32F */, b: 8, c: 2, render: float32_renderable, filter: float32_filterable, rb: true },
1704
+ "rg32float": { gl: 33328 /* RG32F */, b: 8, c: 2, render: false, filter: float32_filterable, rb: true },
1699
1705
  "rgba16uint": { gl: 36214 /* RGBA16UI */, b: 8, c: 4, rb: true },
1700
1706
  "rgba16sint": { gl: 36232 /* RGBA16I */, b: 8, c: 4, rb: true },
1701
1707
  "rgba16float": { gl: 34842 /* RGBA16F */, b: 8, c: 4, render: float16_renderable, filter: float16_filterable },
@@ -1881,36 +1887,35 @@ var __exports__ = (() => {
1881
1887
  return true;
1882
1888
  }
1883
1889
  function isTextureFormatFilterable(gl, format, extensions) {
1884
- if (!isTextureFormatSupported(gl, format, extensions)) {
1885
- return false;
1886
- }
1887
- if (format.startsWith("depth") || format.startsWith("stencil")) {
1888
- return false;
1889
- }
1890
- try {
1891
- const decoded = (0, import_core.decodeTextureFormat)(format);
1892
- if (decoded.signed) {
1893
- return false;
1894
- }
1895
- } catch {
1896
- return false;
1897
- }
1898
- if (format.endsWith("32float")) {
1899
- return Boolean(getWebGLExtension(gl, "OES_texture_float_linear, extensions", extensions));
1900
- }
1901
- if (format.endsWith("16float")) {
1902
- return Boolean(getWebGLExtension(gl, "OES_texture_half_float_linear, extensions", extensions));
1903
- }
1904
- return true;
1890
+ return getTextureFormatSupportWebGL(gl, format, extensions).filterable || false;
1905
1891
  }
1906
1892
  function isTextureFormatRenderable(gl, format, extensions) {
1907
- if (!isTextureFormatSupported(gl, format, extensions)) {
1908
- return false;
1909
- }
1910
- if (typeof format === "number") {
1911
- return false;
1912
- }
1913
- return true;
1893
+ return getTextureFormatSupportWebGL(gl, format, extensions).renderable || false;
1894
+ }
1895
+ function getTextureFormatSupportWebGL(gl, format, extensions) {
1896
+ const formatInto = (0, import_core.decodeTextureFormat)(format);
1897
+ if (!formatInto) {
1898
+ return { supported: false };
1899
+ }
1900
+ const webglFormatInfo = TEXTURE_FORMATS[format];
1901
+ if (!webglFormatInfo) {
1902
+ return { supported: false };
1903
+ }
1904
+ let supported = webglFormatInfo.gl !== void 0;
1905
+ supported = supported && checkTextureFeature(gl, webglFormatInfo.f, extensions);
1906
+ const isDepthStencil = format.startsWith("depth") || format.startsWith("stencil");
1907
+ const isSigned = formatInto?.signed;
1908
+ const renderable = supported && !isSigned && webglFormatInfo.render && checkTextureFeature(gl, webglFormatInfo.render, extensions);
1909
+ const filterable = supported && !isDepthStencil && !isSigned && webglFormatInfo.filter && checkTextureFeature(gl, webglFormatInfo.filter, extensions);
1910
+ return {
1911
+ supported,
1912
+ renderable,
1913
+ filterable,
1914
+ blendable: false,
1915
+ // TODO,
1916
+ storable: false
1917
+ // TODO
1918
+ };
1914
1919
  }
1915
1920
  function getTextureFormatWebGL(format) {
1916
1921
  const formatData = TEXTURE_FORMATS[format];
@@ -2189,7 +2194,7 @@ var __exports__ = (() => {
2189
2194
  );
2190
2195
  this._attachTextureView(attachmentPoint, this.depthStencilAttachment);
2191
2196
  }
2192
- if (this.props.check !== false) {
2197
+ if (this.device.props.debug) {
2193
2198
  const status = this.gl.checkFramebufferStatus(36160 /* FRAMEBUFFER */);
2194
2199
  if (status !== 36053 /* FRAMEBUFFER_COMPLETE */) {
2195
2200
  throw new Error(`Framebuffer ${_getFrameBufferStatus(status)}`);
@@ -2341,17 +2346,17 @@ var __exports__ = (() => {
2341
2346
  var spector = null;
2342
2347
  var initialized = false;
2343
2348
  var DEFAULT_SPECTOR_PROPS = {
2344
- debugWithSpectorJS: import_core6.log.get("spector") || import_core6.log.get("spectorjs"),
2349
+ debugSpectorJS: import_core6.log.get("debug-spectorjs"),
2345
2350
  // https://github.com/BabylonJS/Spector.js#basic-usage
2346
2351
  // https://forum.babylonjs.com/t/spectorcdn-is-temporarily-off/48241
2347
2352
  // spectorUrl: 'https://spectorcdn.babylonjs.com/spector.bundle.js';
2348
- spectorUrl: "https://cdn.jsdelivr.net/npm/spectorjs@0.9.30/dist/spector.bundle.js",
2353
+ debugSpectorJSUrl: "https://cdn.jsdelivr.net/npm/spectorjs@0.9.30/dist/spector.bundle.js",
2349
2354
  gl: void 0
2350
2355
  };
2351
2356
  async function loadSpectorJS(props) {
2352
2357
  if (!globalThis.SPECTOR) {
2353
2358
  try {
2354
- await loadScript(props.spectorUrl || DEFAULT_SPECTOR_PROPS.spectorUrl);
2359
+ await loadScript(props.debugSpectorJSUrl || DEFAULT_SPECTOR_PROPS.debugSpectorJSUrl);
2355
2360
  } catch (error) {
2356
2361
  import_core6.log.warn(String(error));
2357
2362
  }
@@ -2359,13 +2364,13 @@ var __exports__ = (() => {
2359
2364
  }
2360
2365
  function initializeSpectorJS(props) {
2361
2366
  props = { ...DEFAULT_SPECTOR_PROPS, ...props };
2362
- if (!props.debugWithSpectorJS) {
2367
+ if (!props.debugSpectorJS) {
2363
2368
  return null;
2364
2369
  }
2365
2370
  if (!spector && globalThis.SPECTOR && !globalThis.luma?.spector) {
2366
2371
  import_core6.log.probe(LOG_LEVEL, "SPECTOR found and initialized. Start with `luma.spector.displayUI()`")();
2367
- const { Spector } = globalThis.SPECTOR;
2368
- spector = new Spector();
2372
+ const { Spector: SpectorJS } = globalThis.SPECTOR;
2373
+ spector = new SpectorJS();
2369
2374
  if (globalThis.luma) {
2370
2375
  globalThis.luma.spector = spector;
2371
2376
  }
@@ -2468,7 +2473,7 @@ var __exports__ = (() => {
2468
2473
  }
2469
2474
  }
2470
2475
  function makeDebugContext(gl, props = {}) {
2471
- return props.debug ? getDebugContext(gl, props) : getRealContext(gl);
2476
+ return props.debugWebGL || props.traceWebGL ? getDebugContext(gl, props) : getRealContext(gl);
2472
2477
  }
2473
2478
  function getRealContext(gl) {
2474
2479
  const data = getWebGLContextData(gl);
@@ -2517,34 +2522,19 @@ var __exports__ = (() => {
2517
2522
  const message2 = `${errorMessage} in gl.${functionName}(${functionArgs})`;
2518
2523
  import_core7.log.error(message2)();
2519
2524
  debugger;
2520
- if (props.throwOnError) {
2521
- throw new Error(message2);
2522
- }
2523
2525
  }
2524
2526
  function onValidateGLFunc(props, functionName, functionArgs) {
2525
2527
  let functionString = "";
2526
2528
  if (import_core7.log.level >= 1) {
2527
2529
  functionString = getFunctionString(functionName, functionArgs);
2528
- import_core7.log.log(1, functionString)();
2529
- }
2530
- if (props.break && props.break.length > 0) {
2531
- functionString = functionString || getFunctionString(functionName, functionArgs);
2532
- const isBreakpoint = props.break.every(
2533
- (breakOn) => functionString.indexOf(breakOn) !== -1
2534
- );
2535
- if (isBreakpoint) {
2536
- debugger;
2530
+ if (props.traceWebGL) {
2531
+ import_core7.log.log(1, functionString)();
2537
2532
  }
2538
2533
  }
2539
2534
  for (const arg of functionArgs) {
2540
2535
  if (arg === void 0) {
2541
2536
  functionString = functionString || getFunctionString(functionName, functionArgs);
2542
- if (props.throwOnError) {
2543
- throw new Error(`Undefined argument: ${functionString}`);
2544
- } else {
2545
- import_core7.log.error(`Undefined argument: ${functionString}`)();
2546
- debugger;
2547
- }
2537
+ debugger;
2548
2538
  }
2549
2539
  }
2550
2540
  }
@@ -2754,13 +2744,16 @@ var __exports__ = (() => {
2754
2744
  this.destroyed = true;
2755
2745
  }
2756
2746
  }
2747
+ get asyncCompilationStatus() {
2748
+ return this._waitForCompilationComplete().then(() => this.compilationStatus);
2749
+ }
2757
2750
  async getCompilationInfo() {
2758
2751
  await this._waitForCompilationComplete();
2759
2752
  return this.getCompilationInfoSync();
2760
2753
  }
2761
2754
  getCompilationInfoSync() {
2762
- const log12 = this.device.gl.getShaderInfoLog(this.handle);
2763
- return log12 ? parseShaderCompilerLog(log12) : [];
2755
+ const shaderLog = this.device.gl.getShaderInfoLog(this.handle);
2756
+ return shaderLog ? parseShaderCompilerLog(shaderLog) : [];
2764
2757
  }
2765
2758
  getTranslatedSource() {
2766
2759
  const extensions = this.device.getExtension("WEBGL_debug_shaders");
@@ -2770,13 +2763,12 @@ var __exports__ = (() => {
2770
2763
  // PRIVATE METHODS
2771
2764
  /** Compile a shader and get compilation status */
2772
2765
  async _compile(source) {
2773
- const addGLSLVersion = (source2) => source2.startsWith("#version ") ? source2 : `#version 300 es
2774
- ${source2}`;
2775
- source = addGLSLVersion(source);
2766
+ source = source.startsWith("#version ") ? source : `#version 300 es
2767
+ ${source}`;
2776
2768
  const { gl } = this.device;
2777
2769
  gl.shaderSource(this.handle, source);
2778
2770
  gl.compileShader(this.handle);
2779
- if (import_core9.log.level === 0) {
2771
+ if (!this.device.props.debug) {
2780
2772
  this.compilationStatus = "pending";
2781
2773
  return;
2782
2774
  }
@@ -3145,15 +3137,17 @@ ${source2}`;
3145
3137
  return 9729 /* LINEAR */;
3146
3138
  }
3147
3139
  }
3148
- function convertMinFilterMode(minFilter, mipmapFilter) {
3140
+ function convertMinFilterMode(minFilter, mipmapFilter = "none") {
3149
3141
  if (!mipmapFilter) {
3150
3142
  return convertMaxFilterMode(minFilter);
3151
3143
  }
3152
- switch (minFilter) {
3144
+ switch (mipmapFilter) {
3145
+ case "none":
3146
+ return convertMaxFilterMode(minFilter);
3153
3147
  case "nearest":
3154
- return mipmapFilter === "nearest" ? 9984 /* NEAREST_MIPMAP_NEAREST */ : 9986 /* NEAREST_MIPMAP_LINEAR */;
3148
+ return minFilter === "nearest" ? 9984 /* NEAREST_MIPMAP_NEAREST */ : 9986 /* NEAREST_MIPMAP_LINEAR */;
3155
3149
  case "linear":
3156
- return mipmapFilter === "nearest" ? 9985 /* LINEAR_MIPMAP_NEAREST */ : 9987 /* LINEAR_MIPMAP_LINEAR */;
3150
+ return minFilter === "nearest" ? 9985 /* LINEAR_MIPMAP_NEAREST */ : 9987 /* LINEAR_MIPMAP_LINEAR */;
3157
3151
  }
3158
3152
  }
3159
3153
 
@@ -3303,14 +3297,20 @@ ${source2}`;
3303
3297
  case 6406 /* ALPHA */:
3304
3298
  case 33326 /* R32F */:
3305
3299
  case 6403 /* RED */:
3300
+ case 36244 /* RED_INTEGER */:
3306
3301
  return 1;
3302
+ case 33339 /* RG32I */:
3303
+ case 33340 /* RG32UI */:
3307
3304
  case 33328 /* RG32F */:
3305
+ case 33320 /* RG_INTEGER */:
3308
3306
  case 33319 /* RG */:
3309
3307
  return 2;
3310
3308
  case 6407 /* RGB */:
3309
+ case 36248 /* RGB_INTEGER */:
3311
3310
  case 34837 /* RGB32F */:
3312
3311
  return 3;
3313
3312
  case 6408 /* RGBA */:
3313
+ case 36249 /* RGBA_INTEGER */:
3314
3314
  case 34836 /* RGBA32F */:
3315
3315
  return 4;
3316
3316
  default:
@@ -3352,22 +3352,25 @@ ${source2}`;
3352
3352
  const { x = 0, y = 0, z = 0 } = options;
3353
3353
  const { glFormat, glType } = options;
3354
3354
  const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
3355
- switch (dimension) {
3356
- case "2d-array":
3357
- case "3d":
3358
- gl.bindTexture(glTarget, handle);
3359
- gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, glType, image);
3360
- gl.bindTexture(glTarget, null);
3361
- break;
3362
- case "2d":
3363
- case "cube":
3364
- gl.bindTexture(glTarget, handle);
3365
- gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, glType, image);
3366
- gl.bindTexture(glTarget, null);
3367
- break;
3368
- default:
3369
- throw new Error(dimension);
3370
- }
3355
+ const glParameters = options.flipY ? { [37440 /* UNPACK_FLIP_Y_WEBGL */]: true } : {};
3356
+ withGLParameters(gl, glParameters, () => {
3357
+ switch (dimension) {
3358
+ case "2d-array":
3359
+ case "3d":
3360
+ gl.bindTexture(glTarget, handle);
3361
+ gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, glType, image);
3362
+ gl.bindTexture(glTarget, null);
3363
+ break;
3364
+ case "2d":
3365
+ case "cube":
3366
+ gl.bindTexture(glTarget, handle);
3367
+ gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, glType, image);
3368
+ gl.bindTexture(glTarget, null);
3369
+ break;
3370
+ default:
3371
+ throw new Error(dimension);
3372
+ }
3373
+ });
3371
3374
  }
3372
3375
  function copyCPUDataToMipLevel(gl, typedArray, options) {
3373
3376
  const { dimension, width, height, depth = 0, mipLevel = 0, byteOffset = 0 } = options;
@@ -3419,11 +3422,11 @@ ${source2}`;
3419
3422
  const {
3420
3423
  sourceX = 0,
3421
3424
  sourceY = 0,
3422
- sourceAttachment = 36064 /* COLOR_ATTACHMENT0 */
3425
+ sourceAttachment = 0
3423
3426
  // TODO - support gl.readBuffer
3424
3427
  } = options || {};
3425
3428
  let {
3426
- target = null,
3429
+ target: target2 = null,
3427
3430
  // following parameters are auto deduced if not provided
3428
3431
  sourceWidth,
3429
3432
  sourceHeight,
@@ -3433,25 +3436,33 @@ ${source2}`;
3433
3436
  } = options || {};
3434
3437
  const { framebuffer, deleteFramebuffer } = getFramebuffer(source);
3435
3438
  const { gl, handle } = framebuffer;
3436
- const attachment = sourceAttachment - 36064 /* COLOR_ATTACHMENT0 */;
3437
3439
  sourceWidth ||= framebuffer.width;
3438
3440
  sourceHeight ||= framebuffer.height;
3439
- sourceDepth = framebuffer.colorAttachments[attachment]?.texture?.depth || 1;
3440
- sourceFormat ||= framebuffer.colorAttachments[attachment]?.texture?.glFormat || 6408 /* RGBA */;
3441
- sourceType ||= framebuffer.colorAttachments[attachment]?.texture?.glType || 5121 /* UNSIGNED_BYTE */;
3442
- target = getPixelArray(target, sourceType, sourceFormat, sourceWidth, sourceHeight, sourceDepth);
3443
- sourceType = sourceType || getGLTypeFromTypedArray(target);
3444
- const prevHandle = gl.bindFramebuffer(36160 /* FRAMEBUFFER */, handle);
3445
- gl.readPixels(sourceX, sourceY, sourceWidth, sourceHeight, sourceFormat, sourceType, target);
3441
+ const texture = framebuffer.colorAttachments[sourceAttachment]?.texture;
3442
+ if (!texture) {
3443
+ throw new Error(`Invalid framebuffer attachment ${sourceAttachment}`);
3444
+ }
3445
+ sourceDepth = texture?.depth || 1;
3446
+ sourceFormat ||= texture?.glFormat || 6408 /* RGBA */;
3447
+ sourceType ||= texture?.glType || 5121 /* UNSIGNED_BYTE */;
3448
+ target2 = getPixelArray(target2, sourceType, sourceFormat, sourceWidth, sourceHeight, sourceDepth);
3449
+ sourceType = sourceType || getGLTypeFromTypedArray(target2);
3450
+ const prevHandle = gl.bindFramebuffer(
3451
+ 36160 /* FRAMEBUFFER */,
3452
+ handle
3453
+ );
3454
+ gl.readBuffer(gl.COLOR_ATTACHMENT0 + sourceAttachment);
3455
+ gl.readPixels(sourceX, sourceY, sourceWidth, sourceHeight, sourceFormat, sourceType, target2);
3456
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
3446
3457
  gl.bindFramebuffer(36160 /* FRAMEBUFFER */, prevHandle || null);
3447
3458
  if (deleteFramebuffer) {
3448
3459
  framebuffer.destroy();
3449
3460
  }
3450
- return target;
3461
+ return target2;
3451
3462
  }
3452
3463
  function readPixelsToBuffer(source, options) {
3453
3464
  const {
3454
- target,
3465
+ target: target2,
3455
3466
  sourceX = 0,
3456
3467
  sourceY = 0,
3457
3468
  sourceFormat = 6408 /* RGBA */,
@@ -3463,7 +3474,7 @@ ${source2}`;
3463
3474
  sourceHeight = sourceHeight || framebuffer.height;
3464
3475
  const webglFramebuffer = framebuffer;
3465
3476
  sourceType = sourceType || 5121 /* UNSIGNED_BYTE */;
3466
- let webglBufferTarget = target;
3477
+ let webglBufferTarget = target2;
3467
3478
  if (!webglBufferTarget) {
3468
3479
  const components = glFormatToComponents(sourceFormat);
3469
3480
  const byteCount = glTypeToBytes(sourceType);
@@ -3472,11 +3483,11 @@ ${source2}`;
3472
3483
  }
3473
3484
  const commandEncoder = source.device.createCommandEncoder();
3474
3485
  commandEncoder.copyTextureToBuffer({
3475
- source,
3486
+ sourceTexture: source,
3476
3487
  width: sourceWidth,
3477
3488
  height: sourceHeight,
3478
3489
  origin: [sourceX, sourceY],
3479
- destination: webglBufferTarget,
3490
+ destinationBuffer: webglBufferTarget,
3480
3491
  byteOffset: targetByteOffset
3481
3492
  });
3482
3493
  commandEncoder.destroy();
@@ -3502,38 +3513,19 @@ ${source2}`;
3502
3513
  });
3503
3514
  return framebuffer;
3504
3515
  }
3505
- function getPixelArray(pixelArray, type, format, width, height, depth) {
3516
+ function getPixelArray(pixelArray, glType, glFormat, width, height, depth) {
3506
3517
  if (pixelArray) {
3507
3518
  return pixelArray;
3508
3519
  }
3509
- type = type || 5121 /* UNSIGNED_BYTE */;
3510
- const ArrayType = getTypedArrayFromGLType(type, { clamped: false });
3511
- const components = glFormatToComponents(format);
3520
+ glType ||= 5121 /* UNSIGNED_BYTE */;
3521
+ const ArrayType = getTypedArrayFromGLType(glType, { clamped: false });
3522
+ const components = glFormatToComponents(glFormat);
3512
3523
  return new ArrayType(width * height * components);
3513
3524
  }
3514
3525
 
3515
3526
  // src/adapter/resources/webgl-texture.ts
3516
- function normalizeTextureData(data, options) {
3517
- let lodArray;
3518
- if (ArrayBuffer.isView(data)) {
3519
- lodArray = [
3520
- {
3521
- // ts-expect-error does data really need to be Uint8ClampedArray?
3522
- data,
3523
- width: options.width,
3524
- height: options.height
3525
- // depth: options.depth
3526
- }
3527
- ];
3528
- } else if (!Array.isArray(data)) {
3529
- lodArray = [data];
3530
- } else {
3531
- lodArray = data;
3532
- }
3533
- return lodArray;
3534
- }
3535
3527
  var WEBGLTexture = class extends import_core14.Texture {
3536
- MAX_ATTRIBUTES;
3528
+ // readonly MAX_ATTRIBUTES: number;
3537
3529
  device;
3538
3530
  gl;
3539
3531
  handle;
@@ -3541,8 +3533,12 @@ ${source2}`;
3541
3533
  // TODO - currently unused in WebGL. Create dummy sampler?
3542
3534
  view = void 0;
3543
3535
  // TODO - currently unused in WebGL. Create dummy view?
3544
- mipmaps = false;
3536
+ mipmaps;
3537
+ // Texture type
3538
+ /** Whether the internal format is compressed */
3539
+ compressed;
3545
3540
  /**
3541
+ * The WebGL target corresponding to the texture type
3546
3542
  * @note `target` cannot be modified by bind:
3547
3543
  * textures are special because when you first bind them to a target,
3548
3544
  * When you first bind a texture as a GL_TEXTURE_2D, you are saying that this texture is a 2D texture.
@@ -3551,122 +3547,79 @@ ${source2}`;
3551
3547
  * attempting to bind it as GL_TEXTURE_3D will give rise to a run-time error
3552
3548
  */
3553
3549
  glTarget;
3554
- // Texture type
3555
3550
  /** The WebGL format - essentially channel structure */
3556
3551
  glFormat;
3557
3552
  /** The WebGL data format - the type of each channel */
3558
3553
  glType;
3559
3554
  /** The WebGL constant corresponding to the WebGPU style constant in format */
3560
3555
  glInternalFormat;
3561
- /** Whether the internal format is compressed */
3562
- compressed;
3563
- // data;
3564
- // inherited props
3565
- // dimension: ...
3566
- // format: GLTextureTarget;
3567
- // width: number = undefined;
3568
- // height: number = undefined;
3569
- // depth: number = undefined;
3570
3556
  // state
3571
- /** Texture binding slot */
3557
+ /** Texture binding slot - TODO - move to texture view? */
3572
3558
  textureUnit = 0;
3573
- /** For automatically updating video */
3574
- _video = null;
3575
3559
  constructor(device, props) {
3576
- props = import_core14.Texture._fixProps(props);
3577
- super(device, { ...import_core14.Texture.defaultProps, ...props, data: void 0 });
3560
+ super(device, props);
3561
+ const propsWithData = { ...this.props };
3562
+ propsWithData.data = props.data;
3578
3563
  this.device = device;
3579
3564
  this.gl = this.device.gl;
3580
3565
  this.glTarget = getWebGLTextureTarget(this.props.dimension);
3581
- const format = getTextureFormatWebGL(this.props.format);
3582
- this.glInternalFormat = format.internalFormat;
3583
- this.glFormat = format.format;
3584
- this.glType = format.type;
3585
- this.compressed = format.compressed;
3586
- if (typeof HTMLVideoElement !== "undefined" && props.data instanceof HTMLVideoElement && // @ts-expect-error
3587
- props.data.readyState < HTMLVideoElement.HAVE_METADATA) {
3588
- const video = props.data;
3589
- this._video = null;
3590
- video.addEventListener("loadeddata", () => this.initialize(props));
3591
- }
3592
- this.initialize({ ...this.props, data: props.data });
3566
+ const formatInfo = getTextureFormatWebGL(this.props.format);
3567
+ this.glInternalFormat = formatInfo.internalFormat;
3568
+ this.glFormat = formatInfo.format;
3569
+ this.glType = formatInfo.type;
3570
+ this.compressed = formatInfo.compressed;
3571
+ this.mipmaps = Boolean(this.props.mipmaps);
3572
+ this._initialize(propsWithData);
3593
3573
  Object.seal(this);
3594
3574
  }
3595
3575
  /**
3596
3576
  * Initialize texture with supplied props
3597
3577
  */
3598
3578
  // eslint-disable-next-line max-statements
3599
- initialize(props = {}) {
3579
+ _initialize(propsWithData) {
3600
3580
  this.handle = this.props.handle || this.gl.createTexture();
3601
- this.device.setSpectorMetadata(this.handle, { ...this.props, data: typeof this.props.data });
3602
- const data = props.data;
3603
- let { width, height } = props;
3581
+ this.device.setSpectorMetadata(this.handle, { ...this.props, data: propsWithData.data });
3582
+ let { width, height } = propsWithData;
3604
3583
  if (!width || !height) {
3605
- const textureSize = import_core14.Texture.getTextureDataSize(data);
3584
+ const textureSize = import_core14.Texture.getTextureDataSize(propsWithData.data);
3606
3585
  width = textureSize?.width || 1;
3607
3586
  height = textureSize?.height || 1;
3608
3587
  }
3609
3588
  this.width = width;
3610
3589
  this.height = height;
3611
- this.depth = props.depth;
3612
- this.setSampler(props.sampler);
3590
+ this.depth = propsWithData.depth;
3591
+ this.setSampler(propsWithData.sampler);
3613
3592
  this.view = new WEBGLTextureView(this.device, { ...this.props, texture: this });
3614
3593
  this.bind();
3615
- if (!this.props.data) {
3616
- initializeTextureStorage(this.gl, this.mipLevels, this);
3617
- }
3618
- if (props.data) {
3619
- switch (props.dimension) {
3594
+ initializeTextureStorage(this.gl, this.mipLevels, this);
3595
+ if (propsWithData.data) {
3596
+ switch (propsWithData.dimension) {
3620
3597
  case "1d":
3621
- this.setTexture1DData(props.data);
3598
+ this.setTexture1DData(propsWithData.data);
3622
3599
  break;
3623
3600
  case "2d":
3624
- this.setTexture2DData(props.data);
3601
+ this.setTexture2DData(propsWithData.data);
3625
3602
  break;
3626
3603
  case "3d":
3627
- this.setTexture3DData(props.data);
3604
+ this.setTexture3DData(propsWithData.data);
3628
3605
  break;
3629
3606
  case "cube":
3630
- this.setTextureCubeData(props.data);
3607
+ this.setTextureCubeData(propsWithData.data);
3631
3608
  break;
3632
3609
  case "2d-array":
3633
- this.setTextureArrayData(props.data);
3610
+ this.setTextureArrayData(propsWithData.data);
3634
3611
  break;
3635
3612
  case "cube-array":
3636
- this.setTextureCubeArrayData(props.data);
3613
+ this.setTextureCubeArrayData(propsWithData.data);
3637
3614
  break;
3638
3615
  default:
3639
- throw new Error(props.dimension);
3616
+ throw new Error(propsWithData.dimension);
3640
3617
  }
3641
3618
  }
3642
- this.mipmaps = Boolean(props.mipmaps);
3643
3619
  if (this.mipmaps) {
3644
3620
  this.generateMipmap();
3645
3621
  }
3646
3622
  }
3647
- /*
3648
- initializeCube(props?: TextureProps): void {
3649
- const {mipmaps = true} = props; // , parameters = {} as Record<GL, any>} = props;
3650
-
3651
- // Store props for accessors
3652
- // this.props = props;
3653
-
3654
- // @ts-expect-error
3655
- this.setCubeMapData(props).then(() => {
3656
- // TODO - should genMipmap() be called on the cubemap or on the faces?
3657
- // TODO - without generateMipmap() cube textures do not work at all!!! Why?
3658
- if (mipmaps) {
3659
- this.generateMipmap(props);
3660
- }
3661
-
3662
- this.setSampler(props.sampler);
3663
-
3664
- // v8 compatibility?
3665
- // const {parameters = {} as Record<GL, any>} = props;
3666
- // this._setSamplerParameters(parameters);
3667
- });
3668
- }
3669
- */
3670
3623
  destroy() {
3671
3624
  if (this.handle) {
3672
3625
  this.gl.deleteTexture(this.handle);
@@ -3675,9 +3628,6 @@ ${source2}`;
3675
3628
  this.destroyed = true;
3676
3629
  }
3677
3630
  }
3678
- toString() {
3679
- return `Texture(${this.id},${this.width}x${this.height})`;
3680
- }
3681
3631
  createView(props) {
3682
3632
  return new WEBGLTextureView(this.device, { ...props, texture: this });
3683
3633
  }
@@ -3693,35 +3643,33 @@ ${source2}`;
3693
3643
  const parameters = convertSamplerParametersToWebGL(samplerProps);
3694
3644
  this._setSamplerParameters(parameters);
3695
3645
  }
3696
- /** Update external texture (video frame or canvas) */
3697
- update() {
3698
- import_core14.log.warn("Texture.update() not implemented");
3699
- }
3700
3646
  // Call to regenerate mipmaps after modifying texture(s)
3701
3647
  generateMipmap(params = {}) {
3702
- if (!this.props.data) {
3703
- return;
3648
+ if (!this.device.isTextureFormatRenderable(this.props.format) || !this.device.isTextureFormatFilterable(this.props.format)) {
3649
+ import_core14.log.warn(`${this} is not renderable or filterable, may not be able to generate mipmaps`)();
3650
+ }
3651
+ try {
3652
+ this.gl.bindTexture(this.glTarget, this.handle);
3653
+ withGLParameters(this.gl, params, () => {
3654
+ this.gl.generateMipmap(this.glTarget);
3655
+ });
3656
+ } catch (error) {
3657
+ import_core14.log.warn(`Error generating mipmap for ${this}: ${error.message}`)();
3658
+ } finally {
3659
+ this.gl.bindTexture(this.glTarget, null);
3704
3660
  }
3705
- this.mipmaps = true;
3706
- this.gl.bindTexture(this.glTarget, this.handle);
3707
- withGLParameters(this.gl, params, () => {
3708
- this.gl.generateMipmap(this.glTarget);
3709
- });
3710
- this.gl.bindTexture(this.glTarget, null);
3711
3661
  }
3712
3662
  // Image Data Setters
3713
3663
  copyExternalImage(options) {
3714
3664
  const size = import_core14.Texture.getExternalImageSize(options.image);
3715
3665
  const opts = { ...import_core14.Texture.defaultCopyExternalImageOptions, ...size, ...options };
3716
- const { image, depth, mipLevel, x, y, z } = opts;
3666
+ const { image, depth, mipLevel, x, y, z, flipY } = opts;
3717
3667
  let { width, height } = opts;
3718
3668
  const { dimension, glTarget, glFormat, glInternalFormat, glType } = this;
3719
3669
  width = Math.min(width, size.width - x);
3720
3670
  height = Math.min(height, size.height - y);
3721
3671
  if (options.sourceX || options.sourceY) {
3722
- throw new Error(
3723
- "WebGL does not yet support sourceX/sourceY in copyExternalImage; requires copyTexSubImage2D from a framebuffer"
3724
- );
3672
+ throw new Error("WebGL does not support sourceX/sourceY)");
3725
3673
  }
3726
3674
  copyExternalImageToMipLevel(this.device.gl, this.handle, image, {
3727
3675
  dimension,
@@ -3735,7 +3683,8 @@ ${source2}`;
3735
3683
  glFormat,
3736
3684
  glInternalFormat,
3737
3685
  glType,
3738
- glTarget
3686
+ glTarget,
3687
+ flipY
3739
3688
  });
3740
3689
  return { width: opts.width, height: opts.height };
3741
3690
  }
@@ -3745,7 +3694,7 @@ ${source2}`;
3745
3694
  /** Set a simple texture */
3746
3695
  setTexture2DData(lodData, depth = 0) {
3747
3696
  this.bind();
3748
- const lodArray = normalizeTextureData(lodData, this);
3697
+ const lodArray = import_core14.Texture.normalizeTextureData(lodData, this);
3749
3698
  if (lodArray.length > 1 && this.props.mipmaps !== false) {
3750
3699
  import_core14.log.warn(`Texture ${this.id} mipmap and multiple LODs.`)();
3751
3700
  }
@@ -3807,6 +3756,11 @@ ${source2}`;
3807
3756
  const faceDepth = import_core14.Texture.CubeFaces.indexOf(face);
3808
3757
  this.setTexture2DData(lodData, faceDepth);
3809
3758
  }
3759
+ // DEPRECATED METHODS
3760
+ /** Update external texture (video frame or canvas) @deprecated Use ExternalTexture */
3761
+ update() {
3762
+ throw new Error("Texture.update() not implemented. Use ExternalTexture");
3763
+ }
3810
3764
  // INTERNAL METHODS
3811
3765
  /** @todo update this method to accept LODs */
3812
3766
  setImageDataForFace(options) {
@@ -3854,7 +3808,7 @@ ${source2}`;
3854
3808
  * Sets sampler parameters on texture
3855
3809
  */
3856
3810
  _setSamplerParameters(parameters) {
3857
- import_core14.log.log(1, "texture sampler parameters", parameters)();
3811
+ import_core14.log.log(1, `${this.id} sampler parameters`, this.device.getGLKeys(parameters))();
3858
3812
  this.gl.bindTexture(this.glTarget, this.handle);
3859
3813
  for (const [pname, pvalue] of Object.entries(parameters)) {
3860
3814
  const param = Number(pname);
@@ -3883,61 +3837,6 @@ ${source2}`;
3883
3837
  }
3884
3838
  this.gl.bindTexture(this.glTarget, null);
3885
3839
  }
3886
- // CLASSIC
3887
- /*
3888
- setCubeMapData(options: {
3889
- width: number;
3890
- height: number;
3891
- data: Record<GL, Texture2DData> | Record<TextureCubeFace, Texture2DData>;
3892
- format?: any;
3893
- type?: any;
3894
- /** @deprecated Use .data *
3895
- pixels: any;
3896
- }): void {
3897
- const {gl} = this;
3898
-
3899
- const {width, height, pixels, data, format = GL.RGBA, type = GL.UNSIGNED_BYTE} = options;
3900
-
3901
- // pixel data (imageDataMap) is an Object from Face to Image or Promise.
3902
- // For example:
3903
- // {
3904
- // GL.TEXTURE_CUBE_MAP_POSITIVE_X : Image-or-Promise,
3905
- // GL.TEXTURE_CUBE_MAP_NEGATIVE_X : Image-or-Promise,
3906
- // ... }
3907
- // To provide multiple level-of-details (LODs) this can be Face to Array
3908
- // of Image or Promise, like this
3909
- // {
3910
- // GL.TEXTURE_CUBE_MAP_POSITIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
3911
- // GL.TEXTURE_CUBE_MAP_NEGATIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
3912
- // ... }
3913
-
3914
- const imageDataMap = this._getImageDataMap(pixels || data);
3915
-
3916
- const resolvedFaces = WEBGLTexture.FACES.map(face => {
3917
- const facePixels = imageDataMap[face];
3918
- return Array.isArray(facePixels) ? facePixels : [facePixels];
3919
- });
3920
- this.bind();
3921
-
3922
- WEBGLTexture.FACES.forEach((face, index) => {
3923
- if (resolvedFaces[index].length > 1 && this.props.mipmaps !== false) {
3924
- // If the user provides multiple LODs, then automatic mipmap
3925
- // generation generateMipmap() should be disabled to avoid overwritting them.
3926
- log.warn(`${this.id} has mipmap and multiple LODs.`)();
3927
- }
3928
- resolvedFaces[index].forEach((image, lodLevel) => {
3929
- // TODO: adjust width & height for LOD!
3930
- if (width && height) {
3931
- gl.texImage2D(face, lodLevel, format, width, height, 0 /* border*, format, type, image);
3932
- } else {
3933
- gl.texImage2D(face, lodLevel, format, format, type, image);
3934
- }
3935
- });
3936
- });
3937
-
3938
- this.unbind();
3939
- }
3940
- */
3941
3840
  // INTERNAL SETTERS
3942
3841
  /**
3943
3842
  * Copy a region of data from a CPU memory buffer into this texture.
@@ -3949,7 +3848,8 @@ ${source2}`;
3949
3848
  ...this,
3950
3849
  depth,
3951
3850
  mipLevel,
3952
- glTarget
3851
+ glTarget,
3852
+ flipY: this.props.flipY
3953
3853
  });
3954
3854
  return;
3955
3855
  }
@@ -3990,10 +3890,6 @@ ${source2}`;
3990
3890
 
3991
3891
  // src/adapter/resources/webgl-render-pass.ts
3992
3892
  var import_core15 = __toESM(require_core(), 1);
3993
- var GL_DEPTH_BUFFER_BIT = 256;
3994
- var GL_STENCIL_BUFFER_BIT = 1024;
3995
- var GL_COLOR_BUFFER_BIT = 16384;
3996
- var GL_COLOR = 6144;
3997
3893
  var COLOR_CHANNELS = [1, 2, 4, 8];
3998
3894
  var WEBGLRenderPass = class extends import_core15.RenderPass {
3999
3895
  device;
@@ -4014,6 +3910,14 @@ ${source2}`;
4014
3910
  }
4015
3911
  this.device.pushState();
4016
3912
  this.setParameters({ viewport, ...this.props.parameters });
3913
+ if (this.props.framebuffer) {
3914
+ const drawBuffers = this.props.framebuffer.colorAttachments.map(
3915
+ (_, i) => 36064 /* COLOR_ATTACHMENT0 */ + i
3916
+ );
3917
+ this.device.gl.drawBuffers(drawBuffers);
3918
+ } else {
3919
+ this.device.gl.drawBuffers([1029 /* BACK */]);
3920
+ }
4017
3921
  this.clear();
4018
3922
  }
4019
3923
  end() {
@@ -4079,19 +3983,30 @@ ${source2}`;
4079
3983
  * Optionally clears depth, color and stencil buffers based on parameters
4080
3984
  */
4081
3985
  clear() {
3986
+ const DEFAULT_CLEAR_COLOR = [0, 0, 0, 1];
3987
+ const DEFAULT_CLEAR_DEPTH = 1;
3988
+ const DEFAULT_CLEAR_STENCIL = 0;
4082
3989
  const glParameters = { ...this.glParameters };
4083
3990
  let clearMask = 0;
4084
- if (this.props.clearColor !== false) {
4085
- clearMask |= GL_COLOR_BUFFER_BIT;
4086
- glParameters.clearColor = this.props.clearColor;
3991
+ if (this.props.clearColors) {
3992
+ this.props.clearColors.forEach((color, drawBufferIndex) => {
3993
+ if (color) {
3994
+ this.clearColorBuffer(drawBufferIndex, color);
3995
+ }
3996
+ });
3997
+ }
3998
+ if (this.props.clearColor !== false && this.props.clearColors === void 0) {
3999
+ clearMask |= 16384 /* COLOR_BUFFER_BIT */;
4000
+ const clearColor = this.props.clearColor === true ? DEFAULT_CLEAR_COLOR : this.props.clearColor;
4001
+ glParameters.clearColor = clearColor;
4087
4002
  }
4088
4003
  if (this.props.clearDepth !== false) {
4089
- clearMask |= GL_DEPTH_BUFFER_BIT;
4090
- glParameters.clearDepth = this.props.clearDepth;
4004
+ clearMask |= 256 /* DEPTH_BUFFER_BIT */;
4005
+ glParameters.clearDepth = this.props.clearDepth === true ? DEFAULT_CLEAR_DEPTH : this.props.clearDepth;
4091
4006
  }
4092
4007
  if (this.props.clearStencil !== false) {
4093
- clearMask |= GL_STENCIL_BUFFER_BIT;
4094
- glParameters.clearStencil = this.props.clearStencil;
4008
+ clearMask |= 1024 /* STENCIL_BUFFER_BIT */;
4009
+ glParameters.clearStencil = this.props.clearStencil === true ? DEFAULT_CLEAR_STENCIL : this.props.clearStencil;
4095
4010
  }
4096
4011
  if (clearMask !== 0) {
4097
4012
  withGLParameters(this.device.gl, glParameters, () => {
@@ -4105,21 +4020,27 @@ ${source2}`;
4105
4020
  clearColorBuffer(drawBuffer = 0, value = [0, 0, 0, 0]) {
4106
4021
  withGLParameters(this.device.gl, { framebuffer: this.props.framebuffer }, () => {
4107
4022
  switch (value.constructor) {
4023
+ case Int8Array:
4024
+ case Int16Array:
4108
4025
  case Int32Array:
4109
- this.device.gl.clearBufferiv(GL_COLOR, drawBuffer, value);
4026
+ this.device.gl.clearBufferiv(6144 /* COLOR */, drawBuffer, value);
4110
4027
  break;
4028
+ case Uint8Array:
4029
+ case Uint8ClampedArray:
4030
+ case Uint16Array:
4111
4031
  case Uint32Array:
4112
- this.device.gl.clearBufferuiv(GL_COLOR, drawBuffer, value);
4032
+ this.device.gl.clearBufferuiv(6144 /* COLOR */, drawBuffer, value);
4113
4033
  break;
4114
4034
  case Float32Array:
4115
- default:
4116
- this.device.gl.clearBufferfv(GL_COLOR, drawBuffer, value);
4035
+ this.device.gl.clearBufferfv(6144 /* COLOR */, drawBuffer, value);
4117
4036
  break;
4037
+ default:
4038
+ throw new Error("clearColorBuffer: color must be typed array");
4118
4039
  }
4119
4040
  });
4120
4041
  }
4121
4042
  // clearDepthStencil() {
4122
- // const GL_DEPTH = 0x1801;
4043
+ // const GL.DEPTH = 0x1801;
4123
4044
  // const GL_STENCIL = 0x1802;
4124
4045
  // const GL_DEPTH_STENCIL = 0x84f9;
4125
4046
  // case GL_DEPTH:
@@ -4634,9 +4555,9 @@ ${source2}`;
4634
4555
  */
4635
4556
  setBindings(bindings, options) {
4636
4557
  for (const [name, value] of Object.entries(bindings)) {
4637
- const binding = this.shaderLayout.bindings.find((binding2) => binding2.name === name) || this.shaderLayout.bindings.find((binding2) => binding2.name === `${name}Uniforms`);
4558
+ const binding = this.shaderLayout.bindings.find((binding_) => binding_.name === name) || this.shaderLayout.bindings.find((binding_) => binding_.name === `${name}Uniforms`);
4638
4559
  if (!binding) {
4639
- const validBindings = this.shaderLayout.bindings.map((binding2) => `"${binding2.name}"`).join(", ");
4560
+ const validBindings = this.shaderLayout.bindings.map((binding_) => `"${binding_.name}"`).join(", ");
4640
4561
  if (!options?.disableWarnings) {
4641
4562
  import_core16.log.warn(
4642
4563
  `No binding "${name}" in render pipeline "${this.id}", expected one of ${validBindings}`,
@@ -4772,20 +4693,33 @@ ${source2}`;
4772
4693
  this._reportLinkStatus(status);
4773
4694
  }
4774
4695
  /** Report link status. First, check for shader compilation failures if linking fails */
4775
- _reportLinkStatus(status) {
4696
+ async _reportLinkStatus(status) {
4776
4697
  switch (status) {
4777
4698
  case "success":
4778
4699
  return;
4779
4700
  default:
4780
- if (this.vs.compilationStatus === "error") {
4781
- this.vs.debugShader();
4782
- throw new Error(`Error during compilation of shader ${this.vs.id}`);
4701
+ switch (this.vs.compilationStatus) {
4702
+ case "error":
4703
+ this.vs.debugShader();
4704
+ throw new Error(`Error during compilation of shader ${this.vs.id}`);
4705
+ case "pending":
4706
+ this.vs.asyncCompilationStatus.then(() => this.vs.debugShader());
4707
+ break;
4708
+ case "success":
4709
+ break;
4783
4710
  }
4784
- if (this.fs?.compilationStatus === "error") {
4785
- this.fs.debugShader();
4786
- throw new Error(`Error during compilation of shader ${this.fs.id}`);
4711
+ switch (this.fs?.compilationStatus) {
4712
+ case "error":
4713
+ this.fs.debugShader();
4714
+ throw new Error(`Error during compilation of shader ${this.fs.id}`);
4715
+ case "pending":
4716
+ this.fs.asyncCompilationStatus.then(() => this.fs.debugShader());
4717
+ break;
4718
+ case "success":
4719
+ break;
4787
4720
  }
4788
- throw new Error(`Error during ${status}: ${this.device.gl.getProgramInfoLog(this.handle)}`);
4721
+ const linkErrorLog = this.device.gl.getProgramInfoLog(this.handle);
4722
+ throw new Error(`Error during ${status}: ${linkErrorLog}`);
4789
4723
  }
4790
4724
  }
4791
4725
  /**
@@ -4839,11 +4773,6 @@ ${source2}`;
4839
4773
  texturesRenderable = false;
4840
4774
  }
4841
4775
  }
4842
- for (const [, texture] of Object.entries(this.bindings)) {
4843
- if (texture instanceof WEBGLTexture) {
4844
- texture.update();
4845
- }
4846
- }
4847
4776
  return texturesRenderable;
4848
4777
  }
4849
4778
  /** Apply any bindings (before each draw call) */
@@ -4971,13 +4900,15 @@ ${source2}`;
4971
4900
  case "copy-texture-to-texture":
4972
4901
  _copyTextureToTexture(this.device, command.options);
4973
4902
  break;
4903
+ default:
4904
+ throw new Error(command.name);
4974
4905
  }
4975
4906
  }
4976
4907
  }
4977
4908
  };
4978
4909
  function _copyBufferToBuffer(device, options) {
4979
- const source = options.source;
4980
- const destination = options.destination;
4910
+ const source = options.sourceBuffer;
4911
+ const destination = options.destinationBuffer;
4981
4912
  device.gl.bindBuffer(36662 /* COPY_READ_BUFFER */, source.handle);
4982
4913
  device.gl.bindBuffer(36663 /* COPY_WRITE_BUFFER */, destination.handle);
4983
4914
  device.gl.copyBufferSubData(
@@ -4996,20 +4927,20 @@ ${source2}`;
4996
4927
  function _copyTextureToBuffer(device, options) {
4997
4928
  const {
4998
4929
  /** Texture to copy to/from. */
4999
- source,
4930
+ sourceTexture,
5000
4931
  /** Mip-map level of the texture to copy to/from. (Default 0) */
5001
4932
  mipLevel = 0,
5002
4933
  /** Defines which aspects of the texture to copy to/from. */
5003
4934
  aspect = "all",
5004
4935
  /** Width to copy */
5005
- width = options.source.width,
4936
+ width = options.sourceTexture.width,
5006
4937
  /** Height to copy */
5007
- height = options.source.height,
4938
+ height = options.sourceTexture.height,
5008
4939
  depthOrArrayLayers = 0,
5009
4940
  /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
5010
4941
  origin = [0, 0],
5011
4942
  /** Destination buffer */
5012
- destination,
4943
+ destinationBuffer,
5013
4944
  /** Offset, in bytes, from the beginning of the buffer to the start of the image data (default 0) */
5014
4945
  byteOffset = 0,
5015
4946
  /**
@@ -5025,15 +4956,15 @@ ${source2}`;
5025
4956
  rowsPerImage
5026
4957
  } = options;
5027
4958
  if (aspect !== "all") {
5028
- throw new Error("not supported");
4959
+ throw new Error("aspect not supported in WebGL");
5029
4960
  }
5030
4961
  if (mipLevel !== 0 || depthOrArrayLayers !== 0 || bytesPerRow || rowsPerImage) {
5031
4962
  throw new Error("not implemented");
5032
4963
  }
5033
- const { framebuffer, destroyFramebuffer } = getFramebuffer2(source);
4964
+ const { framebuffer, destroyFramebuffer } = getFramebuffer2(sourceTexture);
5034
4965
  let prevHandle;
5035
4966
  try {
5036
- const webglBuffer = destination;
4967
+ const webglBuffer = destinationBuffer;
5037
4968
  const sourceWidth = width || framebuffer.width;
5038
4969
  const sourceHeight = height || framebuffer.height;
5039
4970
  const sourceParams = getTextureFormatWebGL(
@@ -5065,7 +4996,7 @@ ${source2}`;
5065
4996
  function _copyTextureToTexture(device, options) {
5066
4997
  const {
5067
4998
  /** Texture to copy to/from. */
5068
- source,
4999
+ sourceTexture,
5069
5000
  /** Mip-map level of the texture to copy to (Default 0) */
5070
5001
  destinationMipLevel = 0,
5071
5002
  /** Defines which aspects of the texture to copy to/from. */
@@ -5075,7 +5006,7 @@ ${source2}`;
5075
5006
  /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to. */
5076
5007
  destinationOrigin = [0, 0],
5077
5008
  /** Texture to copy to/from. */
5078
- destination
5009
+ destinationTexture
5079
5010
  /** Mip-map level of the texture to copy to/from. (Default 0) */
5080
5011
  // destinationMipLevel = options.mipLevel,
5081
5012
  /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
@@ -5084,11 +5015,11 @@ ${source2}`;
5084
5015
  // destinationAspect = options.aspect,
5085
5016
  } = options;
5086
5017
  let {
5087
- width = options.destination.width,
5088
- height = options.destination.height
5018
+ width = options.destinationTexture.width,
5019
+ height = options.destinationTexture.height
5089
5020
  // depthOrArrayLayers = 0
5090
5021
  } = options;
5091
- const { framebuffer, destroyFramebuffer } = getFramebuffer2(source);
5022
+ const { framebuffer, destroyFramebuffer } = getFramebuffer2(sourceTexture);
5092
5023
  const [sourceX, sourceY] = origin;
5093
5024
  const [destinationX, destinationY, destinationZ] = destinationOrigin;
5094
5025
  const prevHandle = device.gl.bindFramebuffer(
@@ -5097,8 +5028,8 @@ ${source2}`;
5097
5028
  );
5098
5029
  let texture = null;
5099
5030
  let textureTarget;
5100
- if (destination instanceof WEBGLTexture) {
5101
- texture = destination;
5031
+ if (destinationTexture instanceof WEBGLTexture) {
5032
+ texture = destinationTexture;
5102
5033
  width = Number.isFinite(width) ? width : texture.width;
5103
5034
  height = Number.isFinite(height) ? height : texture.height;
5104
5035
  texture.bind(0);
@@ -5187,6 +5118,9 @@ ${source2}`;
5187
5118
  copyTextureToTexture(options) {
5188
5119
  this.commandBuffer.commands.push({ name: "copy-texture-to-texture", options });
5189
5120
  }
5121
+ // clearTexture(options: ClearTextureOptions): void {
5122
+ // this.commandBuffer.commands.push({name: 'copy-texture-to-texture', options});
5123
+ // }
5190
5124
  pushDebugGroup(groupLabel) {
5191
5125
  }
5192
5126
  popDebugGroup() {
@@ -5202,19 +5136,19 @@ ${source2}`;
5202
5136
 
5203
5137
  // src/utils/fill-array.ts
5204
5138
  function fillArray(options) {
5205
- const { target, source, start = 0, count = 1 } = options;
5139
+ const { target: target2, source, start = 0, count = 1 } = options;
5206
5140
  const length = source.length;
5207
5141
  const total = count * length;
5208
5142
  let copied = 0;
5209
5143
  for (let i = start; copied < length; copied++) {
5210
- target[i++] = source[copied];
5144
+ target2[i++] = source[copied];
5211
5145
  }
5212
5146
  while (copied < total) {
5213
5147
  if (copied < total - copied) {
5214
- target.copyWithin(start + copied, start, start + copied);
5148
+ target2.copyWithin(start + copied, start, start + copied);
5215
5149
  copied *= 2;
5216
5150
  } else {
5217
- target.copyWithin(start + copied, start, start + total - copied);
5151
+ target2.copyWithin(start + copied, start, start + total - copied);
5218
5152
  copied = total;
5219
5153
  }
5220
5154
  }
@@ -5631,11 +5565,11 @@ ${source2}`;
5631
5565
  * outstanding queries representing disjoint `begin()`/`end()` intervals.
5632
5566
  * It is not possible to interleave or overlap `begin` and `end` calls.
5633
5567
  */
5634
- _begin(target) {
5568
+ _begin(target2) {
5635
5569
  if (this._queryPending) {
5636
5570
  return;
5637
5571
  }
5638
- this.target = target;
5572
+ this.target = target2;
5639
5573
  this.device.gl.beginQuery(this.target, this.handle);
5640
5574
  return;
5641
5575
  }
@@ -5703,9 +5637,9 @@ ${source2}`;
5703
5637
 
5704
5638
  // src/deprecated/clear.ts
5705
5639
  var import_core22 = __toESM(require_core(), 1);
5706
- var GL_DEPTH_BUFFER_BIT2 = 256;
5707
- var GL_STENCIL_BUFFER_BIT2 = 1024;
5708
- var GL_COLOR_BUFFER_BIT2 = 16384;
5640
+ var GL_DEPTH_BUFFER_BIT = 256;
5641
+ var GL_STENCIL_BUFFER_BIT = 1024;
5642
+ var GL_COLOR_BUFFER_BIT = 16384;
5709
5643
  function clear(device, options) {
5710
5644
  import_core22.log.warn("clear will be removed in next minor release");
5711
5645
  const { framebuffer = null, color = null, depth = null, stencil = null } = options || {};
@@ -5715,19 +5649,19 @@ ${source2}`;
5715
5649
  }
5716
5650
  let clearFlags = 0;
5717
5651
  if (color) {
5718
- clearFlags |= GL_COLOR_BUFFER_BIT2;
5652
+ clearFlags |= GL_COLOR_BUFFER_BIT;
5719
5653
  if (color !== true) {
5720
5654
  parameters.clearColor = color;
5721
5655
  }
5722
5656
  }
5723
5657
  if (depth) {
5724
- clearFlags |= GL_DEPTH_BUFFER_BIT2;
5658
+ clearFlags |= GL_DEPTH_BUFFER_BIT;
5725
5659
  if (depth !== true) {
5726
5660
  parameters.clearDepth = depth;
5727
5661
  }
5728
5662
  }
5729
5663
  if (stencil) {
5730
- clearFlags |= GL_STENCIL_BUFFER_BIT2;
5664
+ clearFlags |= GL_STENCIL_BUFFER_BIT;
5731
5665
  if (depth !== true) {
5732
5666
  parameters.clearStencil = depth;
5733
5667
  }
@@ -5768,33 +5702,57 @@ ${source2}`;
5768
5702
  //
5769
5703
  constructor(props) {
5770
5704
  super({ ...props, id: props.id || uid("webgl-device") });
5771
- const device = props.gl?.device;
5705
+ if (!props.createCanvasContext) {
5706
+ throw new Error("WebGLDevice requires props.createCanvasContext to be set");
5707
+ }
5708
+ const canvasContextProps = props.createCanvasContext === true ? {} : props.createCanvasContext;
5709
+ let device = canvasContextProps.canvas?.gl?.device;
5772
5710
  if (device) {
5773
5711
  throw new Error(`WebGL context already attached to device ${device.id}`);
5774
5712
  }
5775
- const canvas = props.gl?.canvas || props.canvas;
5776
- this.canvasContext = new WebGLCanvasContext(this, { ...props, canvas });
5713
+ this.canvasContext = new WebGLCanvasContext(this, canvasContextProps);
5777
5714
  this.lost = new Promise((resolve) => {
5778
5715
  this._resolveContextLost = resolve;
5779
5716
  });
5780
- this.handle = createBrowserContext(this.canvasContext.canvas, {
5781
- ...props,
5782
- onContextLost: (event) => this._resolveContextLost?.({
5783
- reason: "destroyed",
5784
- message: "Entered sleep mode, or too many apps or browser tabs are using the GPU."
5785
- })
5786
- });
5787
- this.gl = this.handle;
5788
- if (!this.handle) {
5717
+ const webglContextAttributes = { ...props.webgl };
5718
+ if (canvasContextProps.alphaMode === "premultiplied") {
5719
+ webglContextAttributes.premultipliedAlpha = true;
5720
+ }
5721
+ if (props.powerPreference !== void 0) {
5722
+ webglContextAttributes.powerPreference = props.powerPreference;
5723
+ }
5724
+ const gl = createBrowserContext(
5725
+ this.canvasContext.canvas,
5726
+ {
5727
+ onContextLost: (event) => this._resolveContextLost?.({
5728
+ reason: "destroyed",
5729
+ message: "Entered sleep mode, or too many apps or browser tabs are using the GPU."
5730
+ }),
5731
+ // eslint-disable-next-line no-console
5732
+ onContextRestored: (event) => console.log("WebGL context restored")
5733
+ },
5734
+ webglContextAttributes
5735
+ );
5736
+ if (!gl) {
5789
5737
  throw new Error("WebGL context creation failed");
5790
5738
  }
5739
+ device = gl.device;
5740
+ if (device) {
5741
+ throw new Error(`WebGL context already attached to device ${device.id}`);
5742
+ }
5743
+ this.handle = gl;
5744
+ this.gl = gl;
5791
5745
  this.spectorJS = initializeSpectorJS({ ...this.props, gl: this.handle });
5792
5746
  this.gl.device = this;
5793
5747
  this.gl._version = 2;
5794
5748
  this.info = getDeviceInfo(this.gl, this._extensions);
5795
5749
  this.limits = new WebGLDeviceLimits(this.gl);
5796
- this.features = new WebGLDeviceFeatures(this.gl, this._extensions, this.props.disabledFeatures);
5797
- if (this.props.initalizeFeatures) {
5750
+ this.features = new WebGLDeviceFeatures(
5751
+ this.gl,
5752
+ this._extensions,
5753
+ this.props._disabledFeatures
5754
+ );
5755
+ if (this.props._initializeFeatures) {
5798
5756
  this.features.initializeFeatures();
5799
5757
  }
5800
5758
  this.canvasContext.resize();
@@ -5802,11 +5760,14 @@ ${source2}`;
5802
5760
  log: (...args) => import_core23.log.log(1, ...args)()
5803
5761
  });
5804
5762
  glState.trackState(this.gl, { copyState: false });
5805
- if (props.debug) {
5806
- this.gl = makeDebugContext(this.gl, { ...props, throwOnError: true });
5807
- this.debug = true;
5808
- import_core23.log.level = Math.max(import_core23.log.level, 1);
5763
+ const debugWebGL = props.debugWebGL || props.debug;
5764
+ const traceWebGL = props.debugWebGL;
5765
+ if (debugWebGL) {
5766
+ this.gl = makeDebugContext(this.gl, { debugWebGL, traceWebGL });
5809
5767
  import_core23.log.warn("WebGL debug mode activated. Performance reduced.")();
5768
+ if (props.debugWebGL) {
5769
+ import_core23.log.level = Math.max(import_core23.log.level, 1);
5770
+ }
5810
5771
  }
5811
5772
  }
5812
5773
  /**
@@ -5832,7 +5793,7 @@ ${source2}`;
5832
5793
  throw new Error("WebGL only supports a single canvas");
5833
5794
  }
5834
5795
  createBuffer(props) {
5835
- const newProps = this._getBufferProps(props);
5796
+ const newProps = this._normalizeBufferProps(props);
5836
5797
  return new WEBGLBuffer(this, newProps);
5837
5798
  }
5838
5799
  createTexture(props) {
@@ -5954,15 +5915,24 @@ ${source2}`;
5954
5915
  * Be aware that there are some duplicates especially for constants that are 0,
5955
5916
  * so this isn't guaranteed to return the right key in all cases.
5956
5917
  */
5957
- getGLKey(value, gl) {
5958
- gl = gl || this.gl2 || this.gl;
5918
+ getGLKey(value, options) {
5959
5919
  const number = Number(value);
5960
- for (const key in gl) {
5961
- if (gl[key] === number) {
5920
+ for (const key in this.gl) {
5921
+ if (this.gl[key] === number) {
5962
5922
  return `GL.${key}`;
5963
5923
  }
5964
5924
  }
5965
- return String(value);
5925
+ return options?.emptyIfUnknown ? "" : String(value);
5926
+ }
5927
+ /**
5928
+ * Returns a map with any GL.<KEY> constants mapped to strings, both for keys and values
5929
+ */
5930
+ getGLKeys(glParameters) {
5931
+ const opts = { emptyIfUnknown: true };
5932
+ return Object.entries(glParameters).reduce((keys, [key, value]) => {
5933
+ keys[`${key}:${this.getGLKey(key, opts)}`] = `${value}:${this.getGLKey(value, opts)}`;
5934
+ return keys;
5935
+ }, {});
5966
5936
  }
5967
5937
  /** Store constants */
5968
5938
  _constants;
@@ -6176,27 +6146,23 @@ ${source2}`;
6176
6146
  if (!isWebGL(gl)) {
6177
6147
  throw new Error("Invalid WebGL2RenderingContext");
6178
6148
  }
6179
- return new WebGLDevice({ gl });
6149
+ return new WebGLDevice({ _handle: gl });
6180
6150
  }
6181
6151
  async create(props = {}) {
6182
6152
  import_core24.log.groupCollapsed(LOG_LEVEL2, "WebGLDevice created")();
6183
6153
  const promises = [];
6184
- if (props.debug) {
6154
+ if (props.debugWebGL || props.debug) {
6185
6155
  promises.push(loadWebGLDeveloperTools());
6186
6156
  }
6187
- if (props.debugWithSpectorJS) {
6157
+ if (props.debugSpectorJS) {
6188
6158
  promises.push(loadSpectorJS(props));
6189
6159
  }
6190
- if (typeof props.canvas === "string") {
6191
- promises.push(import_core24.CanvasContext.pageLoaded);
6192
- }
6193
6160
  const results = await Promise.allSettled(promises);
6194
6161
  for (const result of results) {
6195
6162
  if (result.status === "rejected") {
6196
6163
  import_core24.log.error(`Failed to initialize debug libraries ${result.reason}`)();
6197
6164
  }
6198
6165
  }
6199
- import_core24.log.probe(LOG_LEVEL2 + 1, "DOM is loaded")();
6200
6166
  const device = new WebGLDevice(props);
6201
6167
  const message2 = `Created ${device.type}${device.debug ? " debug" : ""} context: ${device.info.vendor}, ${device.info.renderer} for canvas: ${device.canvasContext.id}`;
6202
6168
  import_core24.log.probe(LOG_LEVEL2, message2)();