@luma.gl/webgl 9.0.0-alpha.20 → 9.0.0-alpha.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/dist/adapter/converters/device-parameters.d.ts +1 -1
  2. package/dist/adapter/converters/device-parameters.d.ts.map +1 -1
  3. package/dist/adapter/converters/device-parameters.js +10 -10
  4. package/dist/adapter/converters/device-parameters.js.map +1 -1
  5. package/dist/adapter/converters/sampler-parameters.d.ts +1 -1
  6. package/dist/adapter/converters/sampler-parameters.d.ts.map +1 -1
  7. package/dist/adapter/converters/sampler-parameters.js +1 -1
  8. package/dist/adapter/converters/sampler-parameters.js.map +1 -1
  9. package/dist/adapter/converters/texture-formats.d.ts +27 -38
  10. package/dist/adapter/converters/texture-formats.d.ts.map +1 -1
  11. package/dist/adapter/converters/texture-formats.js +152 -114
  12. package/dist/adapter/converters/texture-formats.js.map +1 -1
  13. package/dist/adapter/helpers/attribute-utils.d.ts +1 -1
  14. package/dist/adapter/helpers/attribute-utils.d.ts.map +1 -1
  15. package/dist/adapter/helpers/attribute-utils.js +1 -1
  16. package/dist/adapter/helpers/attribute-utils.js.map +1 -1
  17. package/dist/adapter/helpers/get-shader-info.d.ts.map +1 -1
  18. package/dist/adapter/helpers/get-shader-info.js.map +1 -1
  19. package/dist/adapter/helpers/get-shader-layout.js +1 -1
  20. package/dist/adapter/helpers/get-shader-layout.js.map +1 -1
  21. package/dist/adapter/helpers/uniforms.d.ts +7 -8
  22. package/dist/adapter/helpers/uniforms.d.ts.map +1 -1
  23. package/dist/adapter/helpers/uniforms.js +4 -4
  24. package/dist/adapter/helpers/uniforms.js.map +1 -1
  25. package/dist/adapter/objects/constants-to-keys.d.ts +0 -2
  26. package/dist/adapter/objects/constants-to-keys.d.ts.map +1 -1
  27. package/dist/adapter/objects/constants-to-keys.js +0 -20
  28. package/dist/adapter/objects/constants-to-keys.js.map +1 -1
  29. package/dist/adapter/objects/webgl-renderbuffer.d.ts +14 -11
  30. package/dist/adapter/objects/webgl-renderbuffer.d.ts.map +1 -1
  31. package/dist/adapter/objects/webgl-renderbuffer.js +31 -21
  32. package/dist/adapter/objects/webgl-renderbuffer.js.map +1 -1
  33. package/dist/adapter/objects/webgl-resource.d.ts +2 -3
  34. package/dist/adapter/objects/webgl-resource.d.ts.map +1 -1
  35. package/dist/adapter/objects/webgl-resource.js +6 -9
  36. package/dist/adapter/objects/webgl-resource.js.map +1 -1
  37. package/dist/adapter/objects/webgl-vertex-array-object.d.ts +6 -6
  38. package/dist/adapter/objects/webgl-vertex-array-object.d.ts.map +1 -1
  39. package/dist/adapter/objects/webgl-vertex-array-object.js +2 -2
  40. package/dist/adapter/objects/webgl-vertex-array-object.js.map +1 -1
  41. package/dist/adapter/resources/webgl-buffer.d.ts +2 -2
  42. package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
  43. package/dist/adapter/resources/webgl-buffer.js +4 -3
  44. package/dist/adapter/resources/webgl-buffer.js.map +1 -1
  45. package/dist/adapter/resources/webgl-command-buffer.d.ts +9 -3
  46. package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
  47. package/dist/adapter/resources/webgl-command-buffer.js +168 -25
  48. package/dist/adapter/resources/webgl-command-buffer.js.map +1 -1
  49. package/dist/adapter/resources/webgl-command-encoder.d.ts +5 -4
  50. package/dist/adapter/resources/webgl-command-encoder.d.ts.map +1 -1
  51. package/dist/adapter/resources/webgl-command-encoder.js +7 -3
  52. package/dist/adapter/resources/webgl-command-encoder.js.map +1 -1
  53. package/dist/adapter/resources/webgl-external-texture.js.map +1 -1
  54. package/dist/adapter/resources/webgl-framebuffer.d.ts +18 -21
  55. package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
  56. package/dist/adapter/resources/webgl-framebuffer.js +36 -86
  57. package/dist/adapter/resources/webgl-framebuffer.js.map +1 -1
  58. package/dist/adapter/resources/webgl-render-pass.d.ts +18 -3
  59. package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
  60. package/dist/adapter/resources/webgl-render-pass.js +81 -1
  61. package/dist/adapter/resources/webgl-render-pass.js.map +1 -1
  62. package/dist/adapter/resources/webgl-render-pipeline.d.ts +5 -5
  63. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  64. package/dist/adapter/resources/webgl-render-pipeline.js +7 -8
  65. package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -1
  66. package/dist/adapter/resources/webgl-sampler.d.ts +3 -3
  67. package/dist/adapter/resources/webgl-sampler.d.ts.map +1 -1
  68. package/dist/adapter/resources/webgl-sampler.js +2 -2
  69. package/dist/adapter/resources/webgl-sampler.js.map +1 -1
  70. package/dist/adapter/resources/webgl-shader.d.ts +2 -2
  71. package/dist/adapter/resources/webgl-shader.d.ts.map +1 -1
  72. package/dist/adapter/resources/webgl-shader.js +1 -1
  73. package/dist/adapter/resources/webgl-shader.js.map +1 -1
  74. package/dist/adapter/resources/webgl-texture.d.ts +41 -21
  75. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  76. package/dist/adapter/resources/webgl-texture.js +35 -33
  77. package/dist/adapter/resources/webgl-texture.js.map +1 -1
  78. package/dist/adapter/webgl-canvas-context.d.ts +4 -5
  79. package/dist/adapter/webgl-canvas-context.d.ts.map +1 -1
  80. package/dist/adapter/webgl-canvas-context.js +2 -2
  81. package/dist/adapter/webgl-canvas-context.js.map +1 -1
  82. package/dist/adapter/webgl-device.d.ts +22 -15
  83. package/dist/adapter/webgl-device.d.ts.map +1 -1
  84. package/dist/adapter/webgl-device.js +29 -11
  85. package/dist/adapter/webgl-device.js.map +1 -1
  86. package/dist/classic/accessor.d.ts +1 -1
  87. package/dist/classic/accessor.d.ts.map +1 -1
  88. package/dist/classic/accessor.js +1 -1
  89. package/dist/classic/accessor.js.map +1 -1
  90. package/dist/classic/buffer.d.ts +3 -4
  91. package/dist/classic/buffer.d.ts.map +1 -1
  92. package/dist/classic/buffer.js +4 -10
  93. package/dist/classic/buffer.js.map +1 -1
  94. package/dist/classic/typed-array-utils.d.ts +15 -17
  95. package/dist/classic/typed-array-utils.d.ts.map +1 -1
  96. package/dist/classic/typed-array-utils.js +1 -1
  97. package/dist/classic/typed-array-utils.js.map +1 -1
  98. package/dist/context/context/create-browser-context.js.map +1 -1
  99. package/dist/context/parameters/unified-parameter-api.d.ts +1 -1
  100. package/dist/context/parameters/unified-parameter-api.d.ts.map +1 -1
  101. package/dist/context/parameters/unified-parameter-api.js +1 -1
  102. package/dist/context/parameters/unified-parameter-api.js.map +1 -1
  103. package/dist/context/parameters/webgl-parameter-tables.d.ts +1 -2
  104. package/dist/context/parameters/webgl-parameter-tables.d.ts.map +1 -1
  105. package/dist/context/parameters/webgl-parameter-tables.js +1 -1
  106. package/dist/context/parameters/webgl-parameter-tables.js.map +1 -1
  107. package/dist/context/state-tracker/with-parameters.js +1 -1
  108. package/dist/context/state-tracker/with-parameters.js.map +1 -1
  109. package/dist/dist.dev.js +1107 -676
  110. package/dist/index.cjs +1088 -901
  111. package/dist/index.d.ts +18 -17
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +17 -16
  114. package/dist/index.js.map +1 -1
  115. package/dist.min.js +22 -21
  116. package/package.json +7 -4
  117. package/src/adapter/converters/device-parameters.ts +47 -23
  118. package/src/adapter/converters/sampler-parameters.ts +1 -2
  119. package/src/adapter/converters/texture-formats.ts +242 -161
  120. package/src/adapter/helpers/attribute-utils.ts +1 -2
  121. package/src/adapter/helpers/get-shader-info.ts +3 -0
  122. package/src/adapter/helpers/get-shader-layout.ts +1 -1
  123. package/src/adapter/helpers/uniforms.ts +9 -10
  124. package/src/adapter/objects/constants-to-keys.ts +0 -25
  125. package/src/adapter/objects/webgl-renderbuffer.ts +35 -32
  126. package/src/adapter/objects/webgl-resource.ts +6 -10
  127. package/src/adapter/objects/webgl-vertex-array-object.ts +6 -6
  128. package/src/adapter/resources/webgl-buffer.ts +6 -7
  129. package/src/adapter/resources/webgl-command-buffer.ts +330 -23
  130. package/src/adapter/resources/webgl-command-encoder.ts +9 -4
  131. package/src/adapter/resources/webgl-external-texture.ts +1 -1
  132. package/src/adapter/resources/webgl-framebuffer.ts +75 -123
  133. package/src/adapter/resources/webgl-render-pass.ts +148 -4
  134. package/src/adapter/resources/webgl-render-pipeline.ts +12 -9
  135. package/src/adapter/resources/webgl-sampler.ts +3 -4
  136. package/src/adapter/resources/webgl-shader.ts +2 -2
  137. package/src/adapter/resources/webgl-texture.ts +64 -46
  138. package/src/adapter/webgl-canvas-context.ts +5 -5
  139. package/src/adapter/webgl-device.ts +47 -18
  140. package/src/classic/accessor.ts +1 -1
  141. package/src/classic/buffer.ts +7 -7
  142. package/src/classic/typed-array-utils.ts +15 -26
  143. package/src/context/context/create-browser-context.ts +2 -2
  144. package/src/context/parameters/unified-parameter-api.ts +2 -2
  145. package/src/context/parameters/webgl-parameter-tables.ts +2 -2
  146. package/src/context/state-tracker/with-parameters.ts +1 -1
  147. package/src/index.ts +24 -22
  148. package/dist/adapter/converters/renderbuffer-formats.d.ts +0 -16
  149. package/dist/adapter/converters/renderbuffer-formats.d.ts.map +0 -1
  150. package/dist/adapter/converters/renderbuffer-formats.js +0 -181
  151. package/dist/adapter/converters/renderbuffer-formats.js.map +0 -1
  152. package/dist/types/webgl.d.ts +0 -145
  153. package/dist/types/webgl.d.ts.map +0 -1
  154. package/dist/types/webgl.js +0 -2
  155. package/dist/types/webgl.js.map +0 -1
  156. package/src/adapter/converters/renderbuffer-formats.ts +0 -92
  157. package/src/types/webgl.ts +0 -286
