@motion-core/motion-gpu 0.4.1 → 0.5.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 +99 -0
- package/dist/advanced.d.ts +1 -0
- package/dist/advanced.d.ts.map +1 -0
- package/dist/advanced.js +14 -6
- package/dist/core/advanced.d.ts +1 -0
- package/dist/core/advanced.d.ts.map +1 -0
- package/dist/core/advanced.js +14 -5
- package/dist/core/compute-shader.d.ts +87 -0
- package/dist/core/compute-shader.d.ts.map +1 -0
- package/dist/core/compute-shader.js +205 -0
- package/dist/core/compute-shader.js.map +1 -0
- package/dist/core/current-value.d.ts +1 -0
- package/dist/core/current-value.d.ts.map +1 -0
- package/dist/core/current-value.js +35 -34
- package/dist/core/current-value.js.map +1 -0
- package/dist/core/error-diagnostics.d.ts +1 -0
- package/dist/core/error-diagnostics.d.ts.map +1 -0
- package/dist/core/error-diagnostics.js +70 -137
- package/dist/core/error-diagnostics.js.map +1 -0
- package/dist/core/error-report.d.ts +2 -1
- package/dist/core/error-report.d.ts.map +1 -0
- package/dist/core/error-report.js +247 -233
- package/dist/core/error-report.js.map +1 -0
- package/dist/core/frame-registry.d.ts +1 -0
- package/dist/core/frame-registry.d.ts.map +1 -0
- package/dist/core/frame-registry.js +546 -662
- package/dist/core/frame-registry.js.map +1 -0
- package/dist/core/index.d.ts +6 -2
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +13 -12
- package/dist/core/material-preprocess.d.ts +1 -0
- package/dist/core/material-preprocess.d.ts.map +1 -0
- package/dist/core/material-preprocess.js +131 -152
- package/dist/core/material-preprocess.js.map +1 -0
- package/dist/core/material.d.ts +23 -6
- package/dist/core/material.d.ts.map +1 -0
- package/dist/core/material.js +290 -317
- package/dist/core/material.js.map +1 -0
- package/dist/core/recompile-policy.d.ts +1 -0
- package/dist/core/recompile-policy.d.ts.map +1 -0
- package/dist/core/recompile-policy.js +18 -13
- package/dist/core/recompile-policy.js.map +1 -0
- package/dist/core/render-graph.d.ts +8 -3
- package/dist/core/render-graph.d.ts.map +1 -0
- package/dist/core/render-graph.js +77 -68
- package/dist/core/render-graph.js.map +1 -0
- package/dist/core/render-targets.d.ts +1 -0
- package/dist/core/render-targets.d.ts.map +1 -0
- package/dist/core/render-targets.js +52 -53
- package/dist/core/render-targets.js.map +1 -0
- package/dist/core/renderer.d.ts +1 -0
- package/dist/core/renderer.d.ts.map +1 -0
- package/dist/core/renderer.js +1337 -1081
- package/dist/core/renderer.js.map +1 -0
- package/dist/core/runtime-loop.d.ts +3 -2
- package/dist/core/runtime-loop.d.ts.map +1 -0
- package/dist/core/runtime-loop.js +353 -362
- package/dist/core/runtime-loop.js.map +1 -0
- package/dist/core/scheduler-helpers.d.ts +1 -0
- package/dist/core/scheduler-helpers.d.ts.map +1 -0
- package/dist/core/scheduler-helpers.js +52 -51
- package/dist/core/scheduler-helpers.js.map +1 -0
- package/dist/core/shader.d.ts +10 -1
- package/dist/core/shader.d.ts.map +1 -0
- package/dist/core/shader.js +109 -115
- package/dist/core/shader.js.map +1 -0
- package/dist/core/storage-buffers.d.ts +37 -0
- package/dist/core/storage-buffers.d.ts.map +1 -0
- package/dist/core/storage-buffers.js +95 -0
- package/dist/core/storage-buffers.js.map +1 -0
- package/dist/core/texture-loader.d.ts +1 -0
- package/dist/core/texture-loader.d.ts.map +1 -0
- package/dist/core/texture-loader.js +209 -273
- package/dist/core/texture-loader.js.map +1 -0
- package/dist/core/textures.d.ts +13 -0
- package/dist/core/textures.d.ts.map +1 -0
- package/dist/core/textures.js +111 -116
- package/dist/core/textures.js.map +1 -0
- package/dist/core/types.d.ts +147 -4
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +0 -4
- package/dist/core/uniforms.d.ts +1 -0
- package/dist/core/uniforms.d.ts.map +1 -0
- package/dist/core/uniforms.js +170 -191
- package/dist/core/uniforms.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -6
- package/dist/passes/BlitPass.d.ts +1 -0
- package/dist/passes/BlitPass.d.ts.map +1 -0
- package/dist/passes/BlitPass.js +23 -18
- package/dist/passes/BlitPass.js.map +1 -0
- package/dist/passes/ComputePass.d.ts +83 -0
- package/dist/passes/ComputePass.d.ts.map +1 -0
- package/dist/passes/ComputePass.js +92 -0
- package/dist/passes/ComputePass.js.map +1 -0
- package/dist/passes/CopyPass.d.ts +1 -0
- package/dist/passes/CopyPass.d.ts.map +1 -0
- package/dist/passes/CopyPass.js +58 -52
- package/dist/passes/CopyPass.js.map +1 -0
- package/dist/passes/FullscreenPass.d.ts +1 -0
- package/dist/passes/FullscreenPass.d.ts.map +1 -0
- package/dist/passes/FullscreenPass.js +127 -130
- package/dist/passes/FullscreenPass.js.map +1 -0
- package/dist/passes/PingPongComputePass.d.ts +104 -0
- package/dist/passes/PingPongComputePass.d.ts.map +1 -0
- package/dist/passes/PingPongComputePass.js +132 -0
- package/dist/passes/PingPongComputePass.js.map +1 -0
- package/dist/passes/ShaderPass.d.ts +1 -0
- package/dist/passes/ShaderPass.d.ts.map +1 -0
- package/dist/passes/ShaderPass.js +41 -37
- package/dist/passes/ShaderPass.js.map +1 -0
- package/dist/passes/index.d.ts +3 -0
- package/dist/passes/index.d.ts.map +1 -0
- package/dist/passes/index.js +6 -3
- package/dist/react/FragCanvas.d.ts +3 -2
- package/dist/react/FragCanvas.d.ts.map +1 -0
- package/dist/react/FragCanvas.js +234 -211
- package/dist/react/FragCanvas.js.map +1 -0
- package/dist/react/MotionGPUErrorOverlay.d.ts +1 -0
- package/dist/react/MotionGPUErrorOverlay.d.ts.map +1 -0
- package/dist/react/MotionGPUErrorOverlay.js +200 -14
- package/dist/react/MotionGPUErrorOverlay.js.map +1 -0
- package/dist/react/Portal.d.ts +1 -0
- package/dist/react/Portal.d.ts.map +1 -0
- package/dist/react/Portal.js +18 -21
- package/dist/react/Portal.js.map +1 -0
- package/dist/react/advanced.d.ts +1 -0
- package/dist/react/advanced.d.ts.map +1 -0
- package/dist/react/advanced.js +14 -6
- package/dist/react/frame-context.d.ts +1 -0
- package/dist/react/frame-context.d.ts.map +1 -0
- package/dist/react/frame-context.js +88 -94
- package/dist/react/frame-context.js.map +1 -0
- package/dist/react/index.d.ts +6 -2
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +12 -9
- package/dist/react/motiongpu-context.d.ts +1 -0
- package/dist/react/motiongpu-context.d.ts.map +1 -0
- package/dist/react/motiongpu-context.js +18 -15
- package/dist/react/motiongpu-context.js.map +1 -0
- package/dist/react/use-motiongpu-user-context.d.ts +1 -0
- package/dist/react/use-motiongpu-user-context.d.ts.map +1 -0
- package/dist/react/use-motiongpu-user-context.js +83 -82
- package/dist/react/use-motiongpu-user-context.js.map +1 -0
- package/dist/react/use-texture.d.ts +1 -0
- package/dist/react/use-texture.d.ts.map +1 -0
- package/dist/react/use-texture.js +132 -152
- package/dist/react/use-texture.js.map +1 -0
- package/dist/svelte/FragCanvas.svelte +2 -2
- package/dist/svelte/FragCanvas.svelte.d.ts +3 -2
- package/dist/svelte/FragCanvas.svelte.d.ts.map +1 -0
- package/dist/svelte/MotionGPUErrorOverlay.svelte +137 -7
- package/dist/svelte/MotionGPUErrorOverlay.svelte.d.ts +1 -0
- package/dist/svelte/MotionGPUErrorOverlay.svelte.d.ts.map +1 -0
- package/dist/svelte/Portal.svelte.d.ts +1 -0
- package/dist/svelte/Portal.svelte.d.ts.map +1 -0
- package/dist/svelte/advanced.d.ts +1 -0
- package/dist/svelte/advanced.d.ts.map +1 -0
- package/dist/svelte/advanced.js +13 -6
- package/dist/svelte/frame-context.d.ts +1 -0
- package/dist/svelte/frame-context.d.ts.map +1 -0
- package/dist/svelte/frame-context.js +27 -27
- package/dist/svelte/frame-context.js.map +1 -0
- package/dist/svelte/index.d.ts +6 -2
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +12 -9
- package/dist/svelte/motiongpu-context.d.ts +1 -0
- package/dist/svelte/motiongpu-context.d.ts.map +1 -0
- package/dist/svelte/motiongpu-context.js +24 -21
- package/dist/svelte/motiongpu-context.js.map +1 -0
- package/dist/svelte/use-motiongpu-user-context.d.ts +1 -0
- package/dist/svelte/use-motiongpu-user-context.d.ts.map +1 -0
- package/dist/svelte/use-motiongpu-user-context.js +69 -70
- package/dist/svelte/use-motiongpu-user-context.js.map +1 -0
- package/dist/svelte/use-texture.d.ts +1 -0
- package/dist/svelte/use-texture.d.ts.map +1 -0
- package/dist/svelte/use-texture.js +125 -147
- package/dist/svelte/use-texture.js.map +1 -0
- package/package.json +12 -7
- package/src/lib/advanced.ts +6 -0
- package/src/lib/core/advanced.ts +12 -0
- package/src/lib/core/compute-shader.ts +326 -0
- package/src/lib/core/current-value.ts +64 -0
- package/src/lib/core/error-diagnostics.ts +236 -0
- package/src/lib/core/error-report.ts +535 -0
- package/src/lib/core/frame-registry.ts +1190 -0
- package/src/lib/core/index.ts +94 -0
- package/src/lib/core/material-preprocess.ts +295 -0
- package/src/lib/core/material.ts +748 -0
- package/src/lib/core/recompile-policy.ts +31 -0
- package/src/lib/core/render-graph.ts +173 -0
- package/src/lib/core/render-targets.ts +107 -0
- package/src/lib/core/renderer.ts +2161 -0
- package/src/lib/core/runtime-loop.ts +537 -0
- package/src/lib/core/scheduler-helpers.ts +136 -0
- package/src/lib/core/shader.ts +301 -0
- package/src/lib/core/storage-buffers.ts +142 -0
- package/src/lib/core/texture-loader.ts +482 -0
- package/src/lib/core/textures.ts +257 -0
- package/src/lib/core/types.ts +743 -0
- package/src/lib/core/uniforms.ts +282 -0
- package/src/lib/index.ts +6 -0
- package/src/lib/passes/BlitPass.ts +54 -0
- package/src/lib/passes/ComputePass.ts +136 -0
- package/src/lib/passes/CopyPass.ts +80 -0
- package/src/lib/passes/FullscreenPass.ts +173 -0
- package/src/lib/passes/PingPongComputePass.ts +180 -0
- package/src/lib/passes/ShaderPass.ts +89 -0
- package/src/lib/passes/index.ts +9 -0
- package/src/lib/react/FragCanvas.tsx +345 -0
- package/src/lib/react/MotionGPUErrorOverlay.tsx +524 -0
- package/src/lib/react/Portal.tsx +34 -0
- package/src/lib/react/advanced.ts +36 -0
- package/src/lib/react/frame-context.ts +169 -0
- package/src/lib/react/index.ts +68 -0
- package/src/lib/react/motiongpu-context.ts +88 -0
- package/src/lib/react/use-motiongpu-user-context.ts +186 -0
- package/src/lib/react/use-texture.ts +233 -0
- package/src/lib/svelte/FragCanvas.svelte +249 -0
- package/src/lib/svelte/MotionGPUErrorOverlay.svelte +512 -0
- package/src/lib/svelte/Portal.svelte +31 -0
- package/src/lib/svelte/advanced.ts +32 -0
- package/src/lib/svelte/frame-context.ts +87 -0
- package/src/lib/svelte/index.ts +68 -0
- package/src/lib/svelte/motiongpu-context.ts +97 -0
- package/src/lib/svelte/use-motiongpu-user-context.ts +145 -0
- package/src/lib/svelte/use-texture.ts +232 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { assertUniformName } from "./uniforms.js";
|
|
2
|
+
//#region src/lib/core/storage-buffers.ts
|
|
3
|
+
/**
|
|
4
|
+
* Valid WGSL storage buffer element types.
|
|
5
|
+
*/
|
|
6
|
+
var VALID_STORAGE_BUFFER_TYPES = new Set([
|
|
7
|
+
"array<f32>",
|
|
8
|
+
"array<vec2f>",
|
|
9
|
+
"array<vec3f>",
|
|
10
|
+
"array<vec4f>",
|
|
11
|
+
"array<u32>",
|
|
12
|
+
"array<i32>",
|
|
13
|
+
"array<vec4u>",
|
|
14
|
+
"array<vec4i>"
|
|
15
|
+
]);
|
|
16
|
+
/**
|
|
17
|
+
* Storage-compatible texture formats for `texture_storage_2d`.
|
|
18
|
+
*/
|
|
19
|
+
var STORAGE_TEXTURE_FORMATS = new Set([
|
|
20
|
+
"r32float",
|
|
21
|
+
"r32sint",
|
|
22
|
+
"r32uint",
|
|
23
|
+
"rg32float",
|
|
24
|
+
"rg32sint",
|
|
25
|
+
"rg32uint",
|
|
26
|
+
"rgba8unorm",
|
|
27
|
+
"rgba8snorm",
|
|
28
|
+
"rgba8uint",
|
|
29
|
+
"rgba8sint",
|
|
30
|
+
"rgba16float",
|
|
31
|
+
"rgba16uint",
|
|
32
|
+
"rgba16sint",
|
|
33
|
+
"rgba32float",
|
|
34
|
+
"rgba32uint",
|
|
35
|
+
"rgba32sint",
|
|
36
|
+
"bgra8unorm"
|
|
37
|
+
]);
|
|
38
|
+
/**
|
|
39
|
+
* Validates a single storage buffer definition.
|
|
40
|
+
*
|
|
41
|
+
* @param name - Buffer identifier.
|
|
42
|
+
* @param definition - Storage buffer definition to validate.
|
|
43
|
+
* @throws {Error} When any field is invalid.
|
|
44
|
+
*/
|
|
45
|
+
function assertStorageBufferDefinition(name, definition) {
|
|
46
|
+
assertUniformName(name);
|
|
47
|
+
if (!Number.isFinite(definition.size) || definition.size <= 0) throw new Error(`Storage buffer "${name}" size must be a finite number greater than 0, got ${definition.size}`);
|
|
48
|
+
if (definition.size % 4 !== 0) throw new Error(`Storage buffer "${name}" size must be a multiple of 4, got ${definition.size}`);
|
|
49
|
+
if (!VALID_STORAGE_BUFFER_TYPES.has(definition.type)) throw new Error(`Storage buffer "${name}" has unknown type "${definition.type}". Supported types: ${[...VALID_STORAGE_BUFFER_TYPES].join(", ")}`);
|
|
50
|
+
if (definition.access !== void 0 && definition.access !== "read" && definition.access !== "read-write") throw new Error(`Storage buffer "${name}" has invalid access mode "${definition.access}". Use 'read' or 'read-write'.`);
|
|
51
|
+
if (definition.initialData !== void 0) {
|
|
52
|
+
if (definition.initialData.byteLength > definition.size) throw new Error(`Storage buffer "${name}" initialData byte length (${definition.initialData.byteLength}) exceeds buffer size (${definition.size})`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Validates and returns sorted storage buffer keys.
|
|
57
|
+
*
|
|
58
|
+
* @param definitions - Storage buffer definition map.
|
|
59
|
+
* @returns Lexicographically sorted buffer keys.
|
|
60
|
+
*/
|
|
61
|
+
function resolveStorageBufferKeys(definitions) {
|
|
62
|
+
const keys = Object.keys(definitions).sort();
|
|
63
|
+
for (const key of keys) {
|
|
64
|
+
const definition = definitions[key];
|
|
65
|
+
if (definition) assertStorageBufferDefinition(key, definition);
|
|
66
|
+
}
|
|
67
|
+
return keys;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Normalizes a storage buffer definition with defaults applied.
|
|
71
|
+
*
|
|
72
|
+
* @param definition - Raw definition.
|
|
73
|
+
* @returns Normalized definition with access default.
|
|
74
|
+
*/
|
|
75
|
+
function normalizeStorageBufferDefinition(definition) {
|
|
76
|
+
return {
|
|
77
|
+
size: definition.size,
|
|
78
|
+
type: definition.type,
|
|
79
|
+
access: definition.access ?? "read-write"
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Validates that a texture format is storage-compatible.
|
|
84
|
+
*
|
|
85
|
+
* @param name - Texture identifier.
|
|
86
|
+
* @param format - GPU texture format.
|
|
87
|
+
* @throws {Error} When format is not storage-compatible.
|
|
88
|
+
*/
|
|
89
|
+
function assertStorageTextureFormat(name, format) {
|
|
90
|
+
if (!STORAGE_TEXTURE_FORMATS.has(format)) throw new Error(`Texture "${name}" with storage:true requires a storage-compatible format, but got "${format}". Supported formats: ${[...STORAGE_TEXTURE_FORMATS].join(", ")}`);
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { STORAGE_TEXTURE_FORMATS, assertStorageBufferDefinition, assertStorageTextureFormat, normalizeStorageBufferDefinition, resolveStorageBufferKeys };
|
|
94
|
+
|
|
95
|
+
//# sourceMappingURL=storage-buffers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-buffers.js","names":[],"sources":["../../src/lib/core/storage-buffers.ts"],"sourcesContent":["import { assertUniformName } from './uniforms.js';\nimport type {\n\tStorageBufferDefinition,\n\tStorageBufferDefinitionMap,\n\tStorageBufferType\n} from './types.js';\n\n/**\n * Valid WGSL storage buffer element types.\n */\nconst VALID_STORAGE_BUFFER_TYPES: ReadonlySet<string> = new Set<StorageBufferType>([\n\t'array<f32>',\n\t'array<vec2f>',\n\t'array<vec3f>',\n\t'array<vec4f>',\n\t'array<u32>',\n\t'array<i32>',\n\t'array<vec4u>',\n\t'array<vec4i>'\n]);\n\n/**\n * Storage-compatible texture formats for `texture_storage_2d`.\n */\nexport const STORAGE_TEXTURE_FORMATS: ReadonlySet<GPUTextureFormat> = new Set([\n\t'r32float',\n\t'r32sint',\n\t'r32uint',\n\t'rg32float',\n\t'rg32sint',\n\t'rg32uint',\n\t'rgba8unorm',\n\t'rgba8snorm',\n\t'rgba8uint',\n\t'rgba8sint',\n\t'rgba16float',\n\t'rgba16uint',\n\t'rgba16sint',\n\t'rgba32float',\n\t'rgba32uint',\n\t'rgba32sint',\n\t'bgra8unorm'\n] as GPUTextureFormat[]);\n\n/**\n * Validates a single storage buffer definition.\n *\n * @param name - Buffer identifier.\n * @param definition - Storage buffer definition to validate.\n * @throws {Error} When any field is invalid.\n */\nexport function assertStorageBufferDefinition(\n\tname: string,\n\tdefinition: StorageBufferDefinition\n): void {\n\tassertUniformName(name);\n\n\tif (!Number.isFinite(definition.size) || definition.size <= 0) {\n\t\tthrow new Error(\n\t\t\t`Storage buffer \"${name}\" size must be a finite number greater than 0, got ${definition.size}`\n\t\t);\n\t}\n\n\tif (definition.size % 4 !== 0) {\n\t\tthrow new Error(\n\t\t\t`Storage buffer \"${name}\" size must be a multiple of 4, got ${definition.size}`\n\t\t);\n\t}\n\n\tif (!VALID_STORAGE_BUFFER_TYPES.has(definition.type)) {\n\t\tthrow new Error(\n\t\t\t`Storage buffer \"${name}\" has unknown type \"${definition.type}\". Supported types: ${[...VALID_STORAGE_BUFFER_TYPES].join(', ')}`\n\t\t);\n\t}\n\n\tif (\n\t\tdefinition.access !== undefined &&\n\t\tdefinition.access !== 'read' &&\n\t\tdefinition.access !== 'read-write'\n\t) {\n\t\tthrow new Error(\n\t\t\t`Storage buffer \"${name}\" has invalid access mode \"${definition.access}\". Use 'read' or 'read-write'.`\n\t\t);\n\t}\n\n\tif (definition.initialData !== undefined) {\n\t\tif (definition.initialData.byteLength > definition.size) {\n\t\t\tthrow new Error(\n\t\t\t\t`Storage buffer \"${name}\" initialData byte length (${definition.initialData.byteLength}) exceeds buffer size (${definition.size})`\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Validates and returns sorted storage buffer keys.\n *\n * @param definitions - Storage buffer definition map.\n * @returns Lexicographically sorted buffer keys.\n */\nexport function resolveStorageBufferKeys(definitions: StorageBufferDefinitionMap): string[] {\n\tconst keys = Object.keys(definitions).sort();\n\tfor (const key of keys) {\n\t\tconst definition = definitions[key];\n\t\tif (definition) {\n\t\t\tassertStorageBufferDefinition(key, definition);\n\t\t}\n\t}\n\treturn keys;\n}\n\n/**\n * Normalizes a storage buffer definition with defaults applied.\n *\n * @param definition - Raw definition.\n * @returns Normalized definition with access default.\n */\nexport function normalizeStorageBufferDefinition(\n\tdefinition: StorageBufferDefinition\n): Required<Pick<StorageBufferDefinition, 'size' | 'type' | 'access'>> {\n\treturn {\n\t\tsize: definition.size,\n\t\ttype: definition.type,\n\t\taccess: definition.access ?? 'read-write'\n\t};\n}\n\n/**\n * Validates that a texture format is storage-compatible.\n *\n * @param name - Texture identifier.\n * @param format - GPU texture format.\n * @throws {Error} When format is not storage-compatible.\n */\nexport function assertStorageTextureFormat(name: string, format: GPUTextureFormat): void {\n\tif (!STORAGE_TEXTURE_FORMATS.has(format)) {\n\t\tthrow new Error(\n\t\t\t`Texture \"${name}\" with storage:true requires a storage-compatible format, but got \"${format}\". ` +\n\t\t\t\t`Supported formats: ${[...STORAGE_TEXTURE_FORMATS].join(', ')}`\n\t\t);\n\t}\n}\n"],"mappings":";;;;;AAUA,IAAM,6BAAkD,IAAI,IAAuB;CAClF;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;;;;AAKF,IAAa,0BAAyD,IAAI,IAAI;CAC7E;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,CAAuB;;;;;;;;AASxB,SAAgB,8BACf,MACA,YACO;AACP,mBAAkB,KAAK;AAEvB,KAAI,CAAC,OAAO,SAAS,WAAW,KAAK,IAAI,WAAW,QAAQ,EAC3D,OAAM,IAAI,MACT,mBAAmB,KAAK,qDAAqD,WAAW,OACxF;AAGF,KAAI,WAAW,OAAO,MAAM,EAC3B,OAAM,IAAI,MACT,mBAAmB,KAAK,sCAAsC,WAAW,OACzE;AAGF,KAAI,CAAC,2BAA2B,IAAI,WAAW,KAAK,CACnD,OAAM,IAAI,MACT,mBAAmB,KAAK,sBAAsB,WAAW,KAAK,sBAAsB,CAAC,GAAG,2BAA2B,CAAC,KAAK,KAAK,GAC9H;AAGF,KACC,WAAW,WAAW,UACtB,WAAW,WAAW,UACtB,WAAW,WAAW,aAEtB,OAAM,IAAI,MACT,mBAAmB,KAAK,6BAA6B,WAAW,OAAO,gCACvE;AAGF,KAAI,WAAW,gBAAgB,QAC9B;MAAI,WAAW,YAAY,aAAa,WAAW,KAClD,OAAM,IAAI,MACT,mBAAmB,KAAK,6BAA6B,WAAW,YAAY,WAAW,yBAAyB,WAAW,KAAK,GAChI;;;;;;;;;AAWJ,SAAgB,yBAAyB,aAAmD;CAC3F,MAAM,OAAO,OAAO,KAAK,YAAY,CAAC,MAAM;AAC5C,MAAK,MAAM,OAAO,MAAM;EACvB,MAAM,aAAa,YAAY;AAC/B,MAAI,WACH,+BAA8B,KAAK,WAAW;;AAGhD,QAAO;;;;;;;;AASR,SAAgB,iCACf,YACsE;AACtE,QAAO;EACN,MAAM,WAAW;EACjB,MAAM,WAAW;EACjB,QAAQ,WAAW,UAAU;EAC7B;;;;;;;;;AAUF,SAAgB,2BAA2B,MAAc,QAAgC;AACxF,KAAI,CAAC,wBAAwB,IAAI,OAAO,CACvC,OAAM,IAAI,MACT,YAAY,KAAK,qEAAqE,OAAO,wBACtE,CAAC,GAAG,wBAAwB,CAAC,KAAK,KAAK,GAC9D"}
|
|
@@ -127,3 +127,4 @@ export declare function loadTextureFromUrl(url: string, options?: TextureLoadOpt
|
|
|
127
127
|
* @returns Promise resolving to loaded textures in input order.
|
|
128
128
|
*/
|
|
129
129
|
export declare function loadTexturesFromUrls(urls: string[], options?: TextureLoadOptions): Promise<LoadedTexture[]>;
|
|
130
|
+
//# sourceMappingURL=texture-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texture-loader.d.ts","sourceRoot":"","sources":["../../src/lib/core/texture-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,oBAAoB,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1C;;OAEG;IACH,gBAAgB,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC;IACtD;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC/B;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;OAEG;IACH,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;OAEG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;IACpB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC9B;;OAEG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;CACpB;AAiCD;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKpD;AA+FD;;GAEG;AACH,wBAAgB,4BAA4B,CAC3C,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC9B,MAAM,CAQR;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAO5C;AAsGD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,aAAa,CAAC,CAsExB;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACzC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,aAAa,EAAE,CAAC,CAsB1B"}
|
|
@@ -1,295 +1,231 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/lib/core/texture-loader.ts
|
|
2
|
+
var resourceCache = /* @__PURE__ */ new Map();
|
|
2
3
|
function createAbortError() {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
4
|
+
try {
|
|
5
|
+
return new DOMException("Texture request was aborted", "AbortError");
|
|
6
|
+
} catch {
|
|
7
|
+
const error = /* @__PURE__ */ new Error("Texture request was aborted");
|
|
8
|
+
error.name = "AbortError";
|
|
9
|
+
return error;
|
|
10
|
+
}
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
(error.name === 'AbortError' || error.message.toLowerCase().includes('aborted')));
|
|
13
|
+
* Checks whether error represents abort cancellation.
|
|
14
|
+
*/
|
|
15
|
+
function isAbortError(error) {
|
|
16
|
+
return error instanceof Error && (error.name === "AbortError" || error.message.toLowerCase().includes("aborted"));
|
|
18
17
|
}
|
|
19
18
|
function toBodyFingerprint(body) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
if (typeof FormData !== 'undefined' && body instanceof FormData) {
|
|
30
|
-
const entries = Array.from(body.entries()).map(([key, value]) => `${key}:${String(value)}`);
|
|
31
|
-
return `formdata:${entries.join('&')}`;
|
|
32
|
-
}
|
|
33
|
-
if (body instanceof Blob) {
|
|
34
|
-
return `blob:${body.type}:${body.size}`;
|
|
35
|
-
}
|
|
36
|
-
if (body instanceof ArrayBuffer) {
|
|
37
|
-
return `arraybuffer:${body.byteLength}`;
|
|
38
|
-
}
|
|
39
|
-
if (ArrayBuffer.isView(body)) {
|
|
40
|
-
return `view:${body.byteLength}`;
|
|
41
|
-
}
|
|
42
|
-
return `opaque:${Object.prototype.toString.call(body)}`;
|
|
19
|
+
if (body == null) return null;
|
|
20
|
+
if (typeof body === "string") return `string:${body}`;
|
|
21
|
+
if (body instanceof URLSearchParams) return `urlsearchparams:${body.toString()}`;
|
|
22
|
+
if (typeof FormData !== "undefined" && body instanceof FormData) return `formdata:${Array.from(body.entries()).map(([key, value]) => `${key}:${String(value)}`).join("&")}`;
|
|
23
|
+
if (body instanceof Blob) return `blob:${body.type}:${body.size}`;
|
|
24
|
+
if (body instanceof ArrayBuffer) return `arraybuffer:${body.byteLength}`;
|
|
25
|
+
if (ArrayBuffer.isView(body)) return `view:${body.byteLength}`;
|
|
26
|
+
return `opaque:${Object.prototype.toString.call(body)}`;
|
|
43
27
|
}
|
|
44
28
|
function normalizeRequestInit(requestInit) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
normalized.body = toBodyFingerprint(requestInit.body);
|
|
63
|
-
return normalized;
|
|
29
|
+
if (!requestInit) return {};
|
|
30
|
+
const headers = new Headers(requestInit.headers);
|
|
31
|
+
const headerEntries = Array.from(headers.entries()).sort(([a], [b]) => a.localeCompare(b));
|
|
32
|
+
const normalized = {};
|
|
33
|
+
normalized.method = (requestInit.method ?? "GET").toUpperCase();
|
|
34
|
+
normalized.mode = requestInit.mode ?? null;
|
|
35
|
+
normalized.cache = requestInit.cache ?? null;
|
|
36
|
+
normalized.credentials = requestInit.credentials ?? null;
|
|
37
|
+
normalized.redirect = requestInit.redirect ?? null;
|
|
38
|
+
normalized.referrer = requestInit.referrer ?? null;
|
|
39
|
+
normalized.referrerPolicy = requestInit.referrerPolicy ?? null;
|
|
40
|
+
normalized.integrity = requestInit.integrity ?? null;
|
|
41
|
+
normalized.keepalive = requestInit.keepalive ?? false;
|
|
42
|
+
normalized.priority = requestInit.priority ?? null;
|
|
43
|
+
normalized.headers = headerEntries;
|
|
44
|
+
normalized.body = toBodyFingerprint(requestInit.body);
|
|
45
|
+
return normalized;
|
|
64
46
|
}
|
|
65
47
|
function normalizeTextureLoadOptions(options) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
normalized.update = options.update;
|
|
83
|
-
}
|
|
84
|
-
if (options.flipY !== undefined) {
|
|
85
|
-
normalized.flipY = options.flipY;
|
|
86
|
-
}
|
|
87
|
-
if (options.premultipliedAlpha !== undefined) {
|
|
88
|
-
normalized.premultipliedAlpha = options.premultipliedAlpha;
|
|
89
|
-
}
|
|
90
|
-
if (options.generateMipmaps !== undefined) {
|
|
91
|
-
normalized.generateMipmaps = options.generateMipmaps;
|
|
92
|
-
}
|
|
93
|
-
return normalized;
|
|
48
|
+
const colorSpace = options.colorSpace ?? "srgb";
|
|
49
|
+
const normalized = {
|
|
50
|
+
colorSpace,
|
|
51
|
+
decode: {
|
|
52
|
+
colorSpaceConversion: options.decode?.colorSpaceConversion ?? (colorSpace === "linear" ? "none" : "default"),
|
|
53
|
+
premultiplyAlpha: options.decode?.premultiplyAlpha ?? "default",
|
|
54
|
+
imageOrientation: options.decode?.imageOrientation ?? "none"
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
if (options.requestInit !== void 0) normalized.requestInit = options.requestInit;
|
|
58
|
+
if (options.signal !== void 0) normalized.signal = options.signal;
|
|
59
|
+
if (options.update !== void 0) normalized.update = options.update;
|
|
60
|
+
if (options.flipY !== void 0) normalized.flipY = options.flipY;
|
|
61
|
+
if (options.premultipliedAlpha !== void 0) normalized.premultipliedAlpha = options.premultipliedAlpha;
|
|
62
|
+
if (options.generateMipmaps !== void 0) normalized.generateMipmaps = options.generateMipmaps;
|
|
63
|
+
return normalized;
|
|
94
64
|
}
|
|
95
65
|
/**
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
66
|
+
* Builds deterministic resource cache key from full URL IO config.
|
|
67
|
+
*/
|
|
68
|
+
function buildTextureResourceCacheKey(url, options = {}) {
|
|
69
|
+
const normalized = normalizeTextureLoadOptions(options);
|
|
70
|
+
return JSON.stringify({
|
|
71
|
+
url,
|
|
72
|
+
colorSpace: normalized.colorSpace,
|
|
73
|
+
requestInit: normalizeRequestInit(normalized.requestInit),
|
|
74
|
+
decode: normalized.decode
|
|
75
|
+
});
|
|
106
76
|
}
|
|
107
77
|
/**
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
entry.controller.abort();
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
resourceCache.clear();
|
|
78
|
+
* Clears the internal texture resource cache.
|
|
79
|
+
*/
|
|
80
|
+
function clearTextureBlobCache() {
|
|
81
|
+
for (const entry of resourceCache.values()) if (!entry.settled) entry.controller.abort();
|
|
82
|
+
resourceCache.clear();
|
|
117
83
|
}
|
|
118
84
|
function acquireTextureBlob(url, options) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if (released) {
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
released = true;
|
|
177
|
-
entry.refs = Math.max(0, entry.refs - 1);
|
|
178
|
-
if (entry.refs === 0) {
|
|
179
|
-
if (!entry.settled) {
|
|
180
|
-
entry.controller.abort();
|
|
181
|
-
}
|
|
182
|
-
resourceCache.delete(key);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
};
|
|
85
|
+
const key = buildTextureResourceCacheKey(url, options);
|
|
86
|
+
const existing = resourceCache.get(key);
|
|
87
|
+
if (existing) {
|
|
88
|
+
existing.refs += 1;
|
|
89
|
+
let released = false;
|
|
90
|
+
return {
|
|
91
|
+
entry: existing,
|
|
92
|
+
release: () => {
|
|
93
|
+
if (released) return;
|
|
94
|
+
released = true;
|
|
95
|
+
existing.refs = Math.max(0, existing.refs - 1);
|
|
96
|
+
if (existing.refs === 0) {
|
|
97
|
+
if (!existing.settled) existing.controller.abort();
|
|
98
|
+
resourceCache.delete(key);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const normalized = normalizeTextureLoadOptions(options);
|
|
104
|
+
const controller = new AbortController();
|
|
105
|
+
const requestInit = {
|
|
106
|
+
...normalized.requestInit ?? {},
|
|
107
|
+
signal: controller.signal
|
|
108
|
+
};
|
|
109
|
+
const entry = {
|
|
110
|
+
key,
|
|
111
|
+
refs: 1,
|
|
112
|
+
controller,
|
|
113
|
+
settled: false,
|
|
114
|
+
blobPromise: fetch(url, requestInit).then(async (response) => {
|
|
115
|
+
if (!response.ok) throw new Error(`Texture request failed (${response.status}) for ${url}`);
|
|
116
|
+
return response.blob();
|
|
117
|
+
}).then((blob) => {
|
|
118
|
+
entry.settled = true;
|
|
119
|
+
return blob;
|
|
120
|
+
}).catch((error) => {
|
|
121
|
+
resourceCache.delete(key);
|
|
122
|
+
throw error;
|
|
123
|
+
})
|
|
124
|
+
};
|
|
125
|
+
resourceCache.set(key, entry);
|
|
126
|
+
let released = false;
|
|
127
|
+
return {
|
|
128
|
+
entry,
|
|
129
|
+
release: () => {
|
|
130
|
+
if (released) return;
|
|
131
|
+
released = true;
|
|
132
|
+
entry.refs = Math.max(0, entry.refs - 1);
|
|
133
|
+
if (entry.refs === 0) {
|
|
134
|
+
if (!entry.settled) entry.controller.abort();
|
|
135
|
+
resourceCache.delete(key);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
186
139
|
}
|
|
187
140
|
async function awaitWithAbort(promise, signal) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
promise.then(resolve, reject).finally(() => {
|
|
200
|
-
signal.removeEventListener('abort', onAbort);
|
|
201
|
-
});
|
|
202
|
-
});
|
|
141
|
+
if (!signal) return promise;
|
|
142
|
+
if (signal.aborted) throw createAbortError();
|
|
143
|
+
return new Promise((resolve, reject) => {
|
|
144
|
+
const onAbort = () => {
|
|
145
|
+
reject(createAbortError());
|
|
146
|
+
};
|
|
147
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
148
|
+
promise.then(resolve, reject).finally(() => {
|
|
149
|
+
signal.removeEventListener("abort", onAbort);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
203
152
|
}
|
|
204
153
|
/**
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
if (normalized.generateMipmaps !== undefined) {
|
|
256
|
-
loaded.generateMipmaps = normalized.generateMipmaps;
|
|
257
|
-
}
|
|
258
|
-
return loaded;
|
|
259
|
-
}
|
|
260
|
-
catch (error) {
|
|
261
|
-
if (bitmap) {
|
|
262
|
-
bitmap.close();
|
|
263
|
-
}
|
|
264
|
-
throw error;
|
|
265
|
-
}
|
|
266
|
-
finally {
|
|
267
|
-
release();
|
|
268
|
-
}
|
|
154
|
+
* Loads a single texture from URL and converts it to an `ImageBitmap`.
|
|
155
|
+
*
|
|
156
|
+
* @param url - Texture URL.
|
|
157
|
+
* @param options - Loading options.
|
|
158
|
+
* @returns Loaded texture object.
|
|
159
|
+
* @throws {Error} When runtime does not support `createImageBitmap` or request fails.
|
|
160
|
+
*/
|
|
161
|
+
async function loadTextureFromUrl(url, options = {}) {
|
|
162
|
+
if (typeof createImageBitmap !== "function") throw new Error("createImageBitmap is not available in this runtime");
|
|
163
|
+
const normalized = normalizeTextureLoadOptions(options);
|
|
164
|
+
const { entry, release } = acquireTextureBlob(url, options);
|
|
165
|
+
let bitmap = null;
|
|
166
|
+
try {
|
|
167
|
+
const blob = await awaitWithAbort(entry.blobPromise, normalized.signal);
|
|
168
|
+
const bitmapOptions = {
|
|
169
|
+
colorSpaceConversion: normalized.decode.colorSpaceConversion,
|
|
170
|
+
premultiplyAlpha: normalized.decode.premultiplyAlpha,
|
|
171
|
+
imageOrientation: normalized.decode.imageOrientation
|
|
172
|
+
};
|
|
173
|
+
bitmap = bitmapOptions.colorSpaceConversion === "default" && bitmapOptions.premultiplyAlpha === "default" && bitmapOptions.imageOrientation === "none" ? await createImageBitmap(blob) : await createImageBitmap(blob, bitmapOptions);
|
|
174
|
+
if (normalized.signal?.aborted) {
|
|
175
|
+
bitmap.close();
|
|
176
|
+
throw createAbortError();
|
|
177
|
+
}
|
|
178
|
+
let disposed = false;
|
|
179
|
+
const loaded = {
|
|
180
|
+
url,
|
|
181
|
+
source: bitmap,
|
|
182
|
+
width: bitmap.width,
|
|
183
|
+
height: bitmap.height,
|
|
184
|
+
colorSpace: normalized.colorSpace,
|
|
185
|
+
dispose: () => {
|
|
186
|
+
if (disposed) return;
|
|
187
|
+
disposed = true;
|
|
188
|
+
bitmap?.close();
|
|
189
|
+
bitmap = null;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
if (normalized.update !== void 0) loaded.update = normalized.update;
|
|
193
|
+
if (normalized.flipY !== void 0) loaded.flipY = normalized.flipY;
|
|
194
|
+
if (normalized.premultipliedAlpha !== void 0) loaded.premultipliedAlpha = normalized.premultipliedAlpha;
|
|
195
|
+
if (normalized.generateMipmaps !== void 0) loaded.generateMipmaps = normalized.generateMipmaps;
|
|
196
|
+
return loaded;
|
|
197
|
+
} catch (error) {
|
|
198
|
+
if (bitmap) bitmap.close();
|
|
199
|
+
throw error;
|
|
200
|
+
} finally {
|
|
201
|
+
release();
|
|
202
|
+
}
|
|
269
203
|
}
|
|
270
204
|
/**
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
return loaded;
|
|
205
|
+
* Loads many textures in parallel from URLs.
|
|
206
|
+
*
|
|
207
|
+
* @param urls - Texture URLs.
|
|
208
|
+
* @param options - Shared loading options.
|
|
209
|
+
* @returns Promise resolving to loaded textures in input order.
|
|
210
|
+
*/
|
|
211
|
+
async function loadTexturesFromUrls(urls, options = {}) {
|
|
212
|
+
const settled = await Promise.allSettled(urls.map((url) => loadTextureFromUrl(url, options)));
|
|
213
|
+
const loaded = [];
|
|
214
|
+
let firstError = null;
|
|
215
|
+
for (const entry of settled) {
|
|
216
|
+
if (entry.status === "fulfilled") {
|
|
217
|
+
loaded.push(entry.value);
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
firstError ??= entry.reason;
|
|
221
|
+
}
|
|
222
|
+
if (firstError) {
|
|
223
|
+
for (const texture of loaded) texture.dispose();
|
|
224
|
+
throw firstError;
|
|
225
|
+
}
|
|
226
|
+
return loaded;
|
|
295
227
|
}
|
|
228
|
+
//#endregion
|
|
229
|
+
export { buildTextureResourceCacheKey, clearTextureBlobCache, isAbortError, loadTextureFromUrl, loadTexturesFromUrls };
|
|
230
|
+
|
|
231
|
+
//# sourceMappingURL=texture-loader.js.map
|