@flighthq/render-gl 0.2.0 → 0.2.1-next.423.3350e53

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 (66) hide show
  1. package/dist/glCompressedTexture.d.ts +8 -0
  2. package/dist/glCompressedTexture.d.ts.map +1 -0
  3. package/dist/glCompressedTexture.js +270 -0
  4. package/dist/glCompressedTexture.js.map +1 -0
  5. package/dist/glDraw.d.ts +4 -2
  6. package/dist/glDraw.d.ts.map +1 -1
  7. package/dist/glDraw.js +215 -20
  8. package/dist/glDraw.js.map +1 -1
  9. package/dist/glFullscreenPass.d.ts.map +1 -1
  10. package/dist/glFullscreenPass.js +32 -0
  11. package/dist/glFullscreenPass.js.map +1 -1
  12. package/dist/glLinearToSrgbPass.d.ts +4 -0
  13. package/dist/glLinearToSrgbPass.d.ts.map +1 -0
  14. package/dist/glLinearToSrgbPass.js +42 -0
  15. package/dist/glLinearToSrgbPass.js.map +1 -0
  16. package/dist/glPresentRenderTarget.d.ts +3 -0
  17. package/dist/glPresentRenderTarget.d.ts.map +1 -0
  18. package/dist/glPresentRenderTarget.js +35 -0
  19. package/dist/glPresentRenderTarget.js.map +1 -0
  20. package/dist/glRenderPass.d.ts +5 -0
  21. package/dist/glRenderPass.d.ts.map +1 -0
  22. package/dist/glRenderPass.js +130 -0
  23. package/dist/glRenderPass.js.map +1 -0
  24. package/dist/glRenderState.d.ts +1 -1
  25. package/dist/glRenderState.d.ts.map +1 -1
  26. package/dist/glRenderState.js +1 -0
  27. package/dist/glRenderState.js.map +1 -1
  28. package/dist/glRenderTarget.d.ts +2 -15
  29. package/dist/glRenderTarget.d.ts.map +1 -1
  30. package/dist/glRenderTarget.js +48 -57
  31. package/dist/glRenderTarget.js.map +1 -1
  32. package/dist/glRenderTargetPool.d.ts.map +1 -1
  33. package/dist/glRenderTargetPool.js +4 -0
  34. package/dist/glRenderTargetPool.js.map +1 -1
  35. package/dist/glSkinPaletteTexture.d.ts +5 -0
  36. package/dist/glSkinPaletteTexture.d.ts.map +1 -0
  37. package/dist/glSkinPaletteTexture.js +42 -0
  38. package/dist/glSkinPaletteTexture.js.map +1 -0
  39. package/dist/glTestHelper.d.ts.map +1 -1
  40. package/dist/glTestHelper.js +1 -0
  41. package/dist/glTestHelper.js.map +1 -1
  42. package/dist/glTextureUpload.d.ts +5 -0
  43. package/dist/glTextureUpload.d.ts.map +1 -0
  44. package/dist/glTextureUpload.js +27 -0
  45. package/dist/glTextureUpload.js.map +1 -0
  46. package/dist/glTextureVideoUpload.d.ts +3 -0
  47. package/dist/glTextureVideoUpload.d.ts.map +1 -0
  48. package/dist/glTextureVideoUpload.js +24 -0
  49. package/dist/glTextureVideoUpload.js.map +1 -0
  50. package/dist/index.d.ts +7 -0
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +7 -0
  53. package/dist/index.js.map +1 -1
  54. package/package.json +5 -5
  55. package/src/glCompressedTexture.test.ts +276 -0
  56. package/src/glDraw.test.ts +319 -36
  57. package/src/glFullscreenPass.test.ts +22 -1
  58. package/src/glLinearToSrgbPass.test.ts +75 -0
  59. package/src/glPresentRenderTarget.test.ts +62 -0
  60. package/src/glReadback.test.ts +1 -0
  61. package/src/glRenderPass.test.ts +170 -0
  62. package/src/glRenderTarget.test.ts +63 -98
  63. package/src/glRenderTargetPool.test.ts +14 -0
  64. package/src/glSkinPaletteTexture.test.ts +129 -0
  65. package/src/glTextureUpload.test.ts +49 -0
  66. package/src/glTextureVideoUpload.test.ts +53 -0