@@ -21,28 +21,3 @@ export function getKeyValue(gl: WebGLRenderingContext, name: string | GL): GL {
21
21
  assert(value !== undefined, `Accessing undefined constant GL.${name}`);
22
22
  return value;
23
23
  }
24
-
25
- export function getKey(gl: WebGLRenderingContext, value: any): string {
26
- // @ts-ignore expect-error depends on settings
27
- gl = gl.gl || gl;
28
- value = Number(value);
29
- for (const key in gl) {
30
- // @ts-ignore expect-error depends on settings
31
- if (gl[key] === value) {
32
- return `GL.${key}`;
33
- }
34
- }
35
- return String(value);
36
- }
37
-
38
- export function getKeyType(gl: WebGLRenderingContext, value: any): string {
39
- assert(value !== undefined, 'undefined key');
40
- value = Number(value);
41
- for (const key in gl) {
42
- // @ts-ignore expect-error depends on settings
43
- if (gl[key] === value) {
44
- return `GL.${key}`;
45
- }
46
- }
47
- return String(value);
48
- }
@@ -1,29 +1,17 @@
1
- /* eslint-disable no-inline-comments */
2
- import {assert, ResourceProps} from '@luma.gl/api';
1
+ import {assert, ResourceProps, TextureFormat} from '@luma.gl/api';
3
2
  import GL from '@luma.gl/constants';
