@luma.gl/webgl 9.1.0-alpha.2 → 9.1.0-beta.1

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 (216) 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/device-parameters.js +19 -11
  4. package/dist/adapter/converters/device-parameters.js.map +1 -0
  5. package/dist/adapter/converters/sampler-parameters.js +7 -4
  6. package/dist/adapter/converters/sampler-parameters.js.map +1 -0
  7. package/dist/adapter/converters/shader-formats.js +1 -0
  8. package/dist/adapter/converters/shader-formats.js.map +1 -0
  9. package/dist/adapter/converters/vertex-formats.js +1 -0
  10. package/dist/adapter/converters/vertex-formats.js.map +1 -0
  11. package/dist/adapter/converters/webgl-texture-table.d.ts +40 -0
  12. package/dist/adapter/converters/webgl-texture-table.d.ts.map +1 -0
  13. package/dist/adapter/converters/webgl-texture-table.js +304 -0
  14. package/dist/adapter/converters/webgl-texture-table.js.map +1 -0
  15. package/dist/adapter/device-helpers/webgl-device-features.d.ts.map +1 -1
  16. package/dist/adapter/device-helpers/webgl-device-features.js +2 -3
  17. package/dist/adapter/device-helpers/webgl-device-features.js.map +1 -0
  18. package/dist/adapter/device-helpers/webgl-device-info.js +1 -0
  19. package/dist/adapter/device-helpers/webgl-device-info.js.map +1 -0
  20. package/dist/adapter/device-helpers/webgl-device-limits.js +1 -0
  21. package/dist/adapter/device-helpers/webgl-device-limits.js.map +1 -0
  22. package/dist/adapter/helpers/decode-webgl-types.js +1 -0
  23. package/dist/adapter/helpers/decode-webgl-types.js.map +1 -0
  24. package/dist/adapter/helpers/format-utils.d.ts.map +1 -0
  25. package/dist/{classic → adapter/helpers}/format-utils.js +7 -0
  26. package/dist/adapter/helpers/format-utils.js.map +1 -0
  27. package/dist/adapter/helpers/get-shader-layout.d.ts +1 -1
  28. package/dist/adapter/helpers/get-shader-layout.d.ts.map +1 -1
  29. package/dist/adapter/helpers/get-shader-layout.js +5 -4
  30. package/dist/adapter/helpers/get-shader-layout.js.map +1 -0
  31. package/dist/adapter/helpers/parse-shader-compiler-log.js +1 -0
  32. package/dist/adapter/helpers/parse-shader-compiler-log.js.map +1 -0
  33. package/dist/adapter/helpers/set-uniform.js +1 -0
  34. package/dist/adapter/helpers/set-uniform.js.map +1 -0
  35. package/dist/adapter/helpers/typed-array-utils.d.ts.map +1 -0
  36. package/dist/{classic → adapter/helpers}/typed-array-utils.js +1 -0
  37. package/dist/adapter/helpers/typed-array-utils.js.map +1 -0
  38. package/dist/adapter/helpers/webgl-texture-utils.d.ts +100 -29
  39. package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
  40. package/dist/adapter/helpers/webgl-texture-utils.js +231 -240
  41. package/dist/adapter/helpers/webgl-texture-utils.js.map +1 -0
  42. package/dist/adapter/helpers/webgl-topology-utils.js +1 -0
  43. package/dist/adapter/helpers/webgl-topology-utils.js.map +1 -0
  44. package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
  45. package/dist/adapter/resources/webgl-buffer.js +4 -1
  46. package/dist/adapter/resources/webgl-buffer.js.map +1 -0
  47. package/dist/adapter/resources/webgl-command-buffer.d.ts +59 -2
  48. package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
  49. package/dist/adapter/resources/webgl-command-buffer.js +89 -32
  50. package/dist/adapter/resources/webgl-command-buffer.js.map +1 -0
  51. package/dist/adapter/resources/webgl-command-encoder.d.ts.map +1 -1
  52. package/dist/adapter/resources/webgl-command-encoder.js +4 -0
  53. package/dist/adapter/resources/webgl-command-encoder.js.map +1 -0
  54. package/dist/adapter/resources/webgl-external-texture.js +15 -0
  55. package/dist/adapter/resources/webgl-external-texture.js.map +1 -0
  56. package/dist/adapter/resources/webgl-framebuffer.d.ts +33 -35
  57. package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
  58. package/dist/adapter/resources/webgl-framebuffer.js +71 -76
  59. package/dist/adapter/resources/webgl-framebuffer.js.map +1 -0
  60. package/dist/adapter/resources/webgl-query-set.js +1 -0
  61. package/dist/adapter/resources/webgl-query-set.js.map +1 -0
  62. package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
  63. package/dist/adapter/resources/webgl-render-pass.js +49 -21
  64. package/dist/adapter/resources/webgl-render-pass.js.map +1 -0
  65. package/dist/adapter/resources/webgl-render-pipeline.d.ts +3 -4
  66. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  67. package/dist/adapter/resources/webgl-render-pipeline.js +45 -23
  68. package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -0
  69. package/dist/adapter/resources/webgl-sampler.js +1 -0
  70. package/dist/adapter/resources/webgl-sampler.js.map +1 -0
  71. package/dist/adapter/resources/webgl-shader.d.ts +1 -0
  72. package/dist/adapter/resources/webgl-shader.d.ts.map +1 -1
  73. package/dist/adapter/resources/webgl-shader.js +13 -6
  74. package/dist/adapter/resources/webgl-shader.js.map +1 -0
  75. package/dist/adapter/resources/webgl-texture-view.js +1 -0
  76. package/dist/adapter/resources/webgl-texture-view.js.map +1 -0
  77. package/dist/adapter/resources/webgl-texture.d.ts +33 -21
  78. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  79. package/dist/adapter/resources/webgl-texture.js +172 -242
  80. package/dist/adapter/resources/webgl-texture.js.map +1 -0
  81. package/dist/adapter/resources/webgl-transform-feedback.js +1 -0
  82. package/dist/adapter/resources/webgl-transform-feedback.js.map +1 -0
  83. package/dist/adapter/resources/webgl-vertex-array.js +1 -0
  84. package/dist/adapter/resources/webgl-vertex-array.js.map +1 -0
  85. package/dist/adapter/webgl-adapter.d.ts +21 -0
  86. package/dist/adapter/webgl-adapter.d.ts.map +1 -0
  87. package/dist/adapter/webgl-adapter.js +86 -0
  88. package/dist/adapter/webgl-adapter.js.map +1 -0
  89. package/dist/adapter/webgl-canvas-context.d.ts +4 -6
  90. package/dist/adapter/webgl-canvas-context.d.ts.map +1 -1
  91. package/dist/adapter/webgl-canvas-context.js +13 -17
  92. package/dist/adapter/webgl-canvas-context.js.map +1 -0
  93. package/dist/adapter/webgl-device.d.ts +35 -46
  94. package/dist/adapter/webgl-device.d.ts.map +1 -1
  95. package/dist/adapter/webgl-device.js +100 -156
  96. package/dist/adapter/webgl-device.js.map +1 -0
  97. package/dist/context/debug/spector-types.d.ts +1108 -0
  98. package/dist/context/debug/spector-types.d.ts.map +1 -0
  99. package/dist/context/debug/spector-types.js +698 -0
  100. package/dist/context/debug/spector-types.js.map +1 -0
  101. package/dist/context/debug/spector.d.ts +12 -8
  102. package/dist/context/debug/spector.d.ts.map +1 -1
  103. package/dist/context/debug/spector.js +24 -17
  104. package/dist/context/debug/spector.js.map +1 -0
  105. package/dist/context/debug/webgl-developer-tools.d.ts +2 -3
  106. package/dist/context/debug/webgl-developer-tools.d.ts.map +1 -1
  107. package/dist/context/debug/webgl-developer-tools.js +7 -19
  108. package/dist/context/debug/webgl-developer-tools.js.map +1 -0
  109. package/dist/context/helpers/create-browser-context.d.ts +6 -22
  110. package/dist/context/helpers/create-browser-context.d.ts.map +1 -1
  111. package/dist/context/helpers/create-browser-context.js +41 -32
  112. package/dist/context/helpers/create-browser-context.js.map +1 -0
  113. package/dist/context/helpers/webgl-context-data.js +1 -0
  114. package/dist/context/helpers/webgl-context-data.js.map +1 -0
  115. package/dist/context/helpers/webgl-extensions.js +1 -0
  116. package/dist/context/helpers/webgl-extensions.js.map +1 -0
  117. package/dist/context/parameters/unified-parameter-api.js +1 -0
  118. package/dist/context/parameters/unified-parameter-api.js.map +1 -0
  119. package/dist/context/parameters/webgl-parameter-tables.d.ts +1 -1
  120. package/dist/context/parameters/webgl-parameter-tables.d.ts.map +1 -1
  121. package/dist/context/parameters/webgl-parameter-tables.js +3 -2
  122. package/dist/context/parameters/webgl-parameter-tables.js.map +1 -0
  123. package/dist/context/polyfills/polyfill-webgl1-extensions.d.ts +9 -0
  124. package/dist/context/polyfills/polyfill-webgl1-extensions.d.ts.map +1 -0
  125. package/dist/context/polyfills/polyfill-webgl1-extensions.js +182 -0
  126. package/dist/context/polyfills/polyfill-webgl1-extensions.js.map +1 -0
  127. package/dist/context/state-tracker/deep-array-equal.js +1 -0
  128. package/dist/context/state-tracker/deep-array-equal.js.map +1 -0
  129. package/dist/context/state-tracker/webgl-state-tracker.d.ts +43 -0
  130. package/dist/context/state-tracker/webgl-state-tracker.d.ts.map +1 -0
  131. package/dist/context/state-tracker/{track-context-state.js → webgl-state-tracker.js} +45 -74
  132. package/dist/context/state-tracker/webgl-state-tracker.js.map +1 -0
  133. package/dist/context/state-tracker/with-parameters.d.ts.map +1 -1
  134. package/dist/context/state-tracker/with-parameters.js +6 -4
  135. package/dist/context/state-tracker/with-parameters.js.map +1 -0
  136. package/dist/deprecated/accessor.d.ts.map +1 -0
  137. package/dist/{classic → deprecated}/accessor.js +37 -1
  138. package/dist/deprecated/accessor.js.map +1 -0
  139. package/dist/dist.dev.js +2397 -2430
  140. package/dist/dist.min.js +2 -2
  141. package/dist/index.cjs +2273 -2298
  142. package/dist/index.cjs.map +4 -4
  143. package/dist/index.d.ts +5 -4
  144. package/dist/index.d.ts.map +1 -1
  145. package/dist/index.js +6 -6
  146. package/dist/index.js.map +1 -0
  147. package/dist/types.js +1 -0
  148. package/dist/types.js.map +1 -0
  149. package/dist/utils/fill-array.d.ts +4 -4
  150. package/dist/utils/fill-array.d.ts.map +1 -1
  151. package/dist/utils/fill-array.js +1 -0
  152. package/dist/utils/fill-array.js.map +1 -0
  153. package/dist/utils/load-script.js +1 -0
  154. package/dist/utils/load-script.js.map +1 -0
  155. package/dist/utils/split-uniforms-and-bindings.d.ts +1 -1
  156. package/dist/utils/split-uniforms-and-bindings.d.ts.map +1 -1
  157. package/dist/utils/split-uniforms-and-bindings.js +1 -0
  158. package/dist/utils/split-uniforms-and-bindings.js.map +1 -0
  159. package/dist/utils/uid.d.ts +7 -0
  160. package/dist/utils/uid.d.ts.map +1 -0
  161. package/dist/utils/uid.js +15 -0
  162. package/dist/utils/uid.js.map +1 -0
  163. package/package.json +5 -5
  164. package/src/adapter/converters/device-parameters.ts +21 -15
  165. package/src/adapter/converters/sampler-parameters.ts +6 -4
  166. package/src/adapter/converters/webgl-texture-table.ts +404 -0
  167. package/src/adapter/device-helpers/webgl-device-features.ts +5 -3
  168. package/src/{classic → adapter/helpers}/format-utils.ts +6 -0
  169. package/src/adapter/helpers/get-shader-layout.ts +7 -4
  170. package/src/adapter/helpers/webgl-texture-utils.ts +410 -64
  171. package/src/adapter/resources/webgl-buffer.ts +3 -1
  172. package/src/adapter/resources/webgl-command-buffer.ts +125 -41
  173. package/src/adapter/resources/webgl-command-encoder.ts +6 -0
  174. package/src/adapter/resources/webgl-external-texture.ts +14 -0
  175. package/src/adapter/resources/webgl-framebuffer.ts +80 -86
  176. package/src/adapter/resources/webgl-render-pass.ts +72 -45
  177. package/src/adapter/resources/webgl-render-pipeline.ts +58 -27
  178. package/src/adapter/resources/webgl-shader.ts +15 -7
  179. package/src/adapter/resources/webgl-texture.ts +202 -274
  180. package/src/adapter/webgl-adapter.ts +105 -0
  181. package/src/adapter/webgl-canvas-context.ts +16 -19
  182. package/src/adapter/webgl-device.ts +144 -210
  183. package/src/context/debug/spector-types.ts +1154 -0
  184. package/src/context/debug/spector.ts +38 -29
  185. package/src/context/debug/webgl-developer-tools.ts +8 -31
  186. package/src/context/helpers/create-browser-context.ts +53 -63
  187. package/src/context/parameters/webgl-parameter-tables.ts +2 -2
  188. package/src/context/polyfills/polyfill-webgl1-extensions.ts +202 -0
  189. package/src/context/state-tracker/{track-context-state.ts → webgl-state-tracker.ts} +55 -94
  190. package/src/context/state-tracker/with-parameters.ts +5 -4
  191. package/src/{classic → deprecated}/accessor.ts +44 -3
  192. package/src/index.ts +7 -12
  193. package/src/utils/fill-array.ts +4 -4
  194. package/src/utils/split-uniforms-and-bindings.ts +3 -3
  195. package/src/utils/uid.ts +16 -0
  196. package/dist/adapter/converters/texture-formats.d.ts +0 -83
  197. package/dist/adapter/converters/texture-formats.d.ts.map +0 -1
  198. package/dist/adapter/converters/texture-formats.js +0 -518
  199. package/dist/classic/accessor.d.ts.map +0 -1
  200. package/dist/classic/clear.d.ts +0 -22
  201. package/dist/classic/clear.d.ts.map +0 -1
  202. package/dist/classic/clear.js +0 -86
  203. package/dist/classic/copy-and-blit.d.ts +0 -63
  204. package/dist/classic/copy-and-blit.d.ts.map +0 -1
  205. package/dist/classic/copy-and-blit.js +0 -193
  206. package/dist/classic/format-utils.d.ts.map +0 -1
  207. package/dist/classic/typed-array-utils.d.ts.map +0 -1
  208. package/dist/context/state-tracker/track-context-state.d.ts +0 -22
  209. package/dist/context/state-tracker/track-context-state.d.ts.map +0 -1
  210. package/src/adapter/converters/texture-formats.ts +0 -665
  211. package/src/classic/clear.ts +0 -115
  212. package/src/classic/copy-and-blit.ts +0 -318
  213. /package/dist/{classic → adapter/helpers}/format-utils.d.ts +0 -0
  214. /package/dist/{classic → adapter/helpers}/typed-array-utils.d.ts +0 -0
  215. /package/dist/{classic → deprecated}/accessor.d.ts +0 -0
  216. /package/src/{classic → adapter/helpers}/typed-array-utils.ts +0 -0