@@ -0,0 +1,8 @@
1
+ import type { GlCompressedTextureDecoder, GlCompressedTextureSupport, GlRenderState, TextureContainer, TextureContainerFormat } from '@flighthq/types';
2
+ export declare function detectGlCompressedTextureSupport(gl: WebGL2RenderingContext): GlCompressedTextureSupport;
3
+ export declare function getGlCompressedTextureFormat(gl: WebGL2RenderingContext, format: TextureContainerFormat): number;
4
+ export declare function hasGlCompressedTextureFormat(support: Readonly<GlCompressedTextureSupport>, format: TextureContainerFormat): boolean;
5
+ export declare function registerGlCompressedTextureDecoder(state: GlRenderState, decode: GlCompressedTextureDecoder | null): void;
6
+ export declare function registerGlCompressedTextureUpload(state: GlRenderState, uploader?: null): void;
7
+ export declare function uploadGlCompressedTextureContainer(gl: WebGL2RenderingContext, container: Readonly<TextureContainer>, payload: Readonly<Uint8Array>, decode?: GlCompressedTextureDecoder): boolean;
8
+ //# sourceMappingURL=glCompressedTexture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glCompressedTexture.d.ts","sourceRoot":"","sources":["../src/glCompressedTexture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAC1B,0BAA0B,EAC1B,aAAa,EAEb,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,iBAAiB,CAAC;AAmBzB,wBAAgB,gCAAgC,CAAC,EAAE,EAAE,sBAAsB,GAAG,0BAA0B,CAWvG;AAQD,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,sBAAsB,EAAE,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAqG/G;AAKD,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,QAAQ,CAAC,0BAA0B,CAAC,EAC7C,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAuCT;AAOD,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,0BAA0B,GAAG,IAAI,GACxC,IAAI,CAEN;AASD,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAE7F;AAiBD,wBAAgB,kCAAkC,CAChD,EAAE,EAAE,sBAAsB,EAC1B,SAAS,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EACrC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC7B,MAAM,CAAC,EAAE,0BAA0B,GAClC,OAAO,CA0DT"}
@@ -0,0 +1,270 @@
1
+ import { getGlRenderStateRuntime } from './glRenderState';
2
+ // GPU-native block-compressed texture upload for WebGL2: hand a parsed TextureContainer (KTX2 / DDS /
3
+ // ATF) plus its byte payload and this pushes every mip level straight to the GPU with
4
+ // `compressedTexImage2D` — no CPU decode — when the device exposes the matching
5
+ // `WEBGL_compressed_texture_*` extension. When it does not, an optional RGBA decode seam turns each
6
+ // level into plain pixels the portable `texImage2D` path uploads, so an asset still renders on
7
+ // hardware missing that block format (desktop S3TC/BPTC vs mobile ETC2/ASTC).
8
+ //
9
+ // Detection is done once per context via `detectGlCompressedTextureSupport`; the format→GL-enum
10
+ // mapping reads the live extension objects, so the enum constants come from the browser, not a baked
11
+ // table. Basis intermediate formats (`etc1s`/`uastc`) are NOT uploaded here — they must be transcoded
12
+ // to a concrete BCn/ETC/ASTC format first (see the deferred `@flighthq/texture-transcode` seam).
13
+ // Probes which block-compressed families the WebGL2 context can upload natively, from its
14
+ // `WEBGL_compressed_texture_*` extensions. Call once per context and cache the result; each `getExtension`
15
+ // activates the extension so the enum constants become readable by `getGlCompressedTextureFormat`.
16
+ export function detectGlCompressedTextureSupport(gl) {
17
+ return {
18
+ astc: gl.getExtension('WEBGL_compressed_texture_astc') !== null,
19
+ bptc: gl.getExtension('EXT_texture_compression_bptc') !== null,
20
+ etc: gl.getExtension('WEBGL_compressed_texture_etc') !== null,
21
+ pvrtc: gl.getExtension('WEBGL_compressed_texture_pvrtc') !== null,
22
+ rgtc: gl.getExtension('EXT_texture_compression_rgtc') !== null,
23
+ s3tc: gl.getExtension('WEBGL_compressed_texture_s3tc') !== null &&
24
+ gl.getExtension('WEBGL_compressed_texture_s3tc_srgb') !== null,
25
+ };
26
+ }
27
+ // Resolves the GL `internalformat` enum for a container format from the device's live compression
28
+ // extensions, or -1 when the device cannot upload that format natively (missing extension, or an
29
+ // uncompressed / Basis-intermediate format that is not a `compressedTexImage2D` target). The returned
30
+ // number is the exact enum `compressedTexImage2D` expects, read off the extension object so it matches
31
+ // the running browser. Requires the relevant extension to already be enabled (call
32
+ // `detectGlCompressedTextureSupport` first).
33
+ export function getGlCompressedTextureFormat(gl, format) {
34
+ const s3tc = gl.getExtension('WEBGL_compressed_texture_s3tc');
35
+ const s3tcSrgb = gl.getExtension('WEBGL_compressed_texture_s3tc_srgb');
36
+ const rgtc = gl.getExtension('EXT_texture_compression_rgtc');
37
+ const bptc = gl.getExtension('EXT_texture_compression_bptc');
38
+ const etc = gl.getExtension('WEBGL_compressed_texture_etc');
39
+ const astc = gl.getExtension('WEBGL_compressed_texture_astc');
40
+ const pvrtc = gl.getExtension('WEBGL_compressed_texture_pvrtc');
41
+ const enumFromExt = (ext, key) => typeof ext?.[key] === 'number' ? ext[key] : -1;
42
+ switch (format) {
43
+ case 'bc1':
44
+ return enumFromExt(s3tc, 'COMPRESSED_RGBA_S3TC_DXT1_EXT');
45
+ case 'bc1Srgb':
46
+ return enumFromExt(s3tcSrgb, 'COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT');
47
+ case 'bc2':
48
+ return enumFromExt(s3tc, 'COMPRESSED_RGBA_S3TC_DXT3_EXT');
49
+ case 'bc2Srgb':
50
+ return enumFromExt(s3tcSrgb, 'COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT');
51
+ case 'bc3':
52
+ return enumFromExt(s3tc, 'COMPRESSED_RGBA_S3TC_DXT5_EXT');
53
+ case 'bc3Srgb':
54
+ return enumFromExt(s3tcSrgb, 'COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT');
55
+ case 'bc4':
56
+ return enumFromExt(rgtc, 'COMPRESSED_RED_RGTC1_EXT');
57
+ case 'bc4Snorm':
58
+ return enumFromExt(rgtc, 'COMPRESSED_SIGNED_RED_RGTC1_EXT');
59
+ case 'bc5':
60
+ return enumFromExt(rgtc, 'COMPRESSED_RED_GREEN_RGTC2_EXT');
61
+ case 'bc5Snorm':
62
+ return enumFromExt(rgtc, 'COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT');
63
+ case 'bc6hUfloat':
64
+ return enumFromExt(bptc, 'COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT');
65
+ case 'bc6hSfloat':
66
+ return enumFromExt(bptc, 'COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT');
67
+ case 'bc7':
68
+ return enumFromExt(bptc, 'COMPRESSED_RGBA_BPTC_UNORM_EXT');
69
+ case 'bc7Srgb':
70
+ return enumFromExt(bptc, 'COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT');
71
+ case 'etc1':
72
+ case 'etc2Rgb':
73
+ return enumFromExt(etc, 'COMPRESSED_RGB8_ETC2');
74
+ case 'etc2RgbSrgb':
75
+ return enumFromExt(etc, 'COMPRESSED_SRGB8_ETC2');
76
+ case 'etc2Rgba':
77
+ return enumFromExt(etc, 'COMPRESSED_RGBA8_ETC2_EAC');
78
+ case 'etc2RgbaSrgb':
79
+ return enumFromExt(etc, 'COMPRESSED_SRGB8_ALPHA8_ETC2_EAC');
80
+ case 'etc2RgbA1':
81
+ return enumFromExt(etc, 'COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2');
82
+ case 'etc2RgbA1Srgb':
83
+ return enumFromExt(etc, 'COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2');
84
+ case 'eacR11':
85
+ return enumFromExt(etc, 'COMPRESSED_R11_EAC');
86
+ case 'eacR11Snorm':
87
+ return enumFromExt(etc, 'COMPRESSED_SIGNED_R11_EAC');
88
+ case 'eacRg11':
89
+ return enumFromExt(etc, 'COMPRESSED_RG11_EAC');
90
+ case 'eacRg11Snorm':
91
+ return enumFromExt(etc, 'COMPRESSED_SIGNED_RG11_EAC');
92
+ case 'pvrtc2bppRgb':
93
+ return enumFromExt(pvrtc, 'COMPRESSED_RGB_PVRTC_2BPPV1_IMG');
94
+ case 'pvrtc2bppRgba':
95
+ return enumFromExt(pvrtc, 'COMPRESSED_RGBA_PVRTC_2BPPV1_IMG');
96
+ case 'pvrtc4bppRgb':
97
+ return enumFromExt(pvrtc, 'COMPRESSED_RGB_PVRTC_4BPPV1_IMG');
98
+ case 'pvrtc4bppRgba':
99
+ return enumFromExt(pvrtc, 'COMPRESSED_RGBA_PVRTC_4BPPV1_IMG');
100
+ case 'astc4x4':
101
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_4x4_KHR');
102
+ case 'astc5x4':
103
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_5x4_KHR');
104
+ case 'astc5x5':
105
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_5x5_KHR');
106
+ case 'astc6x5':
107
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_6x5_KHR');
108
+ case 'astc6x6':
109
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_6x6_KHR');
110
+ case 'astc8x5':
111
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_8x5_KHR');
112
+ case 'astc8x6':
113
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_8x6_KHR');
114
+ case 'astc8x8':
115
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_8x8_KHR');
116
+ case 'astc10x5':
117
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_10x5_KHR');
118
+ case 'astc10x6':
119
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_10x6_KHR');
120
+ case 'astc10x8':
121
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_10x8_KHR');
122
+ case 'astc10x10':
123
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_10x10_KHR');
124
+ case 'astc12x10':
125
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_12x10_KHR');
126
+ case 'astc12x12':
127
+ return enumFromExt(astc, 'COMPRESSED_RGBA_ASTC_12x12_KHR');
128
+ default:
129
+ // Uncompressed and Basis-intermediate formats have no compressedTexImage2D enum.
130
+ return -1;
131
+ }
132
+ }
133
+ // True when the device's detected support covers a container format's family — the cheap, GL-free gate
134
+ // an asset pipeline uses to pick which of several shipped encodings to upload, without touching the
135
+ // context. `srgb` twins ride the same extension as their unorm base, so both report against one flag.
136
+ export function hasGlCompressedTextureFormat(support, format) {
137
+ switch (format) {
138
+ case 'bc1':
139
+ case 'bc1Srgb':
140
+ case 'bc2':
141
+ case 'bc2Srgb':
142
+ case 'bc3':
143
+ case 'bc3Srgb':
144
+ return support.s3tc;
145
+ case 'bc4':
146
+ case 'bc4Snorm':
147
+ case 'bc5':
148
+ case 'bc5Snorm':
149
+ return support.rgtc;
150
+ case 'bc6hUfloat':
151
+ case 'bc6hSfloat':
152
+ case 'bc7':
153
+ case 'bc7Srgb':
154
+ return support.bptc;
155
+ case 'etc1':
156
+ case 'etc2Rgb':
157
+ case 'etc2RgbSrgb':
158
+ case 'etc2Rgba':
159
+ case 'etc2RgbaSrgb':
160
+ case 'etc2RgbA1':
161
+ case 'etc2RgbA1Srgb':
162
+ case 'eacR11':
163
+ case 'eacR11Snorm':
164
+ case 'eacRg11':
165
+ case 'eacRg11Snorm':
166
+ return support.etc;
167
+ case 'pvrtc2bppRgb':
168
+ case 'pvrtc2bppRgba':
169
+ case 'pvrtc4bppRgb':
170
+ case 'pvrtc4bppRgba':
171
+ return support.pvrtc;
172
+ default:
173
+ return isAstcFormat(format) ? support.astc : false;
174
+ }
175
+ }
176
+ // Installs the RGBA fallback decoder used when the device cannot upload a compressed container's format
177
+ // natively — the seam that lets an S3TC/BPTC asset still render on mobile ETC2/ASTC hardware (and vice
178
+ // versa) by decoding each level to plain pixels. Opt-in and last-write-wins: a state that never draws a
179
+ // compressed texture the device lacks never installs one, so the decoder (and any WASM block-codec it
180
+ // wraps) tree-shakes out. Pass null to clear a previously installed decoder.
181
+ export function registerGlCompressedTextureDecoder(state, decode) {
182
+ getGlRenderStateRuntime(state).compressedTextureDecoder = decode;
183
+ }
184
+ // Installs the block-compressed upload seam on a render state, opting the ~40-format
185
+ // uploadGlCompressedTextureContainer path into the bundle only for a state that actually draws a
186
+ // compressed texture. The 2D display draw path (uploadGlDisplayTexture) reads the installed handler off
187
+ // the runtime and skips a compressed-only resource when none is registered, so a plain element/data
188
+ // bitmap never carries the compression enum table. Opt-in and last-write-wins; pass null to clear a
189
+ // previously installed uploader. The installed handler bridges a compressed ImageResource to
190
+ // uploadGlCompressedTextureContainer, threading through any registered RGBA decode fallback.
191
+ export function registerGlCompressedTextureUpload(state, uploader) {
192
+ getGlRenderStateRuntime(state).compressedTextureUpload = uploader === null ? null : uploadGlCompressedImageResource;
193
+ }
194
+ // Uploads every stored sub-image of a compressed container to the texture the caller has bound. Takes
195
+ // the GPU-native `compressedTexImage2D`/`compressedTexImage3D` path when the device supports the
196
+ // container's format; otherwise, if a `decode` seam is supplied, decompresses each 2D level to RGBA and
197
+ // uploads it through the portable pixel path. Returns `true` when the container was uploaded (either
198
+ // path), `false` when the format is neither natively supported nor decodable, or when the container is
199
+ // still supercompressed (`supercompression !== 'None'`) — a sentinel, not a throw, so a caller falls
200
+ // back to a different asset (or inflates/transcodes first). The caller owns creating/binding the
201
+ // texture (to gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP, or gl.TEXTURE_2D_ARRAY per the container's shape) and
202
+ // setting sampler/mip state; this uploads only the container's own sub-images.
203
+ //
204
+ // `container.levels` is the flat subresource list in `mip + (face + layer * faces) * mipLevels` order;
205
+ // each flat index is decoded back to (mip, face, layer) so a cubemap's six faces land on
206
+ // gl.TEXTURE_CUBE_MAP_POSITIVE_X + face and an array's layers slice into a gl.TEXTURE_2D_ARRAY. The
207
+ // RGBA decode fallback covers only the plain 2D case (faces === 1, layers === 1); a compressed cubemap
208
+ // or array with no native support reports failure rather than a partial 2D upload.
209
+ export function uploadGlCompressedTextureContainer(gl, container, payload, decode) {
210
+ // A still-wrapped supercompressed payload (Zstd/ZLIB deflate or BasisLZ transcode) is not block data;
211
+ // uploading it as if it were would push corrupt pixels. Fail the sentinel and let the caller inflate
212
+ // or transcode through the deferred seam first.
213
+ if (container.supercompression !== 'None')
214
+ return false;
215
+ const nativeFormat = getGlCompressedTextureFormat(gl, container.format);
216
+ const faces = container.faces;
217
+ const layers = container.layers;
218
+ const mipLevels = container.mipLevels;
219
+ if (nativeFormat !== -1) {
220
+ // An array texture is immutable storage: allocate the whole mip chain × depth once with
221
+ // texStorage3D, then blit each layer's slice into its depth slot (layers are non-contiguous in the
222
+ // layer-major flat list, so per-subresource upload is required; compressedTexImage3D cannot
223
+ // allocate a null store the way the 2D path does).
224
+ if (layers > 1) {
225
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, mipLevels, nativeFormat, container.width, container.height, layers);
226
+ }
227
+ for (let index = 0; index < container.levels.length; index += 1) {
228
+ const entry = container.levels[index];
229
+ const view = new Uint8Array(payload.buffer, payload.byteOffset + entry.byteOffset, entry.byteLength);
230
+ const mip = index % mipLevels;
231
+ const faceLayer = (index - mip) / mipLevels;
232
+ const face = faceLayer % faces;
233
+ const layer = (faceLayer - face) / faces;
234
+ if (layers > 1) {
235
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, mip, 0, 0, layer, entry.width, entry.height, 1, nativeFormat, view);
236
+ }
237
+ else {
238
+ const target = faces === 6 ? gl.TEXTURE_CUBE_MAP_POSITIVE_X + face : gl.TEXTURE_2D;
239
+ gl.compressedTexImage2D(target, mip, nativeFormat, entry.width, entry.height, 0, view);
240
+ }
241
+ }
242
+ return true;
243
+ }
244
+ // RGBA decode fallback: plain 2D only. A cubemap/array with no native block support is not decoded
245
+ // face-by-face here — report failure so the caller supplies a different encoding.
246
+ if (decode === undefined || faces !== 1 || layers !== 1)
247
+ return false;
248
+ for (let mip = 0; mip < container.levels.length; mip += 1) {
249
+ const entry = container.levels[mip];
250
+ const view = new Uint8Array(payload.buffer, payload.byteOffset + entry.byteOffset, entry.byteLength);
251
+ const rgba = decode(container.format, entry.width, entry.height, view);
252
+ if (rgba === null)
253
+ return false;
254
+ gl.texImage2D(gl.TEXTURE_2D, mip, gl.RGBA, entry.width, entry.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, rgba);
255
+ }
256
+ return true;
257
+ }
258
+ function isAstcFormat(format) {
259
+ return format.startsWith('astc');
260
+ }
261
+ // The installed GlCompressedTextureUploader: bridges a compressed ImageResource to the container upload,
262
+ // threading through any registered RGBA decode fallback. Returns false when the resource carries no
263
+ // compressed payload so the display path leaves the texture as-is rather than uploading garbage.
264
+ function uploadGlCompressedImageResource(gl, image, decode) {
265
+ const compressed = image.compressed;
266
+ if (compressed === null)
267
+ return false;
268
+ return uploadGlCompressedTextureContainer(gl, compressed.container, compressed.payload, decode ?? undefined);
269
+ }
270
+ //# sourceMappingURL=glCompressedTexture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glCompressedTexture.js","sourceRoot":"","sources":["../src/glCompressedTexture.ts"],"names":[],"mappings":"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"}
package/dist/glDraw.d.ts CHANGED
@@ -1,7 +1,9 @@
1
- import type { GlBitmapShader, GlBlendRealization, GlRenderState } from '@flighthq/types';
1
+ import type { GlBitmapShader, GlBlendRealization, GlRenderState, ImageResource, SamplerLike, VideoTexture } from '@flighthq/types';
2
2
  import { BlendMode } from '@flighthq/types';