4
- import WebGLDevice from '../webgl-device';
5
- import WebGLResource from './webgl-resource';
6
- import {
7
- isRenderbufferFormatSupported, getRenderbufferFormatBytesPerPixel
8
- } from '../converters/renderbuffer-formats';
3
+ import {WebGLDevice} from '../webgl-device';
4
+ import {WebGLResource} from './webgl-resource';
5
+ import {isRenderbufferFormatSupported} from '../converters/texture-formats';
6
+ import {convertTextureFormatToGL, getTextureFormatBytesPerPixel} from '../converters/texture-formats';
9
7
 
10
8
  export type RenderbufferProps = ResourceProps & {
11
- format: number;
9
+ format: TextureFormat;
12
10
  width?: number;
13
11
  height?: number;
14
12
  samples?: number;
15
13
  };
16
14
 
17
- const DEFAULT_RENDERBUFFER_PROPS: Required<RenderbufferProps> = {
18
- id: undefined,
19
- handle: undefined,
20
- userData: undefined,
21
- format: 0,
22
- width: 1,
23
- height: 1,
24
- samples: 0
25
- };
26
-
27
15
  /**
28
16
  * Renderbuffers are GPU objects that contain images.
29
17
  * In contrast to Textures they are optimized for use as render targets, with Framebuffers.
@@ -34,36 +22,54 @@ const DEFAULT_RENDERBUFFER_PROPS: Required<RenderbufferProps> = {
34
22
  * use Textures instead.
35
23
  * Renderbuffer objects also natively accommodate Multisampling (MSAA).
36
24
  */
