@luma.gl/webgl 9.2.6 → 9.3.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/adapter/helpers/get-shader-layout-from-glsl.js +11 -8
  2. package/dist/adapter/helpers/get-shader-layout-from-glsl.js.map +1 -1
  3. package/dist/adapter/helpers/parse-shader-compiler-log.d.ts +1 -1
  4. package/dist/adapter/helpers/parse-shader-compiler-log.d.ts.map +1 -1
  5. package/dist/adapter/helpers/parse-shader-compiler-log.js +20 -0
  6. package/dist/adapter/helpers/parse-shader-compiler-log.js.map +1 -1
  7. package/dist/adapter/resources/webgl-command-buffer.d.ts +2 -3
  8. package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
  9. package/dist/adapter/resources/webgl-command-buffer.js +9 -5
  10. package/dist/adapter/resources/webgl-command-buffer.js.map +1 -1
  11. package/dist/adapter/resources/webgl-fence.d.ts +14 -0
  12. package/dist/adapter/resources/webgl-fence.d.ts.map +1 -0
  13. package/dist/adapter/resources/webgl-fence.js +49 -0
  14. package/dist/adapter/resources/webgl-fence.js.map +1 -0
  15. package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
  16. package/dist/adapter/resources/webgl-render-pass.js +9 -6
  17. package/dist/adapter/resources/webgl-render-pass.js.map +1 -1
  18. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  19. package/dist/adapter/resources/webgl-render-pipeline.js +1 -2
  20. package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -1
  21. package/dist/adapter/resources/webgl-texture.d.ts +21 -4
  22. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  23. package/dist/adapter/resources/webgl-texture.js +148 -22
  24. package/dist/adapter/resources/webgl-texture.js.map +1 -1
  25. package/dist/adapter/resources/webgl-transform-feedback.js +5 -5
  26. package/dist/adapter/resources/webgl-transform-feedback.js.map +1 -1
  27. package/dist/adapter/webgl-adapter.d.ts.map +1 -1
  28. package/dist/adapter/webgl-adapter.js +22 -23
  29. package/dist/adapter/webgl-adapter.js.map +1 -1
  30. package/dist/adapter/webgl-canvas-context.d.ts +2 -2
  31. package/dist/adapter/webgl-canvas-context.d.ts.map +1 -1
  32. package/dist/adapter/webgl-canvas-context.js +16 -6
  33. package/dist/adapter/webgl-canvas-context.js.map +1 -1
  34. package/dist/adapter/webgl-device.d.ts +4 -2
  35. package/dist/adapter/webgl-device.d.ts.map +1 -1
  36. package/dist/adapter/webgl-device.js +39 -24
  37. package/dist/adapter/webgl-device.js.map +1 -1
  38. package/dist/context/debug/spector.d.ts.map +1 -1
  39. package/dist/context/debug/spector.js +4 -4
  40. package/dist/context/debug/spector.js.map +1 -1
  41. package/dist/context/debug/webgl-developer-tools.js +6 -6
  42. package/dist/context/debug/webgl-developer-tools.js.map +1 -1
  43. package/dist/context/helpers/create-browser-context.d.ts.map +1 -1
  44. package/dist/context/helpers/create-browser-context.js +46 -36
  45. package/dist/context/helpers/create-browser-context.js.map +1 -1
  46. package/dist/context/helpers/webgl-context-data.d.ts +5 -1
  47. package/dist/context/helpers/webgl-context-data.d.ts.map +1 -1
  48. package/dist/context/helpers/webgl-context-data.js +9 -10
  49. package/dist/context/helpers/webgl-context-data.js.map +1 -1
  50. package/dist/context/parameters/unified-parameter-api.d.ts +1 -1
  51. package/dist/context/parameters/unified-parameter-api.js +2 -2
  52. package/dist/context/parameters/unified-parameter-api.js.map +1 -1
  53. package/dist/context/state-tracker/webgl-state-tracker.js +2 -2
  54. package/dist/context/state-tracker/webgl-state-tracker.js.map +1 -1
  55. package/dist/dist.dev.js +567 -318
  56. package/dist/dist.min.js +2 -2
  57. package/dist/index.cjs +550 -314
  58. package/dist/index.cjs.map +4 -4
  59. package/dist/index.d.ts +1 -0
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +1 -0
  62. package/dist/index.js.map +1 -1
  63. package/dist/utils/fill-array.js +1 -1
  64. package/dist/utils/fill-array.js.map +1 -1
  65. package/package.json +5 -5
  66. package/src/adapter/helpers/get-shader-layout-from-glsl.ts +11 -9
  67. package/src/adapter/helpers/parse-shader-compiler-log.ts +23 -1
  68. package/src/adapter/resources/webgl-command-buffer.ts +18 -22
  69. package/src/adapter/resources/webgl-fence.ts +55 -0
  70. package/src/adapter/resources/webgl-render-pass.ts +10 -6
  71. package/src/adapter/resources/webgl-render-pipeline.ts +1 -2
  72. package/src/adapter/resources/webgl-texture.ts +209 -37
  73. package/src/adapter/resources/webgl-transform-feedback.ts +5 -5
  74. package/src/adapter/webgl-adapter.ts +26 -24
  75. package/src/adapter/webgl-canvas-context.ts +19 -8
  76. package/src/adapter/webgl-device.ts +41 -29
  77. package/src/context/debug/spector.ts +4 -4
  78. package/src/context/debug/webgl-developer-tools.ts +15 -6
  79. package/src/context/helpers/create-browser-context.ts +54 -43
  80. package/src/context/helpers/webgl-context-data.ts +17 -11
  81. package/src/context/parameters/unified-parameter-api.ts +2 -2
  82. package/src/context/state-tracker/webgl-state-tracker.ts +2 -2
  83. package/src/index.ts +1 -0
  84. package/src/utils/fill-array.ts +1 -1
package/dist/dist.dev.js CHANGED
@@ -847,6 +847,24 @@ var __exports__ = (() => {
847
847
  }
848
848
  });
849
849
 
850
+ // src/context/helpers/webgl-context-data.ts
851
+ function getWebGLContextData(gl) {
852
+ const contextData = gl.luma || {
853
+ _polyfilled: false,
854
+ extensions: {},
855
+ softwareRenderer: false
856
+ };
857
+ contextData._polyfilled ??= false;
858
+ contextData.extensions ||= {};
859
+ gl.luma = contextData;
860
+ return contextData;
861
+ }
862
+ var init_webgl_context_data = __esm({
863
+ "src/context/helpers/webgl-context-data.ts"() {
864
+ "use strict";
865
+ }
866
+ });
867
+
850
868
  // src/context/debug/spector.ts
