@luma.gl/webgl 9.1.0-alpha.14 → 9.1.0-alpha.16
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 +3 -3
- package/dist/adapter/converters/device-parameters.d.ts.map +1 -1
- package/dist/adapter/helpers/webgl-texture-utils.d.ts +24 -22
- package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
- package/dist/adapter/helpers/webgl-texture-utils.js +6 -224
- package/dist/adapter/resources/webgl-command-buffer.js +15 -15
- package/dist/adapter/resources/webgl-framebuffer.d.ts +2 -3
- package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-framebuffer.js +10 -11
- package/dist/adapter/resources/webgl-render-pipeline.d.ts +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.js +24 -11
- package/dist/adapter/resources/webgl-shader.d.ts +1 -0
- package/dist/adapter/resources/webgl-shader.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-shader.js +6 -4
- package/dist/adapter/webgl-adapter.d.ts.map +1 -1
- package/dist/adapter/webgl-adapter.js +4 -10
- package/dist/adapter/webgl-device.d.ts +1 -2
- package/dist/adapter/webgl-device.d.ts.map +1 -1
- package/dist/adapter/webgl-device.js +33 -14
- package/dist/context/debug/spector-types.js +1 -1
- package/dist/context/debug/spector.d.ts +5 -5
- package/dist/context/debug/spector.d.ts.map +1 -1
- package/dist/context/debug/spector.js +6 -6
- package/dist/context/debug/webgl-developer-tools.d.ts +1 -3
- package/dist/context/debug/webgl-developer-tools.d.ts.map +1 -1
- package/dist/context/debug/webgl-developer-tools.js +4 -19
- package/dist/context/helpers/create-browser-context.d.ts +6 -22
- package/dist/context/helpers/create-browser-context.d.ts.map +1 -1
- package/dist/context/helpers/create-browser-context.js +26 -32
- package/dist/dist.dev.js +1762 -1749
- package/dist/dist.min.js +2 -2
- package/dist/index.cjs +1660 -1653
- package/dist/index.cjs.map +4 -4
- package/package.json +4 -4
- package/src/adapter/converters/device-parameters.ts +3 -3
- package/src/adapter/helpers/webgl-texture-utils.ts +33 -30
- package/src/adapter/resources/webgl-command-buffer.ts +16 -16
- package/src/adapter/resources/webgl-framebuffer.ts +12 -12
- package/src/adapter/resources/webgl-render-pipeline.ts +26 -11
- package/src/adapter/resources/webgl-shader.ts +7 -5
- package/src/adapter/webgl-adapter.ts +4 -12
- package/src/adapter/webgl-device.ts +67 -40
- package/src/context/debug/spector-types.ts +1 -1
- package/src/context/debug/spector.ts +11 -11
- package/src/context/debug/webgl-developer-tools.ts +5 -31
- package/src/context/helpers/create-browser-context.ts +39 -64
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luma.gl/webgl",
|
|
3
|
-
"version": "9.1.0-alpha.
|
|
3
|
+
"version": "9.1.0-alpha.16",
|
|
4
4
|
"description": "WebGL2 adapter for the luma.gl core API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,12 +40,12 @@
|
|
|
40
40
|
"prepublishOnly": "npm run build-minified-bundle && npm run build-dev-bundle"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@luma.gl/core": "9.1.0-alpha.
|
|
43
|
+
"@luma.gl/core": "9.1.0-alpha.14"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@luma.gl/constants": "9.1.0-alpha.
|
|
46
|
+
"@luma.gl/constants": "9.1.0-alpha.16",
|
|
47
47
|
"@math.gl/types": "4.1.0-alpha.3",
|
|
48
48
|
"@probe.gl/env": "^4.0.8"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "39eec40d12c826548b636c057fdb8572adfe611f"
|
|
51
51
|
}
|
|
@@ -31,7 +31,7 @@ export function withDeviceAndGLParameters<T = unknown>(
|
|
|
31
31
|
device: Device,
|
|
32
32
|
parameters: Parameters,
|
|
33
33
|
glParameters: GLParameters,
|
|
34
|
-
func: (
|
|
34
|
+
func: (_?: Device) => T
|
|
35
35
|
): T {
|
|
36
36
|
if (isObjectEmpty(parameters)) {
|
|
37
37
|
// Avoid setting state if no parameters provided. Just call and return
|
|
@@ -62,7 +62,7 @@ export function withDeviceAndGLParameters<T = unknown>(
|
|
|
62
62
|
export function withGLParameters<T = unknown>(
|
|
63
63
|
device: Device,
|
|
64
64
|
parameters: GLParameters,
|
|
65
|
-
func: (
|
|
65
|
+
func: (_?: Device) => T
|
|
66
66
|
): T {
|
|
67
67
|
if (isObjectEmpty(parameters)) {
|
|
68
68
|
// Avoid setting state if no parameters provided. Just call and return
|
|
@@ -91,7 +91,7 @@ export function withGLParameters<T = unknown>(
|
|
|
91
91
|
export function withDeviceParameters<T = unknown>(
|
|
92
92
|
device: Device,
|
|
93
93
|
parameters: Parameters,
|
|
94
|
-
func: (
|
|
94
|
+
func: (_?: Device) => T
|
|
95
95
|
): T {
|
|
96
96
|
if (isObjectEmpty(parameters)) {
|
|
97
97
|
// Avoid setting state if no parameters provided. Just call and return
|
|
@@ -490,6 +490,30 @@ export function setMipLevelFromGPUBuffer(
|
|
|
490
490
|
gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, null);
|
|
491
491
|
}
|
|
492
492
|
*/
|
|
493
|
+
export type ReadPixelsToArrayOptions = {
|
|
494
|
+
sourceX?: number;
|
|
495
|
+
sourceY?: number;
|
|
496
|
+
sourceFormat?: number;
|
|
497
|
+
sourceAttachment?: number;
|
|
498
|
+
target?: Uint8Array | Uint16Array | Float32Array;
|
|
499
|
+
// following parameters are auto deduced if not provided
|
|
500
|
+
sourceWidth?: number;
|
|
501
|
+
sourceHeight?: number;
|
|
502
|
+
sourceDepth?: number;
|
|
503
|
+
sourceType?: number;
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
export type ReadPixelsToBufferOptions = {
|
|
507
|
+
sourceX?: number;
|
|
508
|
+
sourceY?: number;
|
|
509
|
+
sourceFormat?: number;
|
|
510
|
+
target?: Buffer; // A new Buffer object is created when not provided.
|
|
511
|
+
targetByteOffset?: number; // byte offset in buffer object
|
|
512
|
+
// following parameters are auto deduced if not provided
|
|
513
|
+
sourceWidth?: number;
|
|
514
|
+
sourceHeight?: number;
|
|
515
|
+
sourceType?: number;
|
|
516
|
+
};
|
|
493
517
|
|
|
494
518
|
/**
|
|
495
519
|
* Copies data from a type or a Texture object into ArrayBuffer object.
|
|
@@ -504,18 +528,7 @@ export function setMipLevelFromGPUBuffer(
|
|
|
504
528
|
*/
|
|
505
529
|
export function readPixelsToArray(
|
|
506
530
|
source: Framebuffer | Texture,
|
|
507
|
-
options?:
|
|
508
|
-
sourceX?: number;
|
|
509
|
-
sourceY?: number;
|
|
510
|
-
sourceFormat?: number;
|
|
511
|
-
sourceAttachment?: number;
|
|
512
|
-
target?: Uint8Array | Uint16Array | Float32Array;
|
|
513
|
-
// following parameters are auto deduced if not provided
|
|
514
|
-
sourceWidth?: number;
|
|
515
|
-
sourceHeight?: number;
|
|
516
|
-
sourceDepth?: number;
|
|
517
|
-
sourceType?: number;
|
|
518
|
-
}
|
|
531
|
+
options?: ReadPixelsToArrayOptions
|
|
519
532
|
): Uint8Array | Uint16Array | Float32Array {
|
|
520
533
|
const {
|
|
521
534
|
sourceX = 0,
|
|
@@ -576,17 +589,7 @@ export function readPixelsToArray(
|
|
|
576
589
|
*/
|
|
577
590
|
export function readPixelsToBuffer(
|
|
578
591
|
source: Framebuffer | Texture,
|
|
579
|
-
options?:
|
|
580
|
-
sourceX?: number;
|
|
581
|
-
sourceY?: number;
|
|
582
|
-
sourceFormat?: number;
|
|
583
|
-
target?: Buffer; // A new Buffer object is created when not provided.
|
|
584
|
-
targetByteOffset?: number; // byte offset in buffer object
|
|
585
|
-
// following parameters are auto deduced if not provided
|
|
586
|
-
sourceWidth?: number;
|
|
587
|
-
sourceHeight?: number;
|
|
588
|
-
sourceType?: number;
|
|
589
|
-
}
|
|
592
|
+
options?: ReadPixelsToBufferOptions
|
|
590
593
|
): WEBGLBuffer {
|
|
591
594
|
const {
|
|
592
595
|
target,
|
|
@@ -620,11 +623,11 @@ export function readPixelsToBuffer(
|
|
|
620
623
|
// TODO(donmccurdy): Do we have tests to confirm this is working?
|
|
621
624
|
const commandEncoder = source.device.createCommandEncoder();
|
|
622
625
|
commandEncoder.copyTextureToBuffer({
|
|
623
|
-
|
|
626
|
+
sourceTexture: source as Texture,
|
|
624
627
|
width: sourceWidth,
|
|
625
628
|
height: sourceHeight,
|
|
626
629
|
origin: [sourceX, sourceY],
|
|
627
|
-
|
|
630
|
+
destinationBuffer: webglBufferTarget,
|
|
628
631
|
byteOffset: targetByteOffset
|
|
629
632
|
});
|
|
630
633
|
commandEncoder.destroy();
|
|
@@ -642,8 +645,8 @@ export function readPixelsToBuffer(
|
|
|
642
645
|
*/
|
|
643
646
|
// eslint-disable-next-line complexity, max-statements
|
|
644
647
|
export function copyToTexture(
|
|
645
|
-
|
|
646
|
-
|
|
648
|
+
sourceTexture: Framebuffer | Texture,
|
|
649
|
+
destinationTexture: Texture | GL,
|
|
647
650
|
options?: {
|
|
648
651
|
sourceX?: number;
|
|
649
652
|
sourceY?: number;
|
|
@@ -673,7 +676,7 @@ export function copyToTexture(
|
|
|
673
676
|
height // defaults to target height
|
|
674
677
|
} = options || {};
|
|
675
678
|
|
|
676
|
-
const {framebuffer, deleteFramebuffer} = getFramebuffer(
|
|
679
|
+
const {framebuffer, deleteFramebuffer} = getFramebuffer(sourceTexture);
|
|
677
680
|
// assert(framebuffer);
|
|
678
681
|
const webglFramebuffer = framebuffer;
|
|
679
682
|
const {device, handle} = webglFramebuffer;
|
|
@@ -690,8 +693,8 @@ export function copyToTexture(
|
|
|
690
693
|
// assert(target);
|
|
691
694
|
let texture: WEBGLTexture | null = null;
|
|
692
695
|
let textureTarget: GL;
|
|
693
|
-
if (
|
|
694
|
-
texture =
|
|
696
|
+
if (destinationTexture instanceof WEBGLTexture) {
|
|
697
|
+
texture = destinationTexture;
|
|
695
698
|
width = Number.isFinite(width) ? width : texture.width;
|
|
696
699
|
height = Number.isFinite(height) ? height : texture.height;
|
|
697
700
|
texture?.bind(0);
|
|
@@ -73,8 +73,8 @@ export class WEBGLCommandBuffer extends CommandBuffer {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
function _copyBufferToBuffer(device: WebGLDevice, options: CopyBufferToBufferOptions): void {
|
|
76
|
-
const source = options.
|
|
77
|
-
const destination = options.
|
|
76
|
+
const source = options.sourceBuffer as WEBGLBuffer;
|
|
77
|
+
const destination = options.destinationBuffer as WEBGLBuffer;
|
|
78
78
|
|
|
79
79
|
// {In WebGL2 we can p}erform the copy on the GPU
|
|
80
80
|
// Use GL.COPY_READ_BUFFER+GL.COPY_WRITE_BUFFER avoid disturbing other targets and locking type
|
|
@@ -106,22 +106,22 @@ function _copyBufferToTexture(device: WebGLDevice, options: CopyBufferToTextureO
|
|
|
106
106
|
function _copyTextureToBuffer(device: WebGLDevice, options: CopyTextureToBufferOptions): void {
|
|
107
107
|
const {
|
|
108
108
|
/** Texture to copy to/from. */
|
|
109
|
-
|
|
109
|
+
sourceTexture,
|
|
110
110
|
/** Mip-map level of the texture to copy to/from. (Default 0) */
|
|
111
111
|
mipLevel = 0,
|
|
112
112
|
/** Defines which aspects of the texture to copy to/from. */
|
|
113
113
|
aspect = 'all',
|
|
114
114
|
|
|
115
115
|
/** Width to copy */
|
|
116
|
-
width = options.
|
|
116
|
+
width = options.sourceTexture.width,
|
|
117
117
|
/** Height to copy */
|
|
118
|
-
height = options.
|
|
118
|
+
height = options.sourceTexture.height,
|
|
119
119
|
depthOrArrayLayers = 0,
|
|
120
120
|
/** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
|
|
121
121
|
origin = [0, 0],
|
|
122
122
|
|
|
123
123
|
/** Destination buffer */
|
|
124
|
-
|
|
124
|
+
destinationBuffer,
|
|
125
125
|
/** Offset, in bytes, from the beginning of the buffer to the start of the image data (default 0) */
|
|
126
126
|
byteOffset = 0,
|
|
127
127
|
/**
|
|
@@ -139,7 +139,7 @@ function _copyTextureToBuffer(device: WebGLDevice, options: CopyTextureToBufferO
|
|
|
139
139
|
|
|
140
140
|
// TODO - Not possible to read just stencil or depth part in WebGL?
|
|
141
141
|
if (aspect !== 'all') {
|
|
142
|
-
throw new Error('not supported');
|
|
142
|
+
throw new Error('aspect not supported in WebGL');
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
// TODO - mipLevels are set when attaching texture to framebuffer
|
|
@@ -148,10 +148,10 @@ function _copyTextureToBuffer(device: WebGLDevice, options: CopyTextureToBufferO
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
// Asynchronous read (PIXEL_PACK_BUFFER) is WebGL2 only feature
|
|
151
|
-
const {framebuffer, destroyFramebuffer} = getFramebuffer(
|
|
151
|
+
const {framebuffer, destroyFramebuffer} = getFramebuffer(sourceTexture);
|
|
152
152
|
let prevHandle: WebGLFramebuffer | null | undefined;
|
|
153
153
|
try {
|
|
154
|
-
const webglBuffer =
|
|
154
|
+
const webglBuffer = destinationBuffer as WEBGLBuffer;
|
|
155
155
|
const sourceWidth = width || framebuffer.width;
|
|
156
156
|
const sourceHeight = height || framebuffer.height;
|
|
157
157
|
const sourceParams = getTextureFormatWebGL(
|
|
@@ -220,7 +220,7 @@ export function readPixelsToBuffer(
|
|
|
220
220
|
function _copyTextureToTexture(device: WebGLDevice, options: CopyTextureToTextureOptions): void {
|
|
221
221
|
const {
|
|
222
222
|
/** Texture to copy to/from. */
|
|
223
|
-
|
|
223
|
+
sourceTexture,
|
|
224
224
|
/** Mip-map level of the texture to copy to (Default 0) */
|
|
225
225
|
destinationMipLevel = 0,
|
|
226
226
|
/** Defines which aspects of the texture to copy to/from. */
|
|
@@ -232,7 +232,7 @@ function _copyTextureToTexture(device: WebGLDevice, options: CopyTextureToTextur
|
|
|
232
232
|
destinationOrigin = [0, 0],
|
|
233
233
|
|
|
234
234
|
/** Texture to copy to/from. */
|
|
235
|
-
|
|
235
|
+
destinationTexture
|
|
236
236
|
/** Mip-map level of the texture to copy to/from. (Default 0) */
|
|
237
237
|
// destinationMipLevel = options.mipLevel,
|
|
238
238
|
/** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
|
|
@@ -242,12 +242,12 @@ function _copyTextureToTexture(device: WebGLDevice, options: CopyTextureToTextur
|
|
|
242
242
|
} = options;
|
|
243
243
|
|
|
244
244
|
let {
|
|
245
|
-
width = options.
|
|
246
|
-
height = options.
|
|
245
|
+
width = options.destinationTexture.width,
|
|
246
|
+
height = options.destinationTexture.height
|
|
247
247
|
// depthOrArrayLayers = 0
|
|
248
248
|
} = options;
|
|
249
249
|
|
|
250
|
-
const {framebuffer, destroyFramebuffer} = getFramebuffer(
|
|
250
|
+
const {framebuffer, destroyFramebuffer} = getFramebuffer(sourceTexture);
|
|
251
251
|
const [sourceX, sourceY] = origin;
|
|
252
252
|
const [destinationX, destinationY, destinationZ] = destinationOrigin;
|
|
253
253
|
|
|
@@ -261,8 +261,8 @@ function _copyTextureToTexture(device: WebGLDevice, options: CopyTextureToTextur
|
|
|
261
261
|
|
|
262
262
|
let texture: WEBGLTexture = null;
|
|
263
263
|
let textureTarget: GL;
|
|
264
|
-
if (
|
|
265
|
-
texture =
|
|
264
|
+
if (destinationTexture instanceof WEBGLTexture) {
|
|
265
|
+
texture = destinationTexture;
|
|
266
266
|
width = Number.isFinite(width) ? width : texture.width;
|
|
267
267
|
height = Number.isFinite(height) ? height : texture.height;
|
|
268
268
|
texture.bind(0);
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import type {FramebufferProps
|
|
6
|
-
import {Framebuffer
|
|
5
|
+
import type {FramebufferProps} from '@luma.gl/core';
|
|
6
|
+
import {Framebuffer} from '@luma.gl/core';
|
|
7
7
|
import {GL} from '@luma.gl/constants';
|
|
8
8
|
import {WebGLDevice} from '../webgl-device';
|
|
9
9
|
import {WEBGLTexture} from './webgl-texture';
|
|
@@ -91,16 +91,16 @@ export class WEBGLFramebuffer extends Framebuffer {
|
|
|
91
91
|
// PRIVATE
|
|
92
92
|
|
|
93
93
|
/** In WebGL we must use renderbuffers for depth/stencil attachments (unless we have extensions) */
|
|
94
|
-
protected override createDepthStencilTexture(format: TextureFormat): Texture {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
94
|
+
// protected override createDepthStencilTexture(format: TextureFormat): Texture {
|
|
95
|
+
// // return new WEBGLRenderbuffer(this.device, {
|
|
96
|
+
// return new WEBGLTexture(this.device, {
|
|
97
|
+
// id: `${this.id}-depth-stencil`,
|
|
98
|
+
// format,
|
|
99
|
+
// width: this.width,
|
|
100
|
+
// height: this.height,
|
|
101
|
+
// mipmaps: false
|
|
102
|
+
// });
|
|
103
|
+
// }
|
|
104
104
|
|
|
105
105
|
/**
|
|
106
106
|
* @param attachment
|
|
@@ -110,12 +110,12 @@ export class WEBGLRenderPipeline extends RenderPipeline {
|
|
|
110
110
|
// and reference them as `app` from both GLSL and JS.
|
|
111
111
|
// TODO - this is rather hacky - we could also remap the name directly in the shader layout.
|
|
112
112
|
const binding =
|
|
113
|
-
this.shaderLayout.bindings.find(
|
|
114
|
-
this.shaderLayout.bindings.find(
|
|
113
|
+
this.shaderLayout.bindings.find(binding_ => binding_.name === name) ||
|
|
114
|
+
this.shaderLayout.bindings.find(binding_ => binding_.name === `${name}Uniforms`);
|
|
115
115
|
|
|
116
116
|
if (!binding) {
|
|
117
117
|
const validBindings = this.shaderLayout.bindings
|
|
118
|
-
.map(
|
|
118
|
+
.map(binding_ => `"${binding_.name}"`)
|
|
119
119
|
.join(', ');
|
|
120
120
|
if (!options?.disableWarnings) {
|
|
121
121
|
log.warn(
|
|
@@ -317,22 +317,37 @@ export class WEBGLRenderPipeline extends RenderPipeline {
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
/** Report link status. First, check for shader compilation failures if linking fails */
|
|
320
|
-
_reportLinkStatus(status: 'success' | 'linking' | 'validation') {
|
|
320
|
+
async _reportLinkStatus(status: 'success' | 'linking' | 'validation'): Promise<void> {
|
|
321
321
|
switch (status) {
|
|
322
322
|
case 'success':
|
|
323
323
|
return;
|
|
324
324
|
|
|
325
325
|
default:
|
|
326
326
|
// First check for shader compilation failures if linking fails
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
327
|
+
switch (this.vs.compilationStatus) {
|
|
328
|
+
case 'error':
|
|
329
|
+
this.vs.debugShader();
|
|
330
|
+
throw new Error(`Error during compilation of shader ${this.vs.id}`);
|
|
331
|
+
case 'pending':
|
|
332
|
+
this.vs.asyncCompilationStatus.then(() => this.vs.debugShader());
|
|
333
|
+
break;
|
|
334
|
+
case 'success':
|
|
335
|
+
break;
|
|
330
336
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
337
|
+
|
|
338
|
+
switch (this.fs?.compilationStatus) {
|
|
339
|
+
case 'error':
|
|
340
|
+
this.fs.debugShader();
|
|
341
|
+
throw new Error(`Error during compilation of shader ${this.fs.id}`);
|
|
342
|
+
case 'pending':
|
|
343
|
+
this.fs.asyncCompilationStatus.then(() => this.fs.debugShader());
|
|
344
|
+
break;
|
|
345
|
+
case 'success':
|
|
346
|
+
break;
|
|
334
347
|
}
|
|
335
|
-
|
|
348
|
+
|
|
349
|
+
const linkErrorLog = this.device.gl.getProgramInfoLog(this.handle);
|
|
350
|
+
throw new Error(`Error during ${status}: ${linkErrorLog}`);
|
|
336
351
|
}
|
|
337
352
|
}
|
|
338
353
|
|
|
@@ -39,14 +39,18 @@ export class WEBGLShader extends Shader {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
get asyncCompilationStatus(): Promise<'pending' | 'success' | 'error'> {
|
|
43
|
+
return this._waitForCompilationComplete().then(() => this.compilationStatus);
|
|
44
|
+
}
|
|
45
|
+
|
|
42
46
|
override async getCompilationInfo(): Promise<readonly CompilerMessage[]> {
|
|
43
47
|
await this._waitForCompilationComplete();
|
|
44
48
|
return this.getCompilationInfoSync();
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
override getCompilationInfoSync(): readonly CompilerMessage[] {
|
|
48
|
-
const
|
|
49
|
-
return
|
|
52
|
+
const shaderLog = this.device.gl.getShaderInfoLog(this.handle);
|
|
53
|
+
return shaderLog ? parseShaderCompilerLog(shaderLog) : [];
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
override getTranslatedSource(): string | null {
|
|
@@ -59,9 +63,7 @@ export class WEBGLShader extends Shader {
|
|
|
59
63
|
|
|
60
64
|
/** Compile a shader and get compilation status */
|
|
61
65
|
protected async _compile(source: string): Promise<void> {
|
|
62
|
-
|
|
63
|
-
source.startsWith('#version ') ? source : `#version 300 es\n${source}`;
|
|
64
|
-
source = addGLSLVersion(source);
|
|
66
|
+
source = source.startsWith('#version ') ? source : `#version 300 es\n${source}`;
|
|
65
67
|
|
|
66
68
|
const {gl} = this.device;
|
|
67
69
|
gl.shaderSource(this.handle, source);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import {Adapter, Device, DeviceProps,
|
|
5
|
+
import {Adapter, Device, DeviceProps, log} from '@luma.gl/core';
|
|
6
6
|
import {WebGLDevice} from './webgl-device';
|
|
7
7
|
import {enforceWebGL2} from '../context/polyfills/polyfill-webgl1-extensions';
|
|
8
8
|
import {loadSpectorJS, DEFAULT_SPECTOR_PROPS} from '../context/debug/spector';
|
|
@@ -52,7 +52,7 @@ export class WebGLAdapter extends Adapter {
|
|
|
52
52
|
if (!isWebGL(gl)) {
|
|
53
53
|
throw new Error('Invalid WebGL2RenderingContext');
|
|
54
54
|
}
|
|
55
|
-
return new WebGLDevice({
|
|
55
|
+
return new WebGLDevice({_handle: gl as WebGL2RenderingContext});
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
async create(props: DeviceProps = {}): Promise<WebGLDevice> {
|
|
@@ -61,20 +61,14 @@ export class WebGLAdapter extends Adapter {
|
|
|
61
61
|
const promises: Promise<unknown>[] = [];
|
|
62
62
|
|
|
63
63
|
// Load webgl and spector debug scripts from CDN if requested
|
|
64
|
-
if (props.
|
|
64
|
+
if (props.debugWebGL) {
|
|
65
65
|
promises.push(loadWebGLDeveloperTools());
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
if (props.
|
|
68
|
+
if (props.debugSpectorJS) {
|
|
69
69
|
promises.push(loadSpectorJS(props));
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
// Wait for page to load: if canvas is a string we need to query the DOM for the canvas element.
|
|
73
|
-
// We only wait when props.canvas is string to avoids setting the global page onload callback unless necessary.
|
|
74
|
-
if (typeof props.canvas === 'string') {
|
|
75
|
-
promises.push(CanvasContext.pageLoaded);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
72
|
// Wait for all the loads to settle before creating the context.
|
|
79
73
|
// The Device.create() functions are async, so in contrast to the constructor, we can `await` here.
|
|
80
74
|
const results = await Promise.allSettled(promises);
|
|
@@ -84,8 +78,6 @@ export class WebGLAdapter extends Adapter {
|
|
|
84
78
|
}
|
|
85
79
|
}
|
|
86
80
|
|
|
87
|
-
log.probe(LOG_LEVEL + 1, 'DOM is loaded')();
|
|
88
|
-
|
|
89
81
|
const device = new WebGLDevice(props);
|
|
90
82
|
|
|
91
83
|
// Log some debug info about the newly created context
|
|
@@ -12,28 +12,7 @@ import type {
|
|
|
12
12
|
Texture,
|
|
13
13
|
Framebuffer,
|
|
14
14
|
VertexArray,
|
|
15
|
-
VertexArrayProps
|
|
16
|
-
} from '@luma.gl/core';
|
|
17
|
-
import {Device, CanvasContext, log} from '@luma.gl/core';
|
|
18
|
-
import type {GLExtensions} from '@luma.gl/constants';
|
|
19
|
-
import {WebGLStateTracker} from '../context/state-tracker/webgl-state-tracker';
|
|
20
|
-
import {createBrowserContext} from '../context/helpers/create-browser-context';
|
|
21
|
-
import {getDeviceInfo} from './device-helpers/webgl-device-info';
|
|
22
|
-
import {WebGLDeviceFeatures} from './device-helpers/webgl-device-features';
|
|
23
|
-
import {WebGLDeviceLimits} from './device-helpers/webgl-device-limits';
|
|
24
|
-
import {WebGLCanvasContext} from './webgl-canvas-context';
|
|
25
|
-
import type {Spector} from '../context/debug/spector-types';
|
|
26
|
-
import {initializeSpectorJS} from '../context/debug/spector';
|
|
27
|
-
import {makeDebugContext} from '../context/debug/webgl-developer-tools';
|
|
28
|
-
import {
|
|
29
|
-
isTextureFormatSupported,
|
|
30
|
-
isTextureFormatRenderable,
|
|
31
|
-
isTextureFormatFilterable
|
|
32
|
-
} from './converters/texture-formats';
|
|
33
|
-
import {uid} from '../utils/uid';
|
|
34
|
-
|
|
35
|
-
// WebGL classes
|
|
36
|
-
import type {
|
|
15
|
+
VertexArrayProps,
|
|
37
16
|
BufferProps,
|
|
38
17
|
ShaderProps,
|
|
39
18
|
// Sampler,
|
|
@@ -55,6 +34,23 @@ import type {
|
|
|
55
34
|
TransformFeedbackProps,
|
|
56
35
|
QuerySetProps
|
|
57
36
|
} from '@luma.gl/core';
|
|
37
|
+
import {Device, CanvasContext, log} from '@luma.gl/core';
|
|
38
|
+
import type {GLExtensions} from '@luma.gl/constants';
|
|
39
|
+
import {WebGLStateTracker} from '../context/state-tracker/webgl-state-tracker';
|
|
40
|
+
import {createBrowserContext} from '../context/helpers/create-browser-context';
|
|
41
|
+
import {getDeviceInfo} from './device-helpers/webgl-device-info';
|
|
42
|
+
import {WebGLDeviceFeatures} from './device-helpers/webgl-device-features';
|
|
43
|
+
import {WebGLDeviceLimits} from './device-helpers/webgl-device-limits';
|
|
44
|
+
import {WebGLCanvasContext} from './webgl-canvas-context';
|
|
45
|
+
import type {Spector} from '../context/debug/spector-types';
|
|
46
|
+
import {initializeSpectorJS} from '../context/debug/spector';
|
|
47
|
+
import {makeDebugContext} from '../context/debug/webgl-developer-tools';
|
|
48
|
+
import {
|
|
49
|
+
isTextureFormatSupported,
|
|
50
|
+
isTextureFormatRenderable,
|
|
51
|
+
isTextureFormatFilterable
|
|
52
|
+
} from './converters/texture-formats';
|
|
53
|
+
import {uid} from '../utils/uid';
|
|
58
54
|
|
|
59
55
|
import {WEBGLBuffer} from './resources/webgl-buffer';
|
|
60
56
|
import {WEBGLShader} from './resources/webgl-shader';
|
|
@@ -120,35 +116,62 @@ export class WebGLDevice extends Device {
|
|
|
120
116
|
constructor(props: DeviceProps) {
|
|
121
117
|
super({...props, id: props.id || uid('webgl-device')});
|
|
122
118
|
|
|
119
|
+
// WebGL requires a canvas to be created before creating the context
|
|
120
|
+
if (!props.createCanvasContext) {
|
|
121
|
+
throw new Error('WebGLDevice requires props.createCanvasContext to be set');
|
|
122
|
+
}
|
|
123
|
+
const canvasContextProps = props.createCanvasContext === true ? {} : props.createCanvasContext;
|
|
124
|
+
|
|
123
125
|
// If attaching to an already attached context, return the attached device
|
|
124
126
|
// @ts-expect-error device is attached to context
|
|
125
|
-
|
|
127
|
+
let device: WebGLDevice | undefined = canvasContextProps.canvas?.gl?.device;
|
|
126
128
|
if (device) {
|
|
127
129
|
throw new Error(`WebGL context already attached to device ${device.id}`);
|
|
128
130
|
}
|
|
129
131
|
|
|
130
132
|
// Create and instrument context
|
|
131
|
-
|
|
132
|
-
this.canvasContext = new WebGLCanvasContext(this, {...props, canvas});
|
|
133
|
+
this.canvasContext = new WebGLCanvasContext(this, canvasContextProps);
|
|
133
134
|
|
|
134
135
|
this.lost = new Promise<{reason: 'destroyed'; message: string}>(resolve => {
|
|
135
136
|
this._resolveContextLost = resolve;
|
|
136
137
|
});
|
|
137
138
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
this.gl = this.handle;
|
|
139
|
+
const webglContextAttributes: WebGLContextAttributes = {...props.webgl};
|
|
140
|
+
// Copy props from CanvasContextProps
|
|
141
|
+
if (canvasContextProps.alphaMode === 'premultiplied') {
|
|
142
|
+
webglContextAttributes.premultipliedAlpha = true;
|
|
143
|
+
}
|
|
144
|
+
if (props.powerPreference !== undefined) {
|
|
145
|
+
webglContextAttributes.powerPreference = props.powerPreference;
|
|
146
|
+
}
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
const gl = createBrowserContext(
|
|
149
|
+
this.canvasContext.canvas,
|
|
150
|
+
{
|
|
151
|
+
onContextLost: (event: Event) =>
|
|
152
|
+
this._resolveContextLost?.({
|
|
153
|
+
reason: 'destroyed',
|
|
154
|
+
message: 'Entered sleep mode, or too many apps or browser tabs are using the GPU.'
|
|
155
|
+
}),
|
|
156
|
+
// eslint-disable-next-line no-console
|
|
157
|
+
onContextRestored: (event: Event) => console.log('WebGL context restored')
|
|
158
|
+
},
|
|
159
|
+
webglContextAttributes
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
if (!gl) {
|
|
149
163
|
throw new Error('WebGL context creation failed');
|
|
150
164
|
}
|
|
151
165
|
|
|
166
|
+
// @ts-expect-error device is attached to context
|
|
167
|
+
device = gl.device;
|
|
168
|
+
if (device) {
|
|
169
|
+
throw new Error(`WebGL context already attached to device ${device.id}`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
this.handle = gl;
|
|
173
|
+
this.gl = gl;
|
|
174
|
+
|
|
152
175
|
// Add spector debug instrumentation to context
|
|
153
176
|
// We need to trust spector integration to decide if spector should be initialized
|
|
154
177
|
// We also run spector instrumentation first, otherwise spector can clobber luma instrumentation.
|
|
@@ -161,8 +184,12 @@ export class WebGLDevice extends Device {
|
|
|
161
184
|
// initialize luma Device fields
|
|
162
185
|
this.info = getDeviceInfo(this.gl, this._extensions);
|
|
163
186
|
this.limits = new WebGLDeviceLimits(this.gl);
|
|
164
|
-
this.features = new WebGLDeviceFeatures(
|
|
165
|
-
|
|
187
|
+
this.features = new WebGLDeviceFeatures(
|
|
188
|
+
this.gl,
|
|
189
|
+
this._extensions,
|
|
190
|
+
this.props._disabledFeatures
|
|
191
|
+
);
|
|
192
|
+
if (this.props._initializeFeatures) {
|
|
166
193
|
this.features.initializeFeatures();
|
|
167
194
|
}
|
|
168
195
|
|
|
@@ -175,8 +202,8 @@ export class WebGLDevice extends Device {
|
|
|
175
202
|
glState.trackState(this.gl, {copyState: false});
|
|
176
203
|
|
|
177
204
|
// DEBUG contexts: Add luma debug instrumentation to the context, force log level to at least 1
|
|
178
|
-
if (props.
|
|
179
|
-
this.gl = makeDebugContext(this.gl, {...props
|
|
205
|
+
if (props.debugWebGL) {
|
|
206
|
+
this.gl = makeDebugContext(this.gl, {...props});
|
|
180
207
|
this.debug = true;
|
|
181
208
|
log.level = Math.max(log.level, 1);
|
|
182
209
|
log.warn('WebGL debug mode activated. Performance reduced.')();
|
|
@@ -212,7 +239,7 @@ export class WebGLDevice extends Device {
|
|
|
212
239
|
}
|
|
213
240
|
|
|
214
241
|
createBuffer(props: BufferProps | ArrayBuffer | ArrayBufferView): WEBGLBuffer {
|
|
215
|
-
const newProps = this.
|
|
242
|
+
const newProps = this._normalizeBufferProps(props);
|
|
216
243
|
return new WEBGLBuffer(this, newProps);
|
|
217
244
|
}
|
|
218
245
|
|