@luma.gl/webgl 9.2.0-alpha.1 → 9.2.0-alpha.3
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/sampler-parameters.js +13 -2
- package/dist/adapter/converters/sampler-parameters.js.map +1 -1
- package/dist/adapter/converters/webgl-shadertypes.d.ts.map +1 -1
- package/dist/adapter/converters/webgl-shadertypes.js +1 -2
- package/dist/adapter/converters/webgl-shadertypes.js.map +1 -1
- package/dist/adapter/converters/webgl-texture-table.d.ts.map +1 -1
- package/dist/adapter/converters/webgl-texture-table.js +15 -11
- package/dist/adapter/converters/webgl-texture-table.js.map +1 -1
- package/dist/adapter/converters/webgl-vertex-formats.d.ts.map +1 -1
- package/dist/adapter/converters/webgl-vertex-formats.js +1 -2
- package/dist/adapter/converters/webgl-vertex-formats.js.map +1 -1
- package/dist/adapter/helpers/webgl-texture-utils.d.ts +0 -217
- package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
- package/dist/adapter/helpers/webgl-texture-utils.js +3 -3
- package/dist/adapter/helpers/webgl-texture-utils.js.map +1 -1
- package/dist/adapter/resources/webgl-buffer.d.ts +7 -7
- package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-buffer.js +24 -15
- package/dist/adapter/resources/webgl-buffer.js.map +1 -1
- package/dist/adapter/resources/webgl-command-buffer.d.ts +2 -1
- package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-command-buffer.js +1 -0
- package/dist/adapter/resources/webgl-command-buffer.js.map +1 -1
- package/dist/adapter/resources/webgl-framebuffer.d.ts +2 -2
- package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-framebuffer.js.map +1 -1
- package/dist/adapter/resources/webgl-query-set.d.ts +2 -2
- package/dist/adapter/resources/webgl-query-set.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-query-set.js.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.d.ts +1 -0
- package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.js +1 -0
- package/dist/adapter/resources/webgl-render-pass.js.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.d.ts +2 -2
- package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.js +2 -1
- package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -1
- package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-texture.js +8 -5
- package/dist/adapter/resources/webgl-texture.js.map +1 -1
- package/dist/adapter/resources/webgl-vertex-array.d.ts +1 -1
- package/dist/adapter/webgl-adapter.d.ts +2 -1
- package/dist/adapter/webgl-adapter.d.ts.map +1 -1
- package/dist/adapter/webgl-adapter.js +35 -25
- package/dist/adapter/webgl-adapter.js.map +1 -1
- package/dist/adapter/webgl-device.d.ts +12 -4
- package/dist/adapter/webgl-device.d.ts.map +1 -1
- package/dist/adapter/webgl-device.js +60 -17
- package/dist/adapter/webgl-device.js.map +1 -1
- package/dist/context/debug/webgl-developer-tools.js +1 -0
- package/dist/context/debug/webgl-developer-tools.js.map +1 -1
- package/dist/dist.dev.js +124 -57
- package/dist/dist.min.js +2 -2
- package/dist/index.cjs +117 -57
- package/dist/index.cjs.map +2 -2
- package/package.json +4 -4
- package/src/adapter/converters/sampler-parameters.ts +13 -2
- package/src/adapter/converters/webgl-shadertypes.ts +1 -2
- package/src/adapter/converters/webgl-texture-table.ts +20 -14
- package/src/adapter/converters/webgl-vertex-formats.ts +1 -2
- package/src/adapter/helpers/webgl-texture-utils.ts +3 -224
- package/src/adapter/resources/webgl-buffer.ts +38 -20
- package/src/adapter/resources/webgl-command-buffer.ts +4 -3
- package/src/adapter/resources/webgl-command-encoder.ts +1 -1
- package/src/adapter/resources/webgl-framebuffer.ts +2 -2
- package/src/adapter/resources/webgl-query-set.ts +2 -2
- package/src/adapter/resources/webgl-render-pass.ts +1 -0
- package/src/adapter/resources/webgl-render-pipeline.ts +7 -3
- package/src/adapter/resources/webgl-texture.ts +8 -5
- package/src/adapter/webgl-adapter.ts +36 -28
- package/src/adapter/webgl-device.ts +85 -31
- package/src/context/debug/webgl-developer-tools.ts +1 -0
|
@@ -45,7 +45,8 @@ export class WebGLAdapter extends Adapter {
|
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* Get a device instance from a GL context
|
|
48
|
-
* Creates
|
|
48
|
+
* Creates a WebGLCanvasContext against the contexts canvas
|
|
49
|
+
* @note autoResize will be disabled, assuming that whoever created the external context will be handling resizes.
|
|
49
50
|
* @param gl
|
|
50
51
|
* @returns
|
|
51
52
|
*/
|
|
@@ -62,51 +63,58 @@ export class WebGLAdapter extends Adapter {
|
|
|
62
63
|
if (!isWebGL(gl)) {
|
|
63
64
|
throw new Error('Invalid WebGL2RenderingContext');
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
+
|
|
67
|
+
// We create a new device using the provided WebGL context and its canvas
|
|
68
|
+
// Assume that whoever created the external context will be handling resizes.
|
|
69
|
+
return new WebGLDevice({
|
|
70
|
+
_handle: gl,
|
|
71
|
+
createCanvasContext: {canvas: gl.canvas, autoResize: false}
|
|
72
|
+
});
|
|
66
73
|
}
|
|
67
74
|
|
|
68
75
|
async create(props: DeviceProps = {}): Promise<WebGLDevice> {
|
|
69
76
|
const {WebGLDevice} = await import('./webgl-device');
|
|
70
77
|
|
|
71
78
|
log.groupCollapsed(LOG_LEVEL, 'WebGLDevice created')();
|
|
79
|
+
try {
|
|
80
|
+
const promises: Promise<unknown>[] = [];
|
|
72
81
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
promises.push(loadWebGLDeveloperTools());
|
|
78
|
-
}
|
|
82
|
+
// Load webgl and spector debug scripts from CDN if requested
|
|
83
|
+
if (props.debugWebGL || props.debug) {
|
|
84
|
+
promises.push(loadWebGLDeveloperTools());
|
|
85
|
+
}
|
|
79
86
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
if (props.debugSpectorJS) {
|
|
88
|
+
promises.push(loadSpectorJS(props));
|
|
89
|
+
}
|
|
83
90
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
// Wait for all the loads to settle before creating the context.
|
|
92
|
+
// The Device.create() functions are async, so in contrast to the constructor, we can `await` here.
|
|
93
|
+
const results = await Promise.allSettled(promises);
|
|
94
|
+
for (const result of results) {
|
|
95
|
+
if (result.status === 'rejected') {
|
|
96
|
+
log.error(`Failed to initialize debug libraries ${result.reason}`)();
|
|
97
|
+
}
|
|
90
98
|
}
|
|
91
|
-
}
|
|
92
99
|
|
|
93
|
-
|
|
100
|
+
const device = new WebGLDevice(props);
|
|
94
101
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
102
|
+
// Log some debug info about the newly created context
|
|
103
|
+
const message = `\
|
|
104
|
+
${device._reused ? 'Reusing' : 'Created'} device with WebGL2 ${device.props.debug ? 'debug ' : ''}context: \
|
|
98
105
|
${device.info.vendor}, ${device.info.renderer} for canvas: ${device.canvasContext.id}`;
|
|
99
|
-
|
|
100
|
-
|
|
106
|
+
log.probe(LOG_LEVEL, message)();
|
|
107
|
+
log.table(LOG_LEVEL, device.info)();
|
|
101
108
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
return device;
|
|
110
|
+
} finally {
|
|
111
|
+
log.groupEnd(LOG_LEVEL)();
|
|
112
|
+
}
|
|
105
113
|
}
|
|
106
114
|
}
|
|
107
115
|
|
|
108
116
|
/** Check if supplied parameter is a WebGL2RenderingContext */
|
|
109
|
-
function isWebGL(gl: any):
|
|
117
|
+
function isWebGL(gl: any): gl is WebGL2RenderingContext {
|
|
110
118
|
if (typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext) {
|
|
111
119
|
return true;
|
|
112
120
|
}
|
|
@@ -29,7 +29,8 @@ import type {
|
|
|
29
29
|
CommandEncoderProps,
|
|
30
30
|
TransformFeedbackProps,
|
|
31
31
|
QuerySetProps,
|
|
32
|
-
Resource
|
|
32
|
+
Resource,
|
|
33
|
+
VertexFormat
|
|
33
34
|
} from '@luma.gl/core';
|
|
34
35
|
import {Device, CanvasContext, log} from '@luma.gl/core';
|
|
35
36
|
import type {GLExtensions} from '@luma.gl/constants';
|
|
@@ -73,25 +74,25 @@ export class WebGLDevice extends Device {
|
|
|
73
74
|
/** type of this device */
|
|
74
75
|
readonly type = 'webgl';
|
|
75
76
|
|
|
77
|
+
// Use the ! assertion to handle the case where _reuseDevices causes the constructor to return early
|
|
76
78
|
/** The underlying WebGL context */
|
|
77
|
-
readonly handle
|
|
78
|
-
features
|
|
79
|
-
limits
|
|
80
|
-
readonly info
|
|
81
|
-
readonly canvasContext
|
|
79
|
+
readonly handle!: WebGL2RenderingContext;
|
|
80
|
+
features!: WebGLDeviceFeatures;
|
|
81
|
+
limits!: WebGLDeviceLimits;
|
|
82
|
+
readonly info!: DeviceInfo;
|
|
83
|
+
readonly canvasContext!: WebGLCanvasContext;
|
|
82
84
|
|
|
83
85
|
readonly preferredColorFormat = 'rgba8unorm';
|
|
84
86
|
readonly preferredDepthFormat = 'depth24plus';
|
|
85
87
|
|
|
86
|
-
commandEncoder
|
|
88
|
+
commandEncoder!: WEBGLCommandEncoder;
|
|
87
89
|
|
|
88
90
|
readonly lost: Promise<{reason: 'destroyed'; message: string}>;
|
|
89
91
|
|
|
90
92
|
private _resolveContextLost?: (value: {reason: 'destroyed'; message: string}) => void;
|
|
91
93
|
|
|
92
94
|
/** WebGL2 context. */
|
|
93
|
-
readonly gl
|
|
94
|
-
readonly debug: boolean = false;
|
|
95
|
+
readonly gl!: WebGL2RenderingContext;
|
|
95
96
|
|
|
96
97
|
/** Store constants */
|
|
97
98
|
// @ts-ignore TODO fix
|
|
@@ -102,26 +103,42 @@ export class WebGLDevice extends Device {
|
|
|
102
103
|
_polyfilled: boolean = false;
|
|
103
104
|
|
|
104
105
|
/** Instance of Spector.js (if initialized) */
|
|
105
|
-
spectorJS
|
|
106
|
+
spectorJS!: Spector | null;
|
|
106
107
|
|
|
107
108
|
//
|
|
108
109
|
// Public API
|
|
109
110
|
//
|
|
110
111
|
|
|
112
|
+
override get [Symbol.toStringTag](): string {
|
|
113
|
+
return 'WebGLDevice';
|
|
114
|
+
}
|
|
115
|
+
|
|
111
116
|
override toString(): string {
|
|
112
117
|
return `${this[Symbol.toStringTag]}(${this.id})`;
|
|
113
118
|
}
|
|
114
119
|
|
|
120
|
+
override isVertexFormatSupported(format: VertexFormat): boolean {
|
|
121
|
+
switch (format) {
|
|
122
|
+
case 'unorm8x4-bgra':
|
|
123
|
+
return false;
|
|
124
|
+
default:
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
115
129
|
constructor(props: DeviceProps) {
|
|
116
130
|
super({...props, id: props.id || uid('webgl-device')});
|
|
117
131
|
|
|
132
|
+
const canvasContextProps = Device._getCanvasContextProps(props)!;
|
|
133
|
+
|
|
118
134
|
// WebGL requires a canvas to be created before creating the context
|
|
119
|
-
if (!
|
|
135
|
+
if (!canvasContextProps) {
|
|
120
136
|
throw new Error('WebGLDevice requires props.createCanvasContext to be set');
|
|
121
137
|
}
|
|
122
|
-
const canvasContextProps = props.createCanvasContext === true ? {} : props.createCanvasContext;
|
|
123
138
|
|
|
124
|
-
//
|
|
139
|
+
// Check if the WebGL context is already associated with a device
|
|
140
|
+
// Note that this can be avoided in webgl2adapter.create() if
|
|
141
|
+
// DeviceProps._reuseDevices is set.
|
|
125
142
|
// @ts-expect-error device is attached to context
|
|
126
143
|
let device: WebGLDevice | undefined = canvasContextProps.canvas?.gl?.device;
|
|
127
144
|
if (device) {
|
|
@@ -144,27 +161,43 @@ export class WebGLDevice extends Device {
|
|
|
144
161
|
webglContextAttributes.powerPreference = props.powerPreference;
|
|
145
162
|
}
|
|
146
163
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
164
|
+
// Check if we should attach to an externally created context or create a new context
|
|
165
|
+
const externalGLContext = this.props._handle as WebGL2RenderingContext | null;
|
|
166
|
+
|
|
167
|
+
const gl =
|
|
168
|
+
externalGLContext ||
|
|
169
|
+
createBrowserContext(
|
|
170
|
+
this.canvasContext.canvas,
|
|
171
|
+
{
|
|
172
|
+
onContextLost: (event: Event) =>
|
|
173
|
+
this._resolveContextLost?.({
|
|
174
|
+
reason: 'destroyed',
|
|
175
|
+
message: 'Entered sleep mode, or too many apps or browser tabs are using the GPU.'
|
|
176
|
+
}),
|
|
177
|
+
// eslint-disable-next-line no-console
|
|
178
|
+
onContextRestored: (event: Event) => console.log('WebGL context restored')
|
|
179
|
+
},
|
|
180
|
+
webglContextAttributes
|
|
181
|
+
);
|
|
160
182
|
|
|
161
183
|
if (!gl) {
|
|
162
184
|
throw new Error('WebGL context creation failed');
|
|
163
185
|
}
|
|
164
186
|
|
|
165
|
-
//
|
|
187
|
+
// Note that the browser will only create one WebGL context per canvas.
|
|
188
|
+
// This means that a newly created gl context may already have a device attached to it.
|
|
189
|
+
// @ts-expect-error luma.gl stores a device reference on the context.
|
|
166
190
|
device = gl.device;
|
|
167
191
|
if (device) {
|
|
192
|
+
if (props._reuseDevices) {
|
|
193
|
+
log.log(
|
|
194
|
+
1,
|
|
195
|
+
`Not creating a new Device, instead returning a reference to Device ${device.id} already attached to WebGL context`,
|
|
196
|
+
device
|
|
197
|
+
)();
|
|
198
|
+
device._reused = true;
|
|
199
|
+
return device;
|
|
200
|
+
}
|
|
168
201
|
throw new Error(`WebGL context already attached to device ${device.id}`);
|
|
169
202
|
}
|
|
170
203
|
|
|
@@ -178,6 +211,7 @@ export class WebGLDevice extends Device {
|
|
|
178
211
|
|
|
179
212
|
// Instrument context
|
|
180
213
|
(this.gl as any).device = this; // Update GL context: Link webgl context back to device
|
|
214
|
+
// TODO - remove, this is only used to detect debug contexts.
|
|
181
215
|
(this.gl as any)._version = 2; // Update GL context: Store WebGL version field on gl context (HACK to identify debug contexts)
|
|
182
216
|
|
|
183
217
|
// initialize luma Device fields
|
|
@@ -213,10 +247,26 @@ export class WebGLDevice extends Device {
|
|
|
213
247
|
}
|
|
214
248
|
|
|
215
249
|
/**
|
|
216
|
-
* Destroys the
|
|
217
|
-
*
|
|
250
|
+
* Destroys the device
|
|
251
|
+
*
|
|
252
|
+
* @note "Detaches" from the WebGL context unless _reuseDevices is true.
|
|
253
|
+
*
|
|
254
|
+
* @note The underlying WebGL context is not immediately destroyed,
|
|
255
|
+
* but may be destroyed later through normal JavaScript garbage collection.
|
|
256
|
+
* This is a fundamental limitation since WebGL does not offer any
|
|
257
|
+
* browser API for destroying WebGL contexts.
|
|
218
258
|
*/
|
|
219
|
-
destroy(): void {
|
|
259
|
+
destroy(): void {
|
|
260
|
+
// Note that deck.gl (especially in React strict mode) depends on being able
|
|
261
|
+
// to asynchronously create a Device against the same canvas (i.e. WebGL context)
|
|
262
|
+
// multiple times and getting the same device back. Since deck.gl is not aware
|
|
263
|
+
// of this sharing, it might call destroy() multiple times on the same device.
|
|
264
|
+
// Therefore we must do nothing in destroy() if props._reuseDevices is true
|
|
265
|
+
if (!this.props._reuseDevices && !this._reused) {
|
|
266
|
+
// Delete the reference to the device that we store on the WebGL context
|
|
267
|
+
delete (this.gl as any).device;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
220
270
|
|
|
221
271
|
get isLost(): boolean {
|
|
222
272
|
return this.gl.isContextLost();
|
|
@@ -224,6 +274,10 @@ export class WebGLDevice extends Device {
|
|
|
224
274
|
|
|
225
275
|
// IMPLEMENTATION OF ABSTRACT DEVICE
|
|
226
276
|
|
|
277
|
+
getTextureByteAlignment(): number {
|
|
278
|
+
return 4;
|
|
279
|
+
}
|
|
280
|
+
|
|
227
281
|
createCanvasContext(props?: CanvasContextProps): CanvasContext {
|
|
228
282
|
throw new Error('WebGL only supports a single canvas');
|
|
229
283
|
}
|
|
@@ -473,7 +527,7 @@ export class WebGLDevice extends Device {
|
|
|
473
527
|
// @ts-expect-error
|
|
474
528
|
handle.luma = resource;
|
|
475
529
|
|
|
476
|
-
const spectorMetadata = {props: options.spector, id: options.spector
|
|
530
|
+
const spectorMetadata = {props: options.spector, id: options.spector['id']};
|
|
477
531
|
// @ts-expect-error
|
|
478
532
|
// eslint-disable-next-line camelcase
|
|
479
533
|
handle.__SPECTOR_Metadata = spectorMetadata;
|
|
@@ -131,6 +131,7 @@ function onGLError(
|
|
|
131
131
|
const errorMessage = globalThis.WebGLDebugUtils.glEnumToString(err);
|
|
132
132
|
const functionArgs = globalThis.WebGLDebugUtils.glFunctionArgsToString(functionName, args);
|
|
133
133
|
const message = `${errorMessage} in gl.${functionName}(${functionArgs})`;
|
|
134
|
+
// TODO - call device.reportError
|
|
134
135
|
log.error(message)();
|
|
135
136
|
debugger; // eslint-disable-line
|
|
136
137
|
// throw new Error(message);
|