37
- export default class WEBGLRenderbuffer extends WebGLResource<RenderbufferProps> {
25
+ export class WEBGLRenderbuffer extends WebGLResource<RenderbufferProps> {
26
+ static override readonly defaultProps: Required<RenderbufferProps> = {
27
+ id: undefined,
28
+ handle: undefined,
29
+ userData: undefined,
30
+ format: undefined, // 'depth16unorm'
31
+ width: 1,
32
+ height: 1,
33
+ samples: 0
34
+ };
35
+
38
36
  override get [Symbol.toStringTag](): string { return 'Renderbuffer'; }
39
37
 
40
38
  get width(): number { return this.props.width; }
41
39
  get height(): number { return this.props.height; }
42
- get format(): number { return this.props.format; }
40
+ get format(): TextureFormat { return this.props.format; }
43
41
  get samples(): number { return this.props.samples; }
42
+ get attachment() { return }
44
43
 
45
- static isSupported(gl: WebGLRenderingContext, options?: {format?: number}): boolean {
46
- return !options?.format || isRenderbufferFormatSupported(gl, options.format);
44
+ /** WebGL format constant */
45
+ glFormat: GL;
46
+
47
+ static isTextureFormatSupported(device: WebGLDevice, format: TextureFormat): boolean {
48
+ return isRenderbufferFormatSupported(device.gl, format);
47
49
  }
48
50
 
49
51
  constructor(device: WebGLDevice, props: RenderbufferProps) {
50
- super(device, props, DEFAULT_RENDERBUFFER_PROPS);
52
+ // TODO - remove temporary sanity check
53
+ if (typeof props.format === 'number') {
54
+ throw new Error('Renderbuffer');
55
+ }
56
+ super(device, props, WEBGLRenderbuffer.defaultProps);
57
+ this.glFormat = convertTextureFormatToGL(this.props.format, device.isWebGL2);
51
58
  this._initialize(this.props);
52
59
  }
53
60
 
54
- resize(size: {width: number, height: number}): this {
61
+ resize(size: {width: number, height: number}): void {
55
62
  // Don't resize if width/height haven't changed
56
63
  if (size.width !== this.width || size.height !== this.height) {
57
64
  Object.assign(this.props, {...size, format: this.format, samples: this.samples});
58
65
  this._initialize(this.props);
59
66
  }
60
- return this;
61
67
  }
62
68
 
63
69
  // PRIVATE METHODS
64
70
 
65
71
  /** Creates and initializes a renderbuffer object's data store */
66
- protected _initialize(props: Required<RenderbufferProps>) {
72
+ protected _initialize(props: Required<RenderbufferProps>): void {
67
73
  const {format, width, height, samples} = props;
68
74
  assert(format, 'Needs format');
69
75
 
@@ -72,19 +78,16 @@ export default class WEBGLRenderbuffer extends WebGLResource<RenderbufferProps>
72
78
  this.gl.bindRenderbuffer(GL.RENDERBUFFER, this.handle);
73
79
 
74
80
  if (samples !== 0 && this.device.isWebGL2) {
75
- // @ts-expect-error
76
- this.gl.renderbufferStorageMultisample(GL.RENDERBUFFER, samples, format, width, height);
81
+ this.gl2.renderbufferStorageMultisample(GL.RENDERBUFFER, samples, this.glFormat, width, height);
77
82
  } else {
78
- this.gl.renderbufferStorage(GL.RENDERBUFFER, format, width, height);
83
+ this.gl.renderbufferStorage(GL.RENDERBUFFER, this.glFormat, width, height);
79
84
  }
80
85
 
81
86
  this.gl.bindRenderbuffer(GL.RENDERBUFFER, null);
82
87
 
83
88
  this.trackAllocatedMemory(
84
- width * height * (samples || 1) * getRenderbufferFormatBytesPerPixel(format)
89
+ width * height * (samples || 1) * getTextureFormatBytesPerPixel(this.glFormat, this.device.isWebGL2)
85
90
  );
86
-
87
- return this;
88
91
  }
89
92
 
90
93
  // RESOURCE IMPLEMENTATION
@@ -3,17 +3,17 @@ import {Resource, assert, uid, stubRemovedMethods} from '@luma.gl/api';
3
3
  import type {Device, ResourceProps} from '@luma.gl/api';
4
4
  import GL from '@luma.gl/constants';
5
5
  import {isWebGL2, assertWebGLContext} from '../../context/context/webgl-checks';
6
- import WebGLDevice from '../webgl-device';
6
+ import {WebGLDevice} from '../webgl-device';
7
7
 
8
8
  // Requires full GL enum to be bundled... Make these bindings dependent on dynamic import (debug)?
9
- import {getKey, getKeyValue} from './constants-to-keys';
9
+ import {getKeyValue} from './constants-to-keys';
10
10
 
11
11
  const ERR_RESOURCE_METHOD_UNDEFINED = 'Resource subclass must define virtual methods';
12
12
 
13
13
  /**
14
14
  * Base class for WebGL object wrappers
15
15
  */
16
- export default abstract class WebGLResource<Props extends ResourceProps> extends Resource<Props> {
16
+ export abstract class WebGLResource<Props extends ResourceProps> extends Resource<Props> {
17
17
  readonly device: WebGLDevice;
18
18
  readonly gl: WebGLRenderingContext;
19
19
  readonly gl2: WebGL2RenderingContext;
@@ -69,10 +69,6 @@ export default abstract class WebGLResource<Props extends ResourceProps> extends
69
69
  return this._handle;
70
70
  }
71
71
 
72
- override destroy(): void {
73
- this.delete();
74
- }
75
-
76
72
  override delete({deleteChildren = false} = {}) {
77
73
  // Delete this object, and get refs to any children
78
74
  // @ts-expect-error
@@ -86,7 +82,7 @@ export default abstract class WebGLResource<Props extends ResourceProps> extends
86
82
  // @ts-expect-error
87
83
  if (children && deleteChildren) {
88
84
  // @ts-expect-error
89
- children.filter(Boolean).forEach((child) => child.delete());
85
+ children.filter(Boolean).forEach((child) => child.destroy());
90
86
  }
91
87
 
92
88
  return this;
@@ -183,10 +179,10 @@ export default abstract class WebGLResource<Props extends ResourceProps> extends
183
179
  (!('extension' in parameter) || this.gl.getExtension(parameter.extension));
184
180
 
185
181
  if (parameterAvailable) {
186
- const key = keys ? getKey(this.gl, pname) : pname;
182
+ const key = keys ? this.device.getGLKey(pname) : pname;
187
183
  values[key] = this.getParameter(pname, options);
188
184
  if (keys && parameter.type === 'GLenum') {
189
- values[key] = getKey(this.gl, values[key]);
185
+ values[key] = this.device.getGLKey(values[key]);
190
186
  }
191
187
  }
192
188
  }
@@ -2,10 +2,10 @@ import {assert, ResourceProps} from '@luma.gl/api';
2
2
  import GL from '@luma.gl/constants';
3
3
  import {getBrowser} from '@probe.gl/env';
4
4
 
5
- import WebGLDevice from '../webgl-device';
6
- import WebGLResource from './webgl-resource';
5
+ import {WebGLDevice} from '../webgl-device';
6
+ import {WebGLResource} from './webgl-resource';
7
7
 
8
- import Buffer from '../resources/webgl-buffer';
8
+ import {WEBGLBuffer} from '../resources/webgl-buffer';
9
9
 
10
10
  const ERR_ELEMENTS = 'elements must be GL.ELEMENT_ARRAY_BUFFER';
11
11
 
@@ -16,7 +16,7 @@ export type VertexArrayObjectProps = ResourceProps & {
16
16
  };
17
17
 
18
18
  /** VertexArrayObject wrapper */
19
- export default class WEBGLVertexArrayObject extends WebGLResource<VertexArrayObjectProps> {
19
+ export class WEBGLVertexArrayObject extends WebGLResource<VertexArrayObjectProps> {
20
20
  override get [Symbol.toStringTag](): string {
21
21
  return 'BaseVertexArrayObject';
22
22
  }
@@ -43,7 +43,7 @@ export default class WEBGLVertexArrayObject extends WebGLResource<VertexArrayObj
43
43
 
44
44
  // Set (bind) an elements buffer, for indexed rendering.
45
45
  // Must be a Buffer bound to GL.ELEMENT_ARRAY_BUFFER. Constants not supported
46
- setElementBuffer(elementBuffer: Buffer | null = null, opts = {}) {
46
+ setElementBuffer(elementBuffer: WEBGLBuffer | null = null, opts = {}) {
47
47
  assert(!elementBuffer || elementBuffer.target === GL.ELEMENT_ARRAY_BUFFER, ERR_ELEMENTS);
48
48
 
49
49
  // The GL.ELEMENT_ARRAY_BUFFER_BINDING is stored on the VertexArrayObject...
@@ -55,7 +55,7 @@ export default class WEBGLVertexArrayObject extends WebGLResource<VertexArrayObj
55
55
  }
56
56
 
57
57
  /** Set a location in vertex attributes array to a buffer, enables the location, sets divisor */
58
- setBuffer(location: number, buffer: Buffer, accessor: any): this {
58
+ setBuffer(location: number, buffer: WEBGLBuffer, accessor: any): this {
59
59
  // Check target
60
60
  if (buffer.target === GL.ELEMENT_ARRAY_BUFFER) {
61
61
  return this.setElementBuffer(buffer, accessor);
@@ -1,12 +1,12 @@
1
1
  import type {BufferProps} from '@luma.gl/api';
2
2
  import {Buffer, assert} from '@luma.gl/api';
3
3
  import GL from '@luma.gl/constants';
4
- import WebGLDevice from '../webgl-device';
4
+ import {WebGLDevice} from '../webgl-device';
5
5
 
6
6
  const DEBUG_DATA_LENGTH = 10;
7
7
 
8
8
  /** WebGL Buffer interface */
9
- export default class WEBGLBuffer extends Buffer {
9
+ export class WEBGLBuffer extends Buffer {
10
10
  readonly device: WebGLDevice;
11
11
  readonly gl: WebGLRenderingContext;
12
12
  readonly gl2: WebGL2RenderingContext | null;
@@ -107,13 +107,14 @@ export default class WEBGLBuffer extends Buffer {
107
107
  this.trackDeallocatedMemory();
108
108
  this.gl.deleteBuffer(this.handle);
109
109
  this.destroyed = true;
110
- // this.handle = null;
110
+ // @ts-expect-error
111
+ this.handle = null;
111
112
  }
112
113
  }
113
114
 
114
115
  override write(data: ArrayBufferView, byteOffset: number = 0): void {
115
116
  const srcOffset = 0;
116
- const byteLength = data.byteLength;
117
+ const byteLength = undefined; // data.byteLength;
117
118
 
118
119
  // Create the buffer - binding it here for the first time locks the type
119
120
  // In WebGL2, use GL.COPY_WRITE_BUFFER to avoid locking the type
@@ -122,9 +123,7 @@ export default class WEBGLBuffer extends Buffer {
122
123
  // WebGL2: subData supports additional srcOffset and length parameters
123
124
  if (srcOffset !== 0 || byteLength !== undefined) {
124
125
  this.device.assertWebGL2();
125
-
126
- // @ts-expect-error
127
- this.gl.bufferSubData(this.target, byteOffset, data, srcOffset, byteLength);
126
+ this.gl2.bufferSubData(target, byteOffset, data, srcOffset, byteLength);
128
127
  } else {
129
128
  this.gl.bufferSubData(target, byteOffset, data);
130
129
  }
@@ -1,12 +1,24 @@
1
+ // luma.gl, MIT license
2
+
1
3
  import type {
2
4
  CopyBufferToBufferOptions,
3
5
  CopyBufferToTextureOptions,
4
6
  CopyTextureToBufferOptions,
5
7
  CopyTextureToTextureOptions
6
8
  } from '@luma.gl/api';
9
+ import {
10
+ CommandBuffer,
11
+ Texture,
12
+ // Buffer,
13
+ Framebuffer
14
+ } from '@luma.gl/api';
7
15
  import GL from '@luma.gl/constants';
8
- import WebGLDevice from '../webgl-device';
9
- import WEBGLBuffer from './webgl-buffer';
16
+
17
+ // import {getTypedArrayFromGLType, getGLTypeFromTypedArray} from '../../classic/typed-array-utils';
18
+ import {WebGLDevice} from '../webgl-device';
19
+ import {WEBGLBuffer} from './webgl-buffer';
20
+ import {WEBGLTexture} from './webgl-texture';
21
+ import {WEBGLFramebuffer} from './webgl-framebuffer';
10
22
 
11
23
  function cast<T>(value: unknown): T {
12
24
  return value as T;
@@ -38,25 +50,31 @@ type Command =
38
50
  | CopyTextureToBufferCommand
39
51
  | CopyTextureToTextureCommand;
40
52
 
41
- export default class CommandBuffer {
53
+ export class WEBGLCommandBuffer extends CommandBuffer {
54
+ device: WebGLDevice;
42
55
  commands: Command[] = [];
43
- }
44
56
 
45
- export function submitCommands(device: WebGLDevice, commands: Command[] = []) {
46
- for (const command of commands) {
47
- switch (command.name) {
48
- case 'copy-buffer-to-buffer':
49
- _copyBufferToBuffer(device, command.options);
50
- break;
51
- case 'copy-buffer-to-texture':
52
- _copyBufferToTexture(device, command.options);
53
- break;
54
- case 'copy-texture-to-buffer':
55
- _copyTextureToBuffer(device, command.options);
56
- break;
57
- case 'copy-texture-to-texture':
58
- _copyTextureToTexture(device, command.options);
59
- break;
57
+ constructor(device: WebGLDevice) {
58
+ super({});
59
+ this.device = device;
60
+ }
61
+
62
+ submitCommands(commands: Command[] = this.commands) {
63
+ for (const command of commands) {
64
+ switch (command.name) {
65
+ case 'copy-buffer-to-buffer':
66
+ _copyBufferToBuffer(this.device, command.options);
67
+ break;
68
+ case 'copy-buffer-to-texture':
69
+ _copyBufferToTexture(this.device, command.options);
70
+ break;
71
+ case 'copy-texture-to-buffer':
72
+ _copyTextureToBuffer(this.device, command.options);
73
+ break;
74
+ case 'copy-texture-to-texture':
75
+ _copyTextureToTexture(this.device, command.options);
76
+ break;
77
+ }
60
78
  }
61
79
  }
62
80
  }
@@ -65,7 +83,7 @@ function _copyBufferToBuffer(device: WebGLDevice, options: CopyBufferToBufferOpt
65
83
  const source = cast<WEBGLBuffer>(options.source);
66
84
  const destination = cast<WEBGLBuffer>(options.destination);
67
85
 
68
- const {gl2} = device;
86
+ const gl2 = device.assertWebGL2();
69
87
  if (gl2) {
70
88
  // In WebGL2 we can perform the copy on the GPU
71
89
  // Use GL.COPY_READ_BUFFER+GL.COPY_WRITE_BUFFER avoid disturbing other targets and locking type
@@ -87,8 +105,297 @@ function _copyBufferToBuffer(device: WebGLDevice, options: CopyBufferToBufferOpt
87
105
  }
88
106
  }
89
107
 
90
- function _copyBufferToTexture(device: WebGLDevice, options: CopyBufferToTextureOptions): void {}
108
+ /**
109
+ * Copies data from a Buffer object into a Texture object
110
+ * NOTE: doesn't wait for copy to be complete
111
+ */
112
+ function _copyBufferToTexture(device: WebGLDevice, options: CopyBufferToTextureOptions): void {
113
+ throw new Error('Not implemented');
114
+ }
115
+
116
+ /**
117
+ * Copies data from a Texture object into a Buffer object.
118
+ * NOTE: doesn't wait for copy to be complete
119
+ */
120
+ function _copyTextureToBuffer(device: WebGLDevice, options: CopyTextureToBufferOptions): void {
121
+ const {
122
+ /** Texture to copy to/from. */
123
+ source,
124
+ /** Mip-map level of the texture to copy to/from. (Default 0) */
125
+ mipLevel = 0,
126
+ /** Defines which aspects of the texture to copy to/from. */
127
+ aspect = 'all',
128
+
129
+ /** Width to copy */
130
+ width = options.source.width,
131
+ /** Height to copy */
132
+ height = options.source.height,
133
+ depthOrArrayLayers = 0,
134
+ /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
135
+ origin = [0, 0],
136
+
137
+ /** Destination buffer */
138
+ destination,
139
+ /** Offset, in bytes, from the beginning of the buffer to the start of the image data (default 0) */
140
+ byteOffset = 0,
141
+ /**
142
+ * The stride, in bytes, between the beginning of each block row and the subsequent block row.
143
+ * Required if there are multiple block rows (i.e. the copy height or depth is more than one block).
144
+ */
145
+ bytesPerRow,
146
+ /**
147
+ * Number of block rows per single image of the texture.
148
+ * rowsPerImage &times; bytesPerRow is the stride, in bytes, between the beginning of each image of data and the subsequent image.
149
+ * Required if there are multiple images (i.e. the copy depth is more than one).
150
+ */
151
+ rowsPerImage
152
+ } = options;
153
+
154
+ // TODO - Not possible to read just stencil or depth part in WebGL?
155
+ if (aspect !== 'all') {
156
+ throw new Error('not supported');
157
+ }
158
+
159
+ // TODO - mipLevels are set when attaching texture to framebuffer
160
+ if (mipLevel !== 0 || depthOrArrayLayers !== undefined || bytesPerRow || rowsPerImage) {
161
+ throw new Error('not implemented');
162
+ }
163
+
164
+ // Asynchronous read (PIXEL_PACK_BUFFER) is WebGL2 only feature
165
+ const gl2 = device.assertWebGL2();
166
+
167
+ const {framebuffer, destroyFramebuffer} = getFramebuffer(source);
168
+ try {
169
+ const webglBuffer = destination as WEBGLBuffer;
170
+ const sourceWidth = width || framebuffer.width;
171
+ const sourceHeight = height || framebuffer.height;
172
+
173
+ // TODO - hack - should be deduced
174
+ const sourceFormat = GL.RGBA;
175
+ const sourceType = GL.UNSIGNED_BYTE;
176
+
177
+ // if (!target) {
178
+ // // Create new buffer with enough size
179
+ // const components = glFormatToComponents(sourceFormat);
180
+ // const byteCount = glTypeToBytes(sourceType);
181
+ // const byteLength = byteOffset + sourceWidth * sourceHeight * components * byteCount;
182
+ // target = device.createBuffer({byteLength});
183
+ // }
184
+
185
+ gl2.bindBuffer(GL.PIXEL_PACK_BUFFER, webglBuffer.handle);
186
+ gl2.bindFramebuffer(GL.FRAMEBUFFER, framebuffer.handle);
187
+
188
+ gl2.readPixels(
189
+ origin[0],
190
+ origin[1],
191
+ sourceWidth,
192
+ sourceHeight,
193
+ sourceFormat,
194
+ sourceType,
195
+ byteOffset
196
+ );
197
+ } finally {
198
+ gl2.bindBuffer(GL.PIXEL_PACK_BUFFER, null);
199
+ gl2.bindFramebuffer(GL.FRAMEBUFFER, null);
200
+
201
+ if (destroyFramebuffer) {
202
+ framebuffer.destroy();
203
+ }
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Copies data from a Framebuffer or a Texture object into a Buffer object.
209
+ * NOTE: doesn't wait for copy to be complete, it programs GPU to perform a DMA transfer.
210
+ export function readPixelsToBuffer(
211
+ source: Framebuffer | Texture,
212
+ options?: {
213
+ sourceX?: number;
214
+ sourceY?: number;
215
+ sourceFormat?: number;
216
+ target?: Buffer; // A new Buffer object is created when not provided.
217
+ targetByteOffset?: number; // byte offset in buffer object
218
+ // following parameters are auto deduced if not provided
219
+ sourceWidth?: number;
220
+ sourceHeight?: number;
221
+ sourceType?: number;
222
+ }
223
+ ): Buffer
224
+ */
225
+
226
+ /**
227
+ * Copy a rectangle from a Framebuffer or Texture object into a texture (at an offset)
228
+ */
229
+ // eslint-disable-next-line complexity, max-statements
230
+ function _copyTextureToTexture(device: WebGLDevice, options: CopyTextureToTextureOptions): void {
231
+ const {
232
+ /** Texture to copy to/from. */
233
+ source,
234
+ /** Mip-map level of the texture to copy to/from. (Default 0) */
235
+ // mipLevel = 0,
236
+ /** Defines which aspects of the texture to copy to/from. */
237
+ // aspect = 'all',
238
+ /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
239
+ origin = [0, 0],
240
+
241
+ /** Texture to copy to/from. */
242
+ destination,
243
+ /** Mip-map level of the texture to copy to/from. (Default 0) */
244
+ // destinationMipLevel = options.mipLevel,
245
+ /** Defines the origin of the copy - the minimum corner of the texture sub-region to copy to/from. */
246
+ // destinationOrigin = [0, 0],
247
+ /** Defines which aspects of the texture to copy to/from. */
248
+ // destinationAspect = options.aspect,
249
+
250
+ } = options;
251
+
252
+ let {
253
+ width = options.destination.width,
254
+ height = options.destination.width,
255
+ // depthOrArrayLayers = 0
256
+ } = options;
257
+
258
+ const destinationMipmaplevel = 0;
259
+ const destinationInternalFormat = GL.RGBA;
260
+
261
+ const {framebuffer, destroyFramebuffer} = getFramebuffer(source);
262
+ const [sourceX, sourceY] = origin;
263
+
264
+ const isSubCopy = false;
265
+ // typeof destinationX !== 'undefined' ||
266
+ // typeof destinationY !== 'undefined' ||
267
+ // typeof destinationZ !== 'undefined';
268
+
269
+ // destinationX = destinationX || 0;
270
+ // destinationY = destinationY || 0;
271
+ // destinationZ = destinationZ || 0;
272
+ device.gl.bindFramebuffer(GL.FRAMEBUFFER, framebuffer.handle);
273
+ // TODO - support gl.readBuffer (WebGL2 only)
274
+ // const prevBuffer = gl.readBuffer(attachment);
275
+
276
+ let texture = null;
277
+ let textureTarget: GL;
278
+ if (destination instanceof WEBGLTexture) {
279
+ texture = destination;
280
+ width = Number.isFinite(width) ? width : texture.width;
281
+ height = Number.isFinite(height) ? height : texture.height;
282
+ texture.bind(0);
283
+ textureTarget = texture.destination;
284
+ } else {
285
+ throw new Error('whoops');
286
+ // textureTarget = destination;
287
+ }
288
+
289
+ if (!isSubCopy) {
290
+ device.gl.copyTexImage2D(
291
+ textureTarget,
292
+ destinationMipmaplevel,
293
+ destinationInternalFormat,
294
+ sourceX,
295
+ sourceY,
296
+ width,
297
+ height,
298
+ 0 /* border must be 0 */
299
+ );
300
+ } else {
301
+ // switch (textureTarget) {
302
+ // case GL.TEXTURE_2D:
303
+ // case GL.TEXTURE_CUBE_MAP:
304
+ // device.gl.copyTexSubImage2D(
305
+ // textureTarget,
306
+ // destinationMipmaplevel,
307
+ // destinationX,
308
+ // destinationY,
309
+ // sourceX,
310
+ // sourceY,
311
+ // width,
312
+ // height
313
+ // );
314
+ // break;
315
+ // case GL.TEXTURE_2D_ARRAY:
316
+ // case GL.TEXTURE_3D:
317
+ // const gl2 = device.assertWebGL2();
318
+ // gl2.copyTexSubImage3D(
319
+ // textureTarget,
320
+ // destinationMipmaplevel,
321
+ // destinationX,
322
+ // destinationY,
323
+ // destinationZ,
324
+ // sourceX,
325
+ // sourceY,
326
+ // width,
327
+ // height
328
+ // );
329
+ // break;
330
+ // default:
331
+ // }
332
+ }
333
+ if (texture) {
334
+ texture.unbind();
335
+ }
336
+ // @ts-expect-error
337
+ device.gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle || null);
338
+ if (destroyFramebuffer) {
339
+ framebuffer.destroy();
340
+ }
341
+ return texture;
342
+ }
343
+
344
+ // Returns number of components in a specific readPixels WebGL format
345
+ export function glFormatToComponents(format): 1 | 2 | 3 | 4 {
346
+ switch (format) {
347
+ case GL.ALPHA:
348
+ case GL.R32F:
349
+ case GL.RED:
350
+ return 1;
351
+ case GL.RG32F:
352
+ case GL.RG:
353
+ return 2;
354
+ case GL.RGB:
355
+ case GL.RGB32F:
356
+ return 3;
357
+ case GL.RGBA:
358
+ case GL.RGBA32F:
359
+ return 4;
360
+ // TODO: Add support for additional WebGL2 formats
361
+ default:
362
+ throw new Error('GLFormat');
363
+ }
364
+ }
91
365
 
92
- function _copyTextureToBuffer(device: WebGLDevice, options: CopyTextureToBufferOptions): void {}
366
+ // Return byte count for given readPixels WebGL type
367
+ export function glTypeToBytes(type: GL): 1 | 2 | 4 {
368
+ switch (type) {
369
+ case GL.UNSIGNED_BYTE:
370
+ return 1;
371
+ case GL.UNSIGNED_SHORT_5_6_5:
372
+ case GL.UNSIGNED_SHORT_4_4_4_4:
373
+ case GL.UNSIGNED_SHORT_5_5_5_1:
374
+ return 2;
375
+ case GL.FLOAT:
376
+ return 4;
377
+ // TODO: Add support for additional WebGL2 types
378
+ default:
379
+ throw new Error('GLType');
380
+ }
381
+ }
382
+
383
+ // Helper methods
93
384
 
94
- function _copyTextureToTexture(device: WebGLDevice, options: CopyTextureToTextureOptions): void {}
385
+ function getFramebuffer(source: Texture | Framebuffer): {
386
+ framebuffer: WEBGLFramebuffer;
387
+ destroyFramebuffer: boolean;
388
+ } {
389
+ if (source instanceof Texture) {
390
+ const {width, height, id} = source;
391
+ const framebuffer = source.device.createFramebuffer({
392
+ id: `framebuffer-for-${id}`,
393
+ width,
394
+ height,
395
+ colorAttachments: [source]
396
+ }) as unknown as WEBGLFramebuffer;
397
+
398
+ return {framebuffer, destroyFramebuffer: true};
399
+ }
400
+ return {framebuffer: source as unknown as WEBGLFramebuffer, destroyFramebuffer: false};
401
+ }