@ludicon/spark.js 0.0.14 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -11
- package/dist/spark.esm.js +995 -471
- package/dist/spark_astc_rgb-CTmg8wnA.js +4 -0
- package/dist/spark_astc_rgba-CDMNWH6H.js +4 -0
- package/dist/spark_bc1_rgb-C0pbbQPO.js +4 -0
- package/dist/spark_bc4_r-YQ6i79H9.js +4 -0
- package/dist/spark_bc5_rg-BqzKgeMU.js +4 -0
- package/dist/spark_bc7_rgb-DBkDHCzE.js +4 -0
- package/dist/spark_bc7_rgba-DQUk89UX.js +4 -0
- package/dist/spark_eac_r-Dvy2qUxf.js +4 -0
- package/dist/spark_eac_rg-DKLVL9co.js +4 -0
- package/dist/spark_etc2_rgb-BpnNweVx.js +4 -0
- package/dist/utils-D_dYVlAC.js +419 -0
- package/package.json +6 -3
- package/src/three-gltf.js +29 -14
- package/dist/utils-BigAnOxg.js +0 -234
package/dist/spark.esm.js
CHANGED
|
@@ -1,6 +1,53 @@
|
|
|
1
|
-
const
|
|
2
|
-
Object.entries(
|
|
3
|
-
)
|
|
1
|
+
const ge = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import("./spark_astc_rgb-DaSIMKXW.js"), "./spark_astc_rgba.wgsl": () => import("./spark_astc_rgba-BToA2Rcq.js"), "./spark_bc1_rgb.wgsl": () => import("./spark_bc1_rgb-DZwuM1tO.js"), "./spark_bc4_r.wgsl": () => import("./spark_bc4_r-DjThizCH.js"), "./spark_bc5_rg.wgsl": () => import("./spark_bc5_rg-6bO0Gvo9.js"), "./spark_bc7_rgb.wgsl": () => import("./spark_bc7_rgb-FXpBw9fE.js"), "./spark_bc7_rgba.wgsl": () => import("./spark_bc7_rgba-C8Hi2pUY.js"), "./spark_eac_r.wgsl": () => import("./spark_eac_r-D8HGiglc.js"), "./spark_eac_rg.wgsl": () => import("./spark_eac_rg-DvsrLP9h.js"), "./spark_etc2_rgb.wgsl": () => import("./spark_etc2_rgb-C-j5FZpn.js"), "./utils.wgsl": () => import("./utils-D_dYVlAC.js") }), Z = Object.fromEntries(
|
|
2
|
+
Object.entries(ge).map(([i, t]) => [i.replace("./", ""), async () => (await t()).default])
|
|
3
|
+
);
|
|
4
|
+
function O(i, t) {
|
|
5
|
+
if (!i)
|
|
6
|
+
throw new Error(t);
|
|
7
|
+
}
|
|
8
|
+
function he() {
|
|
9
|
+
const i = navigator.userAgent;
|
|
10
|
+
if (i.includes("Chrome") || i.includes("Chromium"))
|
|
11
|
+
return null;
|
|
12
|
+
const t = i.match(/Safari\/(\d+(\.\d+)?)/);
|
|
13
|
+
return t && parseFloat(t[1]);
|
|
14
|
+
}
|
|
15
|
+
function J() {
|
|
16
|
+
const i = navigator.userAgent.match(/Firefox\/(\d+(\.\d+)?)/);
|
|
17
|
+
return i && parseFloat(i[1]);
|
|
18
|
+
}
|
|
19
|
+
function pe(i) {
|
|
20
|
+
return /\.svg(?:$|\?)/i.test(i) || /^data:image\/svg\+xml[,;]/i.test(i);
|
|
21
|
+
}
|
|
22
|
+
function ee(i) {
|
|
23
|
+
return new Promise((t, r) => {
|
|
24
|
+
const e = new Image();
|
|
25
|
+
e.crossOrigin = "anonymous", e.decoding = "async", e.onload = () => t(e), e.onerror = r, e.src = i;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
async function _e(i, t = {}) {
|
|
29
|
+
const r = await fetch(i, { mode: "cors" });
|
|
30
|
+
if (!r.ok) throw new Error(`HTTP ${r.status} for ${i}`);
|
|
31
|
+
const e = await r.blob();
|
|
32
|
+
return createImageBitmap(e, {
|
|
33
|
+
imageOrientation: t.flipY ? "flipY" : "none",
|
|
34
|
+
colorSpaceConversion: t.colorSpaceConversion ?? "none",
|
|
35
|
+
premultiplyAlpha: "none"
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const j = he(), Te = 619.1, Ee = j && j < Te;
|
|
39
|
+
async function be(i) {
|
|
40
|
+
const t = document.createElement("canvas");
|
|
41
|
+
return t.width = i.naturalWidth || i.width, t.height = i.naturalHeight || i.height, t.getContext("2d").drawImage(i, 0, 0), createImageBitmap(t);
|
|
42
|
+
}
|
|
43
|
+
async function K(i, t = {}) {
|
|
44
|
+
const r = pe(i);
|
|
45
|
+
if (r && Ee) {
|
|
46
|
+
const e = await ee(i);
|
|
47
|
+
return be(e);
|
|
48
|
+
} else return r || j ? ee(i) : _e(i, t);
|
|
49
|
+
}
|
|
50
|
+
const a = {
|
|
4
51
|
ASTC_4x4_RGB: 0,
|
|
5
52
|
ASTC_4x4_RGBA: 1,
|
|
6
53
|
// ASTC_4x4_RGBM: 2,
|
|
@@ -19,7 +66,7 @@ const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
19
66
|
// BC6H_RGB: 15,
|
|
20
67
|
BC7_RGB: 16,
|
|
21
68
|
BC7_RGBA: 17
|
|
22
|
-
},
|
|
69
|
+
}, N = [
|
|
23
70
|
/* 0 */
|
|
24
71
|
"astc-4x4-rgb",
|
|
25
72
|
// ASTC_4x4_RGB
|
|
@@ -66,7 +113,7 @@ const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
66
113
|
/* 17 */
|
|
67
114
|
"bc7-rgba"
|
|
68
115
|
// BC7_RGBA
|
|
69
|
-
],
|
|
116
|
+
], Re = [
|
|
70
117
|
/* 0 */
|
|
71
118
|
"spark_astc_rgb.wgsl",
|
|
72
119
|
// ASTC_4x4_RGB
|
|
@@ -113,7 +160,7 @@ const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
113
160
|
/* 17 */
|
|
114
161
|
"spark_bc7_rgba.wgsl"
|
|
115
162
|
// BC7_RGBA
|
|
116
|
-
],
|
|
163
|
+
], Be = [
|
|
117
164
|
/* 0 */
|
|
118
165
|
16,
|
|
119
166
|
// ASTC_4x4_RGB
|
|
@@ -160,81 +207,39 @@ const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
160
207
|
/* 17 */
|
|
161
208
|
16
|
|
162
209
|
// BC7_RGB
|
|
163
|
-
],
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
// EAC_RG
|
|
180
|
-
/* 6 */
|
|
181
|
-
8,
|
|
182
|
-
// ETC2_RGB
|
|
183
|
-
/* 7 */
|
|
184
|
-
0,
|
|
185
|
-
/* 8 */
|
|
186
|
-
0,
|
|
187
|
-
/* 9 */
|
|
188
|
-
8,
|
|
189
|
-
// BC1_RGB
|
|
190
|
-
/* 10 */
|
|
191
|
-
0,
|
|
192
|
-
/* 11 */
|
|
193
|
-
0,
|
|
194
|
-
/* 12 */
|
|
195
|
-
0,
|
|
196
|
-
/* 13 */
|
|
197
|
-
2,
|
|
198
|
-
// BC4_R
|
|
199
|
-
/* 14 */
|
|
200
|
-
2,
|
|
201
|
-
// BC5_RG
|
|
202
|
-
/* 15 */
|
|
203
|
-
0,
|
|
204
|
-
/* 16 */
|
|
205
|
-
4,
|
|
206
|
-
// BC7_RGB
|
|
207
|
-
/* 17 */
|
|
208
|
-
4
|
|
209
|
-
// BC7_RGB
|
|
210
|
-
], P = Object.freeze({
|
|
211
|
-
"astc-4x4-rgb": i.ASTC_4x4_RGB,
|
|
212
|
-
"astc-4x4-rgba": i.ASTC_4x4_RGBA,
|
|
213
|
-
"eac-r": i.EAC_R,
|
|
214
|
-
"eac-rg": i.EAC_RG,
|
|
215
|
-
"etc2-rgb": i.ETC2_RGB,
|
|
216
|
-
"bc1-rgb": i.BC1_RGB,
|
|
217
|
-
"bc4-r": i.BC4_R,
|
|
218
|
-
"bc5-rg": i.BC5_RG,
|
|
219
|
-
"bc7-rgb": i.BC7_RGB,
|
|
220
|
-
"bc7-rgba": i.BC7_RGBA,
|
|
210
|
+
], A = {
|
|
211
|
+
Linear: 0,
|
|
212
|
+
sRGB: 1,
|
|
213
|
+
Alpha: 2,
|
|
214
|
+
Normal: 4
|
|
215
|
+
}, z = Object.freeze({
|
|
216
|
+
"astc-4x4-rgb": a.ASTC_4x4_RGB,
|
|
217
|
+
"astc-4x4-rgba": a.ASTC_4x4_RGBA,
|
|
218
|
+
"eac-r": a.EAC_R,
|
|
219
|
+
"eac-rg": a.EAC_RG,
|
|
220
|
+
"etc2-rgb": a.ETC2_RGB,
|
|
221
|
+
"bc1-rgb": a.BC1_RGB,
|
|
222
|
+
"bc4-r": a.BC4_R,
|
|
223
|
+
"bc5-rg": a.BC5_RG,
|
|
224
|
+
"bc7-rgb": a.BC7_RGB,
|
|
225
|
+
"bc7-rgba": a.BC7_RGBA,
|
|
221
226
|
// aliases:
|
|
222
|
-
"astc-rgb":
|
|
223
|
-
"astc-rgba":
|
|
227
|
+
"astc-rgb": a.ASTC_4x4_RGB,
|
|
228
|
+
"astc-rgba": a.ASTC_4x4_RGBA,
|
|
224
229
|
// webgpu aliases:
|
|
225
|
-
"bc1-rgba-unorm":
|
|
226
|
-
"bc1-rgba-unorm-srgb":
|
|
227
|
-
"bc4-r-unorm":
|
|
228
|
-
"bc5-rg-unorm":
|
|
229
|
-
"bc7-rgba-unorm":
|
|
230
|
-
"bc7-rgba-unorm-srgb":
|
|
231
|
-
"etc2-rgb8unorm":
|
|
232
|
-
"etc2-rgb8unorm-srgb":
|
|
233
|
-
"eac-r11unorm":
|
|
234
|
-
"eac-rg11unorm":
|
|
235
|
-
"astc-4x4-unorm":
|
|
236
|
-
"astc-4x4-unorm-srgb":
|
|
237
|
-
}),
|
|
230
|
+
"bc1-rgba-unorm": a.BC1_RGB,
|
|
231
|
+
"bc1-rgba-unorm-srgb": a.BC1_RGB,
|
|
232
|
+
"bc4-r-unorm": a.BC4_R,
|
|
233
|
+
"bc5-rg-unorm": a.BC5_RG,
|
|
234
|
+
"bc7-rgba-unorm": a.BC7_RGBA,
|
|
235
|
+
"bc7-rgba-unorm-srgb": a.BC7_RGBA,
|
|
236
|
+
"etc2-rgb8unorm": a.ETC2_RGB,
|
|
237
|
+
"etc2-rgb8unorm-srgb": a.ETC2_RGB,
|
|
238
|
+
"eac-r11unorm": a.EAC_R,
|
|
239
|
+
"eac-rg11unorm": a.EAC_RG,
|
|
240
|
+
"astc-4x4-unorm": a.ASTC_4x4_RGBA,
|
|
241
|
+
"astc-4x4-unorm-srgb": a.ASTC_4x4_RGBA
|
|
242
|
+
}), xe = [
|
|
238
243
|
/* 0 */
|
|
239
244
|
"astc-4x4-unorm",
|
|
240
245
|
// ASTC_4x4_RGB
|
|
@@ -281,7 +286,7 @@ const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
281
286
|
/* 17 */
|
|
282
287
|
"bc7-rgba-unorm"
|
|
283
288
|
// BC7_RGB
|
|
284
|
-
],
|
|
289
|
+
], Ge = [
|
|
285
290
|
/* 0 */
|
|
286
291
|
!0,
|
|
287
292
|
// ASTC_4x4_RGB
|
|
@@ -329,110 +334,113 @@ const V = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.wgsl": () => import(
|
|
|
329
334
|
!0
|
|
330
335
|
// BC7_RGB
|
|
331
336
|
];
|
|
332
|
-
function
|
|
333
|
-
|
|
334
|
-
throw new Error(e);
|
|
337
|
+
function Ce(i) {
|
|
338
|
+
return Ge[i];
|
|
335
339
|
}
|
|
336
|
-
function
|
|
337
|
-
return
|
|
340
|
+
function Se(i) {
|
|
341
|
+
return i == a.ASTC_4x4_RGBA || i == a.BC7_RGBA;
|
|
338
342
|
}
|
|
339
|
-
function
|
|
343
|
+
function Pe(i) {
|
|
344
|
+
return typeof GPUDevice < "u" && i instanceof GPUDevice;
|
|
345
|
+
}
|
|
346
|
+
function Ae() {
|
|
340
347
|
return ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"].includes(navigator.platform) || // iPad on iOS 13 detection
|
|
341
348
|
navigator.userAgent.includes("Mac") && "ontouchend" in document;
|
|
342
349
|
}
|
|
343
|
-
function
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
const c = navigator.userAgent.match(/Firefox\/(\d+(\.\d+)?)/);
|
|
349
|
-
return c && parseFloat(c[1]);
|
|
350
|
-
}
|
|
351
|
-
function Q(c) {
|
|
352
|
-
const e = /* @__PURE__ */ new Set(), r = {
|
|
353
|
-
"texture-compression-bc": [
|
|
354
|
-
i.BC1_RGB,
|
|
355
|
-
i.BC4_R,
|
|
356
|
-
i.BC5_RG,
|
|
357
|
-
i.BC7_RGB,
|
|
358
|
-
i.BC7_RGBA
|
|
359
|
-
],
|
|
360
|
-
"texture-compression-etc2": [i.ETC2_RGB, i.EAC_R, i.EAC_RG],
|
|
361
|
-
"texture-compression-astc": [i.ASTC_4x4_RGB, i.ASTC_4x4_RGBA]
|
|
350
|
+
function Ue(i) {
|
|
351
|
+
const t = /* @__PURE__ */ new Set(), r = {
|
|
352
|
+
"texture-compression-bc": [a.BC1_RG, a.BC4_R, a.BC5_RG, a.BC7_RGB, a.BC7_RGBA],
|
|
353
|
+
"texture-compression-etc2": [a.ETC2_RGB, a.EAC_R, a.EAC_RG],
|
|
354
|
+
"texture-compression-astc": [a.ASTC_4x4_RGB, a.ASTC_4x4_RGBA]
|
|
362
355
|
};
|
|
363
|
-
for (const [
|
|
364
|
-
if (
|
|
365
|
-
for (const
|
|
366
|
-
|
|
367
|
-
return
|
|
356
|
+
for (const [e, s] of Object.entries(r))
|
|
357
|
+
if (i.features.has(e))
|
|
358
|
+
for (const o of s)
|
|
359
|
+
t.add(o);
|
|
360
|
+
return t;
|
|
368
361
|
}
|
|
369
|
-
function
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
const r =
|
|
373
|
-
r.drawImage(
|
|
374
|
-
const
|
|
375
|
-
return new Uint8Array(
|
|
362
|
+
function we(i) {
|
|
363
|
+
const t = document.createElement("canvas");
|
|
364
|
+
t.width = i.width, t.height = i.height;
|
|
365
|
+
const r = t.getContext("2d");
|
|
366
|
+
r.drawImage(i, 0, 0);
|
|
367
|
+
const e = r.getImageData(0, 0, i.width, i.height);
|
|
368
|
+
return new Uint8Array(e.data.buffer);
|
|
376
369
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
return new Promise((e, r) => {
|
|
382
|
-
const t = new Image();
|
|
383
|
-
t.crossOrigin = "anonymous", t.decoding = "async", t.onload = () => e(t), t.onerror = r, t.src = c;
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
async function ee(c, e = {}) {
|
|
387
|
-
const r = await fetch(c, { mode: "cors" });
|
|
388
|
-
if (!r.ok) throw new Error(`HTTP ${r.status} for ${c}`);
|
|
389
|
-
const t = await r.blob();
|
|
390
|
-
return createImageBitmap(t, {
|
|
391
|
-
imageOrientation: e.flipY ? "flipY" : "none",
|
|
392
|
-
colorSpaceConversion: e.colorSpaceConversion ?? "none",
|
|
393
|
-
premultiplyAlpha: "none"
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
const te = O();
|
|
397
|
-
function N(c) {
|
|
398
|
-
return J(c) || te ? K(c) : ee(c);
|
|
399
|
-
}
|
|
400
|
-
const L = 256, F = 4;
|
|
401
|
-
function re(c, e, r, t) {
|
|
402
|
-
let s = 0, n = 0;
|
|
403
|
-
const a = [];
|
|
370
|
+
const te = 256, re = 4;
|
|
371
|
+
function ye(i, t, r, e) {
|
|
372
|
+
let s = 0, o = 0;
|
|
373
|
+
const c = [];
|
|
404
374
|
do {
|
|
405
|
-
const
|
|
406
|
-
s++,
|
|
407
|
-
} while (
|
|
408
|
-
return { mipmapCount: s, outputSize:
|
|
375
|
+
const n = Math.ceil(i / 4), f = Math.ceil(t / 4), u = Math.ceil(n * r / te) * te, l = f * u;
|
|
376
|
+
s++, c.push({ offset: o, alignedSize: l, w: i, h: t, bw: n, bh: f, bytesPerRow: u }), o += l, i = Math.max(1, Math.floor(i / 2)), t = Math.max(1, Math.floor(t / 2));
|
|
377
|
+
} while (e && (i >= re || t >= re));
|
|
378
|
+
return { mipmapCount: s, outputSize: o, bufferRanges: c };
|
|
409
379
|
}
|
|
410
|
-
class
|
|
380
|
+
class me {
|
|
411
381
|
#e;
|
|
412
|
-
#
|
|
413
|
-
#
|
|
382
|
+
#l;
|
|
383
|
+
#T;
|
|
384
|
+
#h = !1;
|
|
385
|
+
#f = [];
|
|
414
386
|
#g;
|
|
415
|
-
#
|
|
387
|
+
#d;
|
|
388
|
+
#p;
|
|
389
|
+
#a;
|
|
390
|
+
#E;
|
|
416
391
|
#s;
|
|
417
|
-
#o;
|
|
418
|
-
#u;
|
|
419
|
-
#m;
|
|
420
392
|
#i;
|
|
421
|
-
#n
|
|
422
|
-
#
|
|
423
|
-
#
|
|
424
|
-
#
|
|
425
|
-
#
|
|
393
|
+
#n;
|
|
394
|
+
#_;
|
|
395
|
+
#u;
|
|
396
|
+
#t = !1;
|
|
397
|
+
#o = null;
|
|
398
|
+
#c = null;
|
|
399
|
+
#m = null;
|
|
400
|
+
#B = 0;
|
|
401
|
+
#b = !1;
|
|
426
402
|
/**
|
|
427
403
|
* Initialize the encoder by detecting available compression formats.
|
|
428
404
|
* @param {GPUDevice} device - WebGPU device.
|
|
429
405
|
* @param {Object} options - Encoder options.
|
|
430
406
|
* @param {boolean} options.preload - Whether to preload all encoder pipelines (false by default).
|
|
407
|
+
* @param {boolean} options.cacheTempResources - Whether to cache temporary resources for reuse across encodeTexture calls (false by default).
|
|
408
|
+
* @param {boolean} options.verbose - Whether to enable verbose logging (false by default).
|
|
431
409
|
* @returns {Promise<void>} Resolves when initialization is complete.
|
|
432
410
|
*/
|
|
433
|
-
static async create(
|
|
434
|
-
const
|
|
435
|
-
return await
|
|
411
|
+
static async create(t, r = {}) {
|
|
412
|
+
const e = new me();
|
|
413
|
+
return await e.#w(
|
|
414
|
+
t,
|
|
415
|
+
r.preload ?? !1,
|
|
416
|
+
r.useTimestampQueries ?? !1,
|
|
417
|
+
r.verbose ?? !1,
|
|
418
|
+
r.cacheTempResources ?? !1
|
|
419
|
+
), e;
|
|
420
|
+
}
|
|
421
|
+
dispose() {
|
|
422
|
+
for (const t of this.#f)
|
|
423
|
+
t.destroy();
|
|
424
|
+
this.#g.destroy(), this.#p.destroy(), this.#a.destroy(), this.#E.destroy(), this.#s.destroy();
|
|
425
|
+
for (let t = 0; t < 3; t++)
|
|
426
|
+
this.#i[t].destroy();
|
|
427
|
+
this.#n.destroy(), this.#_.destroy(), this.#u.destroy(), this.freeTempResources();
|
|
428
|
+
}
|
|
429
|
+
#x(...t) {
|
|
430
|
+
this.#b && console.log(...t);
|
|
431
|
+
}
|
|
432
|
+
#G(t) {
|
|
433
|
+
this.#b && console.time(t);
|
|
434
|
+
}
|
|
435
|
+
#C(t) {
|
|
436
|
+
this.#b && console.timeEnd(t);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Free cached temporary resources used by encodeTexture.
|
|
440
|
+
* Call this when you're done encoding textures to free up GPU memory.
|
|
441
|
+
*/
|
|
442
|
+
freeTempResources() {
|
|
443
|
+
this.#o && (this.#o.destroy(), this.#o = null), this.#c && (this.#c.destroy(), this.#c = null), this.#m && (this.#m.destroy(), this.#m = null);
|
|
436
444
|
}
|
|
437
445
|
/**
|
|
438
446
|
* Returns a list of supported texture compression format names.
|
|
@@ -441,34 +449,25 @@ class D {
|
|
|
441
449
|
* (ASTC, ETC2, EAC, BCn) and filters it based on the formats actually supported
|
|
442
450
|
* by the current device as determined by `Spark.supportedFormats`.
|
|
443
451
|
*
|
|
444
|
-
* @returns {string[]} An array of format names (e.g., "bc1-rgb", "astc-4x4-rgba") that are supported on the current
|
|
452
|
+
* @returns {string[]} An array of format names (e.g., "bc1-rgb", "astc-4x4-rgba") that are supported on the current device.
|
|
445
453
|
*
|
|
446
454
|
* @example
|
|
447
455
|
* const spark = await Spark.create(device);
|
|
448
|
-
* const formats = spark.
|
|
456
|
+
* const formats = spark.getSupportedFormats();
|
|
449
457
|
* console.log("Supported formats:", formats);
|
|
450
458
|
*/
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
], r = [];
|
|
464
|
-
for (const t of e) {
|
|
465
|
-
const s = P[t];
|
|
466
|
-
if (this.#t(s)) {
|
|
467
|
-
const n = Y[s];
|
|
468
|
-
r.push({ format: t, ratio: n });
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
return r;
|
|
459
|
+
getSupportedFormats() {
|
|
460
|
+
return Array.from(this.#l).map((t) => N[t]).filter(Boolean);
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Returns whether the given format is supported on the current device.
|
|
464
|
+
*
|
|
465
|
+
* @param {string} format
|
|
466
|
+
* @returns {boolean} `true` if the format is supported, `false` otherwise.
|
|
467
|
+
*/
|
|
468
|
+
isFormatSupported(t) {
|
|
469
|
+
const r = typeof t == "string" ? z[t] : t;
|
|
470
|
+
return this.#l.has(r);
|
|
472
471
|
}
|
|
473
472
|
/**
|
|
474
473
|
* Determines the set of WebGPU features to request when initializing the device.
|
|
@@ -488,9 +487,9 @@ class D {
|
|
|
488
487
|
* // Create spark object for the given device.
|
|
489
488
|
* const spark = Spark.create(device)
|
|
490
489
|
*/
|
|
491
|
-
static getRequiredFeatures(
|
|
490
|
+
static getRequiredFeatures(t) {
|
|
492
491
|
const r = [];
|
|
493
|
-
return !
|
|
492
|
+
return !Ae() && t.features.has("texture-compression-bc") && r.push("texture-compression-bc"), t.features.has("texture-compression-etc2") && r.push("texture-compression-etc2"), t.features.has("texture-compression-astc") && r.push("texture-compression-astc"), t.features.has("shader-f16") && r.push("shader-f16"), t.features.has("timestamp-query") && r.push("timestamp-query"), r;
|
|
494
493
|
}
|
|
495
494
|
/**
|
|
496
495
|
* Try to determine the best compression options automatically. Do not use this in production, this is
|
|
@@ -500,12 +499,12 @@ class D {
|
|
|
500
499
|
* @param {Object} options - Encoding options.
|
|
501
500
|
* @returns {Object} - Recommended encoding options with an explicit encoding format.
|
|
502
501
|
*/
|
|
503
|
-
async selectPreferredOptions(
|
|
502
|
+
async selectPreferredOptions(t, r = {}) {
|
|
504
503
|
if (r.format == null || r.format == "auto") {
|
|
505
|
-
const
|
|
504
|
+
const e = t instanceof Image || t instanceof ImageBitmap || t instanceof GPUTexture ? t : await K(t);
|
|
506
505
|
r.format = "auto";
|
|
507
|
-
const s = await this.#
|
|
508
|
-
r.format =
|
|
506
|
+
const s = await this.#A(r, e);
|
|
507
|
+
r.format = N[s], e instanceof GPUTexture && e.format.endsWith("-srgb") && (r.srgb = !0), (s == a.EAC_RG || s == a.BC5_RG) && (r.normal = !0);
|
|
509
508
|
}
|
|
510
509
|
return r;
|
|
511
510
|
}
|
|
@@ -527,13 +526,18 @@ class D {
|
|
|
527
526
|
* - "auto" to analyze the input texture and detect the required channels.
|
|
528
527
|
* This has some overhead, so specifying a format explicitly is preferred.
|
|
529
528
|
*
|
|
530
|
-
* @param {boolean} [options.alpha]
|
|
531
|
-
* Hint for the automatic format selector. When no explicit format is provided,
|
|
532
|
-
* the format is assumed to be "rgb". Supplying `alpha: true` will favor RGBA formats.
|
|
533
|
-
*
|
|
534
529
|
* @param {boolean} [options.mips=false] | [options.generateMipmaps=false]
|
|
535
|
-
* Whether to generate mipmaps.
|
|
536
|
-
*
|
|
530
|
+
* Whether to generate mipmaps.
|
|
531
|
+
*
|
|
532
|
+
* @param {string} [options.mipmapFilter="magic"]
|
|
533
|
+
* The filter to use for mipmap generation. Can be "box" for a simple box filter,
|
|
534
|
+
* or "magic" for a higher-quality 4-tap filter with sharpening properties.
|
|
535
|
+
*
|
|
536
|
+
* @param {number[]} [options.mipsAlphaScale]
|
|
537
|
+
* Optional array of alpha scale values to apply to each generated mipmap level.
|
|
538
|
+
* The array should contain one value per mipmap level (starting with mip level 1,
|
|
539
|
+
* since level 0 is the base image). Each value multiplies the alpha channel of
|
|
540
|
+
* the corresponding mipmap level.
|
|
537
541
|
*
|
|
538
542
|
* @param {boolean} [options.srgb=false]
|
|
539
543
|
* Whether to encode the image in an sRGB format. Also affects mipmap generation.
|
|
@@ -548,97 +552,111 @@ class D {
|
|
|
548
552
|
*
|
|
549
553
|
* @returns {Promise<GPUTexture>} A promise resolving to the encoded GPU texture.
|
|
550
554
|
*/
|
|
551
|
-
async encodeTexture(
|
|
552
|
-
|
|
553
|
-
const
|
|
554
|
-
|
|
555
|
-
const s = await this.#
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
{
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
555
|
+
async encodeTexture(t, r = {}) {
|
|
556
|
+
O(this.#e, "Spark is not initialized");
|
|
557
|
+
const e = t instanceof Image || t instanceof ImageBitmap || t instanceof GPUTexture ? t : await K(t);
|
|
558
|
+
this.#x("Loaded image", e);
|
|
559
|
+
const s = await this.#A(r, e), o = this.#S(s), c = Math.ceil(e.width / 4) * 4, n = Math.ceil(e.height / 4) * 4, f = Be[s], u = r.generateMipmaps || r.mips, { mipmapCount: l, outputSize: h, bufferRanges: m } = ye(c, n, f, u), R = (r.srgb || r.format?.endsWith("srgb")) && Ce(s);
|
|
560
|
+
let T = R ? A.sRGB : A.Linear;
|
|
561
|
+
Se(s) && (T |= A.Alpha), r.normal && (T = A.Normal);
|
|
562
|
+
const d = xe[s] + (R ? "-srgb" : ""), V = R ? ["rgba8unorm", "rgba8unorm-srgb"] : ["rgba8unorm"], x = this.#B++;
|
|
563
|
+
this.#G("create input texture #" + x);
|
|
564
|
+
let y = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST;
|
|
565
|
+
this.#h ? y |= GPUTextureUsage.RENDER_ATTACHMENT : y |= GPUTextureUsage.STORAGE_BINDING;
|
|
566
|
+
const S = r.flipY || c != e.width || n != e.height;
|
|
567
|
+
!S && !(e instanceof GPUTexture) && (y |= GPUTextureUsage.RENDER_ATTACHMENT);
|
|
568
|
+
const _ = this.#e.createCommandEncoder();
|
|
569
|
+
_.pushDebugGroup?.("spark process texture"), this.#n && typeof _.writeTimestamp == "function" && _.writeTimestamp(this.#n, 0);
|
|
570
|
+
let E;
|
|
571
|
+
if (S || !(e instanceof GPUTexture && !u)) {
|
|
572
|
+
const g = !this.#t || !this.#o || this.#o.width < c || this.#o.height < n || this.#o.mipLevelCount < l;
|
|
573
|
+
this.#t && this.#o && !g ? E = this.#o : (this.#t && this.#o && this.#o.destroy(), E = this.#e.createTexture({
|
|
574
|
+
size: [c, n, 1],
|
|
575
|
+
mipLevelCount: l,
|
|
576
|
+
format: "rgba8unorm",
|
|
577
|
+
usage: y,
|
|
578
|
+
viewFormats: V
|
|
579
|
+
}), this.#t && (this.#o = E));
|
|
580
|
+
}
|
|
581
|
+
let P;
|
|
582
|
+
if (S)
|
|
583
|
+
if (e instanceof GPUTexture)
|
|
584
|
+
this.#U(_, e, E, c, n, R, r.flipY);
|
|
585
|
+
else {
|
|
586
|
+
const g = !this.#t || !this.#c || this.#c.width < e.width || this.#c.height < e.height;
|
|
587
|
+
this.#t && this.#c && !g ? P = this.#c : (this.#t && this.#c && this.#c.destroy(), P = this.#e.createTexture({
|
|
588
|
+
size: [e.width, e.height, 1],
|
|
589
|
+
mipLevelCount: 1,
|
|
590
|
+
format: "rgba8unorm",
|
|
591
|
+
// RENDER_ATTACHMENT usage is necessary for copyExternalImageToTexture
|
|
592
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
|
|
593
|
+
viewFormats: V
|
|
594
|
+
}), this.#t && (this.#c = P)), this.#e.queue.copyExternalImageToTexture({ source: e }, { texture: P }, { width: e.width, height: e.height }), this.#U(_, P, E, c, n, T, r.flipY);
|
|
595
|
+
}
|
|
596
|
+
else
|
|
597
|
+
e instanceof GPUTexture ? u ? _.copyTextureToTexture({ texture: e }, { texture: E }, { width: c, height: n }) : E = e : this.#e.queue.copyExternalImageToTexture({ source: e }, { texture: E }, { width: c, height: n });
|
|
598
|
+
u && this.#L(_, E, l, c, n, T, r.mipsAlphaScale, r.mipmapFilter), _.popDebugGroup?.(), this.#C("create input texture #" + x);
|
|
599
|
+
const W = r.outputTexture && r.outputTexture.width == c && r.outputTexture.height == n && r.outputTexture.mipLevelCount == l && r.outputTexture.format == d ? r.outputTexture : this.#e.createTexture({
|
|
600
|
+
size: [c, n, 1],
|
|
601
|
+
mipLevelCount: l,
|
|
602
|
+
format: d,
|
|
588
603
|
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST
|
|
589
|
-
})
|
|
604
|
+
});
|
|
605
|
+
let C;
|
|
606
|
+
this.#t && this.#m && this.#m.size >= h ? C = this.#m : (this.#t && this.#m && this.#m.destroy(), C = this.#e.createBuffer({
|
|
590
607
|
size: h,
|
|
591
608
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
|
|
592
|
-
}),
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
609
|
+
}), this.#t && (this.#m = C));
|
|
610
|
+
const k = `dispatch compute shader '${N[s]}' #${x}`;
|
|
611
|
+
this.#G(k), _.pushDebugGroup?.("spark encode texture");
|
|
612
|
+
let b = {};
|
|
613
|
+
this.#n && typeof _.writeTimestamp != "function" && (b = {
|
|
596
614
|
writeTimestamps: {
|
|
597
|
-
querySet: this.#
|
|
615
|
+
querySet: this.#n,
|
|
598
616
|
beginningOfPassWriteIndex: 0,
|
|
599
617
|
endOfPassWriteIndex: 1
|
|
600
618
|
}
|
|
601
619
|
});
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
for (let g = 0; g <
|
|
605
|
-
const
|
|
606
|
-
layout:
|
|
620
|
+
const U = await o, B = _.beginComputePass(b);
|
|
621
|
+
B.setPipeline(U);
|
|
622
|
+
for (let g = 0; g < l; g++) {
|
|
623
|
+
const L = this.#e.createBindGroup({
|
|
624
|
+
layout: U.getBindGroupLayout(0),
|
|
607
625
|
entries: [
|
|
608
626
|
{
|
|
609
627
|
binding: 0,
|
|
610
|
-
resource:
|
|
628
|
+
resource: E.createView({
|
|
611
629
|
baseMipLevel: g,
|
|
612
630
|
mipLevelCount: 1
|
|
613
631
|
})
|
|
614
632
|
},
|
|
615
633
|
{
|
|
616
634
|
binding: 1,
|
|
617
|
-
resource: this.#
|
|
635
|
+
resource: this.#s
|
|
618
636
|
},
|
|
619
637
|
{
|
|
620
638
|
binding: 2,
|
|
621
639
|
resource: {
|
|
622
|
-
buffer:
|
|
640
|
+
buffer: C,
|
|
623
641
|
offset: m[g].offset,
|
|
624
642
|
size: m[g].size
|
|
625
643
|
}
|
|
626
644
|
}
|
|
627
645
|
]
|
|
628
646
|
});
|
|
629
|
-
|
|
647
|
+
B.setBindGroup(0, L), B.dispatchWorkgroups(Math.ceil(m[g].bw / 16), Math.ceil(m[g].bh / 16));
|
|
630
648
|
}
|
|
631
|
-
|
|
632
|
-
for (let g = 0; g <
|
|
633
|
-
|
|
649
|
+
B.end();
|
|
650
|
+
for (let g = 0; g < l; g++)
|
|
651
|
+
_.copyBufferToTexture(
|
|
634
652
|
{
|
|
635
|
-
buffer:
|
|
653
|
+
buffer: C,
|
|
636
654
|
offset: m[g].offset,
|
|
637
655
|
bytesPerRow: m[g].bytesPerRow,
|
|
638
656
|
rowsPerImage: m[g].bh
|
|
639
657
|
},
|
|
640
658
|
{
|
|
641
|
-
texture:
|
|
659
|
+
texture: W,
|
|
642
660
|
mipLevel: g
|
|
643
661
|
},
|
|
644
662
|
{
|
|
@@ -647,7 +665,7 @@ class D {
|
|
|
647
665
|
depthOrArrayLayers: 1
|
|
648
666
|
}
|
|
649
667
|
);
|
|
650
|
-
return this.#
|
|
668
|
+
return this.#n && typeof _.writeTimestamp == "function" && _.writeTimestamp(this.#n, 1), _.popDebugGroup?.(), this.#e.queue.submit([_.finish()]), this.#C(k), this.#t || (P?.destroy(), E != e && E?.destroy(), C?.destroy()), W;
|
|
651
669
|
}
|
|
652
670
|
/**
|
|
653
671
|
* Returns the time (in milliseconds) it took to perform the most recent `encodeTexture()` call.
|
|
@@ -669,74 +687,71 @@ class D {
|
|
|
669
687
|
* @throws {Error} If the GPU work has not been submitted, or if timestamp queries fail.
|
|
670
688
|
*/
|
|
671
689
|
async getTimeElapsed() {
|
|
672
|
-
if (!this.#
|
|
690
|
+
if (!this.#n)
|
|
673
691
|
return 0;
|
|
674
|
-
const
|
|
675
|
-
|
|
676
|
-
const r = this.#
|
|
677
|
-
return this.#
|
|
692
|
+
const t = this.#e.createCommandEncoder();
|
|
693
|
+
t.resolveQuerySet(this.#n, 0, 2, this.#_, 0), t.copyBufferToBuffer(this.#_, 0, this.#u, 0, 16), this.#e.queue.submit([t.finish()]), await this.#e.queue.onSubmittedWorkDone(), await this.#u.mapAsync(GPUMapMode.READ);
|
|
694
|
+
const r = this.#u.getMappedRange(), e = new BigUint64Array(r), s = e[0], o = e[1];
|
|
695
|
+
return this.#u.unmap(), Number(o - s) / 1e6;
|
|
678
696
|
}
|
|
679
|
-
async #
|
|
680
|
-
|
|
697
|
+
async #w(t, r, e, s, o) {
|
|
698
|
+
if (O(t, "device is required"), O(Pe(t), "device is not a WebGPU device"), this.#e = t, this.#b = s, this.#t = o, this.#l = Ue(this.#e), this.#s = this.#e.createSampler({
|
|
681
699
|
magFilter: "linear",
|
|
682
700
|
minFilter: "linear"
|
|
683
|
-
})
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
if (t && this.#e.features.has("timestamp-query")) {
|
|
690
|
-
const s = O(), n = k();
|
|
691
|
-
(!s || s >= 26) && !n && (this.#r = this.#e.createQuerySet({
|
|
701
|
+
}), this.#i = this.#e.createBuffer({
|
|
702
|
+
size: 16,
|
|
703
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
704
|
+
}), e && this.#e.features.has("timestamp-query")) {
|
|
705
|
+
const c = he(), n = J();
|
|
706
|
+
(!c || c >= 26) && !n && (this.#n = this.#e.createQuerySet({
|
|
692
707
|
type: "timestamp",
|
|
693
708
|
count: 2
|
|
694
|
-
}), this.#
|
|
709
|
+
}), this.#_ = this.#e.createBuffer({
|
|
695
710
|
size: 16,
|
|
696
711
|
// 2 timestamps × 8 bytes each
|
|
697
712
|
usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.QUERY_RESOLVE
|
|
698
|
-
}), this.#
|
|
713
|
+
}), this.#u = this.#e.createBuffer({
|
|
699
714
|
size: 16,
|
|
700
715
|
// 2 timestamps × 8 bytes each
|
|
701
716
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
|
|
702
717
|
}));
|
|
703
718
|
}
|
|
704
|
-
if (this.#
|
|
705
|
-
let
|
|
706
|
-
Array.isArray(r) ?
|
|
707
|
-
for (const n of
|
|
708
|
-
n !== void 0 && !this.#
|
|
709
|
-
console.error(`Failed to preload pipeline for format ${n}:`,
|
|
719
|
+
if (this.#T = this.#e.features.has("shader-f16"), await this.#y(), r) {
|
|
720
|
+
let c;
|
|
721
|
+
Array.isArray(r) ? c = r.map((n) => this.#P(n, !1)) : c = this.#l;
|
|
722
|
+
for (const n of c)
|
|
723
|
+
n !== void 0 && !this.#f[n] && this.#S(n).catch((f) => {
|
|
724
|
+
console.error(`Failed to preload pipeline for format ${n}:`, f);
|
|
710
725
|
});
|
|
711
726
|
}
|
|
712
727
|
}
|
|
713
|
-
async #
|
|
714
|
-
const
|
|
715
|
-
code: await
|
|
728
|
+
async #y() {
|
|
729
|
+
const t = this.#e.createShaderModule({
|
|
730
|
+
code: await Z["utils.wgsl"](),
|
|
716
731
|
label: "utils"
|
|
717
732
|
});
|
|
718
|
-
if (typeof
|
|
719
|
-
const
|
|
720
|
-
if (
|
|
733
|
+
if (typeof t.compilationInfo == "function") {
|
|
734
|
+
const e = await t.compilationInfo();
|
|
735
|
+
if (e.messages.some((s) => s.type == "error")) {
|
|
721
736
|
console.error("WGSL compilation errors:");
|
|
722
|
-
for (const s of
|
|
737
|
+
for (const s of e.messages)
|
|
723
738
|
console.error(s);
|
|
724
739
|
throw new Error("Shader compilation failed");
|
|
725
740
|
}
|
|
726
741
|
}
|
|
727
|
-
if (
|
|
728
|
-
this.#
|
|
729
|
-
const
|
|
730
|
-
for (const s of
|
|
731
|
-
this.#
|
|
742
|
+
if (J() && (this.#h = !0), this.#h) {
|
|
743
|
+
this.#g = {}, this.#p = {}, this.#a = {};
|
|
744
|
+
const e = ["rgba8unorm-srgb", "rgba8unorm"];
|
|
745
|
+
for (const s of e)
|
|
746
|
+
this.#g[s] = this.#e.createRenderPipeline({
|
|
732
747
|
label: `mipmap-pipeline-${s}`,
|
|
733
748
|
layout: "auto",
|
|
734
749
|
vertex: {
|
|
735
|
-
module:
|
|
750
|
+
module: t,
|
|
736
751
|
entryPoint: "fullscreen_vs"
|
|
737
752
|
},
|
|
738
753
|
fragment: {
|
|
739
|
-
module:
|
|
754
|
+
module: t,
|
|
740
755
|
entryPoint: "mipmap_fs",
|
|
741
756
|
targets: [{ format: s }]
|
|
742
757
|
},
|
|
@@ -744,15 +759,15 @@ class D {
|
|
|
744
759
|
topology: "triangle-strip",
|
|
745
760
|
stripIndexFormat: "uint32"
|
|
746
761
|
}
|
|
747
|
-
}), this.#
|
|
762
|
+
}), this.#p[s] = this.#e.createRenderPipeline({
|
|
748
763
|
label: `resize-pipeline-${s}`,
|
|
749
764
|
layout: "auto",
|
|
750
765
|
vertex: {
|
|
751
|
-
module:
|
|
766
|
+
module: t,
|
|
752
767
|
entryPoint: "fullscreen_vs"
|
|
753
768
|
},
|
|
754
769
|
fragment: {
|
|
755
|
-
module:
|
|
770
|
+
module: t,
|
|
756
771
|
entryPoint: "resize_fs",
|
|
757
772
|
targets: [{ format: s }]
|
|
758
773
|
},
|
|
@@ -760,15 +775,15 @@ class D {
|
|
|
760
775
|
topology: "triangle-strip",
|
|
761
776
|
stripIndexFormat: "uint32"
|
|
762
777
|
}
|
|
763
|
-
}), this.#
|
|
778
|
+
}), this.#a[s] = this.#e.createRenderPipeline({
|
|
764
779
|
label: `flip-y-pipeline-${s}`,
|
|
765
780
|
layout: "auto",
|
|
766
781
|
vertex: {
|
|
767
|
-
module:
|
|
782
|
+
module: t,
|
|
768
783
|
entryPoint: "fullscreen_vs"
|
|
769
784
|
},
|
|
770
785
|
fragment: {
|
|
771
|
-
module:
|
|
786
|
+
module: t,
|
|
772
787
|
entryPoint: "flipy_fs",
|
|
773
788
|
targets: [{ format: s }]
|
|
774
789
|
},
|
|
@@ -778,204 +793,186 @@ class D {
|
|
|
778
793
|
}
|
|
779
794
|
});
|
|
780
795
|
} else
|
|
781
|
-
this.#
|
|
796
|
+
this.#g = this.#e.createComputePipeline({
|
|
782
797
|
layout: "auto",
|
|
783
798
|
compute: {
|
|
784
|
-
module:
|
|
799
|
+
module: t,
|
|
785
800
|
entryPoint: "mipmap"
|
|
786
801
|
}
|
|
787
|
-
}), this.#
|
|
802
|
+
}), this.#d = this.#e.createComputePipeline({
|
|
788
803
|
layout: "auto",
|
|
789
804
|
compute: {
|
|
790
|
-
module:
|
|
805
|
+
module: t,
|
|
806
|
+
entryPoint: "magic_mipmap"
|
|
807
|
+
}
|
|
808
|
+
}), this.#p = this.#e.createComputePipeline({
|
|
809
|
+
layout: "auto",
|
|
810
|
+
compute: {
|
|
811
|
+
module: t,
|
|
791
812
|
entryPoint: "resize"
|
|
792
813
|
}
|
|
793
|
-
}), this.#
|
|
814
|
+
}), this.#a = this.#e.createComputePipeline({
|
|
794
815
|
layout: "auto",
|
|
795
816
|
compute: {
|
|
796
|
-
module:
|
|
817
|
+
module: t,
|
|
797
818
|
entryPoint: "flipy"
|
|
798
819
|
}
|
|
799
820
|
});
|
|
800
|
-
this.#
|
|
821
|
+
this.#E = await this.#e.createComputePipelineAsync({
|
|
801
822
|
layout: "auto",
|
|
802
823
|
compute: {
|
|
803
|
-
module:
|
|
824
|
+
module: t,
|
|
804
825
|
entryPoint: "detect_channel_count"
|
|
805
826
|
}
|
|
806
827
|
});
|
|
807
828
|
}
|
|
808
|
-
|
|
809
|
-
if (this.#
|
|
810
|
-
return this.#
|
|
829
|
+
#S(t) {
|
|
830
|
+
if (this.#f[t])
|
|
831
|
+
return this.#f[t];
|
|
811
832
|
const r = (async () => {
|
|
812
|
-
|
|
813
|
-
const
|
|
814
|
-
|
|
815
|
-
let s = await
|
|
816
|
-
this.#
|
|
817
|
-
const
|
|
833
|
+
this.#G("loadPipeline " + N[t]);
|
|
834
|
+
const e = Re[t];
|
|
835
|
+
O(e, `No shader available for format ${N[t]}`);
|
|
836
|
+
let s = await Z[e]();
|
|
837
|
+
this.#T || (s = s.replace(/^enable f16;\s*/m, "").replace(/\bf16\b/g, "f32").replace(/\bvec([234])h\b/g, "vec$1f").replace(/\bmat([234]x[234])h/g, "mat$1f").replace(/\b(\d*\.\d+|\d+\.)h\b/g, "$1"));
|
|
838
|
+
const o = this.#e.createShaderModule({
|
|
818
839
|
code: s,
|
|
819
|
-
label:
|
|
840
|
+
label: N[t]
|
|
820
841
|
});
|
|
821
|
-
if (typeof
|
|
822
|
-
const
|
|
823
|
-
if (
|
|
842
|
+
if (typeof o.getCompilationInfo == "function") {
|
|
843
|
+
const n = await o.getCompilationInfo();
|
|
844
|
+
if (n.messages.some((f) => f.type == "error")) {
|
|
824
845
|
console.error("WGSL compilation errors:");
|
|
825
|
-
for (const
|
|
826
|
-
console.error(
|
|
846
|
+
for (const f of n.messages)
|
|
847
|
+
console.error(f);
|
|
827
848
|
throw new Error("Shader compilation failed");
|
|
828
849
|
}
|
|
829
850
|
}
|
|
830
|
-
const
|
|
851
|
+
const c = await this.#e.createComputePipelineAsync({
|
|
831
852
|
layout: "auto",
|
|
832
853
|
compute: {
|
|
833
|
-
module:
|
|
854
|
+
module: o,
|
|
834
855
|
entryPoint: "main"
|
|
835
856
|
}
|
|
836
857
|
});
|
|
837
|
-
return
|
|
858
|
+
return this.#C("loadPipeline " + N[t]), c;
|
|
838
859
|
})();
|
|
839
|
-
return this.#
|
|
860
|
+
return this.#f[t] = r, r;
|
|
840
861
|
}
|
|
841
|
-
#t
|
|
842
|
-
return this.#
|
|
862
|
+
#r(t) {
|
|
863
|
+
return this.#l.has(t);
|
|
843
864
|
}
|
|
844
|
-
#
|
|
845
|
-
const
|
|
846
|
-
if (
|
|
847
|
-
return
|
|
848
|
-
const s = r ? [
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
"eac-rg",
|
|
853
|
-
"bc1-rgb",
|
|
854
|
-
"etc2-rgb",
|
|
855
|
-
"bc7-rgb",
|
|
856
|
-
"astc-rgb",
|
|
857
|
-
"astc-4x4-rgb",
|
|
858
|
-
"bc7-rgba",
|
|
859
|
-
"astc-rgba",
|
|
860
|
-
"astc-4x4-rgba"
|
|
861
|
-
] : [
|
|
862
|
-
"bc4-r",
|
|
863
|
-
"eac-r",
|
|
864
|
-
"bc5-rg",
|
|
865
|
-
"eac-rg",
|
|
866
|
-
"bc7-rgb",
|
|
867
|
-
"bc1-rgb",
|
|
868
|
-
"astc-rgb",
|
|
869
|
-
"astc-4x4-rgb",
|
|
870
|
-
"etc2-rgb",
|
|
871
|
-
"bc7-rgba",
|
|
872
|
-
"astc-rgba",
|
|
873
|
-
"astc-4x4-rgba"
|
|
874
|
-
];
|
|
875
|
-
for (const n of s)
|
|
876
|
-
if (n.includes(e) && this.#t(P[n]))
|
|
877
|
-
return P[n];
|
|
865
|
+
#P(t, r) {
|
|
866
|
+
const e = z[t];
|
|
867
|
+
if (e != null && this.#r(e))
|
|
868
|
+
return e;
|
|
869
|
+
const s = r ? ["bc4-r", "eac-r", "bc5-rg", "eac-rg", "bc1-rgb", "etc2-rgb", "bc7-rgb", "astc-rgb", "astc-4x4-rgb", "bc7-rgba", "astc-rgba", "astc-4x4-rgba"] : ["bc4-r", "eac-r", "bc5-rg", "eac-rg", "bc7-rgb", "astc-rgb", "astc-4x4-rgb", "bc1-rgb", "etc2-rgb", "bc7-rgba", "astc-rgba", "astc-4x4-rgba"];
|
|
870
|
+
for (const o of s)
|
|
871
|
+
if (o.includes(t) && this.#r(z[o]))
|
|
872
|
+
return z[o];
|
|
878
873
|
}
|
|
879
|
-
async #
|
|
880
|
-
if (
|
|
881
|
-
|
|
882
|
-
else if (
|
|
883
|
-
if (
|
|
884
|
-
if (this.#
|
|
885
|
-
if (this.#
|
|
886
|
-
|
|
887
|
-
if (this.#
|
|
888
|
-
|
|
889
|
-
if (this.#
|
|
890
|
-
if (this.#
|
|
891
|
-
} else if (e.normal) {
|
|
892
|
-
if (this.#t(i.BC5_RG)) return i.BC5_RG;
|
|
893
|
-
if (this.#t(i.EAC_RG)) return i.EAC_RG;
|
|
874
|
+
async #A(t, r) {
|
|
875
|
+
if (t.format == null)
|
|
876
|
+
t.format = "rgb";
|
|
877
|
+
else if (t.format == "auto") {
|
|
878
|
+
if (t.srgb) {
|
|
879
|
+
if (this.#r(a.BC7_RGB)) return a.BC7_RGB;
|
|
880
|
+
if (this.#r(a.ASTC_4x4_RGB)) return a.ASTC_4x4_RGB;
|
|
881
|
+
if (this.#r(a.BC1_RGB)) return a.BC1_RGB;
|
|
882
|
+
if (this.#r(a.ETC2_RGB)) return a.ETC2_RGB;
|
|
883
|
+
} else if (t.normal) {
|
|
884
|
+
if (this.#r(a.BC5_RG)) return a.BC5_RG;
|
|
885
|
+
if (this.#r(a.EAC_RG)) return a.EAC_RG;
|
|
894
886
|
} else {
|
|
895
887
|
let s;
|
|
896
888
|
if (r instanceof GPUTexture)
|
|
897
|
-
r.format == "r8unorm" || r.format == "r16unorm" ? s = 1 : r.format == "rg8unorm" || r.format == "rg16unorm" ? s = 2 : s = await this.#
|
|
889
|
+
r.format == "r8unorm" || r.format == "r16unorm" ? s = 1 : r.format == "rg8unorm" || r.format == "rg16unorm" ? s = 2 : s = await this.#F(r);
|
|
898
890
|
else {
|
|
899
|
-
const
|
|
900
|
-
s = this.#
|
|
891
|
+
const o = we(r);
|
|
892
|
+
s = this.#I(o);
|
|
901
893
|
}
|
|
902
894
|
if (s == 4) {
|
|
903
|
-
if (this.#
|
|
904
|
-
if (this.#
|
|
895
|
+
if (this.#r(a.BC7_RGBA)) return a.BC7_RGBA;
|
|
896
|
+
if (this.#r(a.ASTC_4x4_RGBA)) return a.ASTC_4x4_RGBA;
|
|
905
897
|
} else if (s == 3) {
|
|
906
|
-
if (this.#
|
|
907
|
-
if (this.#
|
|
908
|
-
if (this.#
|
|
909
|
-
if (this.#
|
|
898
|
+
if (this.#r(a.BC7_RGB)) return a.BC7_RGB;
|
|
899
|
+
if (this.#r(a.ASTC_4x4_RGB)) return a.ASTC_4x4_RGB;
|
|
900
|
+
if (this.#r(a.BC1_RGB)) return a.BC1_RGB;
|
|
901
|
+
if (this.#r(a.ETC2_RGB)) return a.ETC2_RGB;
|
|
910
902
|
} else if (s == 2) {
|
|
911
|
-
if (this.#
|
|
912
|
-
if (this.#
|
|
903
|
+
if (this.#r(a.BC5_RG)) return a.BC5_RG;
|
|
904
|
+
if (this.#r(a.EAC_RG)) return a.EAC_RG;
|
|
913
905
|
} else if (s == 1) {
|
|
914
|
-
if (this.#
|
|
915
|
-
if (this.#
|
|
906
|
+
if (this.#r(a.BC4_R)) return a.BC4_R;
|
|
907
|
+
if (this.#r(a.EAC_R)) return a.EAC_R;
|
|
916
908
|
}
|
|
917
909
|
}
|
|
918
910
|
throw new Error("No supported format found.");
|
|
919
911
|
}
|
|
920
|
-
const
|
|
921
|
-
if (
|
|
922
|
-
throw new Error(`Unsupported format: ${
|
|
923
|
-
return
|
|
912
|
+
const e = this.#P(t.format, t.preferLowQuality);
|
|
913
|
+
if (e === void 0)
|
|
914
|
+
throw new Error(`Unsupported format: ${t.format}`);
|
|
915
|
+
return e;
|
|
924
916
|
}
|
|
925
|
-
#
|
|
926
|
-
let r = !0,
|
|
927
|
-
const
|
|
928
|
-
for (let
|
|
929
|
-
const
|
|
930
|
-
|
|
931
|
-
const h = 2 *
|
|
932
|
-
(Math.abs(
|
|
917
|
+
#I(t) {
|
|
918
|
+
let r = !0, e = !0, s = 0;
|
|
919
|
+
const o = Math.min(1024 * 128, t.length);
|
|
920
|
+
for (let c = 0; c < o; c += 4) {
|
|
921
|
+
const n = t[c] / 255, f = t[c + 1] / 255, u = t[c + 2] / 255;
|
|
922
|
+
t[c + 3] < 255 && (r = !1), (n != f || f != u) && (e = !1);
|
|
923
|
+
const h = 2 * n - 1, m = 2 * f - 1, R = 2 * u - 1, T = h * h + m * m + R * R, d = Math.sqrt(T);
|
|
924
|
+
(Math.abs(d - 1) > 0.2 || R < -0.1) && (s += 1);
|
|
933
925
|
}
|
|
934
|
-
return r ?
|
|
926
|
+
return r ? e ? 1 : 16 * s < o ? 2 : 3 : 4;
|
|
935
927
|
}
|
|
936
|
-
async #
|
|
937
|
-
const
|
|
928
|
+
async #F(t) {
|
|
929
|
+
const e = this.#e.createBuffer({
|
|
938
930
|
size: 12,
|
|
939
931
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
|
|
940
932
|
}), s = this.#e.createBuffer({
|
|
941
933
|
size: 12,
|
|
942
934
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
|
|
943
|
-
}),
|
|
944
|
-
layout: this.#
|
|
935
|
+
}), o = this.#e.createBindGroup({
|
|
936
|
+
layout: this.#E.getBindGroupLayout(0),
|
|
945
937
|
entries: [
|
|
946
|
-
{ binding: 0, resource:
|
|
947
|
-
{ binding: 1, resource: { buffer:
|
|
938
|
+
{ binding: 0, resource: t.createView() },
|
|
939
|
+
{ binding: 1, resource: { buffer: e } }
|
|
948
940
|
]
|
|
949
|
-
}),
|
|
950
|
-
|
|
951
|
-
const { width:
|
|
952
|
-
|
|
953
|
-
const m = new Uint32Array(s.getMappedRange()),
|
|
954
|
-
return s.unmap(), s.destroy(),
|
|
941
|
+
}), c = this.#e.createCommandEncoder(), n = c.beginComputePass();
|
|
942
|
+
n.setPipeline(this.#E), n.setBindGroup(0, o);
|
|
943
|
+
const { width: f, height: u } = t, l = Math.ceil(f / 8), h = Math.ceil(u / 8);
|
|
944
|
+
n.dispatchWorkgroups(l, h), n.end(), c.copyBufferToBuffer(e, 0, s, 0, 12), this.#e.queue.submit([c.finish()]), await this.#e.queue.onSubmittedWorkDone(), await s.mapAsync(GPUMapMode.READ);
|
|
945
|
+
const m = new Uint32Array(s.getMappedRange()), R = m[0] == 0, T = m[1] == 0, d = m[2];
|
|
946
|
+
return s.unmap(), s.destroy(), e.destroy(), R ? T ? 1 : 4 * d < f * u ? 2 : 3 : 4;
|
|
947
|
+
}
|
|
948
|
+
#R(t, r, e) {
|
|
949
|
+
const s = r && r.length > 0 ? e < r.length ? r[e] : r[r.length - 1] : 1, o = new ArrayBuffer(8), c = new DataView(o);
|
|
950
|
+
c.setUint32(0, t, !0), c.setFloat32(4, s, !0), this.#e.queue.writeBuffer(this.#i, 0, o);
|
|
955
951
|
}
|
|
956
952
|
// Apply scaling and flipY transform.
|
|
957
|
-
#
|
|
958
|
-
if (this.#
|
|
959
|
-
this.#
|
|
953
|
+
#U(t, r, e, s, o, c, n) {
|
|
954
|
+
if (this.#h) {
|
|
955
|
+
this.#M(t, r, e, s, o, c, n);
|
|
960
956
|
return;
|
|
961
957
|
}
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
958
|
+
this.#R(c);
|
|
959
|
+
const f = t.beginComputePass(), u = n ? this.#a : this.#p;
|
|
960
|
+
f.setPipeline(u);
|
|
961
|
+
const l = this.#e.createBindGroup({
|
|
962
|
+
layout: u.getBindGroupLayout(0),
|
|
966
963
|
entries: [
|
|
967
964
|
{
|
|
968
965
|
binding: 0,
|
|
969
966
|
resource: r.createView({
|
|
970
967
|
baseMipLevel: 0,
|
|
971
968
|
mipLevelCount: 1,
|
|
972
|
-
format:
|
|
969
|
+
format: (c & A.sRGB) != 0 ? "rgba8unorm-srgb" : "rgba8unorm",
|
|
973
970
|
usage: GPUTextureUsage.TEXTURE_BINDING
|
|
974
971
|
})
|
|
975
972
|
},
|
|
976
973
|
{
|
|
977
974
|
binding: 1,
|
|
978
|
-
resource:
|
|
975
|
+
resource: e.createView({
|
|
979
976
|
baseMipLevel: 0,
|
|
980
977
|
mipLevelCount: 1,
|
|
981
978
|
dimension: "2d",
|
|
@@ -985,35 +982,37 @@ class D {
|
|
|
985
982
|
},
|
|
986
983
|
{
|
|
987
984
|
binding: 2,
|
|
988
|
-
resource: this.#
|
|
985
|
+
resource: this.#s
|
|
989
986
|
},
|
|
990
987
|
{
|
|
991
988
|
binding: 3,
|
|
992
|
-
resource: { buffer: this.#
|
|
989
|
+
resource: { buffer: this.#i }
|
|
993
990
|
}
|
|
994
991
|
]
|
|
995
992
|
});
|
|
996
|
-
|
|
993
|
+
f.setBindGroup(0, l), f.dispatchWorkgroups(Math.ceil(s / 8), Math.ceil(o / 8)), f.end();
|
|
997
994
|
}
|
|
998
995
|
// Apply scaling and flipY transform.
|
|
999
|
-
#
|
|
1000
|
-
const
|
|
996
|
+
#M(t, r, e, s, o, c, n) {
|
|
997
|
+
const f = (c & A.sRGB) != 0 ? "rgba8unorm-srgb" : "rgba8unorm", u = e.createView({
|
|
1001
998
|
baseMipLevel: 0,
|
|
1002
999
|
mipLevelCount: 1,
|
|
1003
1000
|
dimension: "2d",
|
|
1004
|
-
format:
|
|
1001
|
+
format: f,
|
|
1005
1002
|
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
1006
|
-
}),
|
|
1003
|
+
}), l = t.beginRenderPass({
|
|
1007
1004
|
colorAttachments: [
|
|
1008
1005
|
{
|
|
1009
|
-
view:
|
|
1006
|
+
view: u,
|
|
1010
1007
|
loadOp: "clear",
|
|
1011
1008
|
storeOp: "store",
|
|
1012
1009
|
clearValue: [0, 0, 0, 0]
|
|
1013
1010
|
}
|
|
1014
1011
|
]
|
|
1015
|
-
})
|
|
1016
|
-
|
|
1012
|
+
});
|
|
1013
|
+
this.#R(c);
|
|
1014
|
+
const h = n ? this.#a[f] : this.#p[f];
|
|
1015
|
+
l.setPipeline(h);
|
|
1017
1016
|
const m = this.#e.createBindGroup({
|
|
1018
1017
|
layout: h.getBindGroupLayout(0),
|
|
1019
1018
|
entries: [
|
|
@@ -1022,52 +1021,53 @@ class D {
|
|
|
1022
1021
|
resource: r.createView({
|
|
1023
1022
|
baseMipLevel: 0,
|
|
1024
1023
|
mipLevelCount: 1,
|
|
1025
|
-
format:
|
|
1024
|
+
format: (c & A.sRGB) != 0 ? "rgba8unorm-srgb" : "rgba8unorm",
|
|
1026
1025
|
usage: GPUTextureUsage.TEXTURE_BINDING
|
|
1027
1026
|
})
|
|
1028
1027
|
},
|
|
1029
1028
|
{
|
|
1030
1029
|
binding: 2,
|
|
1031
|
-
resource: this.#
|
|
1030
|
+
resource: this.#s
|
|
1032
1031
|
},
|
|
1033
1032
|
{
|
|
1034
1033
|
binding: 3,
|
|
1035
|
-
resource: { buffer: this.#
|
|
1034
|
+
resource: { buffer: this.#i }
|
|
1036
1035
|
}
|
|
1037
1036
|
]
|
|
1038
1037
|
});
|
|
1039
|
-
|
|
1038
|
+
l.setBindGroup(0, m), l.draw(4, 1, 0, 0), l.end();
|
|
1040
1039
|
}
|
|
1041
|
-
async #
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1040
|
+
async #L(t, r, e, s, o, c, n, f) {
|
|
1041
|
+
n == null && this.#R(c);
|
|
1042
|
+
let u = s, l = o;
|
|
1043
|
+
if (this.#h)
|
|
1044
|
+
for (let h = 0; h < e - 1; h++)
|
|
1045
|
+
n != null && this.#R(c, n, h), u = Math.max(1, Math.floor(u / 2)), l = Math.max(1, Math.floor(l / 2)), this.#N(t, r, h, h + 1, u, l, c);
|
|
1046
1046
|
else {
|
|
1047
|
-
const
|
|
1048
|
-
|
|
1049
|
-
for (let
|
|
1050
|
-
|
|
1051
|
-
|
|
1047
|
+
const h = t.beginComputePass(), m = f === "box" || (c & A.Alpha) != 0 ? this.#g : this.#d, R = m.getBindGroupLayout(0);
|
|
1048
|
+
h.setPipeline(m);
|
|
1049
|
+
for (let T = 0; T < e - 1; T++)
|
|
1050
|
+
n != null && this.#R(c, n, T), u = Math.max(1, Math.floor(u / 2)), l = Math.max(1, Math.floor(l / 2)), this.#D(h, R, r, T, T + 1, u, l, c);
|
|
1051
|
+
h.end();
|
|
1052
1052
|
}
|
|
1053
1053
|
}
|
|
1054
|
-
#
|
|
1054
|
+
#D(t, r, e, s, o, c, n, f) {
|
|
1055
1055
|
const u = this.#e.createBindGroup({
|
|
1056
|
-
layout:
|
|
1056
|
+
layout: r,
|
|
1057
1057
|
entries: [
|
|
1058
1058
|
{
|
|
1059
1059
|
binding: 0,
|
|
1060
|
-
resource:
|
|
1061
|
-
baseMipLevel:
|
|
1060
|
+
resource: e.createView({
|
|
1061
|
+
baseMipLevel: s,
|
|
1062
1062
|
mipLevelCount: 1,
|
|
1063
|
-
format:
|
|
1063
|
+
format: (f & A.sRGB) != 0 ? "rgba8unorm-srgb" : "rgba8unorm",
|
|
1064
1064
|
usage: GPUTextureUsage.TEXTURE_BINDING
|
|
1065
1065
|
})
|
|
1066
1066
|
},
|
|
1067
1067
|
{
|
|
1068
1068
|
binding: 1,
|
|
1069
|
-
resource:
|
|
1070
|
-
baseMipLevel:
|
|
1069
|
+
resource: e.createView({
|
|
1070
|
+
baseMipLevel: o,
|
|
1071
1071
|
mipLevelCount: 1,
|
|
1072
1072
|
dimension: "2d",
|
|
1073
1073
|
format: "rgba8unorm",
|
|
@@ -1076,57 +1076,581 @@ class D {
|
|
|
1076
1076
|
},
|
|
1077
1077
|
{
|
|
1078
1078
|
binding: 2,
|
|
1079
|
-
resource: this.#
|
|
1079
|
+
resource: this.#s
|
|
1080
1080
|
},
|
|
1081
1081
|
{
|
|
1082
1082
|
binding: 3,
|
|
1083
|
-
resource: { buffer: this.#
|
|
1083
|
+
resource: { buffer: this.#i }
|
|
1084
1084
|
}
|
|
1085
1085
|
]
|
|
1086
1086
|
});
|
|
1087
|
-
|
|
1087
|
+
t.setBindGroup(0, u), t.dispatchWorkgroups(Math.ceil(c / 8), Math.ceil(n / 8));
|
|
1088
1088
|
}
|
|
1089
|
-
#
|
|
1090
|
-
const
|
|
1089
|
+
#N(t, r, e, s, o, c, n) {
|
|
1090
|
+
const f = (n & A.sRGB) != 0 ? "rgba8unorm-srgb" : "rgba8unorm", u = r.createView({
|
|
1091
1091
|
baseMipLevel: s,
|
|
1092
1092
|
mipLevelCount: 1,
|
|
1093
1093
|
dimension: "2d",
|
|
1094
|
-
format:
|
|
1094
|
+
format: f,
|
|
1095
1095
|
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
1096
|
-
}),
|
|
1096
|
+
}), l = t.beginRenderPass({
|
|
1097
1097
|
colorAttachments: [
|
|
1098
1098
|
{
|
|
1099
|
-
view:
|
|
1099
|
+
view: u,
|
|
1100
1100
|
loadOp: "clear",
|
|
1101
1101
|
storeOp: "store",
|
|
1102
1102
|
clearValue: [0, 0, 0, 0]
|
|
1103
1103
|
}
|
|
1104
1104
|
]
|
|
1105
1105
|
}), h = this.#e.createBindGroup({
|
|
1106
|
-
layout: this.#
|
|
1106
|
+
layout: this.#g[f].getBindGroupLayout(0),
|
|
1107
1107
|
entries: [
|
|
1108
1108
|
{
|
|
1109
1109
|
binding: 0,
|
|
1110
1110
|
resource: r.createView({
|
|
1111
|
-
baseMipLevel:
|
|
1111
|
+
baseMipLevel: e,
|
|
1112
1112
|
mipLevelCount: 1,
|
|
1113
|
-
format:
|
|
1113
|
+
format: f,
|
|
1114
1114
|
usage: GPUTextureUsage.TEXTURE_BINDING
|
|
1115
1115
|
})
|
|
1116
1116
|
},
|
|
1117
1117
|
{
|
|
1118
1118
|
binding: 2,
|
|
1119
|
-
resource: this.#
|
|
1119
|
+
resource: this.#s
|
|
1120
1120
|
},
|
|
1121
1121
|
{
|
|
1122
1122
|
binding: 3,
|
|
1123
|
-
resource: { buffer: this.#
|
|
1123
|
+
resource: { buffer: this.#i }
|
|
1124
1124
|
}
|
|
1125
1125
|
]
|
|
1126
1126
|
});
|
|
1127
|
-
|
|
1127
|
+
l.setPipeline(this.#g[f]), l.setBindGroup(0, h), l.draw(4, 1, 0, 0), l.end();
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
const Ie = /* @__PURE__ */ Object.assign({ "./spark_astc_rgb.glsl": () => import("./spark_astc_rgb-CTmg8wnA.js").then((i) => i.default), "./spark_astc_rgba.glsl": () => import("./spark_astc_rgba-CDMNWH6H.js").then((i) => i.default), "./spark_bc1_rgb.glsl": () => import("./spark_bc1_rgb-C0pbbQPO.js").then((i) => i.default), "./spark_bc4_r.glsl": () => import("./spark_bc4_r-YQ6i79H9.js").then((i) => i.default), "./spark_bc5_rg.glsl": () => import("./spark_bc5_rg-BqzKgeMU.js").then((i) => i.default), "./spark_bc7_rgb.glsl": () => import("./spark_bc7_rgb-DBkDHCzE.js").then((i) => i.default), "./spark_bc7_rgba.glsl": () => import("./spark_bc7_rgba-DQUk89UX.js").then((i) => i.default), "./spark_eac_r.glsl": () => import("./spark_eac_r-Dvy2qUxf.js").then((i) => i.default), "./spark_eac_rg.glsl": () => import("./spark_eac_rg-DKLVL9co.js").then((i) => i.default), "./spark_etc2_rgb.glsl": () => import("./spark_etc2_rgb-BpnNweVx.js").then((i) => i.default) }), Fe = Object.fromEntries(
|
|
1131
|
+
Object.entries(Ie).map(([i, t]) => [i.replace("./", ""), async () => await t()])
|
|
1132
|
+
), p = {
|
|
1133
|
+
ASTC_4x4_RGB: 0,
|
|
1134
|
+
ASTC_4x4_RGBA: 1,
|
|
1135
|
+
EAC_R: 4,
|
|
1136
|
+
EAC_RG: 5,
|
|
1137
|
+
ETC2_RGB: 6,
|
|
1138
|
+
BC1_RGB: 9,
|
|
1139
|
+
BC4_R: 13,
|
|
1140
|
+
BC5_RG: 14,
|
|
1141
|
+
BC7_RGB: 16,
|
|
1142
|
+
BC7_RGBA: 17
|
|
1143
|
+
}, v = [
|
|
1144
|
+
/* 0 */
|
|
1145
|
+
"astc-4x4-rgb",
|
|
1146
|
+
/* 1 */
|
|
1147
|
+
"astc-4x4-rgba",
|
|
1148
|
+
/* 2 */
|
|
1149
|
+
null,
|
|
1150
|
+
/* 3 */
|
|
1151
|
+
null,
|
|
1152
|
+
/* 4 */
|
|
1153
|
+
"eac-r",
|
|
1154
|
+
/* 5 */
|
|
1155
|
+
"eac-rg",
|
|
1156
|
+
/* 6 */
|
|
1157
|
+
"etc2-rgb",
|
|
1158
|
+
/* 7 */
|
|
1159
|
+
null,
|
|
1160
|
+
/* 8 */
|
|
1161
|
+
null,
|
|
1162
|
+
/* 9 */
|
|
1163
|
+
"bc1-rgb",
|
|
1164
|
+
/* 10 */
|
|
1165
|
+
null,
|
|
1166
|
+
/* 11 */
|
|
1167
|
+
null,
|
|
1168
|
+
/* 12 */
|
|
1169
|
+
null,
|
|
1170
|
+
/* 13 */
|
|
1171
|
+
"bc4-r",
|
|
1172
|
+
/* 14 */
|
|
1173
|
+
"bc5-rg",
|
|
1174
|
+
/* 15 */
|
|
1175
|
+
null,
|
|
1176
|
+
/* 16 */
|
|
1177
|
+
"bc7-rgb",
|
|
1178
|
+
/* 17 */
|
|
1179
|
+
"bc7-rgba"
|
|
1180
|
+
], Me = [
|
|
1181
|
+
/* 0 */
|
|
1182
|
+
"spark_astc_rgb.glsl",
|
|
1183
|
+
/* 1 */
|
|
1184
|
+
"spark_astc_rgba.glsl",
|
|
1185
|
+
/* 2 */
|
|
1186
|
+
null,
|
|
1187
|
+
/* 3 */
|
|
1188
|
+
null,
|
|
1189
|
+
/* 4 */
|
|
1190
|
+
"spark_eac_r.glsl",
|
|
1191
|
+
/* 5 */
|
|
1192
|
+
"spark_eac_rg.glsl",
|
|
1193
|
+
/* 6 */
|
|
1194
|
+
"spark_etc2_rgb.glsl",
|
|
1195
|
+
/* 7 */
|
|
1196
|
+
null,
|
|
1197
|
+
/* 8 */
|
|
1198
|
+
null,
|
|
1199
|
+
/* 9 */
|
|
1200
|
+
"spark_bc1_rgb.glsl",
|
|
1201
|
+
/* 10 */
|
|
1202
|
+
null,
|
|
1203
|
+
/* 11 */
|
|
1204
|
+
null,
|
|
1205
|
+
/* 12 */
|
|
1206
|
+
null,
|
|
1207
|
+
/* 13 */
|
|
1208
|
+
"spark_bc4_r.glsl",
|
|
1209
|
+
/* 14 */
|
|
1210
|
+
"spark_bc5_rg.glsl",
|
|
1211
|
+
/* 15 */
|
|
1212
|
+
null,
|
|
1213
|
+
/* 16 */
|
|
1214
|
+
"spark_bc7_rgb.glsl",
|
|
1215
|
+
/* 17 */
|
|
1216
|
+
"spark_bc7_rgba.glsl"
|
|
1217
|
+
], Le = [
|
|
1218
|
+
/* 0 */
|
|
1219
|
+
16,
|
|
1220
|
+
/* 1 */
|
|
1221
|
+
16,
|
|
1222
|
+
/* 2 */
|
|
1223
|
+
0,
|
|
1224
|
+
/* 3 */
|
|
1225
|
+
0,
|
|
1226
|
+
/* 4 */
|
|
1227
|
+
8,
|
|
1228
|
+
/* 5 */
|
|
1229
|
+
16,
|
|
1230
|
+
/* 6 */
|
|
1231
|
+
8,
|
|
1232
|
+
/* 7 */
|
|
1233
|
+
0,
|
|
1234
|
+
/* 8 */
|
|
1235
|
+
0,
|
|
1236
|
+
/* 9 */
|
|
1237
|
+
8,
|
|
1238
|
+
/* 10 */
|
|
1239
|
+
0,
|
|
1240
|
+
/* 11 */
|
|
1241
|
+
0,
|
|
1242
|
+
/* 12 */
|
|
1243
|
+
0,
|
|
1244
|
+
/* 13 */
|
|
1245
|
+
8,
|
|
1246
|
+
/* 14 */
|
|
1247
|
+
16,
|
|
1248
|
+
/* 15 */
|
|
1249
|
+
0,
|
|
1250
|
+
/* 16 */
|
|
1251
|
+
16,
|
|
1252
|
+
/* 17 */
|
|
1253
|
+
16
|
|
1254
|
+
], De = [
|
|
1255
|
+
/* 0 */
|
|
1256
|
+
!0,
|
|
1257
|
+
// ASTC_4x4_RGB
|
|
1258
|
+
/* 1 */
|
|
1259
|
+
!0,
|
|
1260
|
+
// ASTC_4x4_RGBA
|
|
1261
|
+
/* 2 */
|
|
1262
|
+
null,
|
|
1263
|
+
/* 3 */
|
|
1264
|
+
null,
|
|
1265
|
+
/* 4 */
|
|
1266
|
+
!1,
|
|
1267
|
+
// EAC_R
|
|
1268
|
+
/* 5 */
|
|
1269
|
+
!1,
|
|
1270
|
+
// EAC_RG
|
|
1271
|
+
/* 6 */
|
|
1272
|
+
!0,
|
|
1273
|
+
// ETC2_RGB
|
|
1274
|
+
/* 7 */
|
|
1275
|
+
null,
|
|
1276
|
+
/* 8 */
|
|
1277
|
+
null,
|
|
1278
|
+
/* 9 */
|
|
1279
|
+
!0,
|
|
1280
|
+
// BC1_RGB
|
|
1281
|
+
/* 10 */
|
|
1282
|
+
null,
|
|
1283
|
+
/* 11 */
|
|
1284
|
+
null,
|
|
1285
|
+
/* 12 */
|
|
1286
|
+
null,
|
|
1287
|
+
/* 13 */
|
|
1288
|
+
!1,
|
|
1289
|
+
// BC4_R
|
|
1290
|
+
/* 14 */
|
|
1291
|
+
!1,
|
|
1292
|
+
// BC5_RG
|
|
1293
|
+
/* 15 */
|
|
1294
|
+
null,
|
|
1295
|
+
/* 16 */
|
|
1296
|
+
!0,
|
|
1297
|
+
// BC7_RGB
|
|
1298
|
+
/* 17 */
|
|
1299
|
+
!0
|
|
1300
|
+
// BC7_RGBA
|
|
1301
|
+
], se = 37808, ie = 37840, ae = 36492, ne = 36493, Ne = 33776, ve = 35916, oe = 36283, ce = 36285, Xe = 37492, ke = 37493, ue = 37488, le = 37490, X = 36208, $ = 36214, Oe = [
|
|
1302
|
+
/* 0 */
|
|
1303
|
+
[se, ie],
|
|
1304
|
+
/* 1 */
|
|
1305
|
+
[se, ie],
|
|
1306
|
+
/* 2 */
|
|
1307
|
+
null,
|
|
1308
|
+
/* 3 */
|
|
1309
|
+
null,
|
|
1310
|
+
/* 4 */
|
|
1311
|
+
[ue, ue],
|
|
1312
|
+
/* 5 */
|
|
1313
|
+
[le, le],
|
|
1314
|
+
/* 6 */
|
|
1315
|
+
[Xe, ke],
|
|
1316
|
+
/* 7 */
|
|
1317
|
+
null,
|
|
1318
|
+
/* 8 */
|
|
1319
|
+
null,
|
|
1320
|
+
/* 9 */
|
|
1321
|
+
[Ne, ve],
|
|
1322
|
+
/* 10 */
|
|
1323
|
+
null,
|
|
1324
|
+
/* 11 */
|
|
1325
|
+
null,
|
|
1326
|
+
/* 12 */
|
|
1327
|
+
null,
|
|
1328
|
+
/* 13 */
|
|
1329
|
+
[oe, oe],
|
|
1330
|
+
/* 14 */
|
|
1331
|
+
[ce, ce],
|
|
1332
|
+
/* 15 */
|
|
1333
|
+
null,
|
|
1334
|
+
/* 16 */
|
|
1335
|
+
[ae, ne],
|
|
1336
|
+
/* 17 */
|
|
1337
|
+
[ae, ne]
|
|
1338
|
+
], Ve = [
|
|
1339
|
+
/* 0 */
|
|
1340
|
+
X,
|
|
1341
|
+
/* 1 */
|
|
1342
|
+
X,
|
|
1343
|
+
/* 2 */
|
|
1344
|
+
null,
|
|
1345
|
+
/* 3 */
|
|
1346
|
+
null,
|
|
1347
|
+
/* 4 */
|
|
1348
|
+
$,
|
|
1349
|
+
/* 5 */
|
|
1350
|
+
X,
|
|
1351
|
+
/* 6 */
|
|
1352
|
+
$,
|
|
1353
|
+
/* 7 */
|
|
1354
|
+
null,
|
|
1355
|
+
/* 8 */
|
|
1356
|
+
null,
|
|
1357
|
+
/* 9 */
|
|
1358
|
+
$,
|
|
1359
|
+
/* 10 */
|
|
1360
|
+
null,
|
|
1361
|
+
/* 11 */
|
|
1362
|
+
null,
|
|
1363
|
+
/* 12 */
|
|
1364
|
+
null,
|
|
1365
|
+
/* 13 */
|
|
1366
|
+
$,
|
|
1367
|
+
/* 14 */
|
|
1368
|
+
X,
|
|
1369
|
+
/* 15 */
|
|
1370
|
+
null,
|
|
1371
|
+
/* 16 */
|
|
1372
|
+
X,
|
|
1373
|
+
/* 17 */
|
|
1374
|
+
X
|
|
1375
|
+
], H = Object.freeze({
|
|
1376
|
+
"astc-4x4-rgb": p.ASTC_4x4_RGB,
|
|
1377
|
+
"astc-4x4-rgba": p.ASTC_4x4_RGBA,
|
|
1378
|
+
"eac-r": p.EAC_R,
|
|
1379
|
+
"eac-rg": p.EAC_RG,
|
|
1380
|
+
"etc2-rgb": p.ETC2_RGB,
|
|
1381
|
+
"bc1-rgb": p.BC1_RGB,
|
|
1382
|
+
"bc4-r": p.BC4_R,
|
|
1383
|
+
"bc5-rg": p.BC5_RG,
|
|
1384
|
+
"bc7-rgb": p.BC7_RGB,
|
|
1385
|
+
"bc7-rgba": p.BC7_RGBA,
|
|
1386
|
+
"astc-rgb": p.ASTC_4x4_RGB,
|
|
1387
|
+
"astc-rgba": p.ASTC_4x4_RGBA
|
|
1388
|
+
});
|
|
1389
|
+
function We(i, t = !1) {
|
|
1390
|
+
const r = /* @__PURE__ */ new Set();
|
|
1391
|
+
if (t) {
|
|
1392
|
+
const u = i.getSupportedExtensions();
|
|
1393
|
+
console.log("Available WebGL extensions:"), u && u.sort().forEach((l) => {
|
|
1394
|
+
console.log(` ${l}`);
|
|
1395
|
+
}), console.log(`Total: ${u ? u.length : 0} extensions`), console.log("");
|
|
1396
|
+
}
|
|
1397
|
+
(i.getExtension("EXT_texture_compression_bptc") || i.getExtension("WEBGL_texture_compression_bptc")) && (r.add(p.BC7_RGB), r.add(p.BC7_RGBA));
|
|
1398
|
+
const s = i.getExtension("WEBGL_compressed_texture_s3tc"), o = i.getExtension("WEBGL_compressed_texture_s3tc_srgb");
|
|
1399
|
+
if ((s || o) && r.add(p.BC1_RGB), i.getExtension("EXT_texture_compression_rgtc") && (r.add(p.BC4_R), r.add(p.BC5_RG)), i.getExtension("WEBGL_compressed_texture_etc") && (r.add(p.ETC2_RGB), r.add(p.EAC_R), r.add(p.EAC_RG)), i.getExtension("WEBGL_compressed_texture_astc") && (r.add(p.ASTC_4x4_RGB), r.add(p.ASTC_4x4_RGBA)), t) {
|
|
1400
|
+
console.log("Supported compression formats:");
|
|
1401
|
+
const u = Array.from(r).map((l) => v[l]).filter(Boolean);
|
|
1402
|
+
u.forEach((l) => {
|
|
1403
|
+
console.log(` ${l}`);
|
|
1404
|
+
}), console.log(`Total: ${u.length} formats`), console.log("");
|
|
1405
|
+
}
|
|
1406
|
+
return r;
|
|
1407
|
+
}
|
|
1408
|
+
async function ze(i) {
|
|
1409
|
+
const t = Fe[i];
|
|
1410
|
+
if (!t)
|
|
1411
|
+
throw new Error(`Shader not found: ${i}`);
|
|
1412
|
+
let r = await t();
|
|
1413
|
+
return r = `#version 300 es
|
|
1414
|
+
precision highp float;
|
|
1415
|
+
precision highp int;
|
|
1416
|
+
` + r, r;
|
|
1417
|
+
}
|
|
1418
|
+
const Y = `#version 300 es
|
|
1419
|
+
void main() {
|
|
1420
|
+
vec2 uv = vec2((gl_VertexID << 1) & 2, gl_VertexID & 2);
|
|
1421
|
+
gl_Position = vec4(uv * 2.0 - 1.0, 0.0, 1.0);
|
|
1422
|
+
}
|
|
1423
|
+
`;
|
|
1424
|
+
function q(i, t, r, e) {
|
|
1425
|
+
const s = i.createShader(t);
|
|
1426
|
+
if (i.shaderSource(s, r), i.compileShader(s), e && !i.getShaderParameter(s, i.COMPILE_STATUS)) {
|
|
1427
|
+
const o = i.getShaderInfoLog(s);
|
|
1428
|
+
throw i.deleteShader(s), new Error(`Shader compilation failed: ${o}`);
|
|
1429
|
+
}
|
|
1430
|
+
return s;
|
|
1431
|
+
}
|
|
1432
|
+
function fe(i, t, r, e) {
|
|
1433
|
+
const s = i.createProgram();
|
|
1434
|
+
if (i.attachShader(s, t), i.attachShader(s, r), i.linkProgram(s), e && !i.getProgramParameter(s, i.LINK_STATUS)) {
|
|
1435
|
+
const o = i.getProgramInfoLog(s);
|
|
1436
|
+
throw i.deleteProgram(s), new Error(`Program linking failed: ${o}`);
|
|
1437
|
+
}
|
|
1438
|
+
return s;
|
|
1439
|
+
}
|
|
1440
|
+
class de {
|
|
1441
|
+
#e;
|
|
1442
|
+
#l;
|
|
1443
|
+
#T = [];
|
|
1444
|
+
#h = !1;
|
|
1445
|
+
#f = !1;
|
|
1446
|
+
#g = 0;
|
|
1447
|
+
#d;
|
|
1448
|
+
#p = !1;
|
|
1449
|
+
// Cached temporary resources for encodeTexture
|
|
1450
|
+
#a = null;
|
|
1451
|
+
#E = 0;
|
|
1452
|
+
#s = null;
|
|
1453
|
+
// For 8-byte per block formats
|
|
1454
|
+
#i = null;
|
|
1455
|
+
// For 16-byte per block formats
|
|
1456
|
+
#n = 0;
|
|
1457
|
+
#_ = 0;
|
|
1458
|
+
#u = null;
|
|
1459
|
+
constructor(t, r = {}) {
|
|
1460
|
+
if (!t)
|
|
1461
|
+
throw new Error("WebGL2 context is required");
|
|
1462
|
+
this.#e = t, this.#h = r.verbose ?? !1, this.#f = r.validateShaders ?? !1, this.#p = r.cacheTempResources ?? !1, this.#l = We(t, this.#h), r.preload && this.#m(r.preload);
|
|
1463
|
+
}
|
|
1464
|
+
dispose() {
|
|
1465
|
+
const t = this.#e;
|
|
1466
|
+
this.#d && t.deleteShader(this.#d);
|
|
1467
|
+
for (const r of this.#T)
|
|
1468
|
+
t.deleteProgram(r);
|
|
1469
|
+
this.freeTempResources();
|
|
1470
|
+
}
|
|
1471
|
+
/**
|
|
1472
|
+
* Initialize the encoder by detecting available compression formats.
|
|
1473
|
+
* @param {WebGL2RenderingContext} gl - WebGL2 context.
|
|
1474
|
+
* @param {Object} options - Encoder options.
|
|
1475
|
+
* @param {boolean|string[]} options.preload - Whether to preload all encoder pipelines, or an array of format names to preload (false by default).
|
|
1476
|
+
* @param {boolean} options.verbose - Whether to enable verbose logging (false by default).
|
|
1477
|
+
* @param {boolean} options.cacheTempResources - Whether to cache temporary resources for reuse across encodeTexture calls (false by default).
|
|
1478
|
+
* @returns {SparkGL} A new SparkGL instance.
|
|
1479
|
+
*/
|
|
1480
|
+
static create(t, r = {}) {
|
|
1481
|
+
return new de(t, r);
|
|
1482
|
+
}
|
|
1483
|
+
#t(...t) {
|
|
1484
|
+
this.#h && console.log(...t);
|
|
1485
|
+
}
|
|
1486
|
+
#o(t) {
|
|
1487
|
+
this.#h && console.time(t);
|
|
1488
|
+
}
|
|
1489
|
+
#c(t) {
|
|
1490
|
+
this.#h && console.timeEnd(t);
|
|
1491
|
+
}
|
|
1492
|
+
async #m(t) {
|
|
1493
|
+
let r;
|
|
1494
|
+
Array.isArray(t) ? r = t.map((e) => this.#b(e, !1)) : r = this.#l;
|
|
1495
|
+
for (const e of r)
|
|
1496
|
+
e !== void 0 && !this.#T[e] && this.#x(e).catch((s) => {
|
|
1497
|
+
console.error(`Failed to preload program for format ${v[e]}:`, s);
|
|
1498
|
+
});
|
|
1499
|
+
}
|
|
1500
|
+
getSupportedFormats() {
|
|
1501
|
+
return Array.from(this.#l).map((t) => v[t]).filter(Boolean);
|
|
1502
|
+
}
|
|
1503
|
+
isFormatSupported(t) {
|
|
1504
|
+
const r = typeof t == "string" ? H[t] : t;
|
|
1505
|
+
return this.#l.has(r);
|
|
1506
|
+
}
|
|
1507
|
+
/**
|
|
1508
|
+
* Free cached temporary resources used by encodeTexture.
|
|
1509
|
+
* Call this when you're done encoding textures to free up GPU memory.
|
|
1510
|
+
*/
|
|
1511
|
+
freeTempResources() {
|
|
1512
|
+
const t = this.#e;
|
|
1513
|
+
this.#a && (t.deleteBuffer(this.#a), this.#a = null, this.#E = 0), this.#s && (t.deleteTexture(this.#s), this.#s = null), this.#i && (t.deleteTexture(this.#i), this.#i = null), this.#u && (t.deleteFramebuffer(this.#u), this.#u = null), this.#n = 0, this.#_ = 0;
|
|
1514
|
+
}
|
|
1515
|
+
#B(t) {
|
|
1516
|
+
return this.#l.has(t);
|
|
1517
|
+
}
|
|
1518
|
+
#b(t, r = !1) {
|
|
1519
|
+
const e = H[t];
|
|
1520
|
+
if (e != null && this.#B(e))
|
|
1521
|
+
return e;
|
|
1522
|
+
const s = r ? ["bc4-r", "eac-r", "bc5-rg", "eac-rg", "bc1-rgb", "etc2-rgb", "bc7-rgb", "astc-rgb", "astc-4x4-rgb", "bc7-rgba", "astc-rgba", "astc-4x4-rgba"] : ["bc4-r", "eac-r", "bc5-rg", "eac-rg", "bc7-rgb", "astc-rgb", "astc-4x4-rgb", "bc1-rgb", "etc2-rgb", "bc7-rgba", "astc-rgba", "astc-4x4-rgba"];
|
|
1523
|
+
for (const o of s)
|
|
1524
|
+
if (o.includes(t) && this.#B(H[o]))
|
|
1525
|
+
return H[o];
|
|
1526
|
+
}
|
|
1527
|
+
#x(t) {
|
|
1528
|
+
if (this.#T[t])
|
|
1529
|
+
return this.#T[t];
|
|
1530
|
+
const r = (async () => {
|
|
1531
|
+
const e = "Loading program for format: " + v[t];
|
|
1532
|
+
this.#o(e);
|
|
1533
|
+
const s = this.#e, o = Me[t];
|
|
1534
|
+
this.#d || (this.#d = q(s, s.VERTEX_SHADER, Y, this.#f));
|
|
1535
|
+
const c = await ze(o), n = q(s, s.FRAGMENT_SHADER, c, this.#f), f = fe(s, this.#d, n, this.#f);
|
|
1536
|
+
return s.deleteShader(n), this.#c(e), f;
|
|
1537
|
+
})();
|
|
1538
|
+
return this.#T[t] = r, r;
|
|
1539
|
+
}
|
|
1540
|
+
async encodeTexture(t, r = {}) {
|
|
1541
|
+
const e = this.#e;
|
|
1542
|
+
typeof t == "string" && (t = await K(t)), this.#t(`Image type: ${t.constructor.name}`);
|
|
1543
|
+
const s = t.width || t.videoWidth, o = t.height || t.videoHeight;
|
|
1544
|
+
O(s && o);
|
|
1545
|
+
const c = r.format ?? "rgb";
|
|
1546
|
+
let n;
|
|
1547
|
+
if (typeof c == "string") {
|
|
1548
|
+
if (n = this.#b(c, r.preferLowQuality), n === void 0)
|
|
1549
|
+
throw new Error(`Unsupported format: ${c}`);
|
|
1550
|
+
} else if (n = c, !this.#l.has(n))
|
|
1551
|
+
throw new Error(`Format not supported: ${v[n]}`);
|
|
1552
|
+
const f = await this.#x(n);
|
|
1553
|
+
this.#t(`Selected format: ${v[n]}`);
|
|
1554
|
+
const u = Le[n], l = (r.srgb || r.format?.endsWith("srgb")) && De[n], h = Oe[n], m = h ? l ? h[1] : h[0] : null, R = Ve[n];
|
|
1555
|
+
this.#t(`Using ${l ? "sRGB" : "linear"} color space`);
|
|
1556
|
+
const T = `encodeTexture #${++this.#g}`;
|
|
1557
|
+
this.#o(T);
|
|
1558
|
+
const d = {
|
|
1559
|
+
program: e.getParameter(e.CURRENT_PROGRAM),
|
|
1560
|
+
activeTexture: e.getParameter(e.ACTIVE_TEXTURE),
|
|
1561
|
+
textureBinding: e.getParameter(e.TEXTURE_BINDING_2D),
|
|
1562
|
+
framebuffer: e.getParameter(e.FRAMEBUFFER_BINDING),
|
|
1563
|
+
readFramebuffer: e.getParameter(e.READ_FRAMEBUFFER_BINDING),
|
|
1564
|
+
viewport: e.getParameter(e.VIEWPORT),
|
|
1565
|
+
blend: e.getParameter(e.BLEND),
|
|
1566
|
+
depthTest: e.getParameter(e.DEPTH_TEST),
|
|
1567
|
+
stencilTest: e.getParameter(e.STENCIL_TEST),
|
|
1568
|
+
cullFace: e.getParameter(e.CULL_FACE),
|
|
1569
|
+
scissorTest: e.getParameter(e.SCISSOR_TEST),
|
|
1570
|
+
pixelPackBuffer: e.getParameter(e.PIXEL_PACK_BUFFER_BINDING),
|
|
1571
|
+
pixelUnpackBuffer: e.getParameter(e.PIXEL_UNPACK_BUFFER_BINDING),
|
|
1572
|
+
arrayBuffer: e.getParameter(e.ARRAY_BUFFER_BINDING),
|
|
1573
|
+
vertexArray: e.getParameter(e.VERTEX_ARRAY_BINDING)
|
|
1574
|
+
};
|
|
1575
|
+
e.activeTexture(e.TEXTURE0), e.disable(e.BLEND), e.disable(e.DEPTH_TEST), e.disable(e.STENCIL_TEST), e.disable(e.CULL_FACE), e.disable(e.SCISSOR_TEST);
|
|
1576
|
+
const V = r.wrap || "repeat";
|
|
1577
|
+
let x;
|
|
1578
|
+
switch (V) {
|
|
1579
|
+
case "repeat":
|
|
1580
|
+
x = e.REPEAT;
|
|
1581
|
+
break;
|
|
1582
|
+
case "mirror":
|
|
1583
|
+
x = e.MIRRORED_REPEAT;
|
|
1584
|
+
break;
|
|
1585
|
+
case "clamp":
|
|
1586
|
+
default:
|
|
1587
|
+
x = e.CLAMP_TO_EDGE;
|
|
1588
|
+
break;
|
|
1589
|
+
}
|
|
1590
|
+
const y = r.generateMipmaps || r.mips;
|
|
1591
|
+
let S = 1;
|
|
1592
|
+
if (y) {
|
|
1593
|
+
let w = s, I = o;
|
|
1594
|
+
for (; w > 4 || I > 4; )
|
|
1595
|
+
S++, w = Math.max(1, Math.floor(w / 2)), I = Math.max(1, Math.floor(I / 2));
|
|
1596
|
+
}
|
|
1597
|
+
const _ = e.createTexture();
|
|
1598
|
+
e.bindTexture(e.TEXTURE_2D, _), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, x), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, x), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAX_LEVEL, 0), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA8, s, o, 0, e.RGBA, e.UNSIGNED_BYTE, t);
|
|
1599
|
+
let E = _;
|
|
1600
|
+
if (r.flipY) {
|
|
1601
|
+
this.#t("Flipping texture vertically");
|
|
1602
|
+
const G = e.createTexture();
|
|
1603
|
+
e.bindTexture(e.TEXTURE_2D, G), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, x), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, x), e.texStorage2D(e.TEXTURE_2D, 1, e.RGBA8, s, o);
|
|
1604
|
+
const w = e.createFramebuffer();
|
|
1605
|
+
e.bindFramebuffer(e.FRAMEBUFFER, w), e.framebufferTexture2D(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0, e.TEXTURE_2D, G, 0), this.#d || (this.#d = q(e, e.VERTEX_SHADER, Y, this.#f));
|
|
1606
|
+
const I = `#version 300 es
|
|
1607
|
+
precision mediump float;
|
|
1608
|
+
uniform sampler2D uTexture;
|
|
1609
|
+
uniform ivec2 uTextureSize;
|
|
1610
|
+
out vec4 fragColor;
|
|
1611
|
+
void main() {
|
|
1612
|
+
ivec2 coord = ivec2(gl_FragCoord.xy);
|
|
1613
|
+
// Flip Y coordinate
|
|
1614
|
+
coord.y = uTextureSize.y - 1 - coord.y;
|
|
1615
|
+
fragColor = texelFetch(uTexture, coord, 0);
|
|
1616
|
+
}`, F = e.createShader(e.VERTEX_SHADER);
|
|
1617
|
+
e.shaderSource(F, Y), e.compileShader(F);
|
|
1618
|
+
const M = e.createShader(e.FRAGMENT_SHADER);
|
|
1619
|
+
e.shaderSource(M, I), e.compileShader(M);
|
|
1620
|
+
const D = fe(e, F, M, this.#f);
|
|
1621
|
+
e.useProgram(D), e.viewport(0, 0, s, o), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, _), e.uniform1i(e.getUniformLocation(D, "uTexture"), 0), e.uniform2i(e.getUniformLocation(D, "uTextureSize"), s, o), e.drawArrays(e.TRIANGLES, 0, 3), e.deleteShader(F), e.deleteShader(M), e.deleteProgram(D), e.deleteFramebuffer(w), e.deleteTexture(_), E = G;
|
|
1622
|
+
}
|
|
1623
|
+
y && (e.bindTexture(e.TEXTURE_2D, E), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR_MIPMAP_LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAX_LEVEL, S - 1), e.generateMipmap(e.TEXTURE_2D), this.#t(`Generated ${S} mipmap levels`));
|
|
1624
|
+
const P = e.createTexture();
|
|
1625
|
+
e.bindTexture(e.TEXTURE_2D, P), e.texStorage2D(e.TEXTURE_2D, S, m, s, o), y ? (e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR_MIPMAP_LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR)) : (e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR)), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, x), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, x);
|
|
1626
|
+
const Q = Math.ceil(s / 4), W = Math.ceil(o / 4), C = u * Q * W;
|
|
1627
|
+
let k = C;
|
|
1628
|
+
const b = this.#p;
|
|
1629
|
+
let U;
|
|
1630
|
+
b && this.#a && this.#E >= C ? U = this.#a : (b && this.#a && e.deleteBuffer(this.#a), U = e.createBuffer(), b && (this.#a = U, this.#E = C)), e.bindBuffer(e.PIXEL_PACK_BUFFER, U), e.bindBuffer(e.PIXEL_UNPACK_BUFFER, U), e.bufferData(e.PIXEL_PACK_BUFFER, C, e.STREAM_COPY);
|
|
1631
|
+
let B;
|
|
1632
|
+
const g = !b || this.#n < s || this.#_ < o;
|
|
1633
|
+
u === 8 ? b && this.#s && !g ? B = this.#s : (b && this.#s && e.deleteTexture(this.#s), B = e.createTexture(), e.bindTexture(e.TEXTURE_2D, B), e.texStorage2D(e.TEXTURE_2D, 1, R, s, o), b && (this.#s = B, this.#n = s, this.#_ = o)) : b && this.#i && !g ? B = this.#i : (b && this.#i && e.deleteTexture(this.#i), B = e.createTexture(), e.bindTexture(e.TEXTURE_2D, B), e.texStorage2D(e.TEXTURE_2D, 1, R, s, o), b && (this.#i = B, this.#n = s, this.#_ = o));
|
|
1634
|
+
let L;
|
|
1635
|
+
b && this.#u ? L = this.#u : (L = e.createFramebuffer(), b && (this.#u = L)), e.bindFramebuffer(e.FRAMEBUFFER, L), e.readBuffer(e.COLOR_ATTACHMENT0), e.framebufferTexture2D(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0, e.TEXTURE_2D, B, 0), e.useProgram(f);
|
|
1636
|
+
for (let G = 0; G < S; G++) {
|
|
1637
|
+
const w = Math.max(1, Math.floor(s >> G)), I = Math.max(1, Math.floor(o >> G)), F = Math.ceil(w / 4), M = Math.ceil(I / 4), D = u * F * M;
|
|
1638
|
+
k += D, e.bindTexture(e.TEXTURE_2D, E), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_BASE_LEVEL, G), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAX_LEVEL, G), e.viewport(0, 0, F, M), e.drawArrays(e.TRIANGLES, 0, 3), e.readPixels(0, 0, F, M, e.RGBA_INTEGER, u === 16 ? e.UNSIGNED_INT : e.UNSIGNED_SHORT, 0), e.bindTexture(e.TEXTURE_2D, P), e.compressedTexSubImage2D(e.TEXTURE_2D, G, 0, 0, w, I, m, D, 0);
|
|
1639
|
+
}
|
|
1640
|
+
return b || (e.deleteTexture(B), e.deleteBuffer(U), e.deleteFramebuffer(L)), e.deleteTexture(E), e.bindFramebuffer(e.FRAMEBUFFER, d.framebuffer), e.bindFramebuffer(e.READ_FRAMEBUFFER, d.readFramebuffer), e.bindTexture(e.TEXTURE_2D, d.textureBinding), e.useProgram(d.program), e.activeTexture(d.activeTexture), e.viewport(d.viewport[0], d.viewport[1], d.viewport[2], d.viewport[3]), e.bindBuffer(e.PIXEL_PACK_BUFFER, d.pixelPackBuffer), e.bindBuffer(e.PIXEL_UNPACK_BUFFER, d.pixelUnpackBuffer), d.blend ? e.enable(e.BLEND) : e.disable(e.BLEND), d.depthTest ? e.enable(e.DEPTH_TEST) : e.disable(e.DEPTH_TEST), d.stencilTest ? e.enable(e.STENCIL_TEST) : e.disable(e.STENCIL_TEST), d.cullFace ? e.enable(e.CULL_FACE) : e.disable(e.CULL_FACE), d.scissorTest ? e.enable(e.SCISSOR_TEST) : e.disable(e.SCISSOR_TEST), e.bindBuffer(e.ARRAY_BUFFER, d.arrayBuffer), e.bindVertexArray(d.vertexArray), this.#c(T), {
|
|
1641
|
+
texture: P,
|
|
1642
|
+
width: s,
|
|
1643
|
+
height: o,
|
|
1644
|
+
format: m,
|
|
1645
|
+
sparkFormat: n,
|
|
1646
|
+
sparkFormatName: v[n],
|
|
1647
|
+
srgb: l,
|
|
1648
|
+
mipmapCount: S,
|
|
1649
|
+
byteLength: k
|
|
1650
|
+
};
|
|
1128
1651
|
}
|
|
1129
1652
|
}
|
|
1130
1653
|
export {
|
|
1131
|
-
|
|
1654
|
+
me as Spark,
|
|
1655
|
+
de as SparkGL
|
|
1132
1656
|
};
|