@luma.gl/webgl 9.0.0-alpha.7 → 9.0.0-alpha.8
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/resources/webgl-render-pipeline.js +12 -0
- package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -1
- package/dist/adapter/webgl-device.d.ts +13 -7
- package/dist/adapter/webgl-device.d.ts.map +1 -1
- package/dist/adapter/webgl-device.js +65 -17
- package/dist/adapter/webgl-device.js.map +1 -1
- package/dist/classic/accessor.d.ts.map +1 -1
- package/dist/classic/accessor.js.map +1 -1
- package/dist/context/context/create-browser-context.d.ts.map +1 -1
- package/dist/context/context/create-browser-context.js +8 -2
- package/dist/context/context/create-browser-context.js.map +1 -1
- package/dist/context/debug/webgl-developer-tools.d.ts +1 -1
- package/dist/context/debug/webgl-developer-tools.d.ts.map +1 -1
- package/dist/context/debug/webgl-developer-tools.js +1 -1
- package/dist/context/debug/webgl-developer-tools.js.map +1 -1
- package/dist/context/polyfill/polyfill-context.js +0 -1
- package/dist/context/polyfill/polyfill-context.js.map +1 -1
- package/dist/es5/adapter/resources/webgl-render-pipeline.js +12 -0
- package/dist/es5/adapter/resources/webgl-render-pipeline.js.map +1 -1
- package/dist/es5/adapter/webgl-device.js +79 -25
- package/dist/es5/adapter/webgl-device.js.map +1 -1
- package/dist/es5/classic/accessor.js.map +1 -1
- package/dist/es5/context/context/create-browser-context.js +10 -2
- package/dist/es5/context/context/create-browser-context.js.map +1 -1
- package/dist/es5/context/debug/webgl-developer-tools.js +1 -1
- package/dist/es5/context/debug/webgl-developer-tools.js.map +1 -1
- package/dist/es5/context/polyfill/polyfill-context.js +0 -1
- package/dist/es5/context/polyfill/polyfill-context.js.map +1 -1
- package/dist/es5/index.js.map +1 -1
- package/dist/esm/adapter/resources/webgl-render-pipeline.js +12 -0
- package/dist/esm/adapter/resources/webgl-render-pipeline.js.map +1 -1
- package/dist/esm/adapter/webgl-device.js +65 -17
- package/dist/esm/adapter/webgl-device.js.map +1 -1
- package/dist/esm/classic/accessor.js.map +1 -1
- package/dist/esm/context/context/create-browser-context.js +8 -2
- package/dist/esm/context/context/create-browser-context.js.map +1 -1
- package/dist/esm/context/debug/webgl-developer-tools.js +1 -1
- package/dist/esm/context/debug/webgl-developer-tools.js.map +1 -1
- package/dist/esm/context/polyfill/polyfill-context.js +0 -1
- package/dist/esm/context/polyfill/polyfill-context.js.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/adapter/resources/webgl-render-pipeline.ts +5 -1
- package/src/adapter/webgl-device.ts +79 -27
- package/src/classic/accessor.ts +0 -13
- package/src/context/context/create-browser-context.ts +6 -2
- package/src/context/debug/webgl-developer-tools.ts +2 -2
- package/src/context/polyfill/polyfill-context.ts +0 -2
- package/src/index.ts +1 -0
|
@@ -369,14 +369,16 @@ export default class WEBGLRenderPipeline extends RenderPipeline {
|
|
|
369
369
|
/** Get the primitive type for transform feedback */
|
|
370
370
|
function getDrawMode(
|
|
371
371
|
topology: PrimitiveTopology
|
|
372
|
-
): GL.POINTS | GL.LINES | GL.LINE_STRIP | GL.TRIANGLES | GL.TRIANGLE_STRIP {
|
|
372
|
+
): GL.POINTS | GL.LINES | GL.LINE_STRIP | GL.LINE_LOOP | GL.TRIANGLES | GL.TRIANGLE_STRIP | GL.TRIANGLE_FAN {
|
|
373
373
|
// prettier-ignore
|
|
374
374
|
switch (topology) {
|
|
375
375
|
case 'point-list': return GL.POINTS;
|
|
376
376
|
case 'line-list': return GL.LINES;
|
|
377
377
|
case 'line-strip': return GL.LINE_STRIP;
|
|
378
|
+
case 'line-loop': return GL.LINE_LOOP;
|
|
378
379
|
case 'triangle-list': return GL.TRIANGLES;
|
|
379
380
|
case 'triangle-strip': return GL.TRIANGLE_STRIP;
|
|
381
|
+
case 'triangle-fan': return GL.TRIANGLE_FAN;
|
|
380
382
|
default: throw new Error(topology);
|
|
381
383
|
}
|
|
382
384
|
}
|
|
@@ -388,8 +390,10 @@ function getGLPrimitive(topology: PrimitiveTopology): GL.POINTS | GL.LINES | GL.
|
|
|
388
390
|
case 'point-list': return GL.POINTS;
|
|
389
391
|
case 'line-list': return GL.LINES;
|
|
390
392
|
case 'line-strip': return GL.LINES;
|
|
393
|
+
case 'line-loop': return GL.LINES;
|
|
391
394
|
case 'triangle-list': return GL.TRIANGLES;
|
|
392
395
|
case 'triangle-strip': return GL.TRIANGLES;
|
|
396
|
+
case 'triangle-fan': return GL.TRIANGLES;
|
|
393
397
|
default: throw new Error(topology);
|
|
394
398
|
}
|
|
395
399
|
}
|
|
@@ -13,7 +13,10 @@ import {polyfillContext} from '../context/polyfill/polyfill-context';
|
|
|
13
13
|
import {trackContextState} from '../context/state-tracker/track-context-state';
|
|
14
14
|
import {ContextState} from '../context/context/context-state';
|
|
15
15
|
import {createBrowserContext} from '../context/context/create-browser-context';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
createHeadlessContext,
|
|
18
|
+
isHeadlessGLRegistered
|
|
19
|
+
} from '../context/context/create-headless-context';
|
|
17
20
|
import {getDeviceInfo} from './device-helpers/get-device-info';
|
|
18
21
|
import {getDeviceFeatures} from './device-helpers/device-features';
|
|
19
22
|
import {getDeviceLimits, getWebGLLimits, WebGLLimits} from './device-helpers/device-limits';
|
|
@@ -61,7 +64,9 @@ let counter = 0;
|
|
|
61
64
|
|
|
62
65
|
/** WebGPU style Device API for a WebGL context */
|
|
63
66
|
export default class WebGLDevice extends Device implements ContextState {
|
|
64
|
-
//
|
|
67
|
+
//
|
|
68
|
+
// Public `Device` API
|
|
69
|
+
//
|
|
65
70
|
|
|
66
71
|
static type: string = 'webgl';
|
|
67
72
|
|
|
@@ -71,7 +76,7 @@ export default class WebGLDevice extends Device implements ContextState {
|
|
|
71
76
|
|
|
72
77
|
readonly info: DeviceInfo;
|
|
73
78
|
readonly canvasContext: WebGLCanvasContext;
|
|
74
|
-
|
|
79
|
+
|
|
75
80
|
readonly handle: WebGLRenderingContext;
|
|
76
81
|
|
|
77
82
|
get features(): Set<DeviceFeature> {
|
|
@@ -84,12 +89,20 @@ export default class WebGLDevice extends Device implements ContextState {
|
|
|
84
89
|
return this._limits;
|
|
85
90
|
}
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
readonly lost: Promise<{reason: 'destroyed'; message: string}>;
|
|
93
|
+
|
|
94
|
+
private _resolveContextLost?: (value: {reason: 'destroyed'; message: string}) => void;
|
|
95
|
+
private _features?: Set<DeviceFeature>;
|
|
96
|
+
private _limits?: DeviceLimits;
|
|
97
|
+
|
|
98
|
+
//
|
|
99
|
+
// WebGL-only API (not part of `Device` API)
|
|
100
|
+
//
|
|
88
101
|
|
|
89
102
|
/** WebGL1 typed context. Can always be used. */
|
|
90
103
|
readonly gl: WebGLRenderingContext;
|
|
91
104
|
/** WebGL2 typed context. Need to check isWebGL2 or isWebGL1 before using. */
|
|
92
|
-
readonly gl2: WebGL2RenderingContext;
|
|
105
|
+
readonly gl2: WebGL2RenderingContext | null = null;
|
|
93
106
|
readonly debug: boolean = false;
|
|
94
107
|
|
|
95
108
|
/** `true` if this is a WebGL1 context. @note `false` if WebGL2 */
|
|
@@ -102,9 +115,7 @@ export default class WebGLDevice extends Device implements ContextState {
|
|
|
102
115
|
return this._webglLimits;
|
|
103
116
|
}
|
|
104
117
|
|
|
105
|
-
private
|
|
106
|
-
private _limits: DeviceLimits;
|
|
107
|
-
private _webglLimits: WebGLLimits;
|
|
118
|
+
private _webglLimits?: WebGLLimits;
|
|
108
119
|
|
|
109
120
|
/** State used by luma.gl classes: TODO - move to canvasContext*/
|
|
110
121
|
readonly _canvasSizeInfo = {clientWidth: 0, clientHeight: 0, devicePixelRatio: 1};
|
|
@@ -115,6 +126,10 @@ export default class WebGLDevice extends Device implements ContextState {
|
|
|
115
126
|
/** Instance of Spector.js (if initialized) */
|
|
116
127
|
spector;
|
|
117
128
|
|
|
129
|
+
//
|
|
130
|
+
// Static methods, expected to be present by `luma.createDevice()`
|
|
131
|
+
//
|
|
132
|
+
|
|
118
133
|
/**
|
|
119
134
|
* Get a device instance from a GL context
|
|
120
135
|
* Creates and instruments the device if not already created
|
|
@@ -136,7 +151,7 @@ export default class WebGLDevice extends Device implements ContextState {
|
|
|
136
151
|
return new WebGLDevice({gl: gl as WebGLRenderingContext});
|
|
137
152
|
}
|
|
138
153
|
|
|
139
|
-
static async create(props
|
|
154
|
+
static async create(props: DeviceProps = {}): Promise<WebGLDevice> {
|
|
140
155
|
log.groupCollapsed(LOG_LEVEL, 'WebGLDevice created');
|
|
141
156
|
|
|
142
157
|
// Wait for page to load. Only wait when props. canvas is string
|
|
@@ -154,10 +169,20 @@ export default class WebGLDevice extends Device implements ContextState {
|
|
|
154
169
|
await loadSpectorJS();
|
|
155
170
|
}
|
|
156
171
|
|
|
157
|
-
log.probe(LOG_LEVEL, 'DOM is loaded')();
|
|
172
|
+
log.probe(LOG_LEVEL + 1, 'DOM is loaded')();
|
|
173
|
+
|
|
174
|
+
// @ts-expect-error
|
|
175
|
+
if (props.gl && props.gl.device) {
|
|
176
|
+
return WebGLDevice.attach(props.gl);
|
|
177
|
+
}
|
|
178
|
+
|
|
158
179
|
return new WebGLDevice(props);
|
|
159
180
|
}
|
|
160
181
|
|
|
182
|
+
//
|
|
183
|
+
// Public API
|
|
184
|
+
//
|
|
185
|
+
|
|
161
186
|
constructor(props: DeviceProps) {
|
|
162
187
|
super(props);
|
|
163
188
|
|
|
@@ -165,16 +190,31 @@ export default class WebGLDevice extends Device implements ContextState {
|
|
|
165
190
|
// @ts-expect-error device is attached to context
|
|
166
191
|
const device: WebGLDevice | undefined = props.gl?.device;
|
|
167
192
|
if (device) {
|
|
168
|
-
|
|
169
|
-
return device;
|
|
193
|
+
throw new Error(`WebGL context already attached to device ${device.id}`);
|
|
170
194
|
}
|
|
171
195
|
|
|
172
196
|
// Create and instrument context
|
|
173
197
|
this.canvasContext = new WebGLCanvasContext(this, props);
|
|
174
198
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
199
|
+
this.lost = new Promise<{reason: 'destroyed'; message: string}>((resolve) => {
|
|
200
|
+
this._resolveContextLost = resolve;
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const onContextLost = (event: Event) =>
|
|
204
|
+
this._resolveContextLost?.({
|
|
205
|
+
reason: 'destroyed',
|
|
206
|
+
message: 'Computer entered sleep mode, or too many apps or browser tabs are using the GPU.'
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
let gl: WebGLRenderingContext | WebGL2RenderingContext | null = props.gl;
|
|
210
|
+
gl =
|
|
211
|
+
gl ||
|
|
212
|
+
(isBrowser() ? createBrowserContext(this.canvasContext.canvas, {...props, onContextLost}) : null);
|
|
213
|
+
gl = gl || (!isBrowser() ? createHeadlessContext({...props, onContextLost}) : null);
|
|
214
|
+
|
|
215
|
+
if (!gl) {
|
|
216
|
+
throw new Error('WebGL context creation failed');
|
|
217
|
+
}
|
|
178
218
|
|
|
179
219
|
this.handle = gl;
|
|
180
220
|
this.gl = this.handle;
|
|
@@ -187,7 +227,7 @@ export default class WebGLDevice extends Device implements ContextState {
|
|
|
187
227
|
|
|
188
228
|
// @ts-expect-error Link webgl context back to device
|
|
189
229
|
this.gl.device = this;
|
|
190
|
-
// @ts-expect-error Annotate webgl context to handle
|
|
230
|
+
// @ts-expect-error Annotate webgl context to handle
|
|
191
231
|
this.gl._version = this.isWebGL2 ? 2 : 1;
|
|
192
232
|
|
|
193
233
|
// Add subset of WebGL2 methods to WebGL1 context
|
|
@@ -198,7 +238,7 @@ export default class WebGLDevice extends Device implements ContextState {
|
|
|
198
238
|
const {enable = true, copyState = false} = props;
|
|
199
239
|
trackContextState(this.gl, {
|
|
200
240
|
enable,
|
|
201
|
-
copyState,
|
|
241
|
+
copyState,
|
|
202
242
|
log: (...args: any[]) => log.log(1, ...args)()
|
|
203
243
|
});
|
|
204
244
|
|
|
@@ -231,15 +271,26 @@ ${this.info.vendor}, ${this.info.renderer} for canvas: ${this.canvasContext.id}`
|
|
|
231
271
|
* @note Has no effect for browser contexts, there is no browser API for destroying contexts
|
|
232
272
|
*/
|
|
233
273
|
destroy() {
|
|
234
|
-
|
|
274
|
+
const ext = this.gl.getExtension('STACKGL_destroy_context');
|
|
235
275
|
if (ext) {
|
|
236
276
|
ext.destroy();
|
|
237
277
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Loses the context
|
|
282
|
+
* @note Triggers context loss, mainly for testing
|
|
283
|
+
*/
|
|
284
|
+
loseDevice() {
|
|
285
|
+
const ext = this.gl.getExtension('WEBGL_lose_context');
|
|
286
|
+
if (ext) {
|
|
287
|
+
ext.loseContext();
|
|
288
|
+
}
|
|
289
|
+
// loseContext should trigger context loss callback but
|
|
290
|
+
this._resolveContextLost?.({
|
|
291
|
+
reason: 'destroyed',
|
|
292
|
+
message: 'Application triggered context loss'
|
|
293
|
+
});
|
|
243
294
|
}
|
|
244
295
|
|
|
245
296
|
get isLost(): boolean {
|
|
@@ -266,7 +317,9 @@ ${this.info.vendor}, ${this.info.renderer} for canvas: ${this.canvasContext.id}`
|
|
|
266
317
|
|
|
267
318
|
/** Returns a WebGL2RenderingContext or throws an error */
|
|
268
319
|
assertWebGL2(): WebGL2RenderingContext {
|
|
269
|
-
|
|
320
|
+
if (!this.gl2) {
|
|
321
|
+
throw new Error('Requires WebGL2');
|
|
322
|
+
}
|
|
270
323
|
return this.gl2;
|
|
271
324
|
}
|
|
272
325
|
|
|
@@ -316,7 +369,7 @@ ${this.info.vendor}, ${this.info.renderer} for canvas: ${this.canvasContext.id}`
|
|
|
316
369
|
throw new Error('compute shaders not supported in WebGL');
|
|
317
370
|
}
|
|
318
371
|
|
|
319
|
-
private renderPass: WEBGLRenderPass;
|
|
372
|
+
private renderPass: WEBGLRenderPass | null = null;
|
|
320
373
|
|
|
321
374
|
getDefaultRenderPass(): WEBGLRenderPass {
|
|
322
375
|
this.renderPass =
|
|
@@ -333,7 +386,7 @@ ${this.info.vendor}, ${this.info.renderer} for canvas: ${this.canvasContext.id}`
|
|
|
333
386
|
* Chrome's offscreen canvas does not require gl.commit
|
|
334
387
|
*/
|
|
335
388
|
submit(): void {
|
|
336
|
-
this.renderPass
|
|
389
|
+
this.renderPass?.endPass();
|
|
337
390
|
this.renderPass = null;
|
|
338
391
|
// this.canvasContext.commit();
|
|
339
392
|
}
|
|
@@ -351,7 +404,6 @@ function isWebGL(gl: any): boolean {
|
|
|
351
404
|
return Boolean(gl && Number.isFinite(gl._version));
|
|
352
405
|
}
|
|
353
406
|
|
|
354
|
-
|
|
355
407
|
/** Check if supplied parameter is a WebGL2RenderingContext */
|
|
356
408
|
function isWebGL2(gl: any): boolean {
|
|
357
409
|
if (typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext) {
|
package/src/classic/accessor.ts
CHANGED
|
@@ -2,19 +2,6 @@ import {assert, checkProps, Buffer, AccessorObject} from '@luma.gl/api';
|
|
|
2
2
|
import GL from '@luma.gl/constants';
|
|
3
3
|
import {getTypedArrayFromGLType} from './typed-array-utils';
|
|
4
4
|
|
|
5
|
-
// export interface AccessorObject {
|
|
6
|
-
// offset?: number;
|
|
7
|
-
// stride?: number;
|
|
8
|
-
// type?: number;
|
|
9
|
-
// size?: number;
|
|
10
|
-
// divisor?: number;
|
|
11
|
-
// normalized?: boolean;
|
|
12
|
-
// integer?: boolean;
|
|
13
|
-
|
|
14
|
-
// buffer?: Buffer;
|
|
15
|
-
// index?: number;
|
|
16
|
-
// }
|
|
17
|
-
|
|
18
5
|
const DEFAULT_ACCESSOR_VALUES = {
|
|
19
6
|
offset: 0,
|
|
20
7
|
stride: 0,
|
|
@@ -84,10 +84,14 @@ const DEFAULT_CONTEXT_PROPS: ContextProps = {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
if (props.onContextLost) {
|
|
87
|
-
|
|
87
|
+
// Carefully extract and wrap callbacks to prevent addEventListener from rebinding them.
|
|
88
|
+
const {onContextLost} = props;
|
|
89
|
+
canvas.addEventListener('webglcontextlost',(event: Event) => onContextLost(event), false);
|
|
88
90
|
}
|
|
89
91
|
if (props.onContextRestored) {
|
|
90
|
-
|
|
92
|
+
// Carefully extract and wrap callbacks to prevent addEventListener from rebinding them.
|
|
93
|
+
const {onContextRestored} = props;
|
|
94
|
+
canvas.addEventListener('webglcontextrestored', (event: Event) => onContextRestored(event), false);
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
return gl;
|
|
@@ -46,7 +46,7 @@ export async function loadWebGLDeveloperTools(): Promise<void> {
|
|
|
46
46
|
|
|
47
47
|
// Returns (a potentially new) context with debug instrumentation turned off or on.
|
|
48
48
|
// Note that this actually returns a new context
|
|
49
|
-
export function makeDebugContext(gl: WebGLRenderingContext, props: DebugContextProps = {}): WebGLRenderingContext {
|
|
49
|
+
export function makeDebugContext(gl: WebGLRenderingContext, props: DebugContextProps = {}): WebGLRenderingContext | null {
|
|
50
50
|
// Return null to ensure we don't try to create a context in this case (TODO what case is that?)
|
|
51
51
|
if (!gl) {
|
|
52
52
|
return null;
|
|
@@ -133,7 +133,7 @@ function onGLError(props: DebugContextProps, err, functionName: string, args: an
|
|
|
133
133
|
|
|
134
134
|
// Don't generate function string until it is needed
|
|
135
135
|
function onValidateGLFunc(props: DebugContextProps, functionName: string, functionArgs: any[]): void {
|
|
136
|
-
let functionString: string;
|
|
136
|
+
let functionString: string = '';
|
|
137
137
|
if (log.level >= 1) {
|
|
138
138
|
functionString = getFunctionString(functionName, functionArgs);
|
|
139
139
|
log.log(1, functionString)();
|
|
@@ -38,8 +38,6 @@ function initializeExtensions(gl: WebGLRenderingContext): void {
|
|
|
38
38
|
for (const extensionName of EXTENSIONS) {
|
|
39
39
|
const extension = gl.getExtension(extensionName);
|
|
40
40
|
contextState._extensions[extensionName] = extension;
|
|
41
|
-
// TODO - this looks like a mistake?
|
|
42
|
-
contextState[extensionName] = extension;
|
|
43
41
|
}
|
|
44
42
|
}
|
|
45
43
|
|
package/src/index.ts
CHANGED
|
@@ -39,6 +39,7 @@ export {default as WEBGLVertexArrayObject} from './adapter/objects/webgl-vertex-
|
|
|
39
39
|
|
|
40
40
|
// WebGL adapter classes (Legacy, will be moved to gltools)
|
|
41
41
|
export {default as Accessor} from './classic/accessor';
|
|
42
|
+
export type {AccessorObject} from './types';
|
|
42
43
|
export type {ClassicBufferProps, ClassicBufferProps as BufferProps} from './classic/buffer';
|
|
43
44
|
export {default as ClassicBuffer, default as Buffer} from './classic/buffer';
|
|
44
45
|
|