@plasius/gpu-worker 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -1
- package/README.md +41 -0
- package/dist/index.cjs +314 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +311 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.js +379 -0
package/CHANGELOG.md
CHANGED
|
@@ -20,6 +20,47 @@ The format is based on **[Keep a Changelog](https://keepachangelog.com/en/1.1.0/
|
|
|
20
20
|
- **Security**
|
|
21
21
|
- (placeholder)
|
|
22
22
|
|
|
23
|
+
## [0.1.11] - 2026-03-15
|
|
24
|
+
|
|
25
|
+
- **Added**
|
|
26
|
+
- ADR, TDR, and test-first planning coverage for snapshot-driven
|
|
27
|
+
scene-preparation DAG manifests in the ray-tracing-first world pipeline.
|
|
28
|
+
- Added `createScenePreparationManifest(...)` plus scene-preparation
|
|
29
|
+
representation-band and stage-family exports for snapshot-driven chunk DAG
|
|
30
|
+
planning.
|
|
31
|
+
- Added contract tests covering stable snapshot roots, multi-chunk priority
|
|
32
|
+
lanes, local joins, and render-preparation safety guards.
|
|
33
|
+
|
|
34
|
+
- **Changed**
|
|
35
|
+
- TDR-0004 now reflects the implemented scene-preparation manifest helper.
|
|
36
|
+
|
|
37
|
+
- **Fixed**
|
|
38
|
+
- (placeholder)
|
|
39
|
+
|
|
40
|
+
- **Security**
|
|
41
|
+
- (placeholder)
|
|
42
|
+
|
|
43
|
+
## [0.1.10] - 2026-03-14
|
|
44
|
+
|
|
45
|
+
- **Added**
|
|
46
|
+
- (placeholder)
|
|
47
|
+
|
|
48
|
+
- **Changed**
|
|
49
|
+
- DAG queue guidance now treats package manifests as explicit multi-root DAG
|
|
50
|
+
node definitions with priority-lane mapping, rather than loose dependency
|
|
51
|
+
hints.
|
|
52
|
+
- Raised the minimum `@plasius/gpu-lock-free-queue` dependency to `^0.2.14`
|
|
53
|
+
so published installs resolve the new DAG graph metadata through npm.
|
|
54
|
+
- Updated GitHub Actions workflows to run JavaScript actions on Node 24,
|
|
55
|
+
refreshed core workflow action versions, and switched Codecov uploads to
|
|
56
|
+
the Codecov CLI.
|
|
57
|
+
|
|
58
|
+
- **Fixed**
|
|
59
|
+
- (placeholder)
|
|
60
|
+
|
|
61
|
+
- **Security**
|
|
62
|
+
- (placeholder)
|
|
63
|
+
|
|
23
64
|
## [0.1.9] - 2026-03-13
|
|
24
65
|
|
|
25
66
|
- **Added**
|
|
@@ -189,7 +230,7 @@ The format is based on **[Keep a Changelog](https://keepachangelog.com/en/1.1.0/
|
|
|
189
230
|
|
|
190
231
|
---
|
|
191
232
|
|
|
192
|
-
[Unreleased]: https://github.com/Plasius-LTD/gpu-worker/compare/v0.1.
|
|
233
|
+
[Unreleased]: https://github.com/Plasius-LTD/gpu-worker/compare/v0.1.11...HEAD
|
|
193
234
|
[0.1.0-beta.1]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.0-beta.1
|
|
194
235
|
[0.1.0]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.0
|
|
195
236
|
[0.1.2]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.2
|
|
@@ -211,3 +252,5 @@ The format is based on **[Keep a Changelog](https://keepachangelog.com/en/1.1.0/
|
|
|
211
252
|
[0.1.4]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.4
|
|
212
253
|
[0.1.8]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.8
|
|
213
254
|
[0.1.9]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.9
|
|
255
|
+
[0.1.10]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.10
|
|
256
|
+
[0.1.11]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.11
|
package/README.md
CHANGED
|
@@ -158,6 +158,39 @@ const loop = createWorkerLoop({
|
|
|
158
158
|
});
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
+
`@plasius/gpu-worker` also now exposes a scene-preparation manifest helper for
|
|
162
|
+
snapshot-driven chunk DAG planning:
|
|
163
|
+
|
|
164
|
+
```js
|
|
165
|
+
import { createScenePreparationManifest } from "@plasius/gpu-worker";
|
|
166
|
+
|
|
167
|
+
const manifest = createScenePreparationManifest({
|
|
168
|
+
snapshotId: "visual-snapshot-42",
|
|
169
|
+
chunks: [
|
|
170
|
+
{
|
|
171
|
+
chunkId: "chunk-near-0",
|
|
172
|
+
representationBand: "near",
|
|
173
|
+
gameplayImportance: "critical",
|
|
174
|
+
visible: true,
|
|
175
|
+
playerRelevant: true,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
chunkId: "chunk-far-3",
|
|
179
|
+
representationBand: "far",
|
|
180
|
+
gameplayImportance: "medium",
|
|
181
|
+
visible: false,
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
console.log(manifest.graph.chunkRoots);
|
|
187
|
+
console.log(manifest.graph.priorityLanes[0]);
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The helper publishes one chunk-local DAG per stable snapshot, keeps joins local
|
|
191
|
+
to chunk stage boundaries, and rejects render-preparation manifests that try to
|
|
192
|
+
mutate authoritative simulation state.
|
|
193
|
+
|
|
161
194
|
## What this is
|
|
162
195
|
- A minimal GPU worker layer that combines a lock-free queue with user WGSL jobs.
|
|
163
196
|
- A helper to assemble WGSL modules with queue helpers included.
|
|
@@ -176,6 +209,14 @@ budgets or decide priorities itself. Instead it exposes the queue mode and the
|
|
|
176
209
|
completion hook needed by package manifests and `@plasius/gpu-performance` to
|
|
177
210
|
coordinate DAG-shaped workloads.
|
|
178
211
|
|
|
212
|
+
Package manifests should be treated as explicit DAG node definitions, not just
|
|
213
|
+
loose hints. In practice that means:
|
|
214
|
+
|
|
215
|
+
- multiple roots are allowed and expected,
|
|
216
|
+
- manifest labels act as dependency ids,
|
|
217
|
+
- priorities map to ready-queue lanes,
|
|
218
|
+
- downstream jobs are unlocked only when every upstream dependency completes.
|
|
219
|
+
|
|
179
220
|
## Package Integration Model
|
|
180
221
|
|
|
181
222
|
`@plasius/gpu-worker` is the preferred execution plane for discrete GPU work
|
package/dist/index.cjs
CHANGED
|
@@ -30,10 +30,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
32
|
assembleWorkerWgsl: () => assembleWorkerWgsl,
|
|
33
|
+
createScenePreparationManifest: () => createScenePreparationManifest,
|
|
33
34
|
createWorkerLoop: () => createWorkerLoop,
|
|
34
35
|
loadJobWgsl: () => loadJobWgsl,
|
|
35
36
|
loadQueueWgsl: () => loadQueueWgsl,
|
|
36
37
|
loadWorkerWgsl: () => loadWorkerWgsl,
|
|
38
|
+
scenePreparationRepresentationBands: () => scenePreparationRepresentationBands,
|
|
39
|
+
scenePreparationStageFamilies: () => scenePreparationStageFamilies,
|
|
37
40
|
workerWgslUrl: () => workerWgslUrl
|
|
38
41
|
});
|
|
39
42
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -693,13 +696,324 @@ function createWorkerLoop(options = {}) {
|
|
|
693
696
|
}
|
|
694
697
|
};
|
|
695
698
|
}
|
|
699
|
+
var scenePreparationRepresentationBands = Object.freeze([
|
|
700
|
+
"near",
|
|
701
|
+
"mid",
|
|
702
|
+
"far",
|
|
703
|
+
"horizon"
|
|
704
|
+
]);
|
|
705
|
+
var scenePreparationStageFamilies = Object.freeze([
|
|
706
|
+
"snapshotSelection",
|
|
707
|
+
"transformPropagation",
|
|
708
|
+
"animationPose",
|
|
709
|
+
"proceduralAnimation",
|
|
710
|
+
"skinningOrDeformation",
|
|
711
|
+
"boundsUpdate",
|
|
712
|
+
"lodSelection",
|
|
713
|
+
"rtRepresentationSelection",
|
|
714
|
+
"visibility",
|
|
715
|
+
"lightAssignment",
|
|
716
|
+
"renderProxyBuild",
|
|
717
|
+
"rtInstancePreparation"
|
|
718
|
+
]);
|
|
719
|
+
var scenePreparationDefaultStageDependencies = Object.freeze({
|
|
720
|
+
snapshotSelection: Object.freeze([]),
|
|
721
|
+
transformPropagation: Object.freeze(["snapshotSelection"]),
|
|
722
|
+
animationPose: Object.freeze(["transformPropagation"]),
|
|
723
|
+
proceduralAnimation: Object.freeze(["animationPose"]),
|
|
724
|
+
skinningOrDeformation: Object.freeze([
|
|
725
|
+
"animationPose",
|
|
726
|
+
"proceduralAnimation"
|
|
727
|
+
]),
|
|
728
|
+
boundsUpdate: Object.freeze(["skinningOrDeformation"]),
|
|
729
|
+
lodSelection: Object.freeze(["boundsUpdate"]),
|
|
730
|
+
rtRepresentationSelection: Object.freeze(["lodSelection"]),
|
|
731
|
+
visibility: Object.freeze(["boundsUpdate", "lodSelection"]),
|
|
732
|
+
lightAssignment: Object.freeze(["visibility"]),
|
|
733
|
+
renderProxyBuild: Object.freeze(["visibility", "lodSelection"]),
|
|
734
|
+
rtInstancePreparation: Object.freeze([
|
|
735
|
+
"visibility",
|
|
736
|
+
"rtRepresentationSelection"
|
|
737
|
+
])
|
|
738
|
+
});
|
|
739
|
+
var scenePreparationBandPriorityWeights = Object.freeze({
|
|
740
|
+
near: 400,
|
|
741
|
+
mid: 300,
|
|
742
|
+
far: 200,
|
|
743
|
+
horizon: 100
|
|
744
|
+
});
|
|
745
|
+
var scenePreparationImportanceWeights = Object.freeze({
|
|
746
|
+
low: 0,
|
|
747
|
+
medium: 15,
|
|
748
|
+
high: 30,
|
|
749
|
+
critical: 60
|
|
750
|
+
});
|
|
751
|
+
var scenePreparationStagePriorityWeights = Object.freeze({
|
|
752
|
+
snapshotSelection: 60,
|
|
753
|
+
transformPropagation: 54,
|
|
754
|
+
animationPose: 50,
|
|
755
|
+
proceduralAnimation: 46,
|
|
756
|
+
skinningOrDeformation: 42,
|
|
757
|
+
boundsUpdate: 38,
|
|
758
|
+
lodSelection: 32,
|
|
759
|
+
rtRepresentationSelection: 28,
|
|
760
|
+
visibility: 34,
|
|
761
|
+
lightAssignment: 24,
|
|
762
|
+
renderProxyBuild: 22,
|
|
763
|
+
rtInstancePreparation: 26
|
|
764
|
+
});
|
|
765
|
+
function assertScenePreparationIdentifier(name, value) {
|
|
766
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
767
|
+
throw new Error(`${name} must be a non-empty string.`);
|
|
768
|
+
}
|
|
769
|
+
return value.trim();
|
|
770
|
+
}
|
|
771
|
+
function assertScenePreparationEnum(name, value, allowed) {
|
|
772
|
+
const normalized = assertScenePreparationIdentifier(name, value);
|
|
773
|
+
if (!allowed.includes(normalized)) {
|
|
774
|
+
throw new Error(`${name} must be one of: ${allowed.join(", ")}.`);
|
|
775
|
+
}
|
|
776
|
+
return normalized;
|
|
777
|
+
}
|
|
778
|
+
function normalizeScenePreparationStages(stages, chunkLabel) {
|
|
779
|
+
const requested = stages === void 0 ? scenePreparationStageFamilies : stages;
|
|
780
|
+
if (!Array.isArray(requested) || requested.length === 0) {
|
|
781
|
+
throw new Error(`${chunkLabel}.stages must be a non-empty array when provided.`);
|
|
782
|
+
}
|
|
783
|
+
const normalized = [...new Set(
|
|
784
|
+
requested.map(
|
|
785
|
+
(stage, index) => assertScenePreparationEnum(
|
|
786
|
+
`${chunkLabel}.stages[${index}]`,
|
|
787
|
+
stage,
|
|
788
|
+
scenePreparationStageFamilies
|
|
789
|
+
)
|
|
790
|
+
)
|
|
791
|
+
)];
|
|
792
|
+
return normalized.sort(
|
|
793
|
+
(left, right) => scenePreparationStageFamilies.indexOf(left) - scenePreparationStageFamilies.indexOf(right)
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
function collectScenePreparationDependencies(stageFamily, includedStages, seen = /* @__PURE__ */ new Set()) {
|
|
797
|
+
const dependencies = scenePreparationDefaultStageDependencies[stageFamily] ?? [];
|
|
798
|
+
for (const dependency of dependencies) {
|
|
799
|
+
if (includedStages.has(dependency)) {
|
|
800
|
+
seen.add(dependency);
|
|
801
|
+
continue;
|
|
802
|
+
}
|
|
803
|
+
collectScenePreparationDependencies(dependency, includedStages, seen);
|
|
804
|
+
}
|
|
805
|
+
return [...seen].sort(
|
|
806
|
+
(left, right) => scenePreparationStageFamilies.indexOf(left) - scenePreparationStageFamilies.indexOf(right)
|
|
807
|
+
);
|
|
808
|
+
}
|
|
809
|
+
function buildScenePreparationPriority(chunk, stageFamily) {
|
|
810
|
+
const bandWeight = scenePreparationBandPriorityWeights[chunk.representationBand] ?? 0;
|
|
811
|
+
const importanceWeight = scenePreparationImportanceWeights[chunk.gameplayImportance] ?? 0;
|
|
812
|
+
const stageWeight = scenePreparationStagePriorityWeights[stageFamily] ?? 0;
|
|
813
|
+
return bandWeight + importanceWeight + stageWeight + (chunk.visible ? 20 : 0) + (chunk.playerRelevant ? 20 : 0) + (chunk.imageCritical ? 15 : 0);
|
|
814
|
+
}
|
|
815
|
+
function buildScenePreparationPriorityLanes(jobs) {
|
|
816
|
+
const lanes = /* @__PURE__ */ new Map();
|
|
817
|
+
for (const job of jobs) {
|
|
818
|
+
const lane = lanes.get(job.priority) ?? {
|
|
819
|
+
priority: job.priority,
|
|
820
|
+
jobIds: [],
|
|
821
|
+
chunkIds: []
|
|
822
|
+
};
|
|
823
|
+
lane.jobIds.push(job.id);
|
|
824
|
+
if (!lane.chunkIds.includes(job.chunkId)) {
|
|
825
|
+
lane.chunkIds.push(job.chunkId);
|
|
826
|
+
}
|
|
827
|
+
lanes.set(job.priority, lane);
|
|
828
|
+
}
|
|
829
|
+
return Object.freeze(
|
|
830
|
+
[...lanes.values()].sort((left, right) => right.priority - left.priority).map(
|
|
831
|
+
(lane) => Object.freeze({
|
|
832
|
+
priority: lane.priority,
|
|
833
|
+
jobIds: Object.freeze([...lane.jobIds]),
|
|
834
|
+
chunkIds: Object.freeze([...lane.chunkIds]),
|
|
835
|
+
jobCount: lane.jobIds.length
|
|
836
|
+
})
|
|
837
|
+
)
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
function buildScenePreparationTopologicalOrder(jobs) {
|
|
841
|
+
const indegree = new Map(jobs.map((job) => [job.id, job.dependencies.length]));
|
|
842
|
+
const dependentsById = new Map(jobs.map((job) => [job.id, []]));
|
|
843
|
+
for (const job of jobs) {
|
|
844
|
+
for (const dependency of job.dependencies) {
|
|
845
|
+
dependentsById.get(dependency)?.push(job.id);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
const queue = jobs.filter((job) => job.dependencies.length === 0).sort((left, right) => right.priority - left.priority).map((job) => job.id);
|
|
849
|
+
const jobById = new Map(jobs.map((job) => [job.id, job]));
|
|
850
|
+
const order = [];
|
|
851
|
+
while (queue.length > 0) {
|
|
852
|
+
const currentId = queue.shift();
|
|
853
|
+
if (!currentId) {
|
|
854
|
+
continue;
|
|
855
|
+
}
|
|
856
|
+
order.push(currentId);
|
|
857
|
+
const unlocked = [];
|
|
858
|
+
for (const dependentId of dependentsById.get(currentId) ?? []) {
|
|
859
|
+
const next = (indegree.get(dependentId) ?? 0) - 1;
|
|
860
|
+
indegree.set(dependentId, next);
|
|
861
|
+
if (next === 0) {
|
|
862
|
+
unlocked.push(dependentId);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
unlocked.sort(
|
|
866
|
+
(left, right) => (jobById.get(right)?.priority ?? 0) - (jobById.get(left)?.priority ?? 0)
|
|
867
|
+
).forEach((jobId) => {
|
|
868
|
+
queue.push(jobId);
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
if (order.length !== jobs.length) {
|
|
872
|
+
throw new Error("Scene-preparation manifest contains a cycle.");
|
|
873
|
+
}
|
|
874
|
+
return Object.freeze(order);
|
|
875
|
+
}
|
|
876
|
+
function createScenePreparationManifest(options = {}) {
|
|
877
|
+
const snapshotId = assertScenePreparationIdentifier(
|
|
878
|
+
"snapshotId",
|
|
879
|
+
options.snapshotId
|
|
880
|
+
);
|
|
881
|
+
const chunkEntries = Array.isArray(options.chunks) ? options.chunks : [];
|
|
882
|
+
if (chunkEntries.length === 0) {
|
|
883
|
+
throw new Error("createScenePreparationManifest requires at least one chunk.");
|
|
884
|
+
}
|
|
885
|
+
const normalizedChunks = chunkEntries.map((chunk, index) => {
|
|
886
|
+
if (!chunk || typeof chunk !== "object" || Array.isArray(chunk)) {
|
|
887
|
+
throw new Error(`chunks[${index}] must be an object.`);
|
|
888
|
+
}
|
|
889
|
+
const chunkLabel = `chunks[${index}]`;
|
|
890
|
+
if (chunk.mutatesSimulation === true) {
|
|
891
|
+
throw new Error(
|
|
892
|
+
`${chunkLabel}.mutatesSimulation cannot be true for render preparation.`
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
return Object.freeze({
|
|
896
|
+
chunkId: assertScenePreparationIdentifier(`${chunkLabel}.chunkId`, chunk.chunkId),
|
|
897
|
+
representationBand: assertScenePreparationEnum(
|
|
898
|
+
`${chunkLabel}.representationBand`,
|
|
899
|
+
chunk.representationBand ?? "mid",
|
|
900
|
+
scenePreparationRepresentationBands
|
|
901
|
+
),
|
|
902
|
+
gameplayImportance: assertScenePreparationEnum(
|
|
903
|
+
`${chunkLabel}.gameplayImportance`,
|
|
904
|
+
chunk.gameplayImportance ?? "medium",
|
|
905
|
+
Object.keys(scenePreparationImportanceWeights)
|
|
906
|
+
),
|
|
907
|
+
visible: chunk.visible !== false,
|
|
908
|
+
playerRelevant: chunk.playerRelevant === true,
|
|
909
|
+
imageCritical: chunk.imageCritical === true,
|
|
910
|
+
stages: normalizeScenePreparationStages(chunk.stages, chunkLabel)
|
|
911
|
+
});
|
|
912
|
+
});
|
|
913
|
+
const chunkIds = /* @__PURE__ */ new Set();
|
|
914
|
+
for (const chunk of normalizedChunks) {
|
|
915
|
+
if (chunkIds.has(chunk.chunkId)) {
|
|
916
|
+
throw new Error(`Duplicate scene-preparation chunk id detected: ${chunk.chunkId}`);
|
|
917
|
+
}
|
|
918
|
+
chunkIds.add(chunk.chunkId);
|
|
919
|
+
}
|
|
920
|
+
const jobs = [];
|
|
921
|
+
for (const chunk of normalizedChunks) {
|
|
922
|
+
const includedStages = new Set(chunk.stages);
|
|
923
|
+
for (const stageFamily of chunk.stages) {
|
|
924
|
+
const dependencies = collectScenePreparationDependencies(
|
|
925
|
+
stageFamily,
|
|
926
|
+
includedStages
|
|
927
|
+
).map(
|
|
928
|
+
(dependency) => `${snapshotId}:${chunk.chunkId}:${chunk.representationBand}:${dependency}`
|
|
929
|
+
);
|
|
930
|
+
jobs.push(
|
|
931
|
+
Object.freeze({
|
|
932
|
+
id: `${snapshotId}:${chunk.chunkId}:${chunk.representationBand}:${stageFamily}`,
|
|
933
|
+
snapshotId,
|
|
934
|
+
chunkId: chunk.chunkId,
|
|
935
|
+
representationBand: chunk.representationBand,
|
|
936
|
+
stageFamily,
|
|
937
|
+
priority: buildScenePreparationPriority(chunk, stageFamily),
|
|
938
|
+
dependencies: Object.freeze(dependencies),
|
|
939
|
+
dependencyCount: dependencies.length,
|
|
940
|
+
root: dependencies.length === 0,
|
|
941
|
+
authority: "visual",
|
|
942
|
+
mutatesSimulation: false,
|
|
943
|
+
gameplayImportance: chunk.gameplayImportance,
|
|
944
|
+
visible: chunk.visible,
|
|
945
|
+
playerRelevant: chunk.playerRelevant,
|
|
946
|
+
imageCritical: chunk.imageCritical
|
|
947
|
+
})
|
|
948
|
+
);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
const jobById = new Map(jobs.map((job) => [job.id, job]));
|
|
952
|
+
let crossChunkDependencyCount = 0;
|
|
953
|
+
let localJoinCount = 0;
|
|
954
|
+
const finalizedJobs = Object.freeze(
|
|
955
|
+
jobs.map((job) => {
|
|
956
|
+
const dependents = jobs.filter((candidate) => candidate.dependencies.includes(job.id)).map((candidate) => candidate.id);
|
|
957
|
+
const crossChunkDependencies = job.dependencies.filter((dependency) => {
|
|
958
|
+
const parent = jobById.get(dependency);
|
|
959
|
+
return parent && parent.chunkId !== job.chunkId;
|
|
960
|
+
});
|
|
961
|
+
crossChunkDependencyCount += crossChunkDependencies.length;
|
|
962
|
+
if (job.dependencies.length > 1 && crossChunkDependencies.length === 0) {
|
|
963
|
+
localJoinCount += 1;
|
|
964
|
+
}
|
|
965
|
+
return Object.freeze({
|
|
966
|
+
...job,
|
|
967
|
+
dependents: Object.freeze(dependents),
|
|
968
|
+
dependentCount: dependents.length,
|
|
969
|
+
unresolvedDependencyCount: job.dependencies.length,
|
|
970
|
+
localJoin: job.dependencies.length > 1 && crossChunkDependencies.length === 0
|
|
971
|
+
});
|
|
972
|
+
})
|
|
973
|
+
);
|
|
974
|
+
const graph = Object.freeze({
|
|
975
|
+
schedulerMode: "dag",
|
|
976
|
+
jobCount: finalizedJobs.length,
|
|
977
|
+
chunkCount: normalizedChunks.length,
|
|
978
|
+
chunkIds: Object.freeze(normalizedChunks.map((chunk) => chunk.chunkId)),
|
|
979
|
+
representationBands: Object.freeze(
|
|
980
|
+
[...new Set(normalizedChunks.map((chunk) => chunk.representationBand))]
|
|
981
|
+
),
|
|
982
|
+
roots: Object.freeze(
|
|
983
|
+
finalizedJobs.filter((job) => job.root).map((job) => job.id)
|
|
984
|
+
),
|
|
985
|
+
chunkRoots: Object.freeze(
|
|
986
|
+
Object.fromEntries(
|
|
987
|
+
normalizedChunks.map((chunk) => [
|
|
988
|
+
chunk.chunkId,
|
|
989
|
+
finalizedJobs.filter((job) => job.chunkId === chunk.chunkId && job.root).map((job) => job.id)
|
|
990
|
+
])
|
|
991
|
+
)
|
|
992
|
+
),
|
|
993
|
+
topologicalOrder: buildScenePreparationTopologicalOrder(finalizedJobs),
|
|
994
|
+
priorityLanes: buildScenePreparationPriorityLanes(finalizedJobs),
|
|
995
|
+
localJoinCount,
|
|
996
|
+
crossChunkDependencyCount
|
|
997
|
+
});
|
|
998
|
+
return Object.freeze({
|
|
999
|
+
schemaVersion: 1,
|
|
1000
|
+
owner: "scene-preparation",
|
|
1001
|
+
schedulerMode: "dag",
|
|
1002
|
+
snapshotId,
|
|
1003
|
+
jobs: finalizedJobs,
|
|
1004
|
+
graph
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
696
1007
|
// Annotate the CommonJS export names for ESM import in node:
|
|
697
1008
|
0 && (module.exports = {
|
|
698
1009
|
assembleWorkerWgsl,
|
|
1010
|
+
createScenePreparationManifest,
|
|
699
1011
|
createWorkerLoop,
|
|
700
1012
|
loadJobWgsl,
|
|
701
1013
|
loadQueueWgsl,
|
|
702
1014
|
loadWorkerWgsl,
|
|
1015
|
+
scenePreparationRepresentationBands,
|
|
1016
|
+
scenePreparationStageFamilies,
|
|
703
1017
|
workerWgslUrl
|
|
704
1018
|
});
|
|
705
1019
|
//# sourceMappingURL=index.cjs.map
|