@driftengine/assets 4.8.6 → 4.8.7
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/dist/bcLoad.d.ts +4 -0
- package/dist/bcLoad.js +11 -17
- package/dist/bcWorkers.d.ts +27 -0
- package/dist/bcWorkers.js +7 -0
- package/dist/drftLoader.d.ts +8 -0
- package/dist/drftLoader.js +1 -1
- package/package.json +4 -4
- package/src/bcLoad.ts +11 -18
- package/src/bcWorkers.ts +33 -0
- package/src/drftLoader.ts +9 -2
package/dist/bcLoad.d.ts
CHANGED
|
@@ -23,4 +23,8 @@ export interface BcDecoder {
|
|
|
23
23
|
readonly reason: string;
|
|
24
24
|
dispose(): void;
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* A decoder over a worker `spawn` starts, or on the main thread where it is null — the default, since
|
|
28
|
+
* the worker's factory lives behind its own specifier (`bcWorkers.ts`) and a caller names it.
|
|
29
|
+
*/
|
|
26
30
|
export declare function createBcDecoder(spawn?: (() => BcWorker) | null): BcDecoder;
|
package/dist/bcLoad.js
CHANGED
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
* otherwise**, which on a phone is every BC texture: in a worker, because a 2048² BC7 image is
|
|
9
9
|
* 262,144 blocks and a phone's main thread spends the better part of a second on them.
|
|
10
10
|
*
|
|
11
|
-
* **Never silently slower.** Where
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* **Never silently slower.** Where no worker is named (`spawnBcWorker`, behind a specifier of its
|
|
12
|
+
* own so the barrel names none), where there is no `Worker`, or where the one started fails to load —
|
|
13
|
+
* a bundler that does not understand `new Worker(new URL(…))` — the decode moves to the main thread
|
|
14
|
+
* and `reason` says so, and the loader prints it once. A request in flight when the worker fails is
|
|
15
|
+
* decoded again there rather than left waiting.
|
|
15
16
|
*/
|
|
16
17
|
import { uploadsCompressed } from '@driftengine/core';
|
|
17
18
|
import { answerBcRequest } from './bcAnswer.js';
|
|
@@ -36,19 +37,10 @@ function settle(reply, pending) {
|
|
|
36
37
|
pending.reject(new Error(reply.error ?? 'bc: the decode answered nothing'));
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
40
|
+
* A decoder over a worker `spawn` starts, or on the main thread where it is null — the default, since
|
|
41
|
+
* the worker's factory lives behind its own specifier (`bcWorkers.ts`) and a caller names it.
|
|
41
42
|
*/
|
|
42
|
-
|
|
43
|
-
// platform: feature probe — no `Worker` means BC decodes on the main thread, with a reason
|
|
44
|
-
typeof Worker === 'undefined'
|
|
45
|
-
? null
|
|
46
|
-
: () =>
|
|
47
|
-
// platform: browser default — `createBcDecoder(spawn)` is the seam a host supplies
|
|
48
|
-
new Worker(new URL('./bcWorker.js', import.meta.url), {
|
|
49
|
-
type: 'module',
|
|
50
|
-
});
|
|
51
|
-
export function createBcDecoder(spawn = defaultSpawn) {
|
|
43
|
+
export function createBcDecoder(spawn = null) {
|
|
52
44
|
let worker = null;
|
|
53
45
|
let reason = '';
|
|
54
46
|
const pending = new Map();
|
|
@@ -62,7 +54,9 @@ export function createBcDecoder(spawn = defaultSpawn) {
|
|
|
62
54
|
pending.clear();
|
|
63
55
|
};
|
|
64
56
|
if (spawn === null) {
|
|
65
|
-
reason =
|
|
57
|
+
reason =
|
|
58
|
+
'BC textures decode on the main thread: no worker was named. Pass `bcWorker: spawnBcWorker`, ' +
|
|
59
|
+
'exported by @driftengine/assets/src/bcWorkers.ts, to decode them off it';
|
|
66
60
|
}
|
|
67
61
|
else {
|
|
68
62
|
try {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The BC decode worker, behind its own specifier, for the reason `physics/src/workers.ts` gives.
|
|
3
|
+
*
|
|
4
|
+
* **A bundler emits a worker before it decides the code reaching it is unreachable.** The loader's
|
|
5
|
+
* decoder built its worker with `new Worker(new URL('./bcWorker.ts', import.meta.url))` inside the
|
|
6
|
+
* barrel's graph, and Vite rewrites that at transform time, before tree-shaking, so every consumer
|
|
7
|
+
* importing anything from `@driftengine/assets` had the BC decoder's chunk written into its build,
|
|
8
|
+
* whether or not it ever loaded a BC texture. It did so from 4.8.4 to 4.8.6;
|
|
9
|
+
* `scripts/worker-entry.test.mjs` asserts that no barrel names a worker, and it skipped this barrel
|
|
10
|
+
* whenever the packages were not built, which is how the chunk shipped past it.
|
|
11
|
+
*
|
|
12
|
+
* So a loader that should decode BC off the main thread names the factory:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { DrftLoader } from '@driftengine/assets';
|
|
16
|
+
* import { spawnBcWorker } from '@driftengine/assets/src/bcWorkers.ts';
|
|
17
|
+
*
|
|
18
|
+
* const loader = new DrftLoader(renderer, { bcWorker: spawnBcWorker });
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Without it BC textures decode on the main thread, and the loader says so once. **What that costs**
|
|
22
|
+
* is the decode of a texture the device cannot take as blocks, which on a phone is every BC texture:
|
|
23
|
+
* a 2048² BC7 image is 262,144 blocks.
|
|
24
|
+
*/
|
|
25
|
+
import type { BcWorker } from './bcLoad.ts';
|
|
26
|
+
/** A BC decode worker, as a bundler understands one. Throws where the runtime has no `Worker`. */
|
|
27
|
+
export declare function spawnBcWorker(): BcWorker;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** A BC decode worker, as a bundler understands one. Throws where the runtime has no `Worker`. */
|
|
2
|
+
export function spawnBcWorker() {
|
|
3
|
+
// platform: browser default — `DrftLoaderOptions.bcWorker` is the seam a host supplies
|
|
4
|
+
return new Worker(new URL('./bcWorker.js', import.meta.url), {
|
|
5
|
+
type: 'module',
|
|
6
|
+
});
|
|
7
|
+
}
|
package/dist/drftLoader.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { SurfaceTextureHandle } from '@driftengine/core';
|
|
|
5
5
|
import type { DrftMaterial } from '@driftengine/drft';
|
|
6
6
|
import type { DrftFieldPlacement } from './fieldPlacement.ts';
|
|
7
7
|
import { TextureSet } from './drftTextures.ts';
|
|
8
|
+
import type { BcWorker } from './bcLoad.ts';
|
|
8
9
|
import type { DrawSurfaceOverride } from './drawKey.ts';
|
|
9
10
|
import type { AnimationClip, DrftLight, DrftMorph, DrftNode, DrftSkin } from '@driftengine/drft';
|
|
10
11
|
import type { DrftLightVolume, EntsScene, NavPolyMesh } from '@driftengine/drft';
|
|
@@ -48,6 +49,13 @@ export interface DrftLoaderOptions {
|
|
|
48
49
|
* the default.
|
|
49
50
|
*/
|
|
50
51
|
readonly fetchImpl?: FetchLike;
|
|
52
|
+
/**
|
|
53
|
+
* What starts the worker a BC texture the device cannot take as blocks is decoded in:
|
|
54
|
+
* `spawnBcWorker`, from `@driftengine/assets/src/bcWorkers.ts`. Absent, they decode on the main
|
|
55
|
+
* thread and the loader says so once — the factory is behind its own specifier so a consumer that
|
|
56
|
+
* never names it has no worker in its build. See `bcWorkers.ts`.
|
|
57
|
+
*/
|
|
58
|
+
readonly bcWorker?: () => BcWorker;
|
|
51
59
|
/**
|
|
52
60
|
* The most parts one `update` may take, however cheap they turn out to be.
|
|
53
61
|
*
|
package/dist/drftLoader.js
CHANGED
|
@@ -1251,7 +1251,7 @@ export class DrftLoader {
|
|
|
1251
1251
|
return;
|
|
1252
1252
|
}
|
|
1253
1253
|
if (this.bcDecoder === null)
|
|
1254
|
-
this.bcDecoder = createBcDecoder();
|
|
1254
|
+
this.bcDecoder = createBcDecoder(this.options.bcWorker ?? null);
|
|
1255
1255
|
const decoder = this.bcDecoder;
|
|
1256
1256
|
decoder
|
|
1257
1257
|
.decode(image, asImage)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@driftengine/assets",
|
|
3
|
-
"version": "4.8.
|
|
3
|
+
"version": "4.8.7",
|
|
4
4
|
"description": "Model readers and the streaming loader for the .drft container",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
],
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@driftengine/drft": "4.8.
|
|
31
|
-
"@driftengine/texture": "4.8.
|
|
30
|
+
"@driftengine/drft": "4.8.7",
|
|
31
|
+
"@driftengine/texture": "4.8.7"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@driftengine/core": "4.8.
|
|
34
|
+
"@driftengine/core": "4.8.7"
|
|
35
35
|
},
|
|
36
36
|
"author": "Drift Technologies",
|
|
37
37
|
"repository": {
|
package/src/bcLoad.ts
CHANGED
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
* otherwise**, which on a phone is every BC texture: in a worker, because a 2048² BC7 image is
|
|
9
9
|
* 262,144 blocks and a phone's main thread spends the better part of a second on them.
|
|
10
10
|
*
|
|
11
|
-
* **Never silently slower.** Where
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* **Never silently slower.** Where no worker is named (`spawnBcWorker`, behind a specifier of its
|
|
12
|
+
* own so the barrel names none), where there is no `Worker`, or where the one started fails to load —
|
|
13
|
+
* a bundler that does not understand `new Worker(new URL(…))` — the decode moves to the main thread
|
|
14
|
+
* and `reason` says so, and the loader prints it once. A request in flight when the worker fails is
|
|
15
|
+
* decoded again there rather than left waiting.
|
|
15
16
|
*/
|
|
16
17
|
import { uploadsCompressed } from '@driftengine/core';
|
|
17
18
|
import type { CompressedTextureFormat } from '@driftengine/core';
|
|
@@ -74,20 +75,10 @@ function settle(reply: BcReply, pending: Pending): void {
|
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
78
|
+
* A decoder over a worker `spawn` starts, or on the main thread where it is null — the default, since
|
|
79
|
+
* the worker's factory lives behind its own specifier (`bcWorkers.ts`) and a caller names it.
|
|
79
80
|
*/
|
|
80
|
-
|
|
81
|
-
// platform: feature probe — no `Worker` means BC decodes on the main thread, with a reason
|
|
82
|
-
typeof Worker === 'undefined'
|
|
83
|
-
? null
|
|
84
|
-
: (): BcWorker =>
|
|
85
|
-
// platform: browser default — `createBcDecoder(spawn)` is the seam a host supplies
|
|
86
|
-
new Worker(new URL('./bcWorker.ts', import.meta.url), {
|
|
87
|
-
type: 'module',
|
|
88
|
-
}) as unknown as BcWorker;
|
|
89
|
-
|
|
90
|
-
export function createBcDecoder(spawn: (() => BcWorker) | null = defaultSpawn): BcDecoder {
|
|
81
|
+
export function createBcDecoder(spawn: (() => BcWorker) | null = null): BcDecoder {
|
|
91
82
|
let worker: BcWorker | null = null;
|
|
92
83
|
let reason = '';
|
|
93
84
|
const pending = new Map<number, Pending>();
|
|
@@ -103,7 +94,9 @@ export function createBcDecoder(spawn: (() => BcWorker) | null = defaultSpawn):
|
|
|
103
94
|
};
|
|
104
95
|
|
|
105
96
|
if (spawn === null) {
|
|
106
|
-
reason =
|
|
97
|
+
reason =
|
|
98
|
+
'BC textures decode on the main thread: no worker was named. Pass `bcWorker: spawnBcWorker`, ' +
|
|
99
|
+
'exported by @driftengine/assets/src/bcWorkers.ts, to decode them off it';
|
|
107
100
|
} else {
|
|
108
101
|
try {
|
|
109
102
|
worker = spawn();
|
package/src/bcWorkers.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The BC decode worker, behind its own specifier, for the reason `physics/src/workers.ts` gives.
|
|
3
|
+
*
|
|
4
|
+
* **A bundler emits a worker before it decides the code reaching it is unreachable.** The loader's
|
|
5
|
+
* decoder built its worker with `new Worker(new URL('./bcWorker.ts', import.meta.url))` inside the
|
|
6
|
+
* barrel's graph, and Vite rewrites that at transform time, before tree-shaking, so every consumer
|
|
7
|
+
* importing anything from `@driftengine/assets` had the BC decoder's chunk written into its build,
|
|
8
|
+
* whether or not it ever loaded a BC texture. It did so from 4.8.4 to 4.8.6;
|
|
9
|
+
* `scripts/worker-entry.test.mjs` asserts that no barrel names a worker, and it skipped this barrel
|
|
10
|
+
* whenever the packages were not built, which is how the chunk shipped past it.
|
|
11
|
+
*
|
|
12
|
+
* So a loader that should decode BC off the main thread names the factory:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { DrftLoader } from '@driftengine/assets';
|
|
16
|
+
* import { spawnBcWorker } from '@driftengine/assets/src/bcWorkers.ts';
|
|
17
|
+
*
|
|
18
|
+
* const loader = new DrftLoader(renderer, { bcWorker: spawnBcWorker });
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Without it BC textures decode on the main thread, and the loader says so once. **What that costs**
|
|
22
|
+
* is the decode of a texture the device cannot take as blocks, which on a phone is every BC texture:
|
|
23
|
+
* a 2048² BC7 image is 262,144 blocks.
|
|
24
|
+
*/
|
|
25
|
+
import type { BcWorker } from './bcLoad.ts';
|
|
26
|
+
|
|
27
|
+
/** A BC decode worker, as a bundler understands one. Throws where the runtime has no `Worker`. */
|
|
28
|
+
export function spawnBcWorker(): BcWorker {
|
|
29
|
+
// platform: browser default — `DrftLoaderOptions.bcWorker` is the seam a host supplies
|
|
30
|
+
return new Worker(new URL('./bcWorker.ts', import.meta.url), {
|
|
31
|
+
type: 'module',
|
|
32
|
+
}) as unknown as BcWorker;
|
|
33
|
+
}
|
package/src/drftLoader.ts
CHANGED
|
@@ -11,7 +11,7 @@ import type { DrftFieldPlacement } from './fieldPlacement.ts';
|
|
|
11
11
|
import type { DrftTexture } from '@driftengine/drft';
|
|
12
12
|
import { TextureSet, textureColorSpaces } from './drftTextures.ts';
|
|
13
13
|
import { bcPlan, createBcDecoder } from './bcLoad.ts';
|
|
14
|
-
import type { BcDecoder } from './bcLoad.ts';
|
|
14
|
+
import type { BcDecoder, BcWorker } from './bcLoad.ts';
|
|
15
15
|
import { decodeBc } from './bcDecode.ts';
|
|
16
16
|
import { isCompressedSource, uploadsCompressed } from '@driftengine/core';
|
|
17
17
|
import { CODEC_BC, codecName, readBcPayload } from '@driftengine/drft';
|
|
@@ -82,6 +82,13 @@ export interface DrftLoaderOptions {
|
|
|
82
82
|
* the default.
|
|
83
83
|
*/
|
|
84
84
|
readonly fetchImpl?: FetchLike;
|
|
85
|
+
/**
|
|
86
|
+
* What starts the worker a BC texture the device cannot take as blocks is decoded in:
|
|
87
|
+
* `spawnBcWorker`, from `@driftengine/assets/src/bcWorkers.ts`. Absent, they decode on the main
|
|
88
|
+
* thread and the loader says so once — the factory is behind its own specifier so a consumer that
|
|
89
|
+
* never names it has no worker in its build. See `bcWorkers.ts`.
|
|
90
|
+
*/
|
|
91
|
+
readonly bcWorker?: () => BcWorker;
|
|
85
92
|
/**
|
|
86
93
|
* The most parts one `update` may take, however cheap they turn out to be.
|
|
87
94
|
*
|
|
@@ -1523,7 +1530,7 @@ export class DrftLoader {
|
|
|
1523
1530
|
done(image);
|
|
1524
1531
|
return;
|
|
1525
1532
|
}
|
|
1526
|
-
if (this.bcDecoder === null) this.bcDecoder = createBcDecoder();
|
|
1533
|
+
if (this.bcDecoder === null) this.bcDecoder = createBcDecoder(this.options.bcWorker ?? null);
|
|
1527
1534
|
const decoder = this.bcDecoder;
|
|
1528
1535
|
decoder
|
|
1529
1536
|
.decode(image, asImage)
|