3
3
  export declare function applyGlBlendMode(state: GlRenderState, blendMode: BlendMode | null): void;
4
- export declare function bindGlTexture(state: GlRenderState, imageSource: CanvasImageSource): WebGLTexture;
4
+ export declare function bindGlImageResourceTexture(state: GlRenderState, image: Readonly<ImageResource>, sampler?: Readonly<SamplerLike> | null): WebGLTexture;
5
+ export declare function bindGlTexture(state: GlRenderState, imageSource: CanvasImageSource, sampler?: Readonly<SamplerLike> | null): WebGLTexture;
6
+ export declare function bindGlVideoTexture(state: GlRenderState, videoTexture: Readonly<VideoTexture>, sampler?: Readonly<SamplerLike> | null): WebGLTexture;
5
7
  export declare function createGlTexture(state: GlRenderState): WebGLTexture;
6
8
  export declare function drawGlQuad(state: GlRenderState, x0: number, y0: number, x1: number, y1: number, u0: number, v0: number, u1: number, v1: number): void;
7
9
  export declare function enableGlBlendModeSupport(state: GlRenderState): void;
@@ -1 +1 @@
1
- {"version":3,"file":"glDraw.d.ts","sourceRoot":"","sources":["../src/glDraw.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU5C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAQxF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,iBAAiB,GAAG,YAAY,CA2BhG;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY,CAYlE;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,aAAa,EACpB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,IAAI,CA0BN;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAGnE;AAKD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAExF;AAKD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAEtE;AAKD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,kBAAkB,GAAG,IAAI,CAGrH;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,aAAa,EACpB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,IAAI,CAcN;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAW5G;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAShF"}
1
+ {"version":3,"file":"glDraw.d.ts","sourceRoot":"","sources":["../src/glDraw.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,aAAa,EAEb,aAAa,EACb,WAAW,EAGX,YAAY,EACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAY5C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAQxF;AASD,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC9B,OAAO,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,GACrC,YAAY,CAiBd;AAWD,wBAAgB,aAAa,CAC3B,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,iBAAiB,EAC9B,OAAO,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,GACrC,YAAY,CA+Bd;AAWD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC,EACpC,OAAO,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,GACrC,YAAY,CAgBd;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY,CAYlE;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,aAAa,EACpB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,IAAI,CA0BN;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAGnE;AAKD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAExF;AAKD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAEtE;AAKD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,kBAAkB,GAAG,IAAI,CAGrH;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,aAAa,EACpB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,IAAI,CAcN;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAe5G;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAShF"}
package/dist/glDraw.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { BlendMode } from '@flighthq/types';
2
2
  import { getGlRenderStateRuntime } from './glRenderState';
3
3
  import { setGlAttributes, setGlMatrixFromValues } from './glShader';
4
+ import { uploadGlTextureData, uploadGlTextureElement } from './glTextureUpload';
5
+ import { uploadGlTextureVideoFrame } from './glTextureVideoUpload';
4
6
  // Applies the blend mode's registered fixed-function realization to the GL context, skipping the
5
7
  // work when the mode is unchanged. A mode with no registered realization (an unregistered vendor
6
8
  // mode, or a built-in with no fixed-function equivalent such as Overlay) degrades to normal
@@ -16,19 +18,48 @@ export function applyGlBlendMode(state, blendMode) {
16
18
  gl.blendEquation(gl[realization.equation ?? 'FUNC_ADD']);
17
19
  gl.blendFunc(gl[realization.src], gl[realization.dst]);
18
20
  }
19
- export function bindGlTexture(state, imageSource) {
21
+ // Binds (uploading + caching on first use, re-uploading when the pixels change) the GL texture for an
22
+ // ImageResource — a bitmap, sprite atlas, or material map — and applies the sampler's full state. The
23
+ // resource-level sibling of bindGlTexture (which takes a raw element): it accepts an element-backed OR a
24
+ // data-only generated Surface (source-or-data upload via uploadGlDisplayTexture), and caches by the
25
+ // resource entity in imageResourceTextureCache, keyed with the uploaded `version` so an in-place Surface
26
+ // edit (which bumps version) re-uploads without the caller tracking it. Sampler state is re-applied every
27
+ // bind so a resource reused by two materials with different samplers follows the current draw.
28
+ export function bindGlImageResourceTexture(state, image, sampler) {
29
+ const runtime = getGlRenderStateRuntime(state);
30
+ const gl = state.gl;
31
+ const cache = runtime.imageResourceTextureCache;
32
+ let entry = cache.get(image);
33
+ if (entry === undefined) {
34
+ entry = { texture: gl.createTexture(), version: -1 };
35
+ cache.set(image, entry);
36
+ }
37
+ gl.bindTexture(gl.TEXTURE_2D, entry.texture);
38
+ runtime.currentTexture = entry.texture;
39
+ if (entry.version !== image.version) {
40
+ uploadGlDisplayTexture(state, image);
41
+ entry.version = image.version;
42
+ }
43
+ applyGlSamplerState(state, runtime, entry.texture, sampler ?? null);
44
+ return entry.texture;
45
+ }
46
+ // Binds (uploading + caching on first use) the GL texture for an image source and applies the given
47
+ // sampler's full sampling state — wrap, min/mag filter, anisotropy, and a generated mip chain — to
48
+ // the bound texture. Sampler state is re-applied on every bind, not baked at creation, because the GL
49
+ // texture is cached by image source alone: one image reused by two materials with different samplers
50
+ // (e.g. a map bound as both normal and metallic-roughness with different sampling) shares one GL
51
+ // texture, so its sampling must follow the current draw rather than whoever uploaded it first. WebGL2
52
+ // allows REPEAT and mipmaps on NPOT textures, so no power-of-two constraint applies. Callers without a
53
+ // sampler (2D bitmap/text/sprite) get the historical default: the state's allowSmoothing filter,
54
+ // clamp-to-edge, and no mip chain. See applyGlSamplerState.
55
+ export function bindGlTexture(state, imageSource, sampler) {
20
56
  const runtime = getGlRenderStateRuntime(state);
21
57
  const gl = state.gl;
22
58
  const textureCache = runtime.textureCache;
23
59
  let texture = textureCache.get(imageSource);
24
60
  if (!texture) {
25
- const filter = state.allowSmoothing ? gl.LINEAR : gl.NEAREST;
26
61
  texture = gl.createTexture();
27
62
  gl.bindTexture(gl.TEXTURE_2D, texture);
28
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);
29
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);
30
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
31
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
32
63
  // Both image and canvas sources present straight (un-premultiplied) alpha to texImage2D, so
33
64
  // premultiply on upload to match the premultiplied (ONE, ONE_MINUS_SRC_ALPHA) blend used
34
65
  // everywhere — uploaded images, canvas-backed shapes/text, and render-target composites. (A
@@ -39,12 +70,47 @@ export function bindGlTexture(state, imageSource) {
39
70
  textureCache.set(imageSource, texture);
40
71
  runtime.currentTexture = texture;
41
72
  }
42
- else if (runtime.currentTexture !== texture) {
73
+ else {
74
+ // Always rebind on a cache hit, never skip on runtime.currentTexture. That tracker is the last
75
+ // texture bound to whatever unit was active THEN, but callers change the active unit between binds
76
+ // (a material binds its maps to units 0..4 via gl.activeTexture). Binding one image source to two
77
+ // units — e.g. a map reused as both normal and metallic-roughness — would otherwise leave the
78
+ // second unit unbound. A rebind is one cheap GL call; the sprite batch binds once per batch, so the
79
+ // dropped skip costs nothing meaningful.
43
80
  gl.bindTexture(gl.TEXTURE_2D, texture);
44
81
  runtime.currentTexture = texture;
45
82
  }
83
+ // texture is the active TEXTURE_2D binding in every path above; apply this draw's sampler state here
84
+ // so a cache hit picks it up instead of the first uploader's.
85
+ applyGlSamplerState(state, runtime, texture, sampler ?? null);
46
86
  return texture;
47
87
  }
88
+ // Binds the GL texture for a VideoTexture and re-uploads the backing element's current frame only when
89
+ // its `frameId` has advanced past the one last uploaded — the dynamic, per-frame sibling of
90
+ // bindGlImageResourceTexture (settled ImageResource) and bindGlTexture (raw element). The GL texture is
91
+ // cached by the VideoTexture entity in the runtime's videoTextureCache (lazily created), so it persists
92
+ // across frames while the frameId dirty-gate keeps a paused or stalled stream from re-uploading. Applies
93
+ // the VideoTexture's sampler every bind so a stream shared by two samplers follows the current draw.
94
+ // Leaves the texture bound at the active unit for the caller to sample. Callers advance `frameId` via
95
+ // advanceVideoTexture when the element reports a fresh decoded frame; this reads the current frame
96
+ // through uploadGlTextureElement's zero-copy element fast-path.
97
+ export function bindGlVideoTexture(state, videoTexture, sampler) {
98
+ const runtime = getGlRenderStateRuntime(state);
99
+ const gl = state.gl;
100
+ const cache = (runtime.videoTextureCache ??= new WeakMap());
101
+ let entry = cache.get(videoTexture);
102
+ if (entry === undefined) {
103
+ entry = { texture: gl.createTexture(), uploadedFrameId: -1 };
104
+ cache.set(videoTexture, entry);
105
+ }
106
+ gl.bindTexture(gl.TEXTURE_2D, entry.texture);
107
+ runtime.currentTexture = entry.texture;
108
+ // Straight-alpha element under premultiplied blend would blow out RGB; match the bitmap/element path.
109
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
110
+ entry.uploadedFrameId = uploadGlTextureVideoFrame(gl, videoTexture, entry.uploadedFrameId);
111
+ applyGlSamplerState(state, runtime, entry.texture, sampler ?? videoTexture.sampler ?? null);
112
+ return entry.texture;
113
+ }
48
114
  export function createGlTexture(state) {
49
115
  const runtime = getGlRenderStateRuntime(state);
50
116
  const gl = state.gl;
@@ -116,14 +182,19 @@ export function setGlQuadMatrixFromOffset(state, a, b, c, d, tx, ty, dx, dy) {
116
182
  export function updateGlTexture(state, texture, canvas) {
117
183
  const runtime = getGlRenderStateRuntime(state);
118
184
  const gl = state.gl;
119
- if (runtime.currentTexture !== texture) {
120
- gl.bindTexture(gl.TEXTURE_2D, texture);
121
- runtime.currentTexture = texture;
122
- }
185
+ // Always rebind before uploading — runtime.currentTexture is unit-blind (see bindGlTexture), so a
186
+ // skip could upload into whatever is bound on the currently-active unit instead of `texture`.
187
+ gl.bindTexture(gl.TEXTURE_2D, texture);
188
+ runtime.currentTexture = texture;
123
189
  // Browsers pass canvas pixel data to Gl as straight (unmultiplied) alpha.
124
190
  // Premultiply on upload so the texture matches the (ONE, ONE_MINUS_SRC_ALPHA) blend mode.
125
191
  gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
126
192
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
193
+ // Refresh the mip chain if this texture carries one (a canvas/video that opted into mipmaps); the
194
+ // re-uploaded base level would otherwise leave stale lower mips. The 2D default has no chain, so
195
+ // the common per-frame canvas/video upload skips the cost.
196
+ if (runtime.mipmappedTextures?.has(texture))
197
+ gl.generateMipmap(gl.TEXTURE_2D);
127
198
  }
128
199
  export function useGlProgram(state, shader) {
129
200
  const runtime = getGlRenderStateRuntime(state);
@@ -135,15 +206,144 @@ export function useGlProgram(state, shader) {
135
206
  runtime.currentProgram = program;
136
207
  }
137
208
  }
209
+ // Uploads an ImageResource into the currently-bound texture for the 2D display pipeline. The element
210
+ // fast-path premultiplies via UNPACK_PREMULTIPLY_ALPHA_WEBGL (straight-alpha element under a premultiplied
211
+ // (ONE, ONE_MINUS_SRC_ALPHA) blend would otherwise blow a 40%-white shape to opaque white). That flag is
212
+ // ignored for raw-data (ArrayBufferView) uploads, so straight-alpha `data` is premultiplied on the CPU
213
+ // first; opaque data (alpha 255, e.g. a normal/roughness map) premultiplies to itself, so this is a no-op
214
+ // there. The data path is what makes a memory-generated Surface a first-class 2D texture. A resource that
215
+ // carries only a block-`compressed` payload (no element or data) uploads through the GPU-native compressed
216
+ // path — falling back to the state's registered RGBA decoder when the device lacks the block format.
217
+ function uploadGlDisplayTexture(state, image) {
218
+ const gl = state.gl;
219
+ if (image.source !== null) {
220
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
221
+ uploadGlTextureElement(gl, gl.TEXTURE_2D, image.source);
222
+ return;
223
+ }
224
+ if (image.data === null && image.compressed !== null) {
225
+ // The compressed-container upload path is an opt-in seam (registerGlCompressedTextureUpload), so a
226
+ // state that only draws element/data bitmaps never carries its ~40-format enum table. When unset,
227
+ // skip rather than upload garbage — the texture stays empty until an uploader is registered.
228
+ const runtime = getGlRenderStateRuntime(state);
229
+ runtime.compressedTextureUpload?.(gl, image, runtime.compressedTextureDecoder ?? null);
230
+ return;
231
+ }
232
+ const data = image.alphaType === 'straight' ? premultiplyStraightRgba8(image.data) : image.data;
233
+ uploadGlTextureData(gl, gl.TEXTURE_2D, image.width, image.height, data);
234
+ }
235
+ // Returns a new premultiplied rgba8 buffer from a straight-alpha one (rgb *= a/255). Allocates, but runs
236
+ // only on a texture upload (cache miss or content change), never in the per-frame draw path.
237
+ function premultiplyStraightRgba8(data) {
238
+ const out = new Uint8ClampedArray(data.length);
239
+ for (let i = 0; i < data.length; i += 4) {
240
+ const a = data[i + 3];
241
+ out[i] = (data[i] * a) / 255;
242
+ out[i + 1] = (data[i + 1] * a) / 255;
243
+ out[i + 2] = (data[i + 2] * a) / 255;
244
+ out[i + 3] = a;
245
+ }
246
+ return out;
247
+ }
248
+ // Applies a sampler's wrap, filtering, anisotropy, and mip chain to the currently-bound TEXTURE_2D.
249
+ // Without a sampler it falls back to the state's allowSmoothing flag with clamp-to-edge and no mips —
250
+ // the 2D bitmap/sprite default. With one, every field comes from the descriptor. The mip chain is
251
+ // generated once per texture (tracked in runtime.mipmappedTextures) the first time a mip-sampling
252
+ // filter asks for it, so a shared texture first bound without mips and later with them still generates
253
+ // its chain. Filtering and wrap are set every bind (cheap) so a texture shared across samplers follows
254
+ // the current draw; only the one-time mip generation is gated.
255
+ function applyGlSamplerState(state, runtime, texture, sampler) {
256
+ const gl = state.gl;
257
+ if (!sampler) {
258
+ const filter = state.allowSmoothing ? gl.LINEAR : gl.NEAREST;
259
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);
260
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);
261
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
262
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
263
+ return;
264
+ }
265
+ const useMips = sampler.mipmaps && isGlMipmapFilter(sampler.minFilter);
266
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glMinFilterValue(gl, sampler.minFilter, useMips));
267
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glMagFilterValue(gl, sampler.magFilter));
268
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, glTextureWrapValue(gl, sampler.wrapU));
269
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, glTextureWrapValue(gl, sampler.wrapV));
270
+ const ext = ensureGlAnisotropyExt(state, runtime);
271
+ if (ext) {
272
+ // Clamp the requested level to [1, hardware max]; 1 disables anisotropy and also resets a texture
273
+ // that a previous anisotropic sampler left elevated.
274
+ const level = Math.max(1, Math.min(sampler.anisotropy, runtime.maxAnisotropy ?? 1));
275
+ gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, level);
276
+ }
277
+ if (useMips) {
278
+ const mipped = (runtime.mipmappedTextures ??= new WeakSet());
279
+ if (!mipped.has(texture)) {
280
+ gl.generateMipmap(gl.TEXTURE_2D);
281
+ mipped.add(texture);
282
+ }
283
+ }
284
+ }
285
+ // Resolves and caches EXT_texture_filter_anisotropic on the runtime: anisotropyExt is undefined until
286
+ // first queried, then the extension object or null when unsupported, and maxAnisotropy caches the
287
+ // hardware cap. Returns null when anisotropic filtering is unavailable.
288
+ function ensureGlAnisotropyExt(state, runtime) {
289
+ let ext = runtime.anisotropyExt;
290
+ if (ext === undefined) {
291
+ ext = state.gl.getExtension('EXT_texture_filter_anisotropic');
292
+ runtime.anisotropyExt = ext;
293
+ runtime.maxAnisotropy = ext ? state.gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT) : 1;
294
+ }
295
+ return ext;
296
+ }
297
+ // Maps a magnification TextureFilter to its WebGL2 constant. Magnification never samples mips, so the
298
+ // mip-variant names collapse to their base LINEAR/NEAREST.
299
+ function glMagFilterValue(gl, filter) {
300
+ return filter.startsWith('nearest') ? gl.NEAREST : gl.LINEAR;
301
+ }
302
+ // Maps a minification TextureFilter to its WebGL2 constant. When useMips is false (mipmaps disabled or
303
+ // a non-mip filter) the mip-variant names collapse to their base LINEAR/NEAREST, so a filter that
304
+ // names a mip level never selects an absent chain (which would render the texture black).
305
+ function glMinFilterValue(gl, filter, useMips) {
306
+ if (!useMips)
307
+ return filter.startsWith('nearest') ? gl.NEAREST : gl.LINEAR;
308
+ switch (filter) {
309
+ case 'linear-mipmap-linear':
310
+ return gl.LINEAR_MIPMAP_LINEAR;
311
+ case 'linear-mipmap-nearest':
312
+ return gl.LINEAR_MIPMAP_NEAREST;
313
+ case 'nearest-mipmap-linear':
314
+ return gl.NEAREST_MIPMAP_LINEAR;
315
+ case 'nearest-mipmap-nearest':
316
+ return gl.NEAREST_MIPMAP_NEAREST;
317
+ case 'nearest':
318
+ return gl.NEAREST;
319
+ default:
320
+ return gl.LINEAR;
321
+ }
322
+ }
323
+ // True for the mip-sampling minification filters; the two non-mip modes ('linear'/'nearest') sample
324
+ // only the base level and need no mip chain.
325
+ function isGlMipmapFilter(filter) {
326
+ return filter !== 'linear' && filter !== 'nearest';
327
+ }
328
+ // Maps a sampler wrap mode to its WebGL2 texture-wrap constant; clamp-to-edge is the fallback. REPEAT
329
+ // tiles the sampled uv, which is what makes setTextureUvScale / a repeat sampler actually tile.
330
+ function glTextureWrapValue(gl, wrap) {
331
+ if (wrap === 'repeat')
332
+ return gl.REPEAT;
333
+ if (wrap === 'mirror-repeat')
334
+ return gl.MIRRORED_REPEAT;
335
+ return gl.CLAMP_TO_EDGE;
336
+ }
138
337
  const NORMAL_BLEND = { src: 'ONE', dst: 'ONE_MINUS_SRC_ALPHA' };