@@ -5,54 +5,61 @@
5
5
  import {log} from '@luma.gl/core';
6
6
  import {loadScript} from '../../utils/load-script';
7
7
 
8
+ import type {Spector} from './spector-types';
9
+
8
10
  /** Spector debug initialization options */
9
11
  type SpectorProps = {
12
+ /** Whether spector.js is enabled */
13
+ debugSpectorJS?: boolean;
14
+ /** URL to load spector script from. Typically a CDN URL */
15
+ debugSpectorJSUrl?: string;
10
16
  /** Canvas to monitor */
11
- canvas?: HTMLCanvasElement | OffscreenCanvas;
12
- /** Whether debug is enabled. Auto-detected if ommitted */
13
- debug?: boolean;
14
- /** Whether spector is disabled */
15
- spector?: boolean | string | object;
16
- };
17
-
18
- const DEFAULT_SPECTOR_PROPS: SpectorProps = {
19
- spector: log.get('spector') || log.get('inspect')
17
+ gl?: WebGL2RenderingContext;
20
18
  };
21
19
 
22
- // https://github.com/BabylonJS/Spector.js#basic-usage
23
- const SPECTOR_CDN_URL = 'https://spectorcdn.babylonjs.com/spector.bundle.js';
24
20
  const LOG_LEVEL = 1;