851
869
  async function loadSpectorJS(props) {
852
870
  if (!globalThis.SPECTOR) {
@@ -888,9 +906,10 @@ var __exports__ = (() => {
888
906
  }
889
907
  if (props.gl) {
890
908
  const gl = props.gl;
891
- const device = gl.device;
909
+ const contextData = getWebGLContextData(gl);
910
+ const device = contextData.device;
892
911
  spector?.startCapture(props.gl, 500);
893
- gl.device = device;
912
+ contextData.device = device;
894
913
  new Promise((resolve) => setTimeout(resolve, 2e3)).then((_) => {
895
914
  import_core.log.info("Spector capture stopped after 2 seconds")();
896
915
  spector?.stopCapture();
@@ -904,6 +923,7 @@ var __exports__ = (() => {
904
923
  "use strict";
905
924
  import_core = __toESM(require_core(), 1);
906
925
  init_load_script();
926
+ init_webgl_context_data();
907
927
  LOG_LEVEL = 1;
908
928
  spector = null;
909
929
  initialized = false;
@@ -1000,7 +1020,7 @@ var __exports__ = (() => {
1000
1020
  });
1001
1021
 
1002
1022
  // src/context/debug/webgl-developer-tools.ts
1003
- function getWebGLContextData(gl) {
1023
+ function getWebGLContextData2(gl) {
1004
1024
  gl.luma = gl.luma || {};
1005
1025
  return gl.luma;
1006
1026
  }
@@ -1015,7 +1035,7 @@ var __exports__ = (() => {
1015
1035
  return props.debugWebGL || props.traceWebGL ? getDebugContext(gl, props) : getRealContext(gl);
1016
1036
  }
1017
1037
  function getRealContext(gl) {
1018
- const data = getWebGLContextData(gl);
1038
+ const data = getWebGLContextData2(gl);
1019
1039
  return data.realContext ? data.realContext : gl;
1020
1040
  }
1021
1041
  function getDebugContext(gl, props) {
@@ -1023,7 +1043,7 @@ var __exports__ = (() => {
1023
1043
  import_core2.log.warn("webgl-debug not loaded")();
1024
1044
  return gl;
1025
1045
  }
1026
- const data = getWebGLContextData(gl);
1046
+ const data = getWebGLContextData2(gl);
1027
1047
  if (data.debugContext) {
1028
1048
  return data.debugContext;
1029
1049
  }
@@ -1045,6 +1065,7 @@ var __exports__ = (() => {
1045
1065
  const debugContext = Object.create(WebGLDebugContext);
1046
1066
  data.realContext = gl;
1047
1067
  data.debugContext = debugContext;
1068
+ debugContext.luma = data;
1048
1069
  debugContext.debug = true;
1049
1070
  return debugContext;
1050
1071
  }
@@ -1059,16 +1080,24 @@ var __exports__ = (() => {
1059
1080
  const errorMessage = globalThis.WebGLDebugUtils.glEnumToString(err);
1060
1081
  const functionArgs = globalThis.WebGLDebugUtils.glFunctionArgsToString(functionName, args);
1061
1082
  const message2 = `${errorMessage} in gl.${functionName}(${functionArgs})`;
1062
- import_core2.log.error(message2)();
1083
+ import_core2.log.error(
1084
+ "%cWebGL",
1085
+ "color: white; background: red; padding: 2px 6px; border-radius: 3px;",
1086
+ message2
1087
+ )();
1063
1088
  debugger;
1089
+ throw new Error(message2);
1064
1090
  }
1065
1091
  function onValidateGLFunc(props, functionName, functionArgs) {
1066
1092
  let functionString = "";
1067
- if (import_core2.log.level >= 1) {
1093
+ if (props.traceWebGL && import_core2.log.level >= 1) {
1068
1094
  functionString = getFunctionString(functionName, functionArgs);
1069
- if (props.traceWebGL) {
1070
- import_core2.log.log(1, functionString)();
1071
- }
1095
+ import_core2.log.info(
1096
+ 1,
1097
+ "%cWebGL",
1098
+ "color: white; background: blue; padding: 2px 6px; border-radius: 3px;",
1099
+ functionString
1100
+ )();
1072
1101
  }
1073
1102
  for (const arg of functionArgs) {
1074
1103
  if (arg === void 0) {
@@ -1621,7 +1650,7 @@ var __exports__ = (() => {
1621
1650
  }
1622
1651
  }
1623
1652
  }
1624
- const cache = gl.state && gl.state.cache;
1653
+ const cache = gl.lumaState?.cache;
1625
1654
  if (cache) {
1626
1655
  for (const key in compositeSetters) {
1627
1656
  const compositeSetter = GL_COMPOSITE_PARAMETER_SETTERS[key];
@@ -1744,7 +1773,7 @@ var __exports__ = (() => {
1744
1773
  init_webgl_parameter_tables();
1745
1774
  WebGLStateTracker = class {
1746
1775
  static get(gl) {
1747
- return gl.state;
1776
+ return gl.lumaState;
1748
1777
  }
1749
1778
  gl;
1750
1779
  program = null;
@@ -1782,7 +1811,7 @@ var __exports__ = (() => {
1782
1811
  throw new Error("WebGLStateTracker");
1783
1812
  }
1784
1813
  this.initialized = true;
1785
- this.gl.state = this;
1814
+ this.gl.lumaState = this;
1786
1815
  installProgramSpy(gl);
1787
1816
  for (const key in GL_HOOKED_SETTERS) {
1788
1817
  const setter = GL_HOOKED_SETTERS[key];
@@ -1822,46 +1851,61 @@ var __exports__ = (() => {
1822
1851
  // src/context/helpers/create-browser-context.ts
1823
1852
  function createBrowserContext(canvas, props, webglContextAttributes) {
1824
1853
  let errorMessage = "";
1854
+ const onCreateError = (event) => {
1855
+ const statusMessage = event.statusMessage;
1856
+ if (statusMessage) {
1857
+ errorMessage ||= statusMessage;
1858
+ }
1859
+ };
1860
+ canvas.addEventListener("webglcontextcreationerror", onCreateError, false);
1861
+ const allowSoftwareRenderer = webglContextAttributes.failIfMajorPerformanceCaveat !== true;
1825
1862
  const webglProps = {
1826
1863
  preserveDrawingBuffer: true,
1827
- // failIfMajorPerformanceCaveat: true,
1828
- ...webglContextAttributes
1864
+ ...webglContextAttributes,
1865
+ // Always start by requesting a high-performance context.
1866
+ failIfMajorPerformanceCaveat: true
1829
1867
  };
1830
1868
  let gl = null;
1831
- gl ||= canvas.getContext("webgl2", webglProps);
1832
- if (webglProps.failIfMajorPerformanceCaveat) {
1833
- errorMessage ||= "Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow.";
1834
- }
1835
- if (!gl && !webglContextAttributes.failIfMajorPerformanceCaveat) {
1836
- webglProps.failIfMajorPerformanceCaveat = false;
1837
- gl = canvas.getContext("webgl2", webglProps);
1838
- gl.luma ||= {};
1839
- gl.luma.softwareRenderer = true;
1840
- }
1841
- if (!gl) {
1842
- gl = canvas.getContext("webgl", {});
1843
- if (gl) {
1844
- gl = null;
1845
- errorMessage ||= "Your browser only supports WebGL1";
1869
+ try {
1870
+ gl ||= canvas.getContext("webgl2", webglProps);
1871
+ if (!gl && webglProps.failIfMajorPerformanceCaveat) {
1872
+ errorMessage ||= "Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow.";
1846
1873
  }
1874
+ let softwareRenderer = false;
1875
+ if (!gl && allowSoftwareRenderer) {
1876
+ webglProps.failIfMajorPerformanceCaveat = false;
1877
+ gl = canvas.getContext("webgl2", webglProps);
1878
+ softwareRenderer = true;
1879
+ }
1880
+ if (!gl) {
1881
+ gl = canvas.getContext("webgl", {});
1882
+ if (gl) {
1883
+ gl = null;
1884
+ errorMessage ||= "Your browser only supports WebGL1";
1885
+ }
1886
+ }
1887
+ if (!gl) {
1888
+ errorMessage ||= "Your browser does not support WebGL";
1889
+ throw new Error(`Failed to create WebGL context: ${errorMessage}`);
1890
+ }
1891
+ const luma = getWebGLContextData(gl);
1892
+ luma.softwareRenderer = softwareRenderer;
1893
+ const { onContextLost, onContextRestored } = props;
1894
+ canvas.addEventListener("webglcontextlost", (event) => onContextLost(event), false);
1895
+ canvas.addEventListener(
1896
+ "webglcontextrestored",
1897
+ (event) => onContextRestored(event),
1898
+ false
1899
+ );
1900
+ return gl;
1901
+ } finally {
1902
+ canvas.removeEventListener("webglcontextcreationerror", onCreateError, false);
1847
1903
  }
1848
- if (!gl) {
1849
- errorMessage ||= "Your browser does not support WebGL";
1850
- throw new Error(`Failed to create WebGL context: ${errorMessage}`);
1851
- }
1852
- const { onContextLost, onContextRestored } = props;
1853
- canvas.addEventListener("webglcontextlost", (event) => onContextLost(event), false);
1854
- canvas.addEventListener(
1855
- "webglcontextrestored",
1856
- (event) => onContextRestored(event),
1857
- false
1858
- );
1859
- gl.luma ||= {};
1860
- return gl;
1861
1904
  }
1862
1905
  var init_create_browser_context = __esm({
1863
1906
  "src/context/helpers/create-browser-context.ts"() {
1864
1907
  "use strict";
1908
+ init_webgl_context_data();
1865
1909
  }
1866
1910
  });
1867
1911
 
@@ -2608,14 +2652,24 @@ var __exports__ = (() => {
2608
2652
  super(props);
2609
2653
  this.device = device;
2610
2654
  this._setAutoCreatedCanvasId(`${this.device.id}-canvas`);
2611
- this._updateDevice();
2612
- }
2613
- getCurrentFramebuffer() {
2614
- this._framebuffer = this._framebuffer || new WEBGLFramebuffer(this.device, { handle: null });
2615
- return this._framebuffer;
2655
+ this._configureDevice();
2616
2656
  }
2617
2657
  // IMPLEMENTATION OF ABSTRACT METHODS
2618
- _updateDevice() {
2658
+ _configureDevice() {
2659
+ const shouldResize = this.drawingBufferWidth !== this._framebuffer?.width || this.drawingBufferHeight !== this._framebuffer?.height;
2660
+ if (shouldResize) {
2661
+ this._framebuffer?.resize([this.drawingBufferWidth, this.drawingBufferHeight]);
2662
+ }
2663
+ }
2664
+ _getCurrentFramebuffer() {
2665
+ this._framebuffer ||= new WEBGLFramebuffer(this.device, {
2666
+ id: "canvas-context-framebuffer",
2667
+ handle: null,
2668
+ // Setting handle to null returns a reference to the default WebGL framebuffer
2669
+ width: this.drawingBufferWidth,
2670
+ height: this.drawingBufferHeight
2671
+ });
2672
+ return this._framebuffer;
2619
2673
  }
2620
2674
  };
2621
2675
  }
@@ -2782,9 +2836,20 @@ var __exports__ = (() => {
2782
2836
  if (line.length <= 1) {
2783
2837
  continue;
2784
2838
  }
2839
+ const lineWithTrimmedWhitespace = line.trim();
2785
2840
  const segments = line.split(":");
2841
+ const trimmedMessageType = segments[0]?.trim();
2786
2842
  if (segments.length === 2) {
2787
2843
  const [messageType2, message2] = segments;
2844
+ if (!messageType2 || !message2) {
2845
+ messages.push({
2846
+ message: lineWithTrimmedWhitespace,
2847
+ type: getMessageType(trimmedMessageType || "info"),
2848
+ lineNum: 0,
2849
+ linePos: 0
2850
+ });
2851
+ continue;
2852
+ }
2788
2853
  messages.push({
2789
2854
  message: message2.trim(),
2790
2855
  type: getMessageType(messageType2),
@@ -2794,6 +2859,15 @@ var __exports__ = (() => {
2794
2859
  continue;
2795
2860
  }
2796
2861
  const [messageType, linePosition, lineNumber, ...rest] = segments;
2862
+ if (!messageType || !linePosition || !lineNumber) {
2863
+ messages.push({
2864
+ message: segments.slice(1).join(":").trim() || lineWithTrimmedWhitespace,
2865
+ type: getMessageType(trimmedMessageType || "info"),
2866
+ lineNum: 0,
2867
+ linePos: 0
2868
+ });
2869
+ continue;
2870
+ }
2797
2871
  let lineNum = parseInt(lineNumber, 10);
2798
2872
  if (isNaN(lineNum)) {
2799
2873
  lineNum = 0;
@@ -3400,6 +3474,127 @@ ${source}`;
3400
3474
  }
3401
3475
  });
3402
3476
 
3477
+ // src/adapter/converters/webgl-shadertypes.ts
3478
+ function convertDataTypeToGLDataType(normalizedType) {
3479
+ return NORMALIZED_SHADER_TYPE_TO_WEBGL[normalizedType];
3480
+ }
3481
+ function convertGLUniformTypeToShaderVariableType(glUniformType) {
3482
+ return WEBGL_SHADER_TYPES[glUniformType];
3483
+ }
3484
+ function isGLSamplerType(type) {
3485
+ return Boolean(WEBGL_SAMPLER_TO_TEXTURE_BINDINGS[type]);
3486
+ }
3487
+ function getTextureBindingFromGLSamplerType(glSamplerType) {
3488
+ return WEBGL_SAMPLER_TO_TEXTURE_BINDINGS[glSamplerType];
3489
+ }
3490
+ var WEBGL_SHADER_TYPES, WEBGL_SAMPLER_TO_TEXTURE_BINDINGS, NORMALIZED_SHADER_TYPE_TO_WEBGL, WEBGL_TO_NORMALIZED_DATA_TYPE;
3491
+ var init_webgl_shadertypes = __esm({
3492
+ "src/adapter/converters/webgl-shadertypes.ts"() {
3493
+ "use strict";
3494
+ WEBGL_SHADER_TYPES = {
3495
+ [5126 /* FLOAT */]: "f32",
3496
+ [35664 /* FLOAT_VEC2 */]: "vec2<f32>",
3497
+ [35665 /* FLOAT_VEC3 */]: "vec3<f32>",
3498
+ [35666 /* FLOAT_VEC4 */]: "vec4<f32>",
3499
+ [5124 /* INT */]: "i32",
3500
+ [35667 /* INT_VEC2 */]: "vec2<i32>",
3501
+ [35668 /* INT_VEC3 */]: "vec3<i32>",
3502
+ [35669 /* INT_VEC4 */]: "vec4<i32>",
3503
+ [5125 /* UNSIGNED_INT */]: "u32",
3504
+ [36294 /* UNSIGNED_INT_VEC2 */]: "vec2<u32>",
3505
+ [36295 /* UNSIGNED_INT_VEC3 */]: "vec3<u32>",
3506
+ [36296 /* UNSIGNED_INT_VEC4 */]: "vec4<u32>",
3507
+ [35670 /* BOOL */]: "f32",
3508
+ [35671 /* BOOL_VEC2 */]: "vec2<f32>",
3509
+ [35672 /* BOOL_VEC3 */]: "vec3<f32>",
3510
+ [35673 /* BOOL_VEC4 */]: "vec4<f32>",
3511
+ // TODO - are sizes/components below correct?
3512
+ [35674 /* FLOAT_MAT2 */]: "mat2x2<f32>",
3513
+ [35685 /* FLOAT_MAT2x3 */]: "mat2x3<f32>",
3514
+ [35686 /* FLOAT_MAT2x4 */]: "mat2x4<f32>",
3515
+ [35687 /* FLOAT_MAT3x2 */]: "mat3x2<f32>",
3516
+ [35675 /* FLOAT_MAT3 */]: "mat3x3<f32>",
3517
+ [35688 /* FLOAT_MAT3x4 */]: "mat3x4<f32>",
3518
+ [35689 /* FLOAT_MAT4x2 */]: "mat4x2<f32>",
3519
+ [35690 /* FLOAT_MAT4x3 */]: "mat4x3<f32>",
3520
+ [35676 /* FLOAT_MAT4 */]: "mat4x4<f32>"
3521
+ };
3522
+ WEBGL_SAMPLER_TO_TEXTURE_BINDINGS = {
3523
+ [35678 /* SAMPLER_2D */]: { viewDimension: "2d", sampleType: "float" },
3524
+ [35680 /* SAMPLER_CUBE */]: { viewDimension: "cube", sampleType: "float" },
3525
+ [35679 /* SAMPLER_3D */]: { viewDimension: "3d", sampleType: "float" },
3526
+ [35682 /* SAMPLER_2D_SHADOW */]: { viewDimension: "3d", sampleType: "depth" },
3527
+ [36289 /* SAMPLER_2D_ARRAY */]: { viewDimension: "2d-array", sampleType: "float" },
3528
+ [36292 /* SAMPLER_2D_ARRAY_SHADOW */]: { viewDimension: "2d-array", sampleType: "depth" },
3529
+ [36293 /* SAMPLER_CUBE_SHADOW */]: { viewDimension: "cube", sampleType: "float" },
3530
+ [36298 /* INT_SAMPLER_2D */]: { viewDimension: "2d", sampleType: "sint" },
3531
+ [36299 /* INT_SAMPLER_3D */]: { viewDimension: "3d", sampleType: "sint" },
3532
+ [36300 /* INT_SAMPLER_CUBE */]: { viewDimension: "cube", sampleType: "sint" },
3533
+ [36303 /* INT_SAMPLER_2D_ARRAY */]: { viewDimension: "2d-array", sampleType: "uint" },
3534
+ [36306 /* UNSIGNED_INT_SAMPLER_2D */]: { viewDimension: "2d", sampleType: "uint" },
3535
+ [36307 /* UNSIGNED_INT_SAMPLER_3D */]: { viewDimension: "3d", sampleType: "uint" },
3536
+ [36308 /* UNSIGNED_INT_SAMPLER_CUBE */]: { viewDimension: "cube", sampleType: "uint" },
3537
+ [36311 /* UNSIGNED_INT_SAMPLER_2D_ARRAY */]: { viewDimension: "2d-array", sampleType: "uint" }
3538
+ };
3539
+ NORMALIZED_SHADER_TYPE_TO_WEBGL = {
3540
+ uint8: 5121 /* UNSIGNED_BYTE */,
3541
+ sint8: 5120 /* BYTE */,
3542
+ unorm8: 5121 /* UNSIGNED_BYTE */,
3543
+ snorm8: 5120 /* BYTE */,
3544
+ uint16: 5123 /* UNSIGNED_SHORT */,
3545
+ sint16: 5122 /* SHORT */,
3546
+ unorm16: 5123 /* UNSIGNED_SHORT */,
3547
+ snorm16: 5122 /* SHORT */,
3548
+ uint32: 5125 /* UNSIGNED_INT */,
3549
+ sint32: 5124 /* INT */,
3550
+ // WebGPU does not support normalized 32 bit integer attributes
3551
+ // 'unorm32': GL.UNSIGNED_INT,
3552
+ // 'snorm32': GL.INT,
3553
+ float16: 5131 /* HALF_FLOAT */,
3554
+ float32: 5126 /* FLOAT */
3555
+ };
3556
+ WEBGL_TO_NORMALIZED_DATA_TYPE = {
3557
+ [5120 /* BYTE */]: ["sint8", "snorm16"],
3558
+ [5121 /* UNSIGNED_BYTE */]: ["uint8", "unorm8"],
3559
+ [5122 /* SHORT */]: ["sint16", "unorm16"],
3560
+ [5123 /* UNSIGNED_SHORT */]: ["uint16", "unorm16"],
3561
+ [5124 /* INT */]: ["sint32", "sint32"],
3562
+ [5125 /* UNSIGNED_INT */]: ["uint32", "uint32"],
3563
+ [5126 /* FLOAT */]: ["float32", "float32"],
3564
+ [5131 /* HALF_FLOAT */]: ["float16", "float16"]
3565
+ };
3566
+ }
3567
+ });
3568
+
3569
+ // src/adapter/converters/shader-formats.ts
3570
+ function convertGLDataTypeToDataType(type) {
3571
+ return GL_DATA_TYPE_MAP[type];
3572
+ }
3573
+ var GL_DATA_TYPE_MAP;
3574
+ var init_shader_formats = __esm({
3575
+ "src/adapter/converters/shader-formats.ts"() {
3576
+ "use strict";
3577
+ GL_DATA_TYPE_MAP = {
3578
+ [5124 /* INT */]: "sint32",
3579
+ [5125 /* UNSIGNED_INT */]: "uint32",
3580
+ [5122 /* SHORT */]: "sint16",
3581
+ [5123 /* UNSIGNED_SHORT */]: "uint16",
3582
+ [5120 /* BYTE */]: "sint8",
3583
+ [5121 /* UNSIGNED_BYTE */]: "uint8",
3584
+ [5126 /* FLOAT */]: "float32",
3585
+ [5131 /* HALF_FLOAT */]: "float16",
3586
+ [33635 /* UNSIGNED_SHORT_5_6_5 */]: "uint16",
3587
+ [32819 /* UNSIGNED_SHORT_4_4_4_4 */]: "uint16",
3588
+ [32820 /* UNSIGNED_SHORT_5_5_5_1 */]: "uint16",
3589
+ [33640 /* UNSIGNED_INT_2_10_10_10_REV */]: "uint32",
3590
+ [35899 /* UNSIGNED_INT_10F_11F_11F_REV */]: "uint32",
3591
+ [35902 /* UNSIGNED_INT_5_9_9_9_REV */]: "uint32",
3592
+ [34042 /* UNSIGNED_INT_24_8 */]: "uint32",
3593
+ [36269 /* FLOAT_32_UNSIGNED_INT_24_8_REV */]: "uint32"
3594
+ };
3595
+ }
3596
+ });
3597
+
3403
3598
  // src/adapter/resources/webgl-texture.ts
3404
3599
  function getWebGLTextureTarget(dimension) {
3405
3600
  switch (dimension) {
@@ -3421,7 +3616,7 @@ ${source}`;
3421
3616
  function getWebGLCubeFaceTarget(glTarget, dimension, level) {
3422
3617
  return dimension === "cube" ? 34069 /* TEXTURE_CUBE_MAP_POSITIVE_X */ + level : glTarget;
3423
3618
  }
3424
- var import_core13, WEBGLTexture;
3619
+ var import_core13, import_core14, WEBGLTexture;
3425
3620
  var init_webgl_texture = __esm({
3426
3621
  "src/adapter/resources/webgl-texture.ts"() {
3427
3622
  "use strict";
@@ -3430,6 +3625,9 @@ ${source}`;
3430
3625
  init_sampler_parameters();
3431
3626
  init_with_parameters();
3432
3627
  init_webgl_texture_view();
3628
+ init_webgl_shadertypes();
3629
+ init_shader_formats();
3630
+ import_core14 = __toESM(require_core(), 1);
3433
3631
  WEBGLTexture = class extends import_core13.Texture {
3434
3632
  // readonly MAX_ATTRIBUTES: number;
3435
3633
  device;
@@ -3459,8 +3657,10 @@ ${source}`;
3459
3657
  // state
3460
3658
  /** Texture binding slot - TODO - move to texture view? */
3461
3659
  _textureUnit = 0;
3660
+ /** Chached framebuffer */
3661
+ _framebuffer = null;
3462
3662
  constructor(device, props) {
3463
- super(device, props);
3663
+ super(device, props, { byteAlignment: 1 });
3464
3664
  this.device = device;
3465
3665
  this.gl = this.device.gl;
3466
3666
  const formatInfo = getTextureFormatWebGL(this.props.format);
@@ -3493,6 +3693,8 @@ ${source}`;
3493
3693
  }
3494
3694
  destroy() {
3495
3695
  if (this.handle) {
3696
+ this._framebuffer?.destroy();
3697
+ this._framebuffer = null;
3496
3698
  this.gl.deleteTexture(this.handle);
3497
3699
  this.removeStats();
3498
3700
  this.trackDeallocatedMemory("Texture");
@@ -3507,11 +3709,37 @@ ${source}`;
3507
3709
  const parameters = convertSamplerParametersToWebGL(this.sampler.props);
3508
3710
  this._setSamplerParameters(parameters);
3509
3711
  }
3712
+ copyExternalImage(options_) {
3713
+ const options = this._normalizeCopyExternalImageOptions(options_);
3714
+ if (options.sourceX || options.sourceY) {
3715
+ throw new Error("WebGL does not support sourceX/sourceY)");
3716
+ }
3717
+ const { glFormat, glType } = this;
3718
+ const { image, depth, mipLevel, x, y, z, width, height } = options;
3719
+ const glTarget = getWebGLCubeFaceTarget(this.glTarget, this.dimension, z);
3720
+ const glParameters = options.flipY ? { [37440 /* UNPACK_FLIP_Y_WEBGL */]: true } : {};
3721
+ this.gl.bindTexture(this.glTarget, this.handle);
3722
+ withGLParameters(this.gl, glParameters, () => {
3723
+ switch (this.dimension) {
3724
+ case "2d":
3725
+ case "cube":
3726
+ this.gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, glType, image);
3727
+ break;
3728
+ case "2d-array":
3729
+ case "3d":
3730
+ this.gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, glType, image);
3731
+ break;
3732
+ default:
3733
+ }
3734
+ });
3735
+ this.gl.bindTexture(this.glTarget, null);
3736
+ return { width: options.width, height: options.height };
3737
+ }
3510
3738
  copyImageData(options_) {
3511
3739
  const options = this._normalizeCopyImageDataOptions(options_);
3512
3740
  const typedArray = options.data;
3513
- const { width, height, depth } = this;
3514
- const { mipLevel = 0, byteOffset = 0, x = 0, y = 0, z = 0 } = options;
3741
+ const { width, height, depth, z = 0 } = options;
3742
+ const { mipLevel = 0, byteOffset = 0, x = 0, y = 0 } = options;
3515
3743
  const { glFormat, glType, compressed } = this;
3516
3744
  const glTarget = getWebGLCubeFaceTarget(this.glTarget, this.dimension, z);
3517
3745
  let unpackRowLength;
@@ -3527,10 +3755,11 @@ ${source}`;
3527
3755
  }
3528
3756
  }
3529
3757
  const glParameters = !this.compressed ? {
3758
+ [3317 /* UNPACK_ALIGNMENT */]: this.byteAlignment,
3530
3759
  ...unpackRowLength !== void 0 ? { [3314 /* UNPACK_ROW_LENGTH */]: unpackRowLength } : {},
3531
3760
  [32878 /* UNPACK_IMAGE_HEIGHT */]: options.rowsPerImage
3532
3761
  } : {};
3533
- this.gl.bindTexture(glTarget, this.handle);
3762
+ this.gl.bindTexture(this.glTarget, this.handle);
3534
3763
  withGLParameters(this.gl, glParameters, () => {
3535
3764
  switch (this.dimension) {
3536
3765
  case "2d":
@@ -3552,35 +3781,103 @@ ${source}`;
3552
3781
  default:
3553
3782
  }
3554
3783
  });
3555
- this.gl.bindTexture(glTarget, null);
3784
+ this.gl.bindTexture(this.glTarget, null);
3556
3785
  }
3557
- copyExternalImage(options_) {
3558
- const options = this._normalizeCopyExternalImageOptions(options_);
3559
- if (options.sourceX || options.sourceY) {
3560
- throw new Error("WebGL does not support sourceX/sourceY)");
3561
- }
3562
- const { glFormat, glType } = this;
3563
- const { image, depth, mipLevel, x, y, z, width, height } = options;
3786
+ readBuffer(options = {}, buffer) {
3787
+ throw new Error("readBuffer not implemented");
3788
+ }
3789
+ async readDataAsync(options = {}) {
3790
+ return this.readDataSyncWebGL(options);
3791
+ }
3792
+ writeBuffer(buffer, options_ = {}) {
3793
+ }
3794
+ writeData(data, options_ = {}) {
3795
+ const options = this._normalizeTextureWriteOptions(options_);
3796
+ const typedArray = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
3797
+ const {} = this;
3798
+ const { width, height, mipLevel, x, y, z } = options;
3799
+ const { glFormat, glType, compressed } = this;
3800
+ const depth = 0;
3564
3801
  const glTarget = getWebGLCubeFaceTarget(this.glTarget, this.dimension, depth);
3565
- const glParameters = options.flipY ? { [37440 /* UNPACK_FLIP_Y_WEBGL */]: true } : {};
3566
- this.gl.bindTexture(this.glTarget, this.handle);
3802
+ const glParameters = !this.compressed ? {
3803
+ // WebGL does not require byte alignment, but allows it to be specified
3804
+ [3317 /* UNPACK_ALIGNMENT */]: this.byteAlignment
3805
+ // [GL.UNPACK_ROW_LENGTH]: bytesPerRow,
3806
+ // [GL.UNPACK_IMAGE_HEIGHT]: rowsPerImage
3807
+ } : {};
3808
+ this.gl.bindTexture(glTarget, this.handle);
3809
+ this.gl.bindBuffer(35052 /* PIXEL_UNPACK_BUFFER */, null);
3567
3810
  withGLParameters(this.gl, glParameters, () => {
3568
3811
  switch (this.dimension) {
3569
3812
  case "2d":
3570
3813
  case "cube":
3571
- this.gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, glType, image);
3814
+ if (compressed) {
3815
+ this.gl.compressedTexSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, typedArray);
3816
+ } else {
3817
+ this.gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, glType, typedArray);
3818
+ }
3572
3819
  break;
3573
3820
  case "2d-array":
3574
3821
  case "3d":
3575
- this.gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, glType, image);
3822
+ if (compressed) {
3823
+ this.gl.compressedTexSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, typedArray);
3824
+ } else {
3825
+ this.gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, glType, typedArray);
3826
+ }
3576
3827
  break;
3577
3828
  default:
3578
3829
  }
3579
3830
  });
3580
- this.gl.bindTexture(this.glTarget, null);
3581
- return { width: options.width, height: options.height };
3831
+ this.gl.bindTexture(glTarget, null);
3832
+ }
3833
+ // IMPLEMENTATION SPECIFIC
3834
+ /** @todo - for now we always use 1 for maximum compatibility, we can fine tune later */
3835
+ _getRowByteAlignment(format, width) {
3836
+ return 1;
3837
+ }
3838
+ /**
3839
+ * Wraps a given texture into a framebuffer object, that can be further used
3840
+ * to read data from the texture object.
3841
+ */
3842
+ _getFramebuffer() {
3843
+ this._framebuffer ||= this.device.createFramebuffer({
3844
+ id: `framebuffer-for-${this.id}`,
3845
+ width: this.width,
3846
+ height: this.height,
3847
+ colorAttachments: [this]
3848
+ });
3849
+ return this._framebuffer;
3582
3850
  }
3583
3851
  // WEBGL SPECIFIC
3852
+ readDataSyncWebGL(options_ = {}) {
3853
+ const options = this._normalizeTextureReadOptions(options_);
3854
+ const memoryLayout = this.computeMemoryLayout(options);
3855
+ const shaderType = convertGLDataTypeToDataType(this.glType);
3856
+ const ArrayType = (0, import_core14.getTypedArrayConstructor)(shaderType);
3857
+ const targetArray = new ArrayType(memoryLayout.byteLength);
3858
+ const signedType = (0, import_core14.getDataType)(targetArray);
3859
+ const sourceType = convertDataTypeToGLDataType(signedType);
3860
+ const framebuffer = this._getFramebuffer();
3861
+ const prevHandle = this.gl.bindFramebuffer(
3862
+ 36160 /* FRAMEBUFFER */,
3863
+ framebuffer.handle
3864
+ );
3865
+ this.gl.readBuffer(36064 /* COLOR_ATTACHMENT0 */);
3866
+ this.gl.readPixels(
3867
+ options.x,
3868
+ options.y,
3869
+ options.width,
3870
+ options.height,
3871
+ this.glFormat,
3872
+ sourceType,
3873
+ targetArray
3874
+ );
3875
+ this.gl.bindFramebuffer(36160 /* FRAMEBUFFER */, prevHandle || null);
3876
+ return targetArray.buffer;
3877
+ }
3878
+ /**
3879
+ * @note - this is used by the DynamicTexture class to generate mipmaps on WebGL
3880
+ */
3584
3881
  generateMipmapsWebGL(options) {
3585
3882
  const isFilterableAndRenderable = this.device.isTextureFormatRenderable(this.props.format) && this.device.isTextureFormatFilterable(this.props.format);
3586
3883
  if (!isFilterableAndRenderable) {
@@ -3660,98 +3957,6 @@ ${source}`;
3660
3957
  }
3661
3958
  });
3662
3959
 
3663
- // src/adapter/converters/webgl-shadertypes.ts
3664
- function convertDataTypeToGLDataType(normalizedType) {
3665
- return NORMALIZED_SHADER_TYPE_TO_WEBGL[normalizedType];
3666
- }
3667
- function convertGLUniformTypeToShaderVariableType(glUniformType) {
3668
- return WEBGL_SHADER_TYPES[glUniformType];
3669
- }
3670
- function isGLSamplerType(type) {
3671
- return Boolean(WEBGL_SAMPLER_TO_TEXTURE_BINDINGS[type]);
3672
- }
3673
- function getTextureBindingFromGLSamplerType(glSamplerType) {
3674
- return WEBGL_SAMPLER_TO_TEXTURE_BINDINGS[glSamplerType];
3675
- }
3676
- var WEBGL_SHADER_TYPES, WEBGL_SAMPLER_TO_TEXTURE_BINDINGS, NORMALIZED_SHADER_TYPE_TO_WEBGL, WEBGL_TO_NORMALIZED_DATA_TYPE;
3677
- var init_webgl_shadertypes = __esm({
3678
- "src/adapter/converters/webgl-shadertypes.ts"() {
3679
- "use strict";
3680
- WEBGL_SHADER_TYPES = {
3681
- [5126 /* FLOAT */]: "f32",
3682
- [35664 /* FLOAT_VEC2 */]: "vec2<f32>",
3683
- [35665 /* FLOAT_VEC3 */]: "vec3<f32>",
3684
- [35666 /* FLOAT_VEC4 */]: "vec4<f32>",
3685
- [5124 /* INT */]: "i32",
3686
- [35667 /* INT_VEC2 */]: "vec2<i32>",
3687
- [35668 /* INT_VEC3 */]: "vec3<i32>",
3688
- [35669 /* INT_VEC4 */]: "vec4<i32>",
3689
- [5125 /* UNSIGNED_INT */]: "u32",
3690
- [36294 /* UNSIGNED_INT_VEC2 */]: "vec2<u32>",
3691
- [36295 /* UNSIGNED_INT_VEC3 */]: "vec3<u32>",
3692
- [36296 /* UNSIGNED_INT_VEC4 */]: "vec4<u32>",
3693
- [35670 /* BOOL */]: "f32",
3694
- [35671 /* BOOL_VEC2 */]: "vec2<f32>",
3695
- [35672 /* BOOL_VEC3 */]: "vec3<f32>",
3696
- [35673 /* BOOL_VEC4 */]: "vec4<f32>",
3697
- // TODO - are sizes/components below correct?
3698
- [35674 /* FLOAT_MAT2 */]: "mat2x2<f32>",
3699
- [35685 /* FLOAT_MAT2x3 */]: "mat2x3<f32>",
3700
- [35686 /* FLOAT_MAT2x4 */]: "mat2x4<f32>",
3701
- [35687 /* FLOAT_MAT3x2 */]: "mat3x2<f32>",
3702
- [35675 /* FLOAT_MAT3 */]: "mat3x3<f32>",
3703
- [35688 /* FLOAT_MAT3x4 */]: "mat3x4<f32>",
3704
- [35689 /* FLOAT_MAT4x2 */]: "mat4x2<f32>",
3705
- [35690 /* FLOAT_MAT4x3 */]: "mat4x3<f32>",
3706
- [35676 /* FLOAT_MAT4 */]: "mat4x4<f32>"
3707
- };
3708
- WEBGL_SAMPLER_TO_TEXTURE_BINDINGS = {
3709
- [35678 /* SAMPLER_2D */]: { viewDimension: "2d", sampleType: "float" },
3710
- [35680 /* SAMPLER_CUBE */]: { viewDimension: "cube", sampleType: "float" },
3711
- [35679 /* SAMPLER_3D */]: { viewDimension: "3d", sampleType: "float" },
3712
- [35682 /* SAMPLER_2D_SHADOW */]: { viewDimension: "3d", sampleType: "depth" },
3713
- [36289 /* SAMPLER_2D_ARRAY */]: { viewDimension: "2d-array", sampleType: "float" },
3714
- [36292 /* SAMPLER_2D_ARRAY_SHADOW */]: { viewDimension: "2d-array", sampleType: "depth" },
3715
- [36293 /* SAMPLER_CUBE_SHADOW */]: { viewDimension: "cube", sampleType: "float" },
3716
- [36298 /* INT_SAMPLER_2D */]: { viewDimension: "2d", sampleType: "sint" },
3717
- [36299 /* INT_SAMPLER_3D */]: { viewDimension: "3d", sampleType: "sint" },
3718
- [36300 /* INT_SAMPLER_CUBE */]: { viewDimension: "cube", sampleType: "sint" },
3719
- [36303 /* INT_SAMPLER_2D_ARRAY */]: { viewDimension: "2d-array", sampleType: "uint" },
3720
- [36306 /* UNSIGNED_INT_SAMPLER_2D */]: { viewDimension: "2d", sampleType: "uint" },
3721
- [36307 /* UNSIGNED_INT_SAMPLER_3D */]: { viewDimension: "3d", sampleType: "uint" },
3722
- [36308 /* UNSIGNED_INT_SAMPLER_CUBE */]: { viewDimension: "cube", sampleType: "uint" },
3723
- [36311 /* UNSIGNED_INT_SAMPLER_2D_ARRAY */]: { viewDimension: "2d-array", sampleType: "uint" }
3724
- };
3725
- NORMALIZED_SHADER_TYPE_TO_WEBGL = {
3726
- uint8: 5121 /* UNSIGNED_BYTE */,
3727
- sint8: 5120 /* BYTE */,
3728
- unorm8: 5121 /* UNSIGNED_BYTE */,
3729
- snorm8: 5120 /* BYTE */,
3730
- uint16: 5123 /* UNSIGNED_SHORT */,
3731
- sint16: 5122 /* SHORT */,
3732
- unorm16: 5123 /* UNSIGNED_SHORT */,
3733
- snorm16: 5122 /* SHORT */,
3734
- uint32: 5125 /* UNSIGNED_INT */,
3735
- sint32: 5124 /* INT */,
3736
- // WebGPU does not support normalized 32 bit integer attributes
3737
- // 'unorm32': GL.UNSIGNED_INT,
3738
- // 'snorm32': GL.INT,
3739
- float16: 5131 /* HALF_FLOAT */,
3740
- float32: 5126 /* FLOAT */
3741
- };
3742
- WEBGL_TO_NORMALIZED_DATA_TYPE = {
3743
- [5120 /* BYTE */]: ["sint8", "snorm16"],
3744
- [5121 /* UNSIGNED_BYTE */]: ["uint8", "unorm8"],
3745
- [5122 /* SHORT */]: ["sint16", "unorm16"],
3746
- [5123 /* UNSIGNED_SHORT */]: ["uint16", "unorm16"],
3747
- [5124 /* INT */]: ["sint32", "sint32"],
3748
- [5125 /* UNSIGNED_INT */]: ["uint32", "uint32"],
3749
- [5126 /* FLOAT */]: ["float32", "float32"],
3750
- [5131 /* HALF_FLOAT */]: ["float16", "float16"]
3751
- };
3752
- }
3753
- });
3754
-
3755
3960
  // src/adapter/helpers/get-shader-layout-from-glsl.ts
3756
3961
  function getShaderLayoutFromGLSL(gl, program) {
3757
3962
  const shaderLayout = {
@@ -3843,7 +4048,7 @@ ${source}`;
3843
4048
  }
3844
4049
  const { name, type: glUniformType, size } = activeInfo;
3845
4050
  const uniformType = convertGLUniformTypeToShaderVariableType(glUniformType);
3846
- const { type, components } = (0, import_core14.getVariableShaderTypeInfo)(uniformType);
4051
+ const { type, components } = (0, import_core15.getVariableShaderTypeInfo)(uniformType);
3847
4052
  varyings.push({ location, name, type, size: size * components });
3848
4053
  }
3849
4054
  varyings.sort((a, b) => a.location - b.location);
@@ -3904,7 +4109,11 @@ ${source}`;
3904
4109
  const uniformOffset = gl.getActiveUniforms(program, uniformIndices, 35387 /* UNIFORM_OFFSET */);
3905
4110
  const uniformStride = gl.getActiveUniforms(program, uniformIndices, 35388 /* UNIFORM_ARRAY_STRIDE */);
3906
4111
  for (let i = 0; i < blockInfo.uniformCount; ++i) {
3907
- const activeInfo = gl.getActiveUniform(program, uniformIndices[i]);
4112
+ const uniformIndex = uniformIndices[i];
4113
+ if (uniformIndex === void 0) {
4114
+ continue;
4115
+ }
4116
+ const activeInfo = gl.getActiveUniform(program, uniformIndex);
3908
4117
  if (!activeInfo) {
3909
4118
  throw new Error("activeInfo");
3910
4119
  }
@@ -3935,20 +4144,19 @@ ${source}`;
3935
4144
  }
3936
4145
  const UNIFORM_NAME_REGEXP = /([^[]*)(\[[0-9]+\])?/;
3937
4146
  const matches = UNIFORM_NAME_REGEXP.exec(name);
3938
- if (!matches || matches.length < 2) {
3939
- throw new Error(`Failed to parse GLSL uniform name ${name}`);
3940
- }
4147
+ const uniformName = (0, import_core15.assertDefined)(matches?.[1], `Failed to parse GLSL uniform name ${name}`);
3941
4148
  return {
3942
- name: matches[1],
3943
- length: matches[2] ? 1 : 0,
3944
- isArray: Boolean(matches[2])
4149
+ name: uniformName,
4150
+ // TODO - is this a bug, shouldn't we return the value?
4151
+ length: matches?.[2] ? 1 : 0,
4152
+ isArray: Boolean(matches?.[2])
3945
4153
  };
3946
4154
  }
3947
- var import_core14;
4155
+ var import_core15;
3948
4156
  var init_get_shader_layout_from_glsl = __esm({
3949
4157
  "src/adapter/helpers/get-shader-layout-from-glsl.ts"() {
3950
4158
  "use strict";
3951
- import_core14 = __toESM(require_core(), 1);
4159
+ import_core15 = __toESM(require_core(), 1);
3952
4160
  init_webgl_shadertypes();
3953
4161
  }
3954
4162
  });
@@ -4091,7 +4299,7 @@ ${source}`;
4091
4299
  for (const attribute of overrideLayout?.attributes || []) {
4092
4300
  const baseAttribute = mergedLayout.attributes.find((attr) => attr.name === attribute.name);
4093
4301
  if (!baseAttribute) {
4094
- import_core15.log.warn(`shader layout attribute ${attribute.name} not present in shader`);
4302
+ import_core16.log.warn(`shader layout attribute ${attribute.name} not present in shader`);
4095
4303
  } else {
4096
4304
  baseAttribute.type = attribute.type || baseAttribute.type;
4097
4305
  baseAttribute.stepMode = attribute.stepMode || baseAttribute.stepMode;
@@ -4099,11 +4307,11 @@ ${source}`;
4099
4307
  }
4100
4308
  return mergedLayout;
4101
4309
  }
4102
- var import_core15, LOG_PROGRAM_PERF_PRIORITY, WEBGLRenderPipeline;
4310
+ var import_core16, LOG_PROGRAM_PERF_PRIORITY, WEBGLRenderPipeline;
4103
4311
  var init_webgl_render_pipeline = __esm({
4104
4312
  "src/adapter/resources/webgl-render-pipeline.ts"() {
4105
4313
  "use strict";
4106
- import_core15 = __toESM(require_core(), 1);
4314
+ import_core16 = __toESM(require_core(), 1);
4107
4315
  init_get_shader_layout_from_glsl();
4108
4316
  init_device_parameters();
4109
4317
  init_set_uniform();
@@ -4113,7 +4321,7 @@ ${source}`;
4113
4321
  init_webgl_texture_view();
4114
4322
  init_webgl_topology_utils();
4115
4323
  LOG_PROGRAM_PERF_PRIORITY = 4;
4116
- WEBGLRenderPipeline = class extends import_core15.RenderPipeline {
4324
+ WEBGLRenderPipeline = class extends import_core16.RenderPipeline {
4117
4325
  /** The WebGL device that created this render pipeline */
4118
4326
  device;
4119
4327
  /** Handle to underlying WebGL program */
@@ -4149,9 +4357,9 @@ ${source}`;
4149
4357
  this.device.gl.transformFeedbackVaryings(this.handle, varyings, bufferMode);
4150
4358
  }
4151
4359
  this._linkShaders();
4152
- import_core15.log.time(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
4360
+ import_core16.log.time(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
4153
4361
  this.introspectedLayout = getShaderLayoutFromGLSL(this.device.gl, this.handle);
4154
- import_core15.log.timeEnd(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
4362
+ import_core16.log.timeEnd(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
4155
4363
  this.shaderLayout = props.shaderLayout ? mergeShaderLayout(this.introspectedLayout, props.shaderLayout) : this.introspectedLayout;
4156
4364
  }
4157
4365
  destroy() {
@@ -4173,7 +4381,7 @@ ${source}`;
4173
4381
  if (!binding) {
4174
4382
  const validBindings = this.shaderLayout.bindings.map((binding_) => `"${binding_.name}"`).join(", ");
4175
4383
  if (!options?.disableWarnings) {
4176
- import_core15.log.warn(
4384
+ import_core16.log.warn(
4177
4385
  `No binding "${name}" in render pipeline "${this.id}", expected one of ${validBindings}`,
4178
4386
  value
4179
4387
  )();
@@ -4181,7 +4389,7 @@ ${source}`;
4181
4389
  continue;
4182
4390
  }
4183
4391
  if (!value) {
4184
- import_core15.log.warn(`Unsetting binding "${name}" in render pipeline "${this.id}"`)();
4392
+ import_core16.log.warn(`Unsetting binding "${name}" in render pipeline "${this.id}"`)();
4185
4393
  }
4186
4394
  switch (binding.type) {
4187
4395
  case "uniform":
@@ -4195,7 +4403,7 @@ ${source}`;
4195
4403
  }
4196
4404
  break;
4197
4405
  case "sampler":
4198
- import_core15.log.warn(`Ignoring sampler ${name}`)();
4406
+ import_core16.log.warn(`Ignoring sampler ${name}`)();
4199
4407
  break;
4200
4408
  default:
4201
4409
  throw new Error(binding.type);
@@ -4227,11 +4435,11 @@ ${source}`;
4227
4435
  const isIndexed = Boolean(vertexArray.indexBuffer);
4228
4436
  const glIndexType = vertexArray.indexBuffer?.glIndexType;
4229
4437
  if (this.linkStatus !== "success") {
4230
- import_core15.log.info(2, `RenderPipeline:${this.id}.draw() aborted - waiting for shader linking`)();
4438
+ import_core16.log.info(2, `RenderPipeline:${this.id}.draw() aborted - waiting for shader linking`)();
4231
4439
  return false;
4232
4440
  }
4233
4441
  if (!this._areTexturesRenderable()) {
4234
- import_core15.log.info(2, `RenderPipeline:${this.id}.draw() aborted - textures not yet loaded`)();
4442
+ import_core16.log.info(2, `RenderPipeline:${this.id}.draw() aborted - textures not yet loaded`)();
4235
4443
  return false;
4236
4444
  }
4237
4445
  this.device.gl.useProgram(this.handle);
@@ -4278,19 +4486,19 @@ ${source}`;
4278
4486
  const { gl } = this.device;
4279
4487
  gl.attachShader(this.handle, this.vs.handle);
4280
4488
  gl.attachShader(this.handle, this.fs.handle);
4281
- import_core15.log.time(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
4489
+ import_core16.log.time(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
4282
4490
  gl.linkProgram(this.handle);
4283
- import_core15.log.timeEnd(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
4284
- if (import_core15.log.level === 0) {
4491
+ import_core16.log.timeEnd(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
4492
+ if (import_core16.log.level === 0) {
4285
4493
  }
4286
4494
  if (!this.device.features.has("compilation-status-async-webgl")) {
4287
4495
  const status2 = this._getLinkStatus();
4288
4496
  this._reportLinkStatus(status2);
4289
4497
  return;
4290
4498
  }
4291
- import_core15.log.once(1, "RenderPipeline linking is asynchronous")();
4499
+ import_core16.log.once(1, "RenderPipeline linking is asynchronous")();
4292
4500
  await this._waitForLinkComplete();
4293
- import_core15.log.info(2, `RenderPipeline ${this.id} - async linking complete: ${this.linkStatus}`)();
4501
+ import_core16.log.info(2, `RenderPipeline ${this.id} - async linking complete: ${this.linkStatus}`)();
4294
4502
  const status = this._getLinkStatus();
4295
4503
  this._reportLinkStatus(status);
4296
4504
  }
@@ -4378,7 +4586,7 @@ ${source}`;
4378
4586
  let texturesRenderable = true;
4379
4587
  for (const bindingInfo of this.shaderLayout.bindings) {
4380
4588
  if (!this.bindings[bindingInfo.name] && !this.bindings[bindingInfo.name.replace(/Uniforms$/, "")]) {
4381
- import_core15.log.warn(`Binding ${bindingInfo.name} not found in ${this.id}`)();
4589
+ import_core16.log.warn(`Binding ${bindingInfo.name} not found in ${this.id}`)();
4382
4590
  texturesRenderable = false;
4383
4591
  }
4384
4592
  }
@@ -4405,7 +4613,7 @@ ${source}`;
4405
4613
  if (location === 4294967295 /* INVALID_INDEX */) {
4406
4614
  throw new Error(`Invalid uniform block name ${name}`);
4407
4615
  }
4408
- gl.uniformBlockBinding(this.handle, uniformBufferIndex, location);
4616
+ gl.uniformBlockBinding(this.handle, location, uniformBufferIndex);
4409
4617
  if (value instanceof WEBGLBuffer) {
4410
4618
  gl.bindBufferBase(35345 /* UNIFORM_BUFFER */, uniformBufferIndex, value.handle);
4411
4619
  } else {
@@ -4432,7 +4640,7 @@ ${source}`;
4432
4640
  } else if (value instanceof WEBGLTexture) {
4433
4641
  texture = value;
4434
4642
  } else if (value instanceof WEBGLFramebuffer && value.colorAttachments[0] instanceof WEBGLTextureView) {
4435
- import_core15.log.warn(
4643
+ import_core16.log.warn(
4436
4644
  "Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead"
4437
4645
  )();
4438
4646
  texture = value.colorAttachments[0].texture;
@@ -4501,7 +4709,7 @@ ${source}`;
4501
4709
  height = options.sourceTexture.height,
4502
4710
  depthOrArrayLayers = 0,
4503
4711
  /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
4504
- origin = [0, 0],
4712
+ origin = [0, 0, 0],
4505
4713
  /** Destination buffer */
4506
4714
  destinationBuffer,
4507
4715
  /** Offset, in bytes, from the beginning of the buffer to the start of the image data (default 0) */
@@ -4530,9 +4738,8 @@ ${source}`;
4530
4738
  const webglBuffer = destinationBuffer;
4531
4739
  const sourceWidth = width || framebuffer.width;
4532
4740
  const sourceHeight = height || framebuffer.height;
4533
- const sourceParams = getTextureFormatWebGL(
4534
- framebuffer.colorAttachments[0].texture.props.format
4535
- );
4741
+ const colorAttachment0 = (0, import_core17.assertDefined)(framebuffer.colorAttachments[0]);
4742
+ const sourceParams = getTextureFormatWebGL(colorAttachment0.texture.props.format);
4536
4743
  const sourceFormat = sourceParams.format;
4537
4744
  const sourceType = sourceParams.type;
4538
4745
  device.gl.bindBuffer(35051 /* PIXEL_PACK_BUFFER */, webglBuffer.handle);
@@ -4567,7 +4774,7 @@ ${source}`;
4567
4774
  /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy from. */
4568
4775
  origin = [0, 0],
4569
4776
  /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to. */
4570
- destinationOrigin = [0, 0],
4777
+ destinationOrigin = [0, 0, 0],
4571
4778
  /** Texture to copy to/from. */
4572
4779
  destinationTexture
4573
4780
  /** Mip-map level of the texture to copy to/from. (Default 0) */
@@ -4583,7 +4790,7 @@ ${source}`;
4583
4790
  // depthOrArrayLayers = 0
4584
4791
  } = options;
4585
4792
  const { framebuffer, destroyFramebuffer } = getFramebuffer(sourceTexture);
4586
- const [sourceX, sourceY] = origin;
4793
+ const [sourceX = 0, sourceY = 0] = origin;
4587
4794
  const [destinationX, destinationY, destinationZ] = destinationOrigin;
4588
4795
  const prevHandle = device.gl.bindFramebuffer(
4589
4796
  36160 /* FRAMEBUFFER */,
@@ -4639,7 +4846,7 @@ ${source}`;
4639
4846
  }
4640
4847
  }
4641
4848
  function getFramebuffer(source) {
4642
- if (source instanceof import_core16.Texture) {
4849
+ if (source instanceof import_core17.Texture) {
4643
4850
  const { width, height, id } = source;
4644
4851
  const framebuffer = source.device.createFramebuffer({
4645
4852
  id: `framebuffer-for-${id}`,
@@ -4651,14 +4858,14 @@ ${source}`;
4651
4858
  }
4652
4859
  return { framebuffer: source, destroyFramebuffer: false };
4653
4860
  }
4654
- var import_core16, WEBGLCommandBuffer;
4861
+ var import_core17, WEBGLCommandBuffer;
4655
4862
  var init_webgl_command_buffer = __esm({
4656
4863
  "src/adapter/resources/webgl-command-buffer.ts"() {
4657
4864
  "use strict";
4658
- import_core16 = __toESM(require_core(), 1);
4865
+ import_core17 = __toESM(require_core(), 1);
4659
4866
  init_webgl_texture();
4660
4867
  init_webgl_texture_table();
4661
- WEBGLCommandBuffer = class extends import_core16.CommandBuffer {
4868
+ WEBGLCommandBuffer = class extends import_core17.CommandBuffer {
4662
4869
  device;
4663
4870
  handle = null;
4664
4871
  commands = [];
@@ -4691,15 +4898,15 @@ ${source}`;
4691
4898
  });
4692
4899
 
4693
4900
  // src/adapter/resources/webgl-render-pass.ts
4694
- var import_core17, COLOR_CHANNELS, WEBGLRenderPass;
4901
+ var import_core18, COLOR_CHANNELS, WEBGLRenderPass;
4695
4902
  var init_webgl_render_pass = __esm({
4696
4903
  "src/adapter/resources/webgl-render-pass.ts"() {
4697
4904
  "use strict";
4698
- import_core17 = __toESM(require_core(), 1);
4905
+ import_core18 = __toESM(require_core(), 1);
4699
4906
  init_with_parameters();
4700
4907
  init_unified_parameter_api();
4701
4908
  COLOR_CHANNELS = [1, 2, 4, 8];
4702
- WEBGLRenderPass = class extends import_core17.RenderPass {
4909
+ WEBGLRenderPass = class extends import_core18.RenderPass {
4703
4910
  device;
4704
4911
  handle = null;
4705
4912
  /** Parameters that should be applied before each draw call */
@@ -4707,6 +4914,9 @@ ${source}`;
4707
4914
  constructor(device, props) {
4708
4915
  super(device, props);
4709
4916
  this.device = device;
4917
+ if (!props?.framebuffer) {
4918
+ device.getDefaultCanvasContext()._resizeDrawingBufferIfNeeded();
4919
+ }
4710
4920
  let viewport;
4711
4921
  if (!props?.parameters?.viewport) {
4712
4922
  if (props?.framebuffer) {
@@ -4725,7 +4935,7 @@ ${source}`;
4725
4935
  (_, i) => 36064 /* COLOR_ATTACHMENT0 */ + i
4726
4936
  );
4727
4937
  this.device.gl.drawBuffers(drawBuffers);
4728
- } else {
4938
+ } else if (!this.props.framebuffer) {
4729
4939
  this.device.gl.drawBuffers([1029 /* BACK */]);
4730
4940
  }
4731
4941
  this.clear();
@@ -4771,9 +4981,9 @@ ${source}`;
4771
4981
  if (parameters.blendConstant) {
4772
4982
  glParameters.blendColor = parameters.blendConstant;
4773
4983
  }
4774
- if (parameters.stencilReference) {
4775
- console.warn("RenderPassParameters.stencilReference not yet implemented in WebGL");
4984
+ if (parameters.stencilReference !== void 0) {
4776
4985
  glParameters[2967 /* STENCIL_REF */] = parameters.stencilReference;
4986
+ glParameters[36003 /* STENCIL_BACK_REF */] = parameters.stencilReference;
4777
4987
  }
4778
4988
  if ("colorMask" in parameters) {
4779
4989
  glParameters.colorMask = COLOR_CHANNELS.map(
@@ -4873,14 +5083,14 @@ ${source}`;
4873
5083
  });
4874
5084
 
4875
5085
  // src/adapter/resources/webgl-command-encoder.ts
4876
- var import_core18, WEBGLCommandEncoder;
5086
+ var import_core19, WEBGLCommandEncoder;
4877
5087
  var init_webgl_command_encoder = __esm({
4878
5088
  "src/adapter/resources/webgl-command-encoder.ts"() {
4879
5089
  "use strict";
4880
- import_core18 = __toESM(require_core(), 1);
5090
+ import_core19 = __toESM(require_core(), 1);
4881
5091
  init_webgl_command_buffer();
4882
5092
  init_webgl_render_pass();
4883
- WEBGLCommandEncoder = class extends import_core18.CommandEncoder {
5093
+ WEBGLCommandEncoder = class extends import_core19.CommandEncoder {
4884
5094
  device;
4885
5095
  handle = null;
4886
5096
  commandBuffer;
@@ -4934,7 +5144,7 @@ ${source}`;
4934
5144
  const total = count * length;
4935
5145
  let copied = 0;
4936
5146
  for (let i = start; copied < length; copied++) {
4937
- target2[i++] = source[copied];
5147
+ target2[i++] = source[copied] ?? 0;
4938
5148
  }
4939
5149
  while (copied < total) {
4940
5150
  if (copied < total - copied) {
@@ -4971,15 +5181,15 @@ ${source}`;
4971
5181
  }
4972
5182
  return true;
4973
5183
  }
4974
- var import_core19, WEBGLVertexArray;
5184
+ var import_core20, WEBGLVertexArray;
4975
5185
  var init_webgl_vertex_array = __esm({
4976
5186
  "src/adapter/resources/webgl-vertex-array.ts"() {
4977
5187
  "use strict";
4978
- import_core19 = __toESM(require_core(), 1);
5188
+ import_core20 = __toESM(require_core(), 1);
4979
5189
  init_dist();
4980
5190
  init_webgl_vertex_formats();
4981
5191
  init_fill_array();
4982
- WEBGLVertexArray = class extends import_core19.VertexArray {
5192
+ WEBGLVertexArray = class extends import_core20.VertexArray {
4983
5193
  get [Symbol.toStringTag]() {
4984
5194
  return "VertexArray";
4985
5195
  }
@@ -5147,7 +5357,7 @@ ${source}`;
5147
5357
  this.buffer = this.buffer || this.device.createBuffer({ byteLength });
5148
5358
  updateNeeded ||= !compareConstantArrayValues(constantValue, this.bufferValue);
5149
5359
  if (updateNeeded) {
5150
- const typedArray = (0, import_core19.getScratchArray)(value.constructor, length);
5360
+ const typedArray = (0, import_core20.getScratchArray)(value.constructor, length);
5151
5361
  fillArray({ target: typedArray, source: constantValue, start: 0, count: length });
5152
5362
  this.buffer.write(typedArray);
5153
5363
  this.bufferValue = value;
@@ -5165,14 +5375,14 @@ ${source}`;
5165
5375
  }
5166
5376
  return /^\d+$/.test(value);
5167
5377
  }
5168
- var import_core20, WEBGLTransformFeedback;
5378
+ var import_core21, WEBGLTransformFeedback;
5169
5379
  var init_webgl_transform_feedback = __esm({
5170
5380
  "src/adapter/resources/webgl-transform-feedback.ts"() {
5171
5381
  "use strict";
5172
- import_core20 = __toESM(require_core(), 1);
5382
+ import_core21 = __toESM(require_core(), 1);
5173
5383
  init_src2();
5174
5384
  init_webgl_topology_utils();
5175
- WEBGLTransformFeedback = class extends import_core20.TransformFeedback {
5385
+ WEBGLTransformFeedback = class extends import_core21.TransformFeedback {
5176
5386
  device;
5177
5387
  gl;
5178
5388
  handle;
@@ -5225,8 +5435,8 @@ ${source}`;
5225
5435
  this.buffers = {};
5226
5436
  this.unusedBuffers = {};
5227
5437
  this.bind(() => {
5228
- for (const bufferName in buffers) {
5229
- this.setBuffer(bufferName, buffers[bufferName]);
5438
+ for (const [bufferName, buffer] of Object.entries(buffers)) {
5439
+ this.setBuffer(bufferName, buffer);
5230
5440
  }
5231
5441
  });
5232
5442
  }
@@ -5235,7 +5445,7 @@ ${source}`;
5235
5445
  const { buffer, byteLength, byteOffset } = this._getBufferRange(bufferOrRange);
5236
5446
  if (location < 0) {
5237
5447
  this.unusedBuffers[locationOrName] = buffer;
5238
- import_core20.log.warn(`${this.id} unusedBuffers varying buffer ${locationOrName}`)();
5448
+ import_core21.log.warn(`${this.id} unusedBuffers varying buffer ${locationOrName}`)();
5239
5449
  return;
5240
5450
  }
5241
5451
  this.buffers[location] = { buffer, byteLength, byteOffset };
@@ -5248,7 +5458,7 @@ ${source}`;
5248
5458
  return this.buffers[locationOrName] || null;
5249
5459
  }
5250
5460
  const location = this._getVaryingIndex(locationOrName);
5251
- return location >= 0 ? this.buffers[location] : null;
5461
+ return this.buffers[location] ?? null;
5252
5462
  }
5253
5463
  bind(funcOrHandle = this.handle) {
5254
5464
  if (typeof funcOrHandle !== "function") {
@@ -5295,8 +5505,8 @@ ${source}`;
5295
5505
  * cannot be bound to 'TRANSFORM_FEEDBACK_BUFFER' target.
5296
5506
  */
5297
5507
  _bindBuffers() {
5298
- for (const bufferIndex in this.buffers) {
5299
- const { buffer, byteLength, byteOffset } = this._getBufferRange(this.buffers[bufferIndex]);
5508
+ for (const [bufferIndex, bufferEntry] of Object.entries(this.buffers)) {
5509
+ const { buffer, byteLength, byteOffset } = this._getBufferRange(bufferEntry);
5300
5510
  this._bindBuffer(Number(bufferIndex), buffer, byteOffset, byteLength);
5301
5511
  }
5302
5512
  }
@@ -5318,12 +5528,12 @@ ${source}`;
5318
5528
  });
5319
5529
 
5320
5530
  // src/adapter/resources/webgl-query-set.ts
5321
- var import_core21, WEBGLQuerySet;
5531
+ var import_core22, WEBGLQuerySet;
5322
5532
  var init_webgl_query_set = __esm({
5323
5533
  "src/adapter/resources/webgl-query-set.ts"() {
5324
5534
  "use strict";
5325
- import_core21 = __toESM(require_core(), 1);
5326
- WEBGLQuerySet = class extends import_core21.QuerySet {
5535
+ import_core22 = __toESM(require_core(), 1);
5536
+ WEBGLQuerySet = class extends import_core22.QuerySet {
5327
5537
  device;
5328
5538
  handle;
5329
5539
  target = null;
@@ -5461,6 +5671,57 @@ ${source}`;
5461
5671
  }
5462
5672
  });
5463
5673
 
5674
+ // src/adapter/resources/webgl-fence.ts
5675
+ var import_core23, WEBGLFence;
5676
+ var init_webgl_fence = __esm({
5677
+ "src/adapter/resources/webgl-fence.ts"() {
5678
+ "use strict";
5679
+ import_core23 = __toESM(require_core(), 1);
5680
+ WEBGLFence = class extends import_core23.Fence {
5681
+ device;
5682
+ gl;
5683
+ handle;
5684
+ signaled;
5685
+ _signaled = false;
5686
+ constructor(device, props = {}) {
5687
+ super(device, {});
5688
+ this.device = device;
5689
+ this.gl = device.gl;
5690
+ const sync = this.props.handle || this.gl.fenceSync(this.gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
5691
+ if (!sync) {
5692
+ throw new Error("Failed to create WebGL fence");
5693
+ }
5694
+ this.handle = sync;
5695
+ this.signaled = new Promise((resolve) => {
5696
+ const poll = () => {
5697
+ const status = this.gl.clientWaitSync(this.handle, 0, 0);
5698
+ if (status === this.gl.ALREADY_SIGNALED || status === this.gl.CONDITION_SATISFIED) {
5699
+ this._signaled = true;
5700
+ resolve();
5701
+ } else {
5702
+ setTimeout(poll, 1);
5703
+ }
5704
+ };
5705
+ poll();
5706
+ });
5707
+ }
5708
+ isSignaled() {
5709
+ if (this._signaled) {
5710
+ return true;
5711
+ }
5712
+ const status = this.gl.getSyncParameter(this.handle, this.gl.SYNC_STATUS);
5713
+ this._signaled = status === this.gl.SIGNALED;
5714
+ return this._signaled;
5715
+ }
5716
+ destroy() {
5717
+ if (!this.destroyed) {
5718
+ this.gl.deleteSync(this.handle);
5719
+ }
5720
+ }
5721
+ };
5722
+ }
5723
+ });
5724
+
5464
5725
  // src/adapter/helpers/format-utils.ts
5465
5726
  function glFormatToComponents(format) {
5466
5727
  switch (format) {
@@ -5507,35 +5768,6 @@ ${source}`;
5507
5768
  }
5508
5769
  });
5509
5770
 
5510
- // src/adapter/converters/shader-formats.ts
5511
- function convertGLDataTypeToDataType(type) {
5512
- return GL_DATA_TYPE_MAP[type];
5513
- }
5514
- var GL_DATA_TYPE_MAP;
5515
- var init_shader_formats = __esm({
5516
- "src/adapter/converters/shader-formats.ts"() {
5517
- "use strict";
5518
- GL_DATA_TYPE_MAP = {
5519
- [5124 /* INT */]: "sint32",
5520
- [5125 /* UNSIGNED_INT */]: "uint32",
5521
- [5122 /* SHORT */]: "sint16",
5522
- [5123 /* UNSIGNED_SHORT */]: "uint16",
5523
- [5120 /* BYTE */]: "sint8",
5524
- [5121 /* UNSIGNED_BYTE */]: "uint8",
5525
- [5126 /* FLOAT */]: "float32",
5526
- [5131 /* HALF_FLOAT */]: "float16",
5527
- [33635 /* UNSIGNED_SHORT_5_6_5 */]: "uint16",
5528
- [32819 /* UNSIGNED_SHORT_4_4_4_4 */]: "uint16",
5529
- [32820 /* UNSIGNED_SHORT_5_5_5_1 */]: "uint16",
5530
- [33640 /* UNSIGNED_INT_2_10_10_10_REV */]: "uint32",
5531
- [35899 /* UNSIGNED_INT_10F_11F_11F_REV */]: "uint32",
5532
- [35902 /* UNSIGNED_INT_5_9_9_9_REV */]: "uint32",
5533
- [34042 /* UNSIGNED_INT_24_8 */]: "uint32",
5534
- [36269 /* FLOAT_32_UNSIGNED_INT_24_8_REV */]: "uint32"
5535
- };
5536
- }
5537
- });
5538
-
5539
5771
  // src/adapter/helpers/webgl-texture-utils.ts
5540
5772
  function readPixelsToArray(source, options) {
5541
5773
  const {
@@ -5565,7 +5797,7 @@ ${source}`;
5565
5797
  sourceFormat ||= texture?.glFormat || 6408 /* RGBA */;
5566
5798
  sourceType ||= texture?.glType || 5121 /* UNSIGNED_BYTE */;
5567
5799
  target2 = getPixelArray(target2, sourceType, sourceFormat, sourceWidth, sourceHeight, sourceDepth);
5568
- const signedType = (0, import_core22.getDataType)(target2);
5800
+ const signedType = (0, import_core24.getDataType)(target2);
5569
5801
  sourceType = sourceType || convertDataTypeToGLDataType(signedType);
5570
5802
  const prevHandle = gl.bindFramebuffer(
5571
5803
  36160 /* FRAMEBUFFER */,
@@ -5617,7 +5849,7 @@ ${source}`;
5617
5849
  return webglBufferTarget;
5618
5850
  }
5619
5851
  function getFramebuffer2(source) {
5620
- if (!(source instanceof import_core22.Framebuffer)) {
5852
+ if (!(source instanceof import_core24.Framebuffer)) {
5621
5853
  return { framebuffer: toFramebuffer(source), deleteFramebuffer: true };
5622
5854
  }
5623
5855
  return { framebuffer: source, deleteFramebuffer: false };
@@ -5639,15 +5871,15 @@ ${source}`;
5639
5871
  }
5640
5872
  glType ||= 5121 /* UNSIGNED_BYTE */;
5641
5873
  const shaderType = convertGLDataTypeToDataType(glType);
5642
- const ArrayType = (0, import_core22.getTypedArrayConstructor)(shaderType);
5874
+ const ArrayType = (0, import_core24.getTypedArrayConstructor)(shaderType);
5643
5875
  const components = glFormatToComponents(glFormat);
5644
5876
  return new ArrayType(width * height * components);
5645
5877
  }
5646
- var import_core22;
5878
+ var import_core24;
5647
5879
  var init_webgl_texture_utils = __esm({
5648
5880
  "src/adapter/helpers/webgl-texture-utils.ts"() {
5649
5881
  "use strict";
5650
- import_core22 = __toESM(require_core(), 1);
5882
+ import_core24 = __toESM(require_core(), 1);
5651
5883
  init_webgl_shadertypes();
5652
5884
  init_format_utils();
5653
5885
  init_shader_formats();
@@ -5693,13 +5925,14 @@ ${source}`;
5693
5925
  }
5694
5926
  return true;
5695
5927
  }
5696
- var import_core23, WebGLDevice;
5928
+ var import_core25, WebGLDevice;
5697
5929
  var init_webgl_device = __esm({
5698
5930
  "src/adapter/webgl-device.ts"() {
5699
5931
  "use strict";
5700
- import_core23 = __toESM(require_core(), 1);
5932
+ import_core25 = __toESM(require_core(), 1);
5701
5933
  init_webgl_state_tracker();
5702
5934
  init_create_browser_context();
5935
+ init_webgl_context_data();
5703
5936
  init_webgl_device_info();
5704
5937
  init_webgl_device_features();
5705
5938
  init_webgl_device_limits();
@@ -5718,11 +5951,18 @@ ${source}`;
5718
5951
  init_webgl_vertex_array();
5719
5952
  init_webgl_transform_feedback();
5720
5953
  init_webgl_query_set();
5954
+ init_webgl_fence();
5721
5955
  init_webgl_texture_utils();
5722
5956
  init_unified_parameter_api();
5723
5957
  init_with_parameters();
5724
5958
  init_webgl_extensions();
5725
- WebGLDevice = class extends import_core23.Device {
5959
+ WebGLDevice = class extends import_core25.Device {
5960
+ static getDeviceFromContext(gl) {
5961
+ if (!gl) {
5962
+ return null;
5963
+ }
5964
+ return gl.luma?.device ?? null;
5965
+ }
5726
5966
  // Public `Device` API
5727
5967
  /** type of this device */
5728
5968
  type = "webgl";
@@ -5744,7 +5984,7 @@ ${source}`;
5744
5984
  // @ts-ignore TODO fix
5745
5985
  _constants;
5746
5986
  /** State used by luma.gl classes - TODO - not used? */
5747
- _extensions = {};
5987
+ extensions;
5748
5988
  _polyfilled = false;
5749
5989
  /** Instance of Spector.js (if initialized) */
5750
5990
  spectorJS;
@@ -5767,11 +6007,12 @@ ${source}`;
5767
6007
  }
5768
6008
  constructor(props) {
5769
6009
  super({ ...props, id: props.id || uid("webgl-device") });
5770
- const canvasContextProps = import_core23.Device._getCanvasContextProps(props);
6010
+ const canvasContextProps = import_core25.Device._getCanvasContextProps(props);
5771
6011
  if (!canvasContextProps) {
5772
6012
  throw new Error("WebGLDevice requires props.createCanvasContext to be set");
5773
6013
  }
5774
- let device = canvasContextProps.canvas?.gl?.device;
6014
+ const existingContext = canvasContextProps.canvas?.gl ?? null;
6015
+ let device = WebGLDevice.getDeviceFromContext(existingContext);
5775
6016
  if (device) {
5776
6017
  throw new Error(`WebGL context already attached to device ${device.id}`);
5777
6018
  }
@@ -5786,6 +6027,9 @@ ${source}`;
5786
6027
  if (props.powerPreference !== void 0) {
5787
6028
  webglContextAttributes.powerPreference = props.powerPreference;
5788
6029
  }
6030
+ if (props.failIfMajorPerformanceCaveat !== void 0) {
6031
+ webglContextAttributes.failIfMajorPerformanceCaveat = props.failIfMajorPerformanceCaveat;
6032
+ }
5789
6033
  const externalGLContext = this.props._handle;
5790
6034
  const gl = externalGLContext || createBrowserContext(
5791
6035
  this.canvasContext.canvas,
@@ -5802,14 +6046,15 @@ ${source}`;
5802
6046
  if (!gl) {
5803
6047
  throw new Error("WebGL context creation failed");
5804
6048
  }
5805
- device = gl.device;
6049
+ device = WebGLDevice.getDeviceFromContext(gl);
5806
6050
  if (device) {
5807
6051
  if (props._reuseDevices) {
5808
- import_core23.log.log(
6052
+ import_core25.log.log(
5809
6053
  1,
5810
6054
  `Not creating a new Device, instead returning a reference to Device ${device.id} already attached to WebGL context`,
5811
6055
  device
5812
6056
  )();
6057
+ this.canvasContext.destroy();
5813
6058
  device._reused = true;
5814
6059
  return device;
5815
6060
  }
@@ -5818,30 +6063,25 @@ ${source}`;
5818
6063
  this.handle = gl;
5819
6064
  this.gl = gl;
5820
6065
  this.spectorJS = initializeSpectorJS({ ...this.props, gl: this.handle });
5821
- this.gl.device = this;
5822
- this.gl._version = 2;
5823
- this.info = getDeviceInfo(this.gl, this._extensions);
6066
+ const contextData = getWebGLContextData(this.handle);
6067
+ contextData.device = this;
6068
+ this.extensions = contextData.extensions || (contextData.extensions = {});
6069
+ this.info = getDeviceInfo(this.gl, this.extensions);
5824
6070
  this.limits = new WebGLDeviceLimits(this.gl);
5825
- this.features = new WebGLDeviceFeatures(
5826
- this.gl,
5827
- this._extensions,
5828
- this.props._disabledFeatures
5829
- );
6071
+ this.features = new WebGLDeviceFeatures(this.gl, this.extensions, this.props._disabledFeatures);
5830
6072
  if (this.props._initializeFeatures) {
5831
6073
  this.features.initializeFeatures();
5832
6074
  }
5833
6075
  const glState = new WebGLStateTracker(this.gl, {
5834
- log: (...args) => import_core23.log.log(1, ...args)()
6076
+ log: (...args) => import_core25.log.log(1, ...args)()
5835
6077
  });
5836
6078
  glState.trackState(this.gl, { copyState: false });
5837
- const debugWebGL = props.debugWebGL || props.debug;
5838
- const traceWebGL = props.debugWebGL;
5839
- if (debugWebGL) {
5840
- this.gl = makeDebugContext(this.gl, { debugWebGL, traceWebGL });
5841
- import_core23.log.warn("WebGL debug mode activated. Performance reduced.")();
5842
- if (props.debugWebGL) {
5843
- import_core23.log.level = Math.max(import_core23.log.level, 1);
5844
- }
6079
+ if (props.debug || props.debugWebGL) {
6080
+ this.gl = makeDebugContext(this.gl, { debugWebGL: true, traceWebGL: props.debugWebGL });
6081
+ import_core25.log.warn("WebGL debug mode activated. Performance reduced.")();
6082
+ }
6083
+ if (props.debugWebGL) {
6084
+ import_core25.log.level = Math.max(import_core25.log.level, 1);
5845
6085
  }
5846
6086
  this.commandEncoder = new WEBGLCommandEncoder(this, { id: `${this}-command-encoder` });
5847
6087
  }
@@ -5857,16 +6097,14 @@ ${source}`;
5857
6097
  */
5858
6098
  destroy() {
5859
6099
  if (!this.props._reuseDevices && !this._reused) {
5860
- delete this.gl.device;
6100
+ const contextData = getWebGLContextData(this.handle);
6101
+ contextData.device = null;
5861
6102
  }
5862
6103
  }
5863
6104
  get isLost() {
5864
6105
  return this.gl.isContextLost();
5865
6106
  }
5866
6107
  // IMPLEMENTATION OF ABSTRACT DEVICE
5867
- getTextureByteAlignment() {
5868
- return 4;
5869
- }
5870
6108
  createCanvasContext(props) {
5871
6109
  throw new Error("WebGL only supports a single canvas");
5872
6110
  }
@@ -5898,6 +6136,9 @@ ${source}`;
5898
6136
  createQuerySet(props) {
5899
6137
  return new WEBGLQuerySet(this, props);
5900
6138
  }
6139
+ createFence() {
6140
+ return new WEBGLFence(this);
6141
+ }
5901
6142
  createRenderPipeline(props) {
5902
6143
  return new WEBGLRenderPipeline(this, props);
5903
6144
  }
@@ -5941,11 +6182,11 @@ ${source}`;
5941
6182
  return withGLParameters(this.gl, parameters, func);
5942
6183
  }
5943
6184
  resetWebGL() {
5944
- import_core23.log.warn("WebGLDevice.resetWebGL is deprecated, use only for debugging")();
6185
+ import_core25.log.warn("WebGLDevice.resetWebGL is deprecated, use only for debugging")();
5945
6186
  resetGLParameters(this.gl);
5946
6187
  }
5947
6188
  _getDeviceSpecificTextureFormatCapabilities(capabilities) {
5948
- return getTextureFormatCapabilitiesWebGL(this.gl, capabilities, this._extensions);
6189
+ return getTextureFormatCapabilitiesWebGL(this.gl, capabilities, this.extensions);
5949
6190
  }
5950
6191
  //
5951
6192
  // WebGL-only API (not part of `Device` API)
@@ -6013,7 +6254,7 @@ ${source}`;
6013
6254
  this._constants = this._constants || new Array(maxVertexAttributes).fill(null);
6014
6255
  const currentConstant = this._constants[location];
6015
6256
  if (currentConstant && compareConstantArrayValues2(currentConstant, constant)) {
6016
- import_core23.log.info(
6257
+ import_core25.log.info(
6017
6258
  1,
6018
6259
  `setConstantAttributeWebGL(${location}) could have been skipped, value unchanged`
6019
6260
  )();
@@ -6035,8 +6276,8 @@ ${source}`;
6035
6276
  }
6036
6277
  /** Ensure extensions are only requested once */
6037
6278
  getExtension(name) {
6038
- getWebGLExtension(this.gl, name, this._extensions);
6039
- return this._extensions;
6279
+ getWebGLExtension(this.gl, name, this.extensions);
6280
+ return this.extensions;
6040
6281
  }
6041
6282
  // INTERNAL SUPPORT METHODS FOR WEBGL RESOURCES
6042
6283
  /**
@@ -6057,23 +6298,23 @@ ${source}`;
6057
6298
  if (typeof WebGL2RenderingContext !== "undefined" && gl instanceof WebGL2RenderingContext) {
6058
6299
  return true;
6059
6300
  }
6060
- return Boolean(gl && Number.isFinite(gl._version));
6301
+ return Boolean(gl && typeof gl.createVertexArray === "function");
6061
6302
  }
6062
- var import_core24, LOG_LEVEL2, WebGLAdapter, webgl2Adapter;
6303
+ var import_core26, LOG_LEVEL2, WebGLAdapter, webgl2Adapter;
6063
6304
  var init_webgl_adapter = __esm({
6064
6305
  "src/adapter/webgl-adapter.ts"() {
6065
6306
  "use strict";
6066
- import_core24 = __toESM(require_core(), 1);
6307
+ import_core26 = __toESM(require_core(), 1);
6067
6308
  init_polyfill_webgl1_extensions();
6068
6309
  init_spector();
6069
6310
  init_webgl_developer_tools();
6070
6311
  LOG_LEVEL2 = 1;
6071
- WebGLAdapter = class extends import_core24.Adapter {
6312
+ WebGLAdapter = class extends import_core26.Adapter {
6072
6313
  /** type of device's created by this adapter */
6073
6314
  type = "webgl";
6074
6315
  constructor() {
6075
6316
  super();
6076
- import_core24.Device.defaultProps = { ...import_core24.Device.defaultProps, ...DEFAULT_SPECTOR_PROPS };
6317
+ import_core26.Device.defaultProps = { ...import_core26.Device.defaultProps, ...DEFAULT_SPECTOR_PROPS };
6077
6318
  }
6078
6319
  /** Force any created WebGL contexts to be WebGL2 contexts, polyfilled with WebGL1 extensions */
6079
6320
  enforceWebGL2(enable2) {
@@ -6088,7 +6329,7 @@ ${source}`;
6088
6329
  return true;
6089
6330
  }
6090
6331
  if (typeof WebGLRenderingContext !== "undefined" && handle instanceof WebGLRenderingContext) {
6091
- import_core24.log.warn("WebGL1 is not supported", handle)();
6332
+ import_core26.log.warn("WebGL1 is not supported", handle)();
6092
6333
  }
6093
6334
  return false;
6094
6335
  }
@@ -6104,8 +6345,9 @@ ${source}`;
6104
6345
  if (gl instanceof WebGLDevice2) {
6105
6346
  return gl;
6106
6347
  }
6107
- if (gl?.device instanceof WebGLDevice2) {
6108
- return gl.device;
6348
+ const existingDevice = WebGLDevice2.getDeviceFromContext(gl);
6349
+ if (existingDevice) {
6350
+ return existingDevice;
6109
6351
  }
6110
6352
  if (!isWebGL(gl)) {
6111
6353
  throw new Error("Invalid WebGL2RenderingContext");
@@ -6119,28 +6361,33 @@ ${source}`;
6119
6361
  }
6120
6362
  async create(props = {}) {
6121
6363
  const { WebGLDevice: WebGLDevice2 } = await Promise.resolve().then(() => (init_webgl_device(), webgl_device_exports));
6122
- import_core24.log.groupCollapsed(LOG_LEVEL2, "WebGLDevice created")();
6123
- try {
6124
- const promises = [];
6125
- if (props.debugWebGL || props.debug) {
6126
- promises.push(loadWebGLDeveloperTools());
6127
- }
6128
- if (props.debugSpectorJS) {
6129
- promises.push(loadSpectorJS(props));
6130
- }
6131
- const results = await Promise.allSettled(promises);
6132
- for (const result of results) {
6133
- if (result.status === "rejected") {
6134
- import_core24.log.error(`Failed to initialize debug libraries ${result.reason}`)();
6135
- }
6364
+ const promises = [];
6365
+ if (props.debugWebGL || props.debug) {
6366
+ promises.push(loadWebGLDeveloperTools());
6367
+ }
6368
+ if (props.debugSpectorJS) {
6369
+ promises.push(loadSpectorJS(props));
6370
+ }
6371
+ const results = await Promise.allSettled(promises);
6372
+ for (const result of results) {
6373
+ if (result.status === "rejected") {
6374
+ import_core26.log.error(`Failed to initialize debug libraries ${result.reason}`)();
6136
6375
  }
6376
+ }
6377
+ try {
6137
6378
  const device = new WebGLDevice2(props);
6379
+ import_core26.log.groupCollapsed(LOG_LEVEL2, `WebGLDevice ${device.id} created`)();
6138
6380
  const message2 = `${device._reused ? "Reusing" : "Created"} device with WebGL2 ${device.props.debug ? "debug " : ""}context: ${device.info.vendor}, ${device.info.renderer} for canvas: ${device.canvasContext.id}`;
6139
- import_core24.log.probe(LOG_LEVEL2, message2)();
6140
- import_core24.log.table(LOG_LEVEL2, device.info)();
6381
+ import_core26.log.probe(LOG_LEVEL2, message2)();
6382
+ import_core26.log.table(LOG_LEVEL2, device.info)();
6141
6383
  return device;
6142
6384
  } finally {
6143
- import_core24.log.groupEnd(LOG_LEVEL2)();
6385
+ import_core26.log.groupEnd(LOG_LEVEL2)();
6386
+ import_core26.log.info(
6387
+ LOG_LEVEL2,
6388
+ `%cWebGL call tracing: luma.log.set('debug-webgl') `,
6389
+ "color: white; background: blue; padding: 2px 6px; border-radius: 3px;"
6390
+ )();
6144
6391
  }
6145
6392
  }
6146
6393
  };
@@ -6160,6 +6407,7 @@ ${source}`;
6160
6407
  init_webgl_shader();
6161
6408
  init_webgl_sampler();
6162
6409
  init_webgl_framebuffer();
6410
+ init_webgl_fence();
6163
6411
  init_webgl_render_pipeline();
6164
6412
  init_webgl_command_encoder();
6165
6413
  init_webgl_render_pass();
@@ -6178,6 +6426,7 @@ ${source}`;
6178
6426
  __export(bundle_exports, {
6179
6427
  WEBGLBuffer: () => WEBGLBuffer,
6180
6428
  WEBGLCommandEncoder: () => WEBGLCommandEncoder,
6429
+ WEBGLFence: () => WEBGLFence,
6181
6430
  WEBGLFramebuffer: () => WEBGLFramebuffer,
6182
6431
  WEBGLRenderPass: () => WEBGLRenderPass,
6183
6432
  WEBGLRenderPipeline: () => WEBGLRenderPipeline,