139
338
  // The built-in blend modes registerDefaultGlBlendModes installs, each with its fixed-function
140
- // realization. Overlay/HardLight/Difference/Invert are deliberately absent they have no
141
- // fixed-function equivalent and need a shader pass.
339
+ // realization the cheap fixed-function set. The Porter-Duff coverage operators (Erase/Alpha/None/…) are
340
+ // a CompositeEffect, the destination-reading blends (Overlay/HardLight/…) a BlendEffect, and rare
341
+ // equations like Subtract are wired on demand via registerGlBlendMode — none belong in the node-property
342
+ // set. Darken/Lighten are exact only for an opaque backdrop (MIN/MAX cannot carry the coverage-restore
343
+ // term); realize them as a BlendEffect for transparent-edge correctness.
142
344
  const DEFAULT_GL_BLEND_MODES = [
143
345
  [BlendMode.Add, { src: 'ONE', dst: 'ONE' }],
144
346
  [BlendMode.Darken, { src: 'ONE', dst: 'ONE', equation: 'MIN' }],
145
- [BlendMode.Erase, { src: 'ZERO', dst: 'ONE_MINUS_SRC_ALPHA' }],
146
- [BlendMode.Layer, NORMAL_BLEND],
147
347
  [BlendMode.Lighten, { src: 'ONE', dst: 'ONE', equation: 'MAX' }],
148
348
  // Premultiplied multiply: result = src.rgb*dst + dst*(1-src.a). The (1-src.a) term restores the
149
349
  // destination where the source is transparent or partially covered (antialiased edges, the quad's
@@ -151,12 +351,7 @@ const DEFAULT_GL_BLEND_MODES = [
151
351
  // toward black — the straight-alpha (DST_COLOR, ZERO) form fringes there because this pipeline
152
352
  // uploads and shades premultiplied. Exact for an opaque backdrop.
153
353
  [BlendMode.Multiply, { src: 'DST_COLOR', dst: 'ONE_MINUS_SRC_ALPHA' }],
154
- // No blending: result = src (the premultiplied source replaces the destination). For opaque
155
- // content this matches Normal; unlike Normal it does not composite, so semi-transparent source
156
- // pixels overwrite the backdrop instead of blending over it.
157
- [BlendMode.None, { src: 'ONE', dst: 'ZERO' }],
158
354
  [BlendMode.Normal, NORMAL_BLEND],
159
355
  [BlendMode.Screen, { src: 'ONE', dst: 'ONE_MINUS_SRC_COLOR' }],
160
- [BlendMode.Subtract, { src: 'ONE', dst: 'ONE', equation: 'FUNC_REVERSE_SUBTRACT' }],
161
356
  ];
162
357
  //# sourceMappingURL=glDraw.js.map