@luma.gl/webgl 9.1.0-alpha.1 → 9.1.0-alpha.12
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.
- package/dist/adapter/converters/device-parameters.d.ts.map +1 -1
- package/dist/adapter/converters/device-parameters.js +18 -11
- package/dist/adapter/converters/texture-formats.d.ts +1 -1
- package/dist/adapter/converters/texture-formats.d.ts.map +1 -1
- package/dist/adapter/converters/texture-formats.js +9 -16
- package/dist/adapter/device-helpers/webgl-device-features.d.ts.map +1 -1
- package/dist/adapter/device-helpers/webgl-device-features.js +1 -3
- package/dist/adapter/helpers/format-utils.d.ts.map +1 -0
- package/dist/adapter/helpers/get-shader-layout.d.ts.map +1 -1
- package/dist/adapter/helpers/get-shader-layout.js +1 -3
- package/dist/adapter/helpers/typed-array-utils.d.ts.map +1 -0
- package/dist/adapter/helpers/webgl-texture-utils.d.ts +89 -22
- package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
- package/dist/adapter/helpers/webgl-texture-utils.js +220 -26
- package/dist/adapter/resources/webgl-framebuffer.js +1 -1
- package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.js +17 -4
- package/dist/adapter/resources/webgl-render-pipeline.d.ts +1 -3
- package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.js +1 -1
- package/dist/adapter/resources/webgl-shader.js +1 -1
- package/dist/adapter/resources/webgl-texture.d.ts +21 -3
- package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-texture.js +49 -30
- package/dist/adapter/resources/webgl-transform-feedback.js +1 -1
- package/dist/adapter/resources/webgl-vertex-array.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-vertex-array.js +3 -0
- package/dist/adapter/webgl-adapter.d.ts +21 -0
- package/dist/adapter/webgl-adapter.d.ts.map +1 -0
- package/dist/adapter/webgl-adapter.js +91 -0
- package/dist/adapter/webgl-device.d.ts +16 -29
- package/dist/adapter/webgl-device.d.ts.map +1 -1
- package/dist/adapter/webgl-device.js +34 -114
- package/dist/context/debug/spector-types.d.ts +1108 -0
- package/dist/context/debug/spector-types.d.ts.map +1 -0
- package/dist/context/debug/spector-types.js +697 -0
- package/dist/context/debug/spector.d.ts +12 -8
- package/dist/context/debug/spector.d.ts.map +1 -1
- package/dist/context/debug/spector.js +23 -17
- package/dist/context/polyfills/polyfill-webgl1-extensions.d.ts +9 -0
- package/dist/context/polyfills/polyfill-webgl1-extensions.d.ts.map +1 -0
- package/dist/context/polyfills/polyfill-webgl1-extensions.js +181 -0
- package/dist/context/state-tracker/webgl-state-tracker.d.ts +43 -0
- package/dist/context/state-tracker/webgl-state-tracker.d.ts.map +1 -0
- package/dist/context/state-tracker/{track-context-state.js → webgl-state-tracker.js} +44 -74
- package/dist/context/state-tracker/with-parameters.d.ts.map +1 -1
- package/dist/context/state-tracker/with-parameters.js +5 -4
- package/dist/deprecated/accessor.d.ts.map +1 -0
- package/dist/{classic → deprecated}/accessor.js +36 -1
- package/dist/deprecated/clear.d.ts.map +1 -0
- package/dist/{classic → deprecated}/clear.js +2 -0
- package/dist/dist.dev.js +816 -642
- package/dist/dist.min.js +2 -2
- package/dist/index.cjs +815 -648
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/utils/fill-array.d.ts +4 -4
- package/dist/utils/fill-array.d.ts.map +1 -1
- package/dist/utils/split-uniforms-and-bindings.d.ts +1 -1
- package/dist/utils/split-uniforms-and-bindings.d.ts.map +1 -1
- package/dist/utils/uid.d.ts +7 -0
- package/dist/utils/uid.d.ts.map +1 -0
- package/dist/utils/uid.js +14 -0
- package/package.json +5 -5
- package/src/adapter/converters/device-parameters.ts +18 -12
- package/src/adapter/converters/texture-formats.ts +12 -20
- package/src/adapter/device-helpers/webgl-device-features.ts +5 -3
- package/src/adapter/helpers/get-shader-layout.ts +1 -3
- package/src/adapter/helpers/webgl-texture-utils.ts +366 -44
- package/src/adapter/resources/webgl-framebuffer.ts +1 -1
- package/src/adapter/resources/webgl-render-pass.ts +20 -7
- package/src/adapter/resources/webgl-render-pipeline.ts +12 -4
- package/src/adapter/resources/webgl-shader.ts +1 -1
- package/src/adapter/resources/webgl-texture.ts +76 -30
- package/src/adapter/resources/webgl-transform-feedback.ts +1 -1
- package/src/adapter/resources/webgl-vertex-array.ts +3 -0
- package/src/adapter/webgl-adapter.ts +113 -0
- package/src/adapter/webgl-device.ts +45 -139
- package/src/context/debug/spector-types.ts +1154 -0
- package/src/context/debug/spector.ts +38 -29
- package/src/context/polyfills/polyfill-webgl1-extensions.ts +202 -0
- package/src/context/state-tracker/{track-context-state.ts → webgl-state-tracker.ts} +55 -94
- package/src/context/state-tracker/with-parameters.ts +5 -4
- package/src/{classic → deprecated}/accessor.ts +44 -3
- package/src/{classic → deprecated}/clear.ts +3 -1
- package/src/index.ts +6 -8
- package/src/utils/fill-array.ts +4 -4
- package/src/utils/split-uniforms-and-bindings.ts +3 -3
- package/src/utils/uid.ts +16 -0
- package/dist/classic/accessor.d.ts.map +0 -1
- package/dist/classic/clear.d.ts.map +0 -1
- package/dist/classic/copy-and-blit.d.ts +0 -63
- package/dist/classic/copy-and-blit.d.ts.map +0 -1
- package/dist/classic/copy-and-blit.js +0 -193
- package/dist/classic/format-utils.d.ts.map +0 -1
- package/dist/classic/typed-array-utils.d.ts.map +0 -1
- package/dist/context/state-tracker/track-context-state.d.ts +0 -22
- package/dist/context/state-tracker/track-context-state.d.ts.map +0 -1
- package/src/classic/copy-and-blit.ts +0 -318
- /package/dist/{classic → adapter/helpers}/format-utils.d.ts +0 -0
- /package/dist/{classic → adapter/helpers}/format-utils.js +0 -0
- /package/dist/{classic → adapter/helpers}/typed-array-utils.d.ts +0 -0
- /package/dist/{classic → adapter/helpers}/typed-array-utils.js +0 -0
- /package/dist/{classic → deprecated}/accessor.d.ts +0 -0
- /package/dist/{classic → deprecated}/clear.d.ts +0 -0
- /package/src/{classic → adapter/helpers}/format-utils.ts +0 -0
- /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 {Spector} from './spector-types';
|
|
9
|
+
|
|
8
10
|
/** Spector debug initialization options */
|
|
9
11
|
type SpectorProps = {
|
|
12
|
+
/** Whether spector is enabled */
|
|
13
|
+
debugWithSpectorJS?: boolean;
|
|
14
|
+
/** URL to load spector script from. Typically a CDN URL */
|
|
15
|
+
spectorUrl?: string;
|
|
10
16
|
/** Canvas to monitor */
|
|
11
|
-
|
|
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:
|
|
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:
|
|
28
|
+
var SPECTOR: Spector;
|
|
32
29
|
}
|
|
33
30
|
|
|
31
|
+
export const DEFAULT_SPECTOR_PROPS: Required<SpectorProps> = {
|
|
32
|
+
debugWithSpectorJS: log.get('spector') || log.get('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
|
+
spectorUrl: '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?:
|
|
41
|
+
export async function loadSpectorJS(props: {spectorUrl?: string}): Promise<void> {
|
|
36
42
|
if (!globalThis.SPECTOR) {
|
|
37
43
|
try {
|
|
38
|
-
await loadScript(
|
|
44
|
+
await loadScript(props.spectorUrl || DEFAULT_SPECTOR_PROPS.spectorUrl);
|
|
39
45
|
} catch (error) {
|
|
40
46
|
log.warn(String(error));
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
}
|
|
44
50
|
|
|
45
|
-
export function initializeSpectorJS(props
|
|
51
|
+
export function initializeSpectorJS(props: SpectorProps): Spector | null {
|
|
46
52
|
props = {...DEFAULT_SPECTOR_PROPS, ...props};
|
|
47
|
-
if (!props
|
|
53
|
+
if (!props.debugWithSpectorJS) {
|
|
48
54
|
return null;
|
|
49
55
|
}
|
|
50
56
|
|
|
51
|
-
if (!spector && globalThis.SPECTOR) {
|
|
52
|
-
log.probe(LOG_LEVEL, 'SPECTOR found and initialized')();
|
|
53
|
-
|
|
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} = globalThis.SPECTOR as any;
|
|
60
|
+
spector = new Spector();
|
|
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
|
|
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
|
-
|
|
90
|
-
|
|
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();
|
|
@@ -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
|
+
*/
|
|
@@ -2,37 +2,43 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import {setGLParameters, getGLParameters} from '../parameters/unified-parameter-api';
|
|
6
|
+
import {deepArrayEqual} from './deep-array-equal';
|
|
7
7
|
import {
|
|
8
8
|
GL_PARAMETER_DEFAULTS,
|
|
9
9
|
GL_HOOKED_SETTERS,
|
|
10
10
|
NON_CACHE_PARAMETERS
|
|
11
11
|
} from '../parameters/webgl-parameter-tables';
|
|
12
|
-
import {setGLParameters, getGLParameters} from '../parameters/unified-parameter-api';
|
|
13
|
-
import {deepArrayEqual} from './deep-array-equal';
|
|
14
12
|
|
|
15
|
-
// HELPER CLASS -
|
|
13
|
+
// HELPER CLASS - WebGLStateTracker
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Support for listening to context state changes and intercepting state queries
|
|
17
|
+
* NOTE: this system does not handle buffer bindings
|
|
18
|
+
*/
|
|
19
|
+
export class WebGLStateTracker {
|
|
20
|
+
static get(gl: WebGL2RenderingContext): WebGLStateTracker {
|
|
21
|
+
// @ts-expect-error
|
|
22
|
+
return gl.state as WebGLStateTracker;
|
|
23
|
+
}
|
|
16
24
|
|
|
17
|
-
/* eslint-disable no-shadow */
|
|
18
|
-
class GLState {
|
|
19
25
|
gl: WebGL2RenderingContext;
|
|
20
26
|
program: unknown = null;
|
|
21
27
|
stateStack: object[] = [];
|
|
22
28
|
enable = true;
|
|
23
|
-
cache: Record<string, any
|
|
29
|
+
cache: Record<string, any> = null!;
|
|
24
30
|
log;
|
|
25
31
|
|
|
32
|
+
protected initialized = false;
|
|
33
|
+
|
|
26
34
|
constructor(
|
|
27
35
|
gl: WebGL2RenderingContext,
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} = {}
|
|
36
|
+
props?: {
|
|
37
|
+
log; // Logging function, called when gl parameter change calls are actually issued
|
|
38
|
+
}
|
|
32
39
|
) {
|
|
33
40
|
this.gl = gl;
|
|
34
|
-
this.
|
|
35
|
-
this.log = log;
|
|
41
|
+
this.log = props?.log || (() => {});
|
|
36
42
|
|
|
37
43
|
this._updateCache = this._updateCache.bind(this);
|
|
38
44
|
Object.seal(this);
|
|
@@ -51,6 +57,38 @@ class GLState {
|
|
|
51
57
|
this.stateStack.pop();
|
|
52
58
|
}
|
|
53
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Initialize WebGL state caching on a context
|
|
62
|
+
* can be called multiple times to enable/disable
|
|
63
|
+
*
|
|
64
|
+
* @note After calling this function, context state will be cached
|
|
65
|
+
* .push() and .pop() will be available for saving,
|
|
66
|
+
* temporarily modifying, and then restoring state.
|
|
67
|
+
*/
|
|
68
|
+
trackState(gl: WebGL2RenderingContext, options?: {copyState?: boolean}): void {
|
|
69
|
+
this.cache = options.copyState ? getGLParameters(gl) : Object.assign({}, GL_PARAMETER_DEFAULTS);
|
|
70
|
+
|
|
71
|
+
if (this.initialized) {
|
|
72
|
+
throw new Error('WebGLStateTracker');
|
|
73
|
+
}
|
|
74
|
+
this.initialized = true;
|
|
75
|
+
|
|
76
|
+
// @ts-expect-error
|
|
77
|
+
this.gl.state = this;
|
|
78
|
+
|
|
79
|
+
installProgramSpy(gl);
|
|
80
|
+
|
|
81
|
+
// intercept all setter functions in the table
|
|
82
|
+
for (const key in GL_HOOKED_SETTERS) {
|
|
83
|
+
const setter = GL_HOOKED_SETTERS[key];
|
|
84
|
+
installSetterSpy(gl, key, setter);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// intercept all getter functions in the table
|
|
88
|
+
installGetterOverride(gl, 'getParameter');
|
|
89
|
+
installGetterOverride(gl, 'isEnabled');
|
|
90
|
+
}
|
|
91
|
+
|
|
54
92
|
/**
|
|
55
93
|
// interceptor for context set functions - update our cache and our stack
|
|
56
94
|
// values (Object) - the key values for this setter
|
|
@@ -89,83 +127,6 @@ class GLState {
|
|
|
89
127
|
}
|
|
90
128
|
}
|
|
91
129
|
|
|
92
|
-
function getContextState(gl: WebGL2RenderingContext): GLState {
|
|
93
|
-
// @ts-expect-error
|
|
94
|
-
return gl.state as GLState;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// PUBLIC API
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Initialize WebGL state caching on a context
|
|
101
|
-
* can be called multiple times to enable/disable
|
|
102
|
-
*
|
|
103
|
-
* @note After calling this function, context state will be cached
|
|
104
|
-
* gl.state.push() and gl.state.pop() will be available for saving,
|
|
105
|
-
* temporarily modifying, and then restoring state.
|
|
106
|
-
*/
|
|
107
|
-
export function trackContextState(
|
|
108
|
-
gl: WebGL2RenderingContext,
|
|
109
|
-
options?: {
|
|
110
|
-
enable?: boolean;
|
|
111
|
-
copyState?: boolean;
|
|
112
|
-
log?: any;
|
|
113
|
-
}
|
|
114
|
-
): WebGL2RenderingContext {
|
|
115
|
-
const {enable = true, copyState} = options || {};
|
|
116
|
-
// assert(copyState !== undefined);
|
|
117
|
-
// @ts-expect-error
|
|
118
|
-
if (!gl.state) {
|
|
119
|
-
// @ts-ignore
|
|
120
|
-
// const {polyfillContext} = global_;
|
|
121
|
-
// if (polyfillContext) {
|
|
122
|
-
// polyfillContext(gl);
|
|
123
|
-
// }
|
|
124
|
-
|
|
125
|
-
// Create a state cache
|
|
126
|
-
// @ts-expect-error
|
|
127
|
-
gl.state = new GLState(gl, {copyState});
|
|
128
|
-
|
|
129
|
-
installProgramSpy(gl);
|
|
130
|
-
|
|
131
|
-
// intercept all setter functions in the table
|
|
132
|
-
for (const key in GL_HOOKED_SETTERS) {
|
|
133
|
-
const setter = GL_HOOKED_SETTERS[key];
|
|
134
|
-
installSetterSpy(gl, key, setter);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// intercept all getter functions in the table
|
|
138
|
-
installGetterOverride(gl, 'getParameter');
|
|
139
|
-
installGetterOverride(gl, 'isEnabled');
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const glState = getContextState(gl);
|
|
143
|
-
glState.enable = enable;
|
|
144
|
-
|
|
145
|
-
return gl;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Saves current WebGL context state onto an internal per-context stack
|
|
150
|
-
*/
|
|
151
|
-
export function pushContextState(gl: WebGL2RenderingContext): void {
|
|
152
|
-
let glState = getContextState(gl);
|
|
153
|
-
if (!glState) {
|
|
154
|
-
trackContextState(gl, {copyState: false});
|
|
155
|
-
glState = getContextState(gl);
|
|
156
|
-
}
|
|
157
|
-
glState.push();
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Restores previously saved WebGL context state
|
|
162
|
-
*/
|
|
163
|
-
export function popContextState(gl: WebGL2RenderingContext): void {
|
|
164
|
-
const glState = getContextState(gl);
|
|
165
|
-
// assert(glState);
|
|
166
|
-
glState.pop();
|
|
167
|
-
}
|
|
168
|
-
|
|
169
130
|
// HELPER FUNCTIONS - INSTALL GET/SET INTERCEPTORS (SPYS) ON THE CONTEXT
|
|
170
131
|
|
|
171
132
|
/**
|
|
@@ -185,7 +146,7 @@ function installGetterOverride(gl: WebGL2RenderingContext, functionName: string)
|
|
|
185
146
|
return originalGetterFunc(pname);
|
|
186
147
|
}
|
|
187
148
|
|
|
188
|
-
const glState =
|
|
149
|
+
const glState = WebGLStateTracker.get(gl);
|
|
189
150
|
if (!(pname in glState.cache)) {
|
|
190
151
|
// WebGL limits are not prepopulated in the cache, call the original getter when first queried.
|
|
191
152
|
glState.cache[pname] = originalGetterFunc(pname);
|
|
@@ -229,7 +190,7 @@ function installSetterSpy(gl: WebGL2RenderingContext, functionName: string, sett
|
|
|
229
190
|
gl[functionName] = function set(...params) {
|
|
230
191
|
// Update the value
|
|
231
192
|
// Call the setter with the state cache and the params so that it can store the parameters
|
|
232
|
-
const glState =
|
|
193
|
+
const glState = WebGLStateTracker.get(gl);
|
|
233
194
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
234
195
|
const {valueChanged, oldValue} = setter(glState._updateCache, ...params);
|
|
235
196
|
|
|
@@ -257,7 +218,7 @@ function installProgramSpy(gl: WebGL2RenderingContext): void {
|
|
|
257
218
|
const originalUseProgram = gl.useProgram.bind(gl);
|
|
258
219
|
|
|
259
220
|
gl.useProgram = function useProgramLuma(handle) {
|
|
260
|
-
const glState =
|
|
221
|
+
const glState = WebGLStateTracker.get(gl);
|
|
261
222
|
if (glState.program !== handle) {
|
|
262
223
|
originalUseProgram(handle);
|
|
263
224
|
glState.program = handle;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
import {GLParameters, setGLParameters} from '../parameters/unified-parameter-api';
|
|
6
|
-
import {
|
|
6
|
+
import {WebGLStateTracker} from './webgl-state-tracker';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Execute a function with a set of temporary WebGL parameter overrides
|
|
@@ -25,7 +25,8 @@ export function withGLParameters(
|
|
|
25
25
|
|
|
26
26
|
const {nocatch = true} = parameters;
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
const webglState = WebGLStateTracker.get(gl);
|
|
29
|
+
webglState.push();
|
|
29
30
|
setGLParameters(gl, parameters);
|
|
30
31
|
|
|
31
32
|
// Setup is done, call the function
|
|
@@ -34,13 +35,13 @@ export function withGLParameters(
|
|
|
34
35
|
if (nocatch) {
|
|
35
36
|
// Avoid try catch to minimize stack size impact for safe execution paths
|
|
36
37
|
value = func(gl);
|
|
37
|
-
|
|
38
|
+
webglState.pop();
|
|
38
39
|
} else {
|
|
39
40
|
// Wrap in a try-catch to ensure that parameters are restored on exceptions
|
|
40
41
|
try {
|
|
41
42
|
value = func(gl);
|
|
42
43
|
} finally {
|
|
43
|
-
|
|
44
|
+
webglState.pop();
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import {Buffer} from '@luma.gl/core';
|
|
6
|
-
import {GL} from '@luma.gl/constants';
|
|
7
|
-
import {
|
|
5
|
+
import {Buffer, log} from '@luma.gl/core';
|
|
6
|
+
import {GL, GLDataType, GLPixelType} from '@luma.gl/constants';
|
|
7
|
+
import {TypedArrayConstructor} from '@math.gl/types';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Attribute descriptor object
|
|
@@ -81,6 +81,7 @@ export class Accessor implements AccessorObject {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
constructor(...accessors: AccessorObject[]) {
|
|
84
|
+
log.warn('Accessor will be removed in next minor release');
|
|
84
85
|
accessors.forEach(accessor => this._assign(accessor)); // Merge in sequence
|
|
85
86
|
Object.freeze(this);
|
|
86
87
|
}
|
|
@@ -180,5 +181,45 @@ export class Accessor implements AccessorObject {
|
|
|
180
181
|
}
|
|
181
182
|
}
|
|
182
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Converts GL constant to corresponding TYPED ARRAY
|
|
186
|
+
* Used to auto deduce gl parameter types
|
|
187
|
+
* @deprecated Use getTypedArrayFromDataType
|
|
188
|
+
* @param glType
|
|
189
|
+
* @param param1
|
|
190
|
+
* @returns
|
|
191
|
+
*/
|
|
192
|
+
// eslint-disable-next-line complexity
|
|
193
|
+
function getTypedArrayFromGLType(
|
|
194
|
+
glType: GLDataType | GLPixelType,
|
|
195
|
+
options?: {
|
|
196
|
+
clamped?: boolean;
|
|
197
|
+
}
|
|
198
|
+
): TypedArrayConstructor {
|
|
199
|
+
const {clamped = true} = options || {};
|
|
200
|
+
// Sorted in some order of likelihood to reduce amount of comparisons
|
|
201
|
+
switch (glType) {
|
|
202
|
+
case GL.FLOAT:
|
|
203
|
+
return Float32Array;
|
|
204
|
+
case GL.UNSIGNED_SHORT:
|
|
205
|
+
case GL.UNSIGNED_SHORT_5_6_5:
|
|
206
|
+
case GL.UNSIGNED_SHORT_4_4_4_4:
|
|
207
|
+
case GL.UNSIGNED_SHORT_5_5_5_1:
|
|
208
|
+
return Uint16Array;
|
|
209
|
+
case GL.UNSIGNED_INT:
|
|
210
|
+
return Uint32Array;
|
|
211
|
+
case GL.UNSIGNED_BYTE:
|
|
212
|
+
return clamped ? Uint8ClampedArray : Uint8Array;
|
|
213
|
+
case GL.BYTE:
|
|
214
|
+
return Int8Array;
|
|
215
|
+
case GL.SHORT:
|
|
216
|
+
return Int16Array;
|
|
217
|
+
case GL.INT:
|
|
218
|
+
return Int32Array;
|
|
219
|
+
default:
|
|
220
|
+
throw new Error('Failed to deduce typed array type from GL constant');
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
183
224
|
// TEST EXPORTS
|
|
184
225
|
export {DEFAULT_ACCESSOR_VALUES};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import {Device, Framebuffer} from '@luma.gl/core';
|
|
5
|
+
import {Device, Framebuffer, log} from '@luma.gl/core';
|
|
6
6
|
import {WebGLDevice} from '../adapter/webgl-device';
|
|
7
7
|
import {withGLParameters} from '../context/state-tracker/with-parameters';
|
|
8
8
|
|
|
@@ -24,6 +24,8 @@ export function clear(
|
|
|
24
24
|
device: Device,
|
|
25
25
|
options?: {framebuffer?: Framebuffer; color?: any; depth?: any; stencil?: any}
|
|
26
26
|
): void {
|
|
27
|
+
log.warn('clear will be removed in next minor release');
|
|
28
|
+
|
|
27
29
|
const {framebuffer = null, color = null, depth = null, stencil = null} = options || {};
|
|
28
30
|
const parameters: any = {};
|
|
29
31
|
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
export type {WebGLDeviceLimits} from './adapter/device-helpers/webgl-device-limits';
|
|
13
13
|
|
|
14
14
|
// WebGL adapter classes
|
|
15
|
+
export {webgl2Adapter} from './adapter/webgl-adapter';
|
|
16
|
+
export type {WebGLAdapter} from './adapter/webgl-adapter';
|
|
17
|
+
|
|
18
|
+
// WebGL Device classes
|
|
15
19
|
export {WebGLDevice} from './adapter/webgl-device';
|
|
16
20
|
export {WebGLCanvasContext} from './adapter/webgl-canvas-context';
|
|
17
21
|
|
|
@@ -34,7 +38,7 @@ export {WEBGLVertexArray} from './adapter/resources/webgl-vertex-array';
|
|
|
34
38
|
export {WEBGLTransformFeedback} from './adapter/resources/webgl-transform-feedback';
|
|
35
39
|
|
|
36
40
|
// WebGL adapter classes
|
|
37
|
-
export {Accessor} from './
|
|
41
|
+
export {Accessor} from './deprecated/accessor';
|
|
38
42
|
export type {AccessorObject} from './types';
|
|
39
43
|
|
|
40
44
|
// Unified parameter API
|
|
@@ -43,18 +47,12 @@ export {setDeviceParameters, withDeviceParameters} from './adapter/converters/de
|
|
|
43
47
|
|
|
44
48
|
// HELPERS - EXPERIMENTAL
|
|
45
49
|
export {getShaderLayout} from './adapter/helpers/get-shader-layout';
|
|
50
|
+
export {WebGLStateTracker} from './context/state-tracker/webgl-state-tracker';
|
|
46
51
|
|
|
47
52
|
// TEST EXPORTS
|
|
48
53
|
export {TEXTURE_FORMATS as _TEXTURE_FORMATS} from './adapter/converters/texture-formats';
|
|
49
54
|
|
|
50
55
|
// DEPRECATED TEST EXPORTS
|
|
51
|
-
// State tracking
|
|
52
|
-
export {
|
|
53
|
-
trackContextState,
|
|
54
|
-
pushContextState,
|
|
55
|
-
popContextState
|
|
56
|
-
} from './context/state-tracker/track-context-state';
|
|
57
|
-
|
|
58
56
|
export {
|
|
59
57
|
resetGLParameters,
|
|
60
58
|
setGLParameters,
|