25
21
 
26
- let spector: any = null;
22
+ let spector: Spector = null;
27
23
  let initialized: boolean = false;
28
24
 
29
25
  declare global {
26
+ // @ts-ignore
30
27
  // eslint-disable-next-line no-var
31
- var SPECTOR: any;
28
+ var SPECTOR: Spector;
32
29
  }
33
30
 
31
+ export const DEFAULT_SPECTOR_PROPS: Required<SpectorProps> = {
32
+ debugSpectorJS: log.get('debug-spectorjs'),
33
+ // https://github.com/BabylonJS/Spector.js#basic-usage
34
+ // https://forum.babylonjs.com/t/spectorcdn-is-temporarily-off/48241
35
+ // spectorUrl: 'https://spectorcdn.babylonjs.com/spector.bundle.js';
36
+ debugSpectorJSUrl: 'https://cdn.jsdelivr.net/npm/spectorjs@0.9.30/dist/spector.bundle.js',
37
+ gl: undefined!
38
+ };
39
+
34
40
  /** Loads spector from CDN if not already installed */
35
- export async function loadSpectorJS(props?: SpectorProps) {
41
+ export async function loadSpectorJS(props: {debugSpectorJSUrl?: string}): Promise<void> {
36
42
  if (!globalThis.SPECTOR) {
37
43
  try {
38
- await loadScript(SPECTOR_CDN_URL);
44
+ await loadScript(props.debugSpectorJSUrl || DEFAULT_SPECTOR_PROPS.debugSpectorJSUrl);
39
45
  } catch (error) {
40
46
  log.warn(String(error));
41
47
  }
42
48
  }
43
49
  }
44
50
 
45
- export function initializeSpectorJS(props?: SpectorProps) {
51
+ export function initializeSpectorJS(props: SpectorProps): Spector | null {
46
52
  props = {...DEFAULT_SPECTOR_PROPS, ...props};
47
- if (!props?.spector) {
53
+ if (!props.debugSpectorJS) {
48
54
  return null;
49
55
  }
50
56
 
51
- if (!spector && globalThis.SPECTOR) {
52
- log.probe(LOG_LEVEL, 'SPECTOR found and initialized')();
53
- spector = new globalThis.SPECTOR.Spector();
57
+ if (!spector && globalThis.SPECTOR && !globalThis.luma?.spector) {
58
+ log.probe(LOG_LEVEL, 'SPECTOR found and initialized. Start with `luma.spector.displayUI()`')();
59
+ const {Spector: SpectorJS} = globalThis.SPECTOR as any;
60
+ spector = new SpectorJS();
54
61
  if (globalThis.luma) {
55
- globalThis.luma.spector = spector;
62
+ (globalThis.luma as any).spector = spector;
56
63
  }
57
64
  }
58
65
 
@@ -74,20 +81,22 @@ export function initializeSpectorJS(props?: SpectorProps) {
74
81
  // Use undocumented Spector API to open the UI with our capture
75
82
  // See https://github.com/BabylonJS/Spector.js/blob/767ad1195a25b85a85c381f400eb50a979239eca/src/spector.ts#L124
76
83
  spector?.getResultUI();
84
+ // @ts-expect-error private
77
85
  spector?.resultView.display();
86
+ // @ts-expect-error private
78
87
  spector?.resultView.addCapture(capture);
79
88
  });
80
89
  }
81
90
 
82
- if (props?.canvas) {
83
- // @ts-expect-error If spector is specified as a canvas id, only monitor that canvas
84
- if (typeof props.spector === 'string' && props.spector !== props.canvas.id) {
85
- return spector;
86
- }
87
-
91
+ if (props.gl) {
88
92
  // capture startup
89
- // spector?.captureCanvas(props?.canvas);
90
- spector?.startCapture(props?.canvas, 500); // 500 commands
93
+ const gl = props.gl;
94
+ // @ts-expect-error
95
+ const device = gl.device;
96
+ spector?.startCapture(props.gl, 500); // 500 commands
97
+ // @ts-expect-error
98
+ gl.device = device;
99
+
91
100
  new Promise(resolve => setTimeout(resolve, 2000)).then(_ => {
92
101
  log.info('Spector capture stopped after 2 seconds')();
93
102
  spector?.stopCapture();
@@ -11,18 +11,10 @@ import {loadScript} from '../../utils/load-script';
11
11
  const WEBGL_DEBUG_CDN_URL = 'https://unpkg.com/webgl-debug@2.0.1/index.js';
12
12
 
13
13
  type DebugContextProps = {
14
- debug?: boolean;
15
- throwOnError?: boolean;
16
- break?: string[];
14
+ debugWebGL?: boolean;
15
+ traceWebGL?: boolean;
17
16
  };
18
17
 
19
- // const DEFAULT_DEBUG_CONTEXT_PROPS: Required<DebugContextProps> = {
20
- // debug: true,
21
- // throwOnError: false,
22
- // break: [],
23
- // webgl2: false,
24
- // }
25
-
26
18
  type ContextData = {
27
19
  realContext?: WebGL2RenderingContext;
28
20
  debugContext?: WebGL2RenderingContext;
@@ -60,7 +52,7 @@ export function makeDebugContext(
60
52
  gl: WebGL2RenderingContext,
61
53
  props: DebugContextProps = {}
62
54
  ): WebGL2RenderingContext {
63
- return props.debug ? getDebugContext(gl, props) : getRealContext(gl);
55
+ return props.debugWebGL || props.traceWebGL ? getDebugContext(gl, props) : getRealContext(gl);
64
56
  }
65
57
 
66
58
  // Returns the real context from either of the real/debug contexts
@@ -136,9 +128,7 @@ function onGLError(props: DebugContextProps, err, functionName: string, args: an
136
128
  const message = `${errorMessage} in gl.${functionName}(${functionArgs})`;
137
129
  log.error(message)();
138
130
  debugger; // eslint-disable-line
139
- if (props.throwOnError) {
140
- throw new Error(message);
141
- }
131
+ // throw new Error(message);
142
132
  }
143
133
 
144
134
  // Don't generate function string until it is needed
@@ -150,29 +140,16 @@ function onValidateGLFunc(
150
140
  let functionString: string = '';
151
141
  if (log.level >= 1) {
152
142
  functionString = getFunctionString(functionName, functionArgs);
153
- log.log(1, functionString)();
154
- }
155
-
156
- // If array of breakpoint strings supplied, check if any of them is contained in current GLEnum function
157
- if (props.break && props.break.length > 0) {
158
- functionString = functionString || getFunctionString(functionName, functionArgs);
159
- const isBreakpoint = props.break.every(
160
- (breakOn: string) => functionString.indexOf(breakOn) !== -1
161
- );
162
- if (isBreakpoint) {
163
- debugger; // eslint-disable-line
143
+ if (props.traceWebGL) {
144
+ log.log(1, functionString)();
164
145
  }
165
146
  }
166
147
 
167
148
  for (const arg of functionArgs) {
168
149
  if (arg === undefined) {
169
150
  functionString = functionString || getFunctionString(functionName, functionArgs);
170
- if (props.throwOnError) {
171
- throw new Error(`Undefined argument: ${functionString}`);
172
- } else {
173
- log.error(`Undefined argument: ${functionString}`)();
174
- debugger; // eslint-disable-line
175
- }
151
+ debugger; // eslint-disable-line
152
+ // throw new Error(`Undefined argument: ${functionString}`);
176
153
  }
177
154
  }
178
155
  }
@@ -5,37 +5,13 @@
5
5
  /**
6
6
  * ContextProps
7
7
  * @param onContextLost
8
- * @param onContextRestored
9
- *
10
- * BROWSER CONTEXT PARAMETERS
11
- * @param debug Instrument context (at the expense of performance).
12
- * @param alpha Default render target has an alpha buffer.
13
- * @param depth Default render target has a depth buffer of at least 16 bits.
14
- * @param stencil Default render target has a stencil buffer of at least 8 bits.
15
- * @param antialias Boolean that indicates whether or not to perform anti-aliasing.
16
- * @param premultipliedAlpha Boolean that indicates that the page compositor will assume the drawing buffer contains colors with pre-multiplied alpha.
17
- * @param preserveDrawingBuffer Default render target buffers will not be automatically cleared and will preserve their values until cleared or overwritten
18
- * @param failIfMajorPerformanceCaveat Do not create if the system performance is low.
8
+ * @param onContextRestored *
19
9
  */
20
10
  type ContextProps = {
21
- onContextLost?: (event: Event) => void;
22
- onContextRestored?: (event: Event) => void;
23
- alpha?: boolean; // indicates if the canvas contains an alpha buffer.
24
- desynchronized?: boolean; // hints the user agent to reduce the latency by desynchronizing the canvas paint cycle from the event loop
25
- antialias?: boolean; // indicates whether or not to perform anti-aliasing.
26
- depth?: boolean; // indicates that the drawing buffer has a depth buffer of at least 16 bits.
27
- failIfMajorPerformanceCaveat?: boolean; // indicates if a context will be created if the system performance is low or if no hardware GPU is available.
28
- powerPreference?: 'default' | 'high-performance' | 'low-power';
29
- premultipliedAlpha?: boolean; // page compositor will assume the drawing buffer contains colors with pre-multiplied alpha.
30
- preserveDrawingBuffer?: boolean; // buffers will not be cleared and will preserve their values until cleared or overwritten by the author.
31
- };
32
-
33
- const DEFAULT_CONTEXT_PROPS: ContextProps = {
34
- powerPreference: 'high-performance', // After all, most apps are using WebGL for performance reasons
35
- // eslint-disable-next-line no-console
36
- onContextLost: () => console.error('WebGL context lost'),
37
- // eslint-disable-next-line no-console
38
- onContextRestored: () => console.info('WebGL context restored')
11
+ /** Called when a context is lost */
12
+ onContextLost: (event: Event) => void;
13
+ /** Called when a context is restored */
14
+ onContextRestored: (event: Event) => void;
39
15
  };
40
16
 
41
17
  /**
@@ -45,53 +21,67 @@ const DEFAULT_CONTEXT_PROPS: ContextProps = {
45
21
  */
46
22
  export function createBrowserContext(
47
23
  canvas: HTMLCanvasElement | OffscreenCanvas,
48
- props: ContextProps
24
+ props: ContextProps,
25
+ webglContextAttributes: WebGLContextAttributes
49
26
  ): WebGL2RenderingContext {
50
- props = {...DEFAULT_CONTEXT_PROPS, ...props};
51
-
52
27
  // Try to extract any extra information about why context creation failed
53
- let errorMessage = null;
54
- const onCreateError = error => (errorMessage = error.statusMessage || errorMessage);
55
- canvas.addEventListener('webglcontextcreationerror', onCreateError, false);
56
-
57
- // Create the desired context
58
- let gl: WebGL2RenderingContext | null = null;
28
+ let errorMessage = '';
29
+ // const onCreateError = error => (errorMessage = error.statusMessage || errorMessage);
59
30
 
60
- // props.failIfMajorPerformanceCaveat = true;
31
+ // Avoid multiple listeners?
32
+ // canvas.removeEventListener('webglcontextcreationerror', onCreateError, false);
33
+ // canvas.addEventListener('webglcontextcreationerror', onCreateError, false);
61
34
 
62
- // We require webgl2 context
63
- gl ||= canvas.getContext('webgl2', props) as WebGL2RenderingContext;
35
+ const webglProps: WebGLContextAttributes = {
36
+ preserveDrawingBuffer: true,
37
+ // failIfMajorPerformanceCaveat: true,
38
+ ...webglContextAttributes
39
+ };
64
40
 
65
- // Software GPU
66
-
67
- // props.failIfMajorPerformanceCaveat = false;
41
+ // Create the desired context
42
+ let gl: WebGL2RenderingContext | null = null;
68
43
 
69
- // if (!gl && props.webgl1) {
70
- // gl = canvas.getContext('webgl', props);
71
- // }
44
+ // Create a webgl2 context
45
+ gl ||= canvas.getContext('webgl2', webglProps);
46
+ if (webglProps.failIfMajorPerformanceCaveat) {
47
+ errorMessage ||=
48
+ 'Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow.';
49
+ }
72
50
 
73
- // TODO are we removing this listener before giving it a chance to fire?
74
- canvas.removeEventListener('webglcontextcreationerror', onCreateError, false);
51
+ // Creation failed with failIfMajorPerformanceCaveat - Try a Software GPU
52
+ if (!gl && !webglContextAttributes.failIfMajorPerformanceCaveat) {
53
+ webglProps.failIfMajorPerformanceCaveat = false;
54
+ gl = canvas.getContext('webgl2', webglProps);
55
+ // @ts-expect-error
56
+ gl.luma ||= {};
57
+ // @ts-expect-error
58
+ gl.luma.softwareRenderer = true;
59
+ }
75
60
 
76
61
  if (!gl) {
77
- throw new Error(`Failed to create WebGL context: ${errorMessage || 'Unknown error'}`);
62
+ gl = canvas.getContext('webgl', {}) as WebGL2RenderingContext;
63
+ if (gl) {
64
+ gl = null;
65
+ errorMessage ||= 'Your browser only supports WebGL1';
66
+ }
78
67
  }
79
68
 
80
- if (props.onContextLost) {
81
- // Carefully extract and wrap callbacks to prevent addEventListener from rebinding them.
82
- const {onContextLost} = props;
83
- canvas.addEventListener('webglcontextlost', (event: Event) => onContextLost(event), false);
84
- }
85
- if (props.onContextRestored) {
86
- // Carefully extract and wrap callbacks to prevent addEventListener from rebinding them.
87
- const {onContextRestored} = props;
88
- canvas.addEventListener(
89
- 'webglcontextrestored',
90
- (event: Event) => onContextRestored(event),
91
- false
92
- );
69
+ if (!gl) {
70
+ errorMessage ||= 'Your browser does not support WebGL';
71
+ throw new Error(`Failed to create WebGL context: ${errorMessage}`);
93
72
  }
94
73
 
74
+ // Carefully extract and wrap callbacks to prevent addEventListener from rebinding them.
75
+ const {onContextLost, onContextRestored} = props;
76
+ canvas.addEventListener('webglcontextlost', (event: Event) => onContextLost(event), false);
77
+ canvas.addEventListener(
78
+ 'webglcontextrestored',
79
+ (event: Event) => onContextRestored(event),
80
+ false
81
+ );
82
+
83
+ // @ts-expect-error
84
+ gl.luma ||= {};
95
85
  return gl;
96
86
  }
97
87
 
@@ -412,9 +412,9 @@ export const GL_HOOKED_SETTERS = {
412
412
  update({
413
413
  [pname]: value
414
414
  }),
415
- hint: (update: UpdateFunc, pname: GL, hint: GL) =>
415
+ hint: (update: UpdateFunc, pname: GL, value: GL) =>
416
416
  update({
417
- [pname]: hint
417
+ [pname]: value
418
418
  }),
419
419
 
420
420
  // SPECIFIC SETTERS
@@ -0,0 +1,202 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ // Goal is to make WebGL2 contexts look like WebGL1
6
+ // @note Partly inspired by with some older code from the `regl` library
7
+
8
+ /* eslint-disable camelcase */
9
+
10
+ import {GL} from '@luma.gl/constants';
11
+
12
+ // webgl1 extensions natively supported by webgl2
13
+ const WEBGL1_STATIC_EXTENSIONS = {
14
+ WEBGL_depth_texture: {
15
+ UNSIGNED_INT_24_8_WEBGL: GL.UNSIGNED_INT_24_8
16
+ } as const satisfies WEBGL_depth_texture,
17
+ OES_element_index_uint: {} as const satisfies OES_element_index_uint,
18
+ OES_texture_float: {} as const satisfies OES_texture_float,
19
+ OES_texture_half_float: {
20
+ // @ts-expect-error different numbers?
21
+ HALF_FLOAT_OES: GL.HALF_FLOAT
22
+ } as const satisfies OES_texture_half_float,
23
+ EXT_color_buffer_float: {} as const satisfies EXT_color_buffer_float,
24
+ OES_standard_derivatives: {
25
+ FRAGMENT_SHADER_DERIVATIVE_HINT_OES: GL.FRAGMENT_SHADER_DERIVATIVE_HINT
26
+ } as const satisfies OES_standard_derivatives,
27
+ EXT_frag_depth: {} as const satisfies EXT_frag_depth,
28
+ EXT_blend_minmax: {
29
+ MIN_EXT: GL.MIN,
30
+ MAX_EXT: GL.MAX
31
+ } as const satisfies EXT_blend_minmax,
32
+ EXT_shader_texture_lod: {} as const satisfies EXT_shader_texture_lod
33
+ };
34
+
35
+ const getWEBGL_draw_buffers = (gl: WebGL2RenderingContext) =>
36
+ ({
37
+ drawBuffersWEBGL(buffers: number[]) {
38
+ return gl.drawBuffers(buffers);
39
+ },
40
+ COLOR_ATTACHMENT0_WEBGL: GL.COLOR_ATTACHMENT0,
41
+ COLOR_ATTACHMENT1_WEBGL: GL.COLOR_ATTACHMENT1,
42
+ COLOR_ATTACHMENT2_WEBGL: GL.COLOR_ATTACHMENT2,
43
+ COLOR_ATTACHMENT3_WEBGL: GL.COLOR_ATTACHMENT3
44
+ }) as const satisfies Partial<WEBGL_draw_buffers>; // - too many fields
45
+
46
+ const getOES_vertex_array_object = (gl: WebGL2RenderingContext) =>
47
+ ({
48
+ VERTEX_ARRAY_BINDING_OES: GL.VERTEX_ARRAY_BINDING,
49
+ createVertexArrayOES() {
50
+ return gl.createVertexArray();
51
+ },
52
+ deleteVertexArrayOES(vertexArray: WebGLVertexArrayObject): void {
53
+ return gl.deleteVertexArray(vertexArray);
54
+ },
55
+ isVertexArrayOES(vertexArray: WebGLVertexArrayObject): boolean {
56
+ return gl.isVertexArray(vertexArray);
57
+ },
58
+ bindVertexArrayOES(vertexArray: WebGLVertexArrayObject): void {
59
+ return gl.bindVertexArray(vertexArray);
60
+ }
61
+ }) as const satisfies OES_vertex_array_object;
62
+
63
+ const getANGLE_instanced_arrays = (gl: WebGL2RenderingContext) =>
64
+ ({
65
+ VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: 0x88fe,
66
+ drawArraysInstancedANGLE(...args) {
67
+ return gl.drawArraysInstanced(...args);
68
+ },
69
+ drawElementsInstancedANGLE(...args) {
70
+ return gl.drawElementsInstanced(...args);
71
+ },
72
+ vertexAttribDivisorANGLE(...args) {
73
+ return gl.vertexAttribDivisor(...args);
74
+ }
75
+ }) as const satisfies ANGLE_instanced_arrays;
76
+
77
+ /**
78
+ * Make browser return WebGL2 contexts even if WebGL1 contexts are requested
79
+ * @param enforce
80
+ * @returns
81
+ */
82
+ export function enforceWebGL2(enforce: boolean = true): void {
83
+ const prototype = HTMLCanvasElement.prototype as any;
84
+ if (!enforce && prototype.originalGetContext) {
85
+ // Reset the original getContext function
86
+ prototype.getContext = prototype.originalGetContext;
87
+ prototype.originalGetContext = undefined;
88
+ return;
89
+ }
90
+
91
+ // Store the original getContext function
92
+ prototype.originalGetContext = prototype.getContext;
93
+
94
+ // Override the getContext function
95
+ prototype.getContext = function (contextId: string, options?: WebGLContextAttributes) {
96
+ // Attempt to force WebGL2 for all WebGL1 contexts
97
+ if (contextId === 'webgl' || contextId === 'experimental-webgl') {
98
+ const context = this.originalGetContext('webgl2', options) as WebGL2RenderingContext;
99
+ // Work around test mocking
100
+ if (context instanceof HTMLElement) {
101
+ polyfillWebGL1Extensions(context);
102
+ }
103
+ return context;
104
+ }
105
+ // For any other type, return the original context
106
+ return this.originalGetContext(contextId, options);
107
+ };
108
+ }
109
+
110
+ /** Install WebGL1-only extensions on WebGL2 contexts */
111
+ export function polyfillWebGL1Extensions(gl: WebGL2RenderingContext): void {
112
+ // Enable, to support float and half-float textures
113
+ gl.getExtension('EXT_color_buffer_float');
114
+
115
+ // WebGL1 extensions implemented using WebGL2 APIs
116
+ const boundExtensions = {
117
+ ...WEBGL1_STATIC_EXTENSIONS,
118
+ WEBGL_disjoint_timer_query: gl.getExtension('EXT_disjoint_timer_query_webgl2'),
119
+ WEBGL_draw_buffers: getWEBGL_draw_buffers(gl),
120
+ OES_vertex_array_object: getOES_vertex_array_object(gl),
121
+ ANGLE_instanced_arrays: getANGLE_instanced_arrays(gl)
122
+ };
123
+
124
+ // Override gl.getExtension
125
+ // eslint-disable-next-line @typescript-eslint/unbound-method
126
+ const originalGetExtension = gl.getExtension;
127
+ gl.getExtension = function (extensionName: string) {
128
+ const ext = originalGetExtension.call(gl, extensionName);
129
+ if (ext) {
130
+ return ext;
131
+ }
132
+
133
+ // Injected extensions
134
+ if (extensionName in boundExtensions) {
135
+ return boundExtensions[extensionName];
136
+ }
137
+
138
+ return null;
139
+ };
140
+
141
+ // Override gl.getSupportedExtensions
142
+ // eslint-disable-next-line @typescript-eslint/unbound-method
143
+ const originalGetSupportedExtensions = gl.getSupportedExtensions;
144
+ gl.getSupportedExtensions = function (): string[] | null {
145
+ const extensions = originalGetSupportedExtensions.apply(gl) || [];
146
+ return extensions?.concat(Object.keys(boundExtensions));
147
+ };
148
+ }
149
+
150
+ // Update unsized WebGL1 formats to sized WebGL2 formats
151
+ // todo move to texture format file
152
+ // export function getInternalFormat(gl: WebGL2RenderingContext, format: GL, type: GL): GL {
153
+ // // webgl2 texture formats
154
+ // // https://webgl2fundamentals.org/webgl/lessons/webgl-data-textures.html
155
+ // switch (format) {
156
+ // case GL.DEPTH_COMPONENT:
157
+ // return GL.DEPTH_COMPONENT24;
158
+ // case GL.DEPTH_STENCIL:
159
+ // return GL.DEPTH24_STENCIL8;
160
+ // case GL.RGBA:
161
+ // return type === GL.HALF_FLOAT ? GL.RGBA16F : GL.RGBA32F;
162
+ // case GL.RGB:
163
+ // return type === GL.HALF_FLOAT ? GL.RGB16F : GL.RGB32F;
164
+ // default:
165
+ // return format;
166
+ // }
167
+ // }
168
+
169
+ /*
170
+ // texture type to update on the fly
171
+ export function getTextureType(gl: WebGL2RenderingContext, type: GL): GL {
172
+ if (type === HALF_FLOAT_OES) {
173
+ return GL.HALF_FLOAT;
174
+ }
175
+ return type;
176
+ }
177
+
178
+ // And texImage2D to convert the internalFormat to webgl2.
179
+ const webgl2 = this;
180
+ const origTexImage = gl.texImage2D;
181
+ gl.texImage2D = function (target, miplevel, iformat, a, typeFor6, c, d, typeFor9, f) {
182
+ if (arguments.length == 6) {
183
+ var ifmt = webgl2.getInternalFormat(gl, iformat, typeFor6);
184
+ origTexImage.apply(gl, [target, miplevel, ifmt, a, webgl.getTextureType(gl, typeFor6), c]);
185
+ } else {
186
+ // arguments.length == 9
187
+ var ifmt = webgl2.getInternalFormat(gl, iformat, typeFor9);
188
+ origTexImage.apply(gl, [
189
+ target,
190
+ miplevel,
191
+ ifmt,
192
+ a,
193
+ typeFor6,
194
+ c,
195
+ d,
196
+ webgl2.getTextureType(gl, typeFor9),
197
+ f
198
+ ]);
199
+ }
200
+ };
201
+ };
202
+ */