@luma.gl/webgl 9.1.0-alpha.9 → 9.1.0-beta.11

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 (198) hide show
  1. package/dist/adapter/converters/device-parameters.d.ts +3 -3
  2. package/dist/adapter/converters/device-parameters.d.ts.map +1 -1
  3. package/dist/adapter/converters/device-parameters.js +1 -0
  4. package/dist/adapter/converters/device-parameters.js.map +1 -0
  5. package/dist/adapter/converters/sampler-parameters.js +7 -4
  6. package/dist/adapter/converters/sampler-parameters.js.map +1 -0
  7. package/dist/adapter/converters/shader-formats.js +1 -0
  8. package/dist/adapter/converters/shader-formats.js.map +1 -0
  9. package/dist/adapter/converters/vertex-formats.js +1 -0
  10. package/dist/adapter/converters/vertex-formats.js.map +1 -0
  11. package/dist/adapter/converters/webgl-texture-table.d.ts +40 -0
  12. package/dist/adapter/converters/webgl-texture-table.d.ts.map +1 -0
  13. package/dist/adapter/converters/webgl-texture-table.js +304 -0
  14. package/dist/adapter/converters/webgl-texture-table.js.map +1 -0
  15. package/dist/adapter/device-helpers/webgl-device-features.d.ts.map +1 -1
  16. package/dist/adapter/device-helpers/webgl-device-features.js +2 -2
  17. package/dist/adapter/device-helpers/webgl-device-features.js.map +1 -0
  18. package/dist/adapter/device-helpers/webgl-device-info.js +1 -0
  19. package/dist/adapter/device-helpers/webgl-device-info.js.map +1 -0
  20. package/dist/adapter/device-helpers/webgl-device-limits.js +1 -0
  21. package/dist/adapter/device-helpers/webgl-device-limits.js.map +1 -0
  22. package/dist/adapter/helpers/decode-webgl-types.js +1 -0
  23. package/dist/adapter/helpers/decode-webgl-types.js.map +1 -0
  24. package/dist/adapter/helpers/format-utils.d.ts.map +1 -0
  25. package/dist/{classic → adapter/helpers}/format-utils.js +7 -0
  26. package/dist/adapter/helpers/format-utils.js.map +1 -0
  27. package/dist/adapter/helpers/get-shader-layout.d.ts +1 -1
  28. package/dist/adapter/helpers/get-shader-layout.d.ts.map +1 -1
  29. package/dist/adapter/helpers/get-shader-layout.js +5 -4
  30. package/dist/adapter/helpers/get-shader-layout.js.map +1 -0
  31. package/dist/adapter/helpers/parse-shader-compiler-log.js +1 -0
  32. package/dist/adapter/helpers/parse-shader-compiler-log.js.map +1 -0
  33. package/dist/adapter/helpers/set-uniform.js +1 -0
  34. package/dist/adapter/helpers/set-uniform.js.map +1 -0
  35. package/dist/adapter/helpers/typed-array-utils.d.ts.map +1 -0
  36. package/dist/{classic → adapter/helpers}/typed-array-utils.js +1 -0
  37. package/dist/adapter/helpers/typed-array-utils.js.map +1 -0
  38. package/dist/adapter/helpers/webgl-texture-utils.d.ts +96 -25
  39. package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
  40. package/dist/adapter/helpers/webgl-texture-utils.js +225 -236
  41. package/dist/adapter/helpers/webgl-texture-utils.js.map +1 -0
  42. package/dist/adapter/helpers/webgl-topology-utils.js +1 -0
  43. package/dist/adapter/helpers/webgl-topology-utils.js.map +1 -0
  44. package/dist/adapter/resources/webgl-buffer.js +1 -0
  45. package/dist/adapter/resources/webgl-buffer.js.map +1 -0
  46. package/dist/adapter/resources/webgl-command-buffer.d.ts +59 -2
  47. package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
  48. package/dist/adapter/resources/webgl-command-buffer.js +89 -32
  49. package/dist/adapter/resources/webgl-command-buffer.js.map +1 -0
  50. package/dist/adapter/resources/webgl-command-encoder.d.ts.map +1 -1
  51. package/dist/adapter/resources/webgl-command-encoder.js +4 -0
  52. package/dist/adapter/resources/webgl-command-encoder.js.map +1 -0
  53. package/dist/adapter/resources/webgl-external-texture.js +15 -0
  54. package/dist/adapter/resources/webgl-external-texture.js.map +1 -0
  55. package/dist/adapter/resources/webgl-framebuffer.d.ts +33 -35
  56. package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
  57. package/dist/adapter/resources/webgl-framebuffer.js +68 -73
  58. package/dist/adapter/resources/webgl-framebuffer.js.map +1 -0
  59. package/dist/adapter/resources/webgl-query-set.js +1 -0
  60. package/dist/adapter/resources/webgl-query-set.js.map +1 -0
  61. package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
  62. package/dist/adapter/resources/webgl-render-pass.js +30 -17
  63. package/dist/adapter/resources/webgl-render-pass.js.map +1 -0
  64. package/dist/adapter/resources/webgl-render-pipeline.d.ts +2 -4
  65. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  66. package/dist/adapter/resources/webgl-render-pipeline.js +33 -18
  67. package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -0
  68. package/dist/adapter/resources/webgl-sampler.js +1 -0
  69. package/dist/adapter/resources/webgl-sampler.js.map +1 -0
  70. package/dist/adapter/resources/webgl-shader.d.ts +1 -0
  71. package/dist/adapter/resources/webgl-shader.d.ts.map +1 -1
  72. package/dist/adapter/resources/webgl-shader.js +8 -5
  73. package/dist/adapter/resources/webgl-shader.js.map +1 -0
  74. package/dist/adapter/resources/webgl-texture-view.js +1 -0
  75. package/dist/adapter/resources/webgl-texture-view.js.map +1 -0
  76. package/dist/adapter/resources/webgl-texture.d.ts +32 -20
  77. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  78. package/dist/adapter/resources/webgl-texture.js +158 -218
  79. package/dist/adapter/resources/webgl-texture.js.map +1 -0
  80. package/dist/adapter/resources/webgl-transform-feedback.js +1 -0
  81. package/dist/adapter/resources/webgl-transform-feedback.js.map +1 -0
  82. package/dist/adapter/resources/webgl-vertex-array.js +1 -0
  83. package/dist/adapter/resources/webgl-vertex-array.js.map +1 -0
  84. package/dist/adapter/webgl-adapter.d.ts.map +1 -1
  85. package/dist/adapter/webgl-adapter.js +5 -10
  86. package/dist/adapter/webgl-adapter.js.map +1 -0
  87. package/dist/adapter/webgl-canvas-context.d.ts +1 -0
  88. package/dist/adapter/webgl-canvas-context.d.ts.map +1 -1
  89. package/dist/adapter/webgl-canvas-context.js +4 -0
  90. package/dist/adapter/webgl-canvas-context.js.map +1 -0
  91. package/dist/adapter/webgl-device.d.ts +11 -14
  92. package/dist/adapter/webgl-device.d.ts.map +1 -1
  93. package/dist/adapter/webgl-device.js +60 -39
  94. package/dist/adapter/webgl-device.js.map +1 -0
  95. package/dist/context/debug/spector-types.js +2 -1
  96. package/dist/context/debug/spector-types.js.map +1 -0
  97. package/dist/context/debug/spector.d.ts +5 -5
  98. package/dist/context/debug/spector.d.ts.map +1 -1
  99. package/dist/context/debug/spector.js +7 -6
  100. package/dist/context/debug/spector.js.map +1 -0
  101. package/dist/context/debug/webgl-developer-tools.d.ts +2 -3
  102. package/dist/context/debug/webgl-developer-tools.d.ts.map +1 -1
  103. package/dist/context/debug/webgl-developer-tools.js +7 -19
  104. package/dist/context/debug/webgl-developer-tools.js.map +1 -0
  105. package/dist/context/helpers/create-browser-context.d.ts +6 -22
  106. package/dist/context/helpers/create-browser-context.d.ts.map +1 -1
  107. package/dist/context/helpers/create-browser-context.js +41 -32
  108. package/dist/context/helpers/create-browser-context.js.map +1 -0
  109. package/dist/context/helpers/webgl-context-data.js +1 -0
  110. package/dist/context/helpers/webgl-context-data.js.map +1 -0
  111. package/dist/context/helpers/webgl-extensions.js +1 -0
  112. package/dist/context/helpers/webgl-extensions.js.map +1 -0
  113. package/dist/context/parameters/unified-parameter-api.js +1 -0
  114. package/dist/context/parameters/unified-parameter-api.js.map +1 -0
  115. package/dist/context/parameters/webgl-parameter-tables.d.ts +1 -1
  116. package/dist/context/parameters/webgl-parameter-tables.d.ts.map +1 -1
  117. package/dist/context/parameters/webgl-parameter-tables.js +3 -2
  118. package/dist/context/parameters/webgl-parameter-tables.js.map +1 -0
  119. package/dist/context/polyfills/polyfill-webgl1-extensions.js +1 -0
  120. package/dist/context/polyfills/polyfill-webgl1-extensions.js.map +1 -0
  121. package/dist/context/state-tracker/deep-array-equal.js +1 -0
  122. package/dist/context/state-tracker/deep-array-equal.js.map +1 -0
  123. package/dist/context/state-tracker/webgl-state-tracker.js +1 -0
  124. package/dist/context/state-tracker/webgl-state-tracker.js.map +1 -0
  125. package/dist/context/state-tracker/with-parameters.js +1 -0
  126. package/dist/context/state-tracker/with-parameters.js.map +1 -0
  127. package/dist/deprecated/accessor.d.ts.map +1 -0
  128. package/dist/{classic → deprecated}/accessor.js +37 -1
  129. package/dist/deprecated/accessor.js.map +1 -0
  130. package/dist/dist.dev.js +2217 -2366
  131. package/dist/dist.min.js +2 -2
  132. package/dist/index.cjs +2098 -2240
  133. package/dist/index.cjs.map +4 -4
  134. package/dist/index.d.ts +2 -3
  135. package/dist/index.d.ts.map +1 -1
  136. package/dist/index.js +3 -4
  137. package/dist/index.js.map +1 -0
  138. package/dist/types.js +1 -0
  139. package/dist/types.js.map +1 -0
  140. package/dist/utils/fill-array.d.ts +4 -4
  141. package/dist/utils/fill-array.d.ts.map +1 -1
  142. package/dist/utils/fill-array.js +1 -0
  143. package/dist/utils/fill-array.js.map +1 -0
  144. package/dist/utils/load-script.js +1 -0
  145. package/dist/utils/load-script.js.map +1 -0
  146. package/dist/utils/split-uniforms-and-bindings.d.ts +1 -1
  147. package/dist/utils/split-uniforms-and-bindings.d.ts.map +1 -1
  148. package/dist/utils/split-uniforms-and-bindings.js +1 -0
  149. package/dist/utils/split-uniforms-and-bindings.js.map +1 -0
  150. package/dist/utils/uid.js +1 -0
  151. package/dist/utils/uid.js.map +1 -0
  152. package/package.json +5 -5
  153. package/src/adapter/converters/device-parameters.ts +3 -3
  154. package/src/adapter/converters/sampler-parameters.ts +6 -4
  155. package/src/adapter/converters/webgl-texture-table.ts +404 -0
  156. package/src/adapter/device-helpers/webgl-device-features.ts +5 -2
  157. package/src/{classic → adapter/helpers}/format-utils.ts +6 -0
  158. package/src/adapter/helpers/get-shader-layout.ts +7 -4
  159. package/src/adapter/helpers/webgl-texture-utils.ts +400 -57
  160. package/src/adapter/resources/webgl-command-buffer.ts +125 -41
  161. package/src/adapter/resources/webgl-command-encoder.ts +6 -0
  162. package/src/adapter/resources/webgl-external-texture.ts +14 -0
  163. package/src/adapter/resources/webgl-framebuffer.ts +77 -83
  164. package/src/adapter/resources/webgl-render-pass.ts +52 -41
  165. package/src/adapter/resources/webgl-render-pipeline.ts +44 -21
  166. package/src/adapter/resources/webgl-shader.ts +8 -6
  167. package/src/adapter/resources/webgl-texture.ts +183 -250
  168. package/src/adapter/webgl-adapter.ts +4 -12
  169. package/src/adapter/webgl-canvas-context.ts +4 -0
  170. package/src/adapter/webgl-device.ts +100 -72
  171. package/src/context/debug/spector-types.ts +1 -1
  172. package/src/context/debug/spector.ts +11 -11
  173. package/src/context/debug/webgl-developer-tools.ts +8 -31
  174. package/src/context/helpers/create-browser-context.ts +53 -63
  175. package/src/context/parameters/webgl-parameter-tables.ts +2 -2
  176. package/src/{classic → deprecated}/accessor.ts +44 -3
  177. package/src/index.ts +2 -5
  178. package/src/utils/fill-array.ts +4 -4
  179. package/src/utils/split-uniforms-and-bindings.ts +3 -3
  180. package/dist/adapter/converters/texture-formats.d.ts +0 -83
  181. package/dist/adapter/converters/texture-formats.d.ts.map +0 -1
  182. package/dist/adapter/converters/texture-formats.js +0 -511
  183. package/dist/classic/accessor.d.ts.map +0 -1
  184. package/dist/classic/clear.d.ts +0 -22
  185. package/dist/classic/clear.d.ts.map +0 -1
  186. package/dist/classic/clear.js +0 -86
  187. package/dist/classic/copy-and-blit.d.ts +0 -64
  188. package/dist/classic/copy-and-blit.d.ts.map +0 -1
  189. package/dist/classic/copy-and-blit.js +0 -194
  190. package/dist/classic/format-utils.d.ts.map +0 -1
  191. package/dist/classic/typed-array-utils.d.ts.map +0 -1
  192. package/src/adapter/converters/texture-formats.ts +0 -657
  193. package/src/classic/clear.ts +0 -115
  194. package/src/classic/copy-and-blit.ts +0 -323
  195. /package/dist/{classic → adapter/helpers}/format-utils.d.ts +0 -0
  196. /package/dist/{classic → adapter/helpers}/typed-array-utils.d.ts +0 -0
  197. /package/dist/{classic → deprecated}/accessor.d.ts +0 -0
  198. /package/src/{classic → adapter/helpers}/typed-array-utils.ts +0 -0
@@ -2,14 +2,6 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- // @todo texture refactor
6
- // - [ ] cube texture init params P1
7
- // - [ ] 3d texture init params P1
8
- // - [ ] GPU memory tracking
9
- // - [ ] raw data inputs
10
- // - [ ] video (external) textures
11
-
12
- // import {TypedArray} from '@math.gl/types';
13
5
  import type {
14
6
  Device,
15
7
  TextureProps,
@@ -17,10 +9,8 @@ import type {
17
9
  Sampler,
18
10
  SamplerProps,
19
11
  SamplerParameters,
20
- // TextureFormat,
21
12
  TextureCubeFace,
22
13
  ExternalImage,
23
- TextureLevelData,
24
14
  Texture1DData,
25
15
  Texture2DData,
26
16
  Texture3DData,
@@ -28,8 +18,6 @@ import type {
28
18
  TextureArrayData,
29
19
  TextureCubeArrayData
30
20
  } from '@luma.gl/core';
31
- // import {decodeTextureFormat} from '@luma.gl/core';
32
- // import {Buffer, Texture, log} from '@luma.gl/core';
33
21
  import {Texture, log} from '@luma.gl/core';
34
22
  import {
35
23
  GL,
@@ -38,62 +26,26 @@ import {
38
26
  GLTexelDataFormat,
39
27
  GLTextureTarget
40
28
  } from '@luma.gl/constants';
41
- // import {GLPixelDataType} from '@luma.gl/constants';
42
- import {withGLParameters} from '../../context/state-tracker/with-parameters';
43
- // getTextureFormatBytesPerPixel
44
- import {getTextureFormatWebGL} from '../converters/texture-formats';
29
+ import {getTextureFormatWebGL} from '../converters/webgl-texture-table';
45
30
  import {convertSamplerParametersToWebGL} from '../converters/sampler-parameters';
46
31
  import {WebGLDevice} from '../webgl-device';
47
- // import {WEBGLBuffer} from './webgl-buffer';
48
32
  import {WEBGLSampler} from './webgl-sampler';
49
33
  import {WEBGLTextureView} from './webgl-texture-view';
50
34
 
51
- // import type {WebGLSetTextureOptions, WebGLCopyTextureOptions} from '../helpers/webgl-texture-utils';
52
35
  import {
53
36
  initializeTextureStorage,
54
37
  // clearMipLevel,
55
- copyCPUImageToMipLevel,
38
+ copyExternalImageToMipLevel,
56
39
  copyCPUDataToMipLevel,
57
40
  // copyGPUBufferToMipLevel,
58
41
  getWebGLTextureTarget
59
42
  } from '../helpers/webgl-texture-utils';
60
43
 
61
- // PORTABLE HELPERS (Move to methods on Texture?)
62
-
63
- /**
64
- * Normalize TextureData to an array of TextureLevelData / ExternalImages
65
- * @param data
66
- * @param options
67
- * @returns array of TextureLevelData / ExternalImages
68
- */
69
- function normalizeTextureData(
70
- data: Texture2DData,
71
- options: {width: number; height: number; depth: number}
72
- ): (TextureLevelData | ExternalImage)[] {
73
- let lodArray: (TextureLevelData | ExternalImage)[];
74
- if (ArrayBuffer.isView(data)) {
75
- lodArray = [
76
- {
77
- // ts-expect-error does data really need to be Uint8ClampedArray?
78
- data,
79
- width: options.width,
80
- height: options.height
81
- // depth: options.depth
82
- }
83
- ];
84
- } else if (!Array.isArray(data)) {
85
- lodArray = [data];
86
- } else {
87
- lodArray = data;
88
- }
89
- return lodArray;
90
- }
91
-
92
44
  /**
93
45
  * WebGL... the texture API from hell... hopefully made simpler
94
46
  */
95
47
  export class WEBGLTexture extends Texture {
96
- readonly MAX_ATTRIBUTES: number;
48
+ // readonly MAX_ATTRIBUTES: number;
97
49
  readonly device: WebGLDevice;
98
50
  readonly gl: WebGL2RenderingContext;
99
51
  handle: WebGLTexture;
@@ -101,9 +53,14 @@ export class WEBGLTexture extends Texture {
101
53
  sampler: WEBGLSampler = undefined; // TODO - currently unused in WebGL. Create dummy sampler?
102
54
  view: WEBGLTextureView = undefined; // TODO - currently unused in WebGL. Create dummy view?
103
55
 
104
- mipmaps: boolean = false;
56
+ mipmaps: boolean;
57
+
58
+ // Texture type
59
+ /** Whether the internal format is compressed */
60
+ compressed: boolean;
105
61
 
106
62
  /**
63
+ * The WebGL target corresponding to the texture type
107
64
  * @note `target` cannot be modified by bind:
108
65
  * textures are special because when you first bind them to a target,
109
66
  * When you first bind a texture as a GL_TEXTURE_2D, you are saying that this texture is a 2D texture.
@@ -112,39 +69,23 @@ export class WEBGLTexture extends Texture {
112
69
  * attempting to bind it as GL_TEXTURE_3D will give rise to a run-time error
113
70
  */
114
71
  glTarget: GLTextureTarget;
115
-
116
- // Texture type
117
-
118
72
  /** The WebGL format - essentially channel structure */
119
73
  glFormat: GLTexelDataFormat;
120
74
  /** The WebGL data format - the type of each channel */
121
75
  glType: GLPixelType;
122
76
  /** The WebGL constant corresponding to the WebGPU style constant in format */
123
77
  glInternalFormat: GL;
124
- /** Whether the internal format is compressed */
125
- compressed: boolean;
126
-
127
- // data;
128
- // inherited props
129
- // dimension: ...
130
- // format: GLTextureTarget;
131
- // width: number = undefined;
132
- // height: number = undefined;
133
- // depth: number = undefined;
134
78
 
135
79
  // state
136
- /** Texture binding slot */
80
+ /** Texture binding slot - TODO - move to texture view? */
137
81
  textureUnit: number = 0;
138
- /** For automatically updating video */
139
- _video: {
140
- video: HTMLVideoElement;
141
- parameters: any;
142
- lastTime: number;
143
- } | null = null;
144
82
 
145
83
  constructor(device: Device, props: TextureProps) {
146
- // Note: Clear out `props.data` so that we don't hold a reference to any big memory chunks
147
- super(device, {...Texture.defaultProps, ...props, data: undefined!});
84
+ super(device, props);
85
+
86
+ // Texture base class strips out the data prop, so we need to add it back in
87
+ const propsWithData = {...this.props};
88
+ propsWithData.data = props.data;
148
89
 
149
90
  this.device = device as WebGLDevice;
150
91
  this.gl = this.device.gl;
@@ -153,46 +94,28 @@ export class WEBGLTexture extends Texture {
153
94
  this.glTarget = getWebGLTextureTarget(this.props.dimension);
154
95
 
155
96
  // The target format of this texture
156
- const format = getTextureFormatWebGL(this.props.format);
157
- this.glInternalFormat = format.internalFormat;
158
- this.glFormat = format.format;
159
- this.glType = format.type;
160
- this.compressed = format.compressed;
161
-
162
- if (
163
- typeof HTMLVideoElement !== 'undefined' &&
164
- props.data instanceof HTMLVideoElement &&
165
- // @ts-expect-error
166
- props.data.readyState < HTMLVideoElement.HAVE_METADATA
167
- ) {
168
- const video = props.data;
169
- this._video = null; // Declare member before the object is sealed
170
- video.addEventListener('loadeddata', () => this.initialize(props));
171
- }
97
+ const formatInfo = getTextureFormatWebGL(this.props.format);
98
+ this.glInternalFormat = formatInfo.internalFormat;
99
+ this.glFormat = formatInfo.format;
100
+ this.glType = formatInfo.type;
101
+ this.compressed = formatInfo.compressed;
102
+ this.mipmaps = Boolean(this.props.mipmaps);
172
103
 
173
- // We removed data, we need to add it again.
174
- // @ts-expect-error
175
- this.initialize({...this.props, data: props.data});
104
+ this._initialize(propsWithData);
176
105
 
177
106
  Object.seal(this);
178
107
  }
179
108
 
180
- /**
181
- * Initialize texture with supplied props
182
- */
109
+ /** Initialize texture with supplied props */
183
110
  // eslint-disable-next-line max-statements
184
- initialize(props: TextureProps = {}): void {
111
+ _initialize(propsWithData: TextureProps): void {
185
112
  this.handle = this.props.handle || this.gl.createTexture();
186
- this.device.setSpectorMetadata(this.handle, {...this.props, data: typeof this.props.data});
187
-
188
- const data = props.data;
189
-
190
- // const {parameters = {} as Record<GL, any>} = props;
113
+ this.device.setSpectorMetadata(this.handle, {...this.props, data: propsWithData.data});
191
114
 
192
- let {width, height} = props;
115
+ let {width, height} = propsWithData;
193
116
 
194
117
  if (!width || !height) {
195
- const textureSize = this.getTextureDataSize(data);
118
+ const textureSize = Texture.getTextureDataSize(propsWithData.data);
196
119
  width = textureSize?.width || 1;
197
120
  height = textureSize?.height || 1;
198
121
  }
@@ -200,73 +123,35 @@ export class WEBGLTexture extends Texture {
200
123
  // Store opts for accessors
201
124
  this.width = width;
202
125
  this.height = height;
203
- this.depth = props.depth;
126
+ this.depth = propsWithData.depth;
204
127
 
205
128
  // Set texture sampler parameters
206
- this.setSampler(props.sampler);
207
- // @ts-ignore
129
+ this.setSampler(propsWithData.sampler);
130
+ // @ts-ignore TODO - fix types
208
131
  this.view = new WEBGLTextureView(this.device, {...this.props, texture: this});
209
132
 
210
133
  this.bind();
211
- if (!this.props.data) {
212
- initializeTextureStorage(this.gl, this.mipLevels, this);
213
- }
134
+ initializeTextureStorage(this.gl, this.mipLevels, this);
214
135
 
215
- if (props.data) {
136
+ if (propsWithData.data) {
216
137
  // prettier-ignore
217
- switch (props.dimension) {
218
- case '1d': this.setTexture1DData(props.data); break;
219
- case '2d': this.setTexture2DData(props.data); break;
220
- case '3d': this.setTexture3DData(props.data); break;
221
- case 'cube': this.setTextureCubeData(props.data); break;
222
- case '2d-array': this.setTextureArrayData(props.data); break;
223
- case 'cube-array': this.setTextureCubeArrayData(props.data); break;
138
+ switch (propsWithData.dimension) {
139
+ case '1d': this.setTexture1DData(propsWithData.data); break;
140
+ case '2d': this.setTexture2DData(propsWithData.data); break;
141
+ case '3d': this.setTexture3DData(propsWithData.data); break;
142
+ case 'cube': this.setTextureCubeData(propsWithData.data); break;
143
+ case '2d-array': this.setTextureArrayData(propsWithData.data); break;
144
+ case 'cube-array': this.setTextureCubeArrayData(propsWithData.data); break;
224
145
  // @ts-expect-error
225
- default: throw new Error(props.dimension);
146
+ default: throw new Error(propsWithData.dimension);
226
147
  }
227
148
  }
228
149
 
229
- this.mipmaps = Boolean(props.mipmaps);
230
-
231
150
  if (this.mipmaps) {
232
151
  this.generateMipmap();
233
152
  }
234
-
235
- // if (isVideo) {
236
- // this._video = {
237
- // video: data,
238
- // // TODO - should we be using the sampler parameters here?
239
- // parameters: {},
240
- // // @ts-expect-error HTMLVideoElement.HAVE_CURRENT_DATA is not declared
241
- // lastTime: data.readyState >= HTMLVideoElement.HAVE_CURRENT_DATA ? data.currentTime : -1
242
- // };
243
- // }
244
153
  }
245
154
 
246
- /*
247
- initializeCube(props?: TextureProps): void {
248
- const {mipmaps = true} = props; // , parameters = {} as Record<GL, any>} = props;
249
-
250
- // Store props for accessors
251
- // this.props = props;
252
-
253
- // @ts-expect-error
254
- this.setCubeMapData(props).then(() => {
255
- // TODO - should genMipmap() be called on the cubemap or on the faces?
256
- // TODO - without generateMipmap() cube textures do not work at all!!! Why?
257
- if (mipmaps) {
258
- this.generateMipmap(props);
259
- }
260
-
261
- this.setSampler(props.sampler);
262
-
263
- // v8 compatibility?
264
- // const {parameters = {} as Record<GL, any>} = props;
265
- // this._setSamplerParameters(parameters);
266
- });
267
- }
268
- */
269
-
270
155
  override destroy(): void {
271
156
  if (this.handle) {
272
157
  this.gl.deleteTexture(this.handle);
@@ -277,10 +162,6 @@ export class WEBGLTexture extends Texture {
277
162
  }
278
163
  }
279
164
 
280
- override toString(): string {
281
- return `Texture(${this.id},${this.width}x${this.height})`;
282
- }
283
-
284
165
  createView(props: TextureViewProps): WEBGLTextureView {
285
166
  return new WEBGLTextureView(this.device, {...props, texture: this});
286
167
  }
@@ -299,40 +180,79 @@ export class WEBGLTexture extends Texture {
299
180
  this._setSamplerParameters(parameters);
300
181
  }
301
182
 
302
- /** Update external texture (video frame or canvas) */
303
- update(): void {
304
- log.warn('Texture.update() not implemented');
305
- // if (this._video) {
306
- // const {video, parameters, lastTime} = this._video;
307
- // // @ts-expect-error
308
- // if (lastTime === video.currentTime || video.readyState < HTMLVideoElement.HAVE_CURRENT_DATA) {
309
- // return;
310
- // }
311
- // this.setSubImageData({
312
- // data: video,
313
- // parameters
314
- // });
315
- // if (this.mipmaps) {
316
- // this.generateMipmap();
317
- // }
318
- // this._video.lastTime = video.currentTime;
319
- // }
320
- }
321
-
322
183
  // Call to regenerate mipmaps after modifying texture(s)
323
- generateMipmap(params = {}): void {
324
- if (!this.props.data) {
325
- return;
184
+ generateMipmap(options?: {force?: boolean}): void {
185
+ const isFilterableAndRenderable =
186
+ this.device.isTextureFormatRenderable(this.props.format) &&
187
+ this.device.isTextureFormatFilterable(this.props.format);
188
+ if (!isFilterableAndRenderable) {
189
+ log.warn(`${this} is not renderable or filterable, may not be able to generate mipmaps`)();
190
+ if (!options?.force) {
191
+ return;
192
+ }
326
193
  }
327
- this.mipmaps = true;
328
- this.gl.bindTexture(this.glTarget, this.handle);
329
- withGLParameters(this.gl, params, () => {
194
+
195
+ try {
196
+ this.gl.bindTexture(this.glTarget, this.handle);
330
197
  this.gl.generateMipmap(this.glTarget);
331
- });
332
- this.gl.bindTexture(this.glTarget, null);
198
+ } catch (error) {
199
+ log.warn(`Error generating mipmap for ${this}: ${(error as Error).message}`)();
200
+ } finally {
201
+ this.gl.bindTexture(this.glTarget, null);
202
+ }
333
203
  }
334
204
 
335
205
  // Image Data Setters
206
+ copyExternalImage(options: {
207
+ image: ExternalImage;
208
+ sourceX?: number;
209
+ sourceY?: number;
210
+ width?: number;
211
+ height?: number;
212
+ depth?: number;
213
+ mipLevel?: number;
214
+ x?: number;
215
+ y?: number;
216
+ z?: number;
217
+ aspect?: 'all' | 'stencil-only' | 'depth-only';
218
+ colorSpace?: 'srgb';
219
+ premultipliedAlpha?: boolean;
220
+ flipY?: boolean;
221
+ }): {width: number; height: number} {
222
+ const size = Texture.getExternalImageSize(options.image);
223
+ const opts = {...Texture.defaultCopyExternalImageOptions, ...size, ...options};
224
+
225
+ const {image, depth, mipLevel, x, y, z, flipY} = opts;
226
+ let {width, height} = opts;
227
+ const {dimension, glTarget, glFormat, glInternalFormat, glType} = this;
228
+
229
+ // WebGL will error if we try to copy outside the bounds of the texture
230
+ width = Math.min(width, this.width - x);
231
+ height = Math.min(height, this.height - y);
232
+
233
+ if (options.sourceX || options.sourceY) {
234
+ // requires copyTexSubImage2D from a framebuffer'
235
+ throw new Error('WebGL does not support sourceX/sourceY)');
236
+ }
237
+
238
+ copyExternalImageToMipLevel(this.device.gl, this.handle, image, {
239
+ dimension,
240
+ mipLevel,
241
+ x,
242
+ y,
243
+ z,
244
+ width,
245
+ height,
246
+ depth,
247
+ glFormat,
248
+ glInternalFormat,
249
+ glType,
250
+ glTarget,
251
+ flipY
252
+ });
253
+
254
+ return {width: opts.width, height: opts.height};
255
+ }
336
256
 
337
257
  setTexture1DData(data: Texture1DData): void {
338
258
  throw new Error('setTexture1DData not supported in WebGL.');
@@ -342,7 +262,7 @@ export class WEBGLTexture extends Texture {
342
262
  setTexture2DData(lodData: Texture2DData, depth = 0): void {
343
263
  this.bind();
344
264
 
345
- const lodArray = normalizeTextureData(lodData, this);
265
+ const lodArray = Texture.normalizeTextureData(lodData, this);
346
266
 
347
267
  // If the user provides multiple LODs, then automatic mipmap
348
268
  // generation generateMipmap() should be disabled to avoid overwriting them.
@@ -421,6 +341,13 @@ export class WEBGLTexture extends Texture {
421
341
  this.setTexture2DData(lodData, faceDepth);
422
342
  }
423
343
 
344
+ // DEPRECATED METHODS
345
+
346
+ /** Update external texture (video frame or canvas) @deprecated Use ExternalTexture */
347
+ update(): void {
348
+ throw new Error('Texture.update() not implemented. Use ExternalTexture');
349
+ }
350
+
424
351
  // INTERNAL METHODS
425
352
 
426
353
  /** @todo update this method to accept LODs */
@@ -475,7 +402,7 @@ export class WEBGLTexture extends Texture {
475
402
  * Sets sampler parameters on texture
476
403
  */
477
404
  _setSamplerParameters(parameters: GLSamplerParameters): void {
478
- log.log(1, 'texture sampler parameters', parameters)();
405
+ log.log(1, `${this.id} sampler parameters`, this.device.getGLKeys(parameters))();
479
406
 
480
407
  this.gl.bindTexture(this.glTarget, this.handle);
481
408
  for (const [pname, pvalue] of Object.entries(parameters)) {
@@ -513,63 +440,6 @@ export class WEBGLTexture extends Texture {
513
440
  this.gl.bindTexture(this.glTarget, null);
514
441
  }
515
442
 
516
- // CLASSIC
517
-
518
- /*
519
- setCubeMapData(options: {
520
- width: number;
521
- height: number;
522
- data: Record<GL, Texture2DData> | Record<TextureCubeFace, Texture2DData>;
523
- format?: any;
524
- type?: any;
525
- /** @deprecated Use .data *
526
- pixels: any;
527
- }): void {
528
- const {gl} = this;
529
-
530
- const {width, height, pixels, data, format = GL.RGBA, type = GL.UNSIGNED_BYTE} = options;
531
-
532
- // pixel data (imageDataMap) is an Object from Face to Image or Promise.
533
- // For example:
534
- // {
535
- // GL.TEXTURE_CUBE_MAP_POSITIVE_X : Image-or-Promise,
536
- // GL.TEXTURE_CUBE_MAP_NEGATIVE_X : Image-or-Promise,
537
- // ... }
538
- // To provide multiple level-of-details (LODs) this can be Face to Array
539
- // of Image or Promise, like this
540
- // {
541
- // GL.TEXTURE_CUBE_MAP_POSITIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
542
- // GL.TEXTURE_CUBE_MAP_NEGATIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
543
- // ... }
544
-
545
- const imageDataMap = this._getImageDataMap(pixels || data);
546
-
547
- const resolvedFaces = WEBGLTexture.FACES.map(face => {
548
- const facePixels = imageDataMap[face];
549
- return Array.isArray(facePixels) ? facePixels : [facePixels];
550
- });
551
- this.bind();
552
-
553
- WEBGLTexture.FACES.forEach((face, index) => {
554
- if (resolvedFaces[index].length > 1 && this.props.mipmaps !== false) {
555
- // If the user provides multiple LODs, then automatic mipmap
556
- // generation generateMipmap() should be disabled to avoid overwritting them.
557
- log.warn(`${this.id} has mipmap and multiple LODs.`)();
558
- }
559
- resolvedFaces[index].forEach((image, lodLevel) => {
560
- // TODO: adjust width & height for LOD!
561
- if (width && height) {
562
- gl.texImage2D(face, lodLevel, format, width, height, 0 /* border*, format, type, image);
563
- } else {
564
- gl.texImage2D(face, lodLevel, format, format, type, image);
565
- }
566
- });
567
- });
568
-
569
- this.unbind();
570
- }
571
- */
572
-
573
443
  // INTERNAL SETTERS
574
444
 
575
445
  /**
@@ -578,7 +448,7 @@ export class WEBGLTexture extends Texture {
578
448
  */
579
449
  protected _setMipLevel(
580
450
  depth: number,
581
- level: number,
451
+ mipLevel: number,
582
452
  textureData: Texture2DData,
583
453
  glTarget: GL = this.glTarget
584
454
  ) {
@@ -588,16 +458,22 @@ export class WEBGLTexture extends Texture {
588
458
  // }
589
459
 
590
460
  if (Texture.isExternalImage(textureData)) {
591
- copyCPUImageToMipLevel(this.device.gl, textureData, {...this, depth, level, glTarget});
461
+ copyExternalImageToMipLevel(this.device.gl, this.handle, textureData, {
462
+ ...this,
463
+ depth,
464
+ mipLevel,
465
+ glTarget,
466
+ flipY: this.props.flipY
467
+ });
592
468
  return;
593
469
  }
594
470
 
595
471
  // @ts-expect-error
596
- if (this.isTextureLevelData(textureData)) {
472
+ if (Texture.isTextureLevelData(textureData)) {
597
473
  copyCPUDataToMipLevel(this.device.gl, textureData.data, {
598
474
  ...this,
599
475
  depth,
600
- level,
476
+ mipLevel,
601
477
  glTarget
602
478
  });
603
479
  return;
@@ -635,3 +511,60 @@ export class WEBGLTexture extends Texture {
635
511
  return textureUnit;
636
512
  }
637
513
  }
514
+
515
+ // TODO - Remove when texture refactor is complete
516
+
517
+ /*
518
+ setCubeMapData(options: {
519
+ width: number;
520
+ height: number;
521
+ data: Record<GL, Texture2DData> | Record<TextureCubeFace, Texture2DData>;
522
+ format?: any;
523
+ type?: any;
524
+ /** @deprecated Use .data *
525
+ pixels: any;
526
+ }): void {
527
+ const {gl} = this;
528
+
529
+ const {width, height, pixels, data, format = GL.RGBA, type = GL.UNSIGNED_BYTE} = options;
530
+
531
+ // pixel data (imageDataMap) is an Object from Face to Image or Promise.
532
+ // For example:
533
+ // {
534
+ // GL.TEXTURE_CUBE_MAP_POSITIVE_X : Image-or-Promise,
535
+ // GL.TEXTURE_CUBE_MAP_NEGATIVE_X : Image-or-Promise,
536
+ // ... }
537
+ // To provide multiple level-of-details (LODs) this can be Face to Array
538
+ // of Image or Promise, like this
539
+ // {
540
+ // GL.TEXTURE_CUBE_MAP_POSITIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
541
+ // GL.TEXTURE_CUBE_MAP_NEGATIVE_X : [Image-or-Promise-LOD-0, Image-or-Promise-LOD-1],
542
+ // ... }
543
+
544
+ const imageDataMap = this._getImageDataMap(pixels || data);
545
+
546
+ const resolvedFaces = WEBGLTexture.FACES.map(face => {
547
+ const facePixels = imageDataMap[face];
548
+ return Array.isArray(facePixels) ? facePixels : [facePixels];
549
+ });
550
+ this.bind();
551
+
552
+ WEBGLTexture.FACES.forEach((face, index) => {
553
+ if (resolvedFaces[index].length > 1 && this.props.mipmaps !== false) {
554
+ // If the user provides multiple LODs, then automatic mipmap
555
+ // generation generateMipmap() should be disabled to avoid overwritting them.
556
+ log.warn(`${this.id} has mipmap and multiple LODs.`)();
557
+ }
558
+ resolvedFaces[index].forEach((image, lodLevel) => {
559
+ // TODO: adjust width & height for LOD!
560
+ if (width && height) {
561
+ gl.texImage2D(face, lodLevel, format, width, height, 0 /* border*, format, type, image);
562
+ } else {
563
+ gl.texImage2D(face, lodLevel, format, format, type, image);
564
+ }
565
+ });
566
+ });
567
+
568
+ this.unbind();
569
+ }
570
+ */
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {Adapter, Device, DeviceProps, CanvasContext, log} from '@luma.gl/core';
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({gl: gl as WebGL2RenderingContext});
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.debug) {
64
+ if (props.debugWebGL || props.debug) {
65
65
  promises.push(loadWebGLDeveloperTools());
66
66
  }
67
67
 
68
- if (props.debugWithSpectorJS) {
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
@@ -18,6 +18,10 @@ export class WebGLCanvasContext extends CanvasContext {
18
18
  presentationSize: [number, number];
19
19
  private _framebuffer: WEBGLFramebuffer | null = null;
20
20
 
21
+ get [Symbol.toStringTag](): string {
22
+ return 'WebGLCanvasContext';
23
+ }
24
+
21
25
  constructor(device: WebGLDevice, props: CanvasContextProps) {
22
26
  // Note: Base class creates / looks up the canvas (unless under Node.js)
23
27
  super(props);