@forgeax/engine-render 0.1.32 → 0.1.34
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 +1374 -142
- package/dist/assembly/analytic-fog-registration.d.ts +3 -0
- package/dist/assembly/analytic-fog-registration.d.ts.map +1 -0
- package/dist/assembly/backend-contract.d.ts +2 -0
- package/dist/assembly/backend-contract.d.ts.map +1 -1
- package/dist/assembly/barrel-distortion-inspection.d.ts +3 -0
- package/dist/assembly/barrel-distortion-inspection.d.ts.map +1 -0
- package/dist/assembly/canvas-draw-guard.d.ts +3 -0
- package/dist/assembly/canvas-draw-guard.d.ts.map +1 -0
- package/dist/assembly/cloud-shadow-entry.d.ts +4 -0
- package/dist/assembly/cloud-shadow-entry.d.ts.map +1 -0
- package/dist/assembly/dynamic-geometry-host.d.ts +4 -1
- package/dist/assembly/dynamic-geometry-host.d.ts.map +1 -1
- package/dist/assembly/dynamic-geometry-runtime.d.ts +1 -1
- package/dist/assembly/dynamic-geometry-runtime.d.ts.map +1 -1
- package/dist/assembly/factory.d.ts +1 -1
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/fxaa-registration.d.ts +4 -0
- package/dist/assembly/fxaa-registration.d.ts.map +1 -0
- package/dist/assembly/host-contract.d.ts +3 -3
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/lod-observation.d.ts +4 -0
- package/dist/assembly/lod-observation.d.ts.map +1 -0
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/assembly/material/pipeline-helpers.d.ts +5 -0
- package/dist/assembly/material/pipeline-helpers.d.ts.map +1 -1
- package/dist/assembly/material-shader-policy.d.ts +16 -2
- package/dist/assembly/material-shader-policy.d.ts.map +1 -1
- package/dist/assembly/material-shader-prewarm.d.ts.map +1 -1
- package/dist/assembly/motion-blur-registration.d.ts +3 -0
- package/dist/assembly/motion-blur-registration.d.ts.map +1 -0
- package/dist/assembly/recovery/device-loss-fanout.d.ts.map +1 -1
- package/dist/assembly/recovery/renderer-recover.d.ts +2 -0
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/render-feature-post-processes.d.ts +6 -0
- package/dist/assembly/render-feature-post-processes.d.ts.map +1 -0
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts +1 -1
- package/dist/assembly/renderer-feature-inspection.d.ts.map +1 -1
- package/dist/assembly/renderer-frame-transaction.d.ts +12 -0
- package/dist/assembly/renderer-frame-transaction.d.ts.map +1 -1
- package/dist/assembly/renderer-inspection.d.ts +11 -0
- package/dist/assembly/renderer-inspection.d.ts.map +1 -1
- package/dist/assembly/temporal-post-process-prewarm.d.ts +13 -0
- package/dist/assembly/temporal-post-process-prewarm.d.ts.map +1 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts +1 -0
- package/dist/assembly/webgpu-pbr-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-ready-contract.d.ts +4 -3
- package/dist/assembly/webgpu-ready-contract.d.ts.map +1 -1
- package/dist/assembly/webgpu-ready-per-pass.d.ts +39 -0
- package/dist/assembly/webgpu-ready-per-pass.d.ts.map +1 -0
- package/dist/assembly/webgpu-ready.d.ts +2 -2
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-bootstrap.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer-observation-owner.d.ts +35 -0
- package/dist/assembly/webgpu-renderer-observation-owner.d.ts.map +1 -0
- package/dist/assembly/webgpu-renderer.d.ts +1 -1
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/authoring.mjs +1 -1
- package/dist/barrel-distortion.d.ts +47 -0
- package/dist/barrel-distortion.d.ts.map +1 -0
- package/dist/bloom-admission.d.ts +13 -0
- package/dist/bloom-admission.d.ts.map +1 -0
- package/dist/{chunk-PA5DRJNI.mjs → chunk-ELJFJ2BU.mjs} +2 -2
- package/dist/chunk-ELJFJ2BU.mjs.map +1 -0
- package/dist/{chunk-JCIRYQ4V.mjs → chunk-HEB564WF.mjs} +10 -4
- package/dist/chunk-HEB564WF.mjs.map +1 -0
- package/dist/{chunk-JRIPCMYC.mjs → chunk-MKDIT2EM.mjs} +1584 -375
- package/dist/chunk-MKDIT2EM.mjs.map +1 -0
- package/dist/{chunk-S665NJNF.mjs → chunk-OCDLEI6I.mjs} +3 -3
- package/dist/{chunk-S665NJNF.mjs.map → chunk-OCDLEI6I.mjs.map} +1 -1
- package/dist/chunk-ODZWR6JQ.mjs +4927 -0
- package/dist/chunk-ODZWR6JQ.mjs.map +1 -0
- package/dist/{chunk-DRR7D3KX.mjs → chunk-SHFUFJ5N.mjs} +192 -18
- package/dist/chunk-SHFUFJ5N.mjs.map +1 -0
- package/dist/{chunk-4NNZQCL3.mjs → chunk-UI5SFODX.mjs} +223 -277
- package/dist/chunk-UI5SFODX.mjs.map +1 -0
- package/dist/{chunk-GWCEMDVR.mjs → chunk-UINHLCZA.mjs} +787 -80
- package/dist/chunk-UINHLCZA.mjs.map +1 -0
- package/dist/{chunk-6TFBXLRJ.mjs → chunk-WEX45HKH.mjs} +222 -337
- package/dist/chunk-WEX45HKH.mjs.map +1 -0
- package/dist/cloud/density.d.ts +55 -0
- package/dist/cloud/density.d.ts.map +1 -0
- package/dist/cloud/extract.d.ts +25 -0
- package/dist/cloud/extract.d.ts.map +1 -0
- package/dist/cloud/feature.d.ts +57 -0
- package/dist/cloud/feature.d.ts.map +1 -0
- package/dist/cloud/frame-context.d.ts +8 -0
- package/dist/cloud/frame-context.d.ts.map +1 -0
- package/dist/cloud/inspection.d.ts +59 -0
- package/dist/cloud/inspection.d.ts.map +1 -0
- package/dist/cloud/optics.d.ts +56 -0
- package/dist/cloud/optics.d.ts.map +1 -0
- package/dist/cloud/parameters.d.ts +73 -0
- package/dist/cloud/parameters.d.ts.map +1 -0
- package/dist/cloud/resources.d.ts +60 -0
- package/dist/cloud/resources.d.ts.map +1 -0
- package/dist/cloud/shadow.d.ts +42 -0
- package/dist/cloud/shadow.d.ts.map +1 -0
- package/dist/cloud/temporal.d.ts +74 -0
- package/dist/cloud/temporal.d.ts.map +1 -0
- package/dist/components/atmosphere.d.ts +2 -0
- package/dist/components/atmosphere.d.ts.map +1 -1
- package/dist/components/barrel-distortion.d.ts +13 -0
- package/dist/components/barrel-distortion.d.ts.map +1 -0
- package/dist/components/camera.d.ts +20 -4
- package/dist/components/camera.d.ts.map +1 -1
- package/dist/components/cloud-layer.d.ts +29 -0
- package/dist/components/cloud-layer.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/instances.d.ts +20 -6
- package/dist/components/instances.d.ts.map +1 -1
- package/dist/components/mesh-filter.d.ts +6 -5
- package/dist/components/mesh-filter.d.ts.map +1 -1
- package/dist/components/motion-blur.d.ts +1 -0
- package/dist/components/motion-blur.d.ts.map +1 -1
- package/dist/construct-renderer.d.ts +1 -1
- package/dist/construct-renderer.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +9751 -3528
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +6 -0
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/dynamic-geometry.d.ts +5 -1
- package/dist/dynamic-geometry.d.ts.map +1 -1
- package/dist/environment/analytic-fog.d.ts +6 -0
- package/dist/environment/analytic-fog.d.ts.map +1 -0
- package/dist/errors/cloud.d.ts +59 -0
- package/dist/errors/cloud.d.ts.map +1 -0
- package/dist/errors/render.d.ts +23 -5
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/examples/single-layer-medium-surface.d.ts +47 -0
- package/dist/examples/single-layer-medium-surface.d.ts.map +1 -0
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/extract/contracts.d.ts +12 -1
- package/dist/extract/contracts.d.ts.map +1 -1
- package/dist/extract/environment.d.ts +2 -0
- package/dist/extract/environment.d.ts.map +1 -1
- package/dist/features/barrel-distortion.d.ts +29 -0
- package/dist/features/barrel-distortion.d.ts.map +1 -0
- package/dist/features/error-reporting.d.ts +17 -0
- package/dist/features/error-reporting.d.ts.map +1 -0
- package/dist/features/host.d.ts +15 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-feature.d.ts +20 -2
- package/dist/features/motion-blur/motion-blur-feature.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-params.d.ts +21 -0
- package/dist/features/motion-blur/motion-blur-params.d.ts.map +1 -1
- package/dist/features/motion-blur/motion-blur-runtime.d.ts +54 -0
- package/dist/features/motion-blur/motion-blur-runtime.d.ts.map +1 -0
- package/dist/features/plan.d.ts +15 -4
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/prepared-gpu-work.d.ts +9 -5
- package/dist/features/prepared-gpu-work.d.ts.map +1 -1
- package/dist/features/render-graph-compute.d.ts.map +1 -1
- package/dist/features/render-graph-contribution.d.ts +5 -0
- package/dist/features/render-graph-contribution.d.ts.map +1 -1
- package/dist/features/render-graph-raster.d.ts +1 -0
- package/dist/features/render-graph-raster.d.ts.map +1 -1
- package/dist/features/targets.d.ts +2 -0
- package/dist/features/targets.d.ts.map +1 -1
- package/dist/features/types.d.ts +44 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/fullscreen-post-process-pass.d.ts +15 -7
- package/dist/fullscreen-post-process-pass.d.ts.map +1 -1
- package/dist/gpu-dirty-ranges.d.ts +11 -0
- package/dist/gpu-dirty-ranges.d.ts.map +1 -0
- package/dist/gpu-driven/batch-topology.d.ts +17 -0
- package/dist/gpu-driven/batch-topology.d.ts.map +1 -1
- package/dist/gpu-driven/material-artifacts.d.ts +6 -0
- package/dist/gpu-driven/material-artifacts.d.ts.map +1 -1
- package/dist/gpu-driven/prepared-draw.d.ts +7 -0
- package/dist/gpu-driven/prepared-draw.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster-material.d.ts +178 -0
- package/dist/gpu-driven/production-raster-material.d.ts.map +1 -0
- package/dist/gpu-driven/production-raster.d.ts +50 -4
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/gpu-driven/resource-allocation.d.ts +31 -0
- package/dist/gpu-driven/resource-allocation.d.ts.map +1 -0
- package/dist/gpu-driven/shadow-ownership.d.ts +14 -0
- package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -0
- package/dist/gpu-driven/view-gpu.d.ts +35 -2
- package/dist/gpu-driven/view-gpu.d.ts.map +1 -1
- package/dist/gpu-scene.d.ts +11 -1
- package/dist/gpu-scene.d.ts.map +1 -1
- package/dist/hdrp-buffers.d.ts +2 -2
- package/dist/hdrp-buffers.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +10 -1
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +31 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +258 -8
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +178 -3
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instance-buffer-cache.d.ts +4 -4
- package/dist/instance-buffer-cache.d.ts.map +1 -1
- package/dist/instances.d.ts +49 -94
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.mjs +7 -7
- package/dist/pbr-pipeline.d.ts +19 -1
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/single-layer-medium-passes.d.ts +73 -0
- package/dist/pipeline/single-layer-medium-passes.d.ts.map +1 -0
- package/dist/pipeline/standard-forward-lane.d.ts.map +1 -1
- package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
- package/dist/pipeline/standard-output/types.d.ts +4 -2
- package/dist/pipeline/standard-output/types.d.ts.map +1 -1
- package/dist/pipeline/standard-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts +28 -19
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/pipeline-builder.d.ts +1 -1
- package/dist/pipeline-builder.d.ts.map +1 -1
- package/dist/pipeline-spec.d.ts +2 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/prepare/prepared-graphics-resolver.d.ts +2 -0
- package/dist/prepare/prepared-graphics-resolver.d.ts.map +1 -1
- package/dist/record/barrel-distortion-frame.d.ts +15 -0
- package/dist/record/barrel-distortion-frame.d.ts.map +1 -0
- package/dist/record/dynamic-geometry-consumption.d.ts +10 -2
- package/dist/record/dynamic-geometry-consumption.d.ts.map +1 -1
- package/dist/record/fold-buckets.d.ts +95 -0
- package/dist/record/fold-buckets.d.ts.map +1 -0
- package/dist/record/fold-instance-buffer.d.ts +6 -0
- package/dist/record/fold-instance-buffer.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts +1 -0
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +40 -3
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame-targets.d.ts.map +1 -1
- package/dist/record/frame.d.ts +14 -62
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/gpu-draw-receipts.d.ts +11 -0
- package/dist/record/gpu-draw-receipts.d.ts.map +1 -0
- package/dist/record/gpu-timing.d.ts +8 -0
- package/dist/record/gpu-timing.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +21 -5
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +7 -1
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts +13 -2
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/mesh-ssbo.d.ts +6 -5
- package/dist/record/mesh-ssbo.d.ts.map +1 -1
- package/dist/record/motion-blur-receipt.d.ts +11 -0
- package/dist/record/motion-blur-receipt.d.ts.map +1 -0
- package/dist/record/probe-blend-buffer.d.ts +16 -0
- package/dist/record/probe-blend-buffer.d.ts.map +1 -0
- package/dist/record/recovery-pipeline.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +34 -31
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts +2 -0
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts +6 -4
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +22 -2
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +11 -3
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/record/volume-params.d.ts +9 -0
- package/dist/record/volume-params.d.ts.map +1 -0
- package/dist/recovery/render-system-candidate.d.ts +10 -0
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/reflection/record-owner.d.ts.map +1 -1
- package/dist/render-contract.d.ts +66 -8
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +106 -3
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts +3 -2
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +24 -10
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system-presentation.d.ts +23 -0
- package/dist/render-system-presentation.d.ts.map +1 -0
- package/dist/render-system-producer-roots.d.ts +10 -0
- package/dist/render-system-producer-roots.d.ts.map +1 -0
- package/dist/render-system-residency.d.ts +12 -0
- package/dist/render-system-residency.d.ts.map +1 -0
- package/dist/render-system.d.ts +26 -15
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/probe-blend.d.ts +27 -0
- package/dist/scene/probe-blend.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +14 -5
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/ssao-buffers.d.ts +9 -0
- package/dist/ssao-buffers.d.ts.map +1 -1
- package/dist/surface/dynamic-input.d.ts +133 -0
- package/dist/surface/dynamic-input.d.ts.map +1 -0
- package/dist/surface/gpu-driven.d.ts +41 -0
- package/dist/surface/gpu-driven.d.ts.map +1 -0
- package/dist/surface/submission-observation.d.ts +136 -0
- package/dist/surface/submission-observation.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/temporal/frame-coordinator.d.ts.map +1 -1
- package/dist/temporal/frame.d.ts +7 -0
- package/dist/temporal/frame.d.ts.map +1 -1
- package/dist/temporal/gpu.d.ts +13 -1
- package/dist/temporal/gpu.d.ts.map +1 -1
- package/dist/temporal/index.mjs +5 -5
- package/dist/temporal/inspection.d.ts.map +1 -1
- package/dist/temporal/standard-scene-data.d.ts.map +1 -1
- package/dist/temporal/target-coverage-attachment.d.ts.map +1 -1
- package/dist/temporal/view.d.ts +6 -1
- package/dist/temporal/view.d.ts.map +1 -1
- package/dist/transmission/single-layer-medium.d.ts +89 -0
- package/dist/transmission/single-layer-medium.d.ts.map +1 -0
- package/dist/typed-render-graph-primitives.d.ts +24 -9
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/dist/volume/component.d.ts +9 -5
- package/dist/volume/component.d.ts.map +1 -1
- package/dist/volume/extract.d.ts +1 -1
- package/dist/volume/extract.d.ts.map +1 -1
- package/dist/volume/inspection.d.ts +2 -0
- package/dist/volume/inspection.d.ts.map +1 -1
- package/dist/volume/passes.d.ts +4 -1
- package/dist/volume/passes.d.ts.map +1 -1
- package/dist/volume/resources.d.ts.map +1 -1
- package/dist/volume/temporal.d.ts +3 -1
- package/dist/volume/temporal.d.ts.map +1 -1
- package/package.json +22 -21
- package/src/__tests__/analytic-fog-graph.unit.test.ts +199 -0
- package/src/__tests__/analytic-fog-optics.unit.test.ts +38 -0
- package/src/__tests__/atmosphere-daylight.dawn.test.ts +72 -0
- package/src/__tests__/barrel-distortion-lkg.integration.test.ts +353 -0
- package/src/__tests__/barrel-distortion.dawn.test.ts +41 -0
- package/src/__tests__/barrel-distortion.unit.test.ts +364 -0
- package/src/__tests__/bloom-exact-zero.unit.test.ts +112 -18
- package/src/__tests__/bloom-lifecycle.integration.test.ts +17 -4
- package/src/__tests__/construct-renderer-identity.unit.test.ts +49 -0
- package/src/__tests__/detached-recovery-graph.unit.test.ts +277 -0
- package/src/__tests__/device-loss-fanout.unit.test.ts +36 -1
- package/src/__tests__/docs-gate-green.unit.test.ts +112 -1
- package/src/__tests__/dynamic-resolution-plugin.integration.test.ts +20 -0
- package/src/__tests__/environment-fog-lanes.integration.test.ts +14 -0
- package/src/__tests__/environment-selection.unit.test.ts +12 -0
- package/src/__tests__/factory-contract.integration.test.ts +626 -113
- package/src/__tests__/feature-depth-input.dawn.test.ts +129 -2
- package/src/__tests__/frame-camera-selection.unit.test.ts +39 -1
- package/src/__tests__/frame-plan-contract.unit.test.ts +2 -0
- package/src/__tests__/fullscreen-feature-plan.unit.test.ts +14 -3
- package/src/__tests__/gpu-dirty-ranges.unit.test.ts +22 -0
- package/src/__tests__/gpu-driven-baseline.characterization.test.ts +16 -3
- package/src/__tests__/gpu-driven-batch-topology-pbr.unit.test.ts +12 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +2 -1
- package/src/__tests__/gpu-driven-material-artifacts.unit.test.ts +143 -0
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +2 -2
- package/src/__tests__/gpu-driven-production.integration.test.ts +482 -3
- package/src/__tests__/gpu-driven-shadow-views.dawn.test.ts +7 -6
- package/src/__tests__/gpu-driven-shadow-views.integration.test.ts +1 -1
- package/src/__tests__/gpu-driven-view-gpu-evidence.ts +103 -4
- package/src/__tests__/gpu-driven-view-graph.integration.test.ts +18 -2
- package/src/__tests__/gpu-driven-view.browser.test.ts +5 -8
- package/src/__tests__/gpu-driven-view.dawn.test.ts +6 -2
- package/src/__tests__/gpu-driven-view.unit.test.ts +1 -1
- package/src/__tests__/gpu-pass-timing-lifecycle.integration.test.ts +1 -0
- package/src/__tests__/gpu-pass-timing.browser.test.ts +6 -4
- package/src/__tests__/gpu-pass-timing.rhi-null.unit.test.ts +1 -0
- package/src/__tests__/gpu-resource-store-stride.unit.test.ts +12 -0
- package/src/__tests__/gpu-scene.unit.test.ts +210 -9
- package/src/__tests__/instance-allocation-failure.unit.test.ts +57 -0
- package/src/__tests__/instances-culling.integration.test.ts +10 -36
- package/src/__tests__/instances-store.unit.test.ts +105 -238
- package/src/__tests__/instances-world-ownership.integration.test.ts +62 -0
- package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +146 -0
- package/src/__tests__/material-shader-prewarm.unit.test.ts +59 -0
- package/src/__tests__/material-snapshot-mutation.integration.test.ts +39 -1
- package/src/__tests__/mesh-submission-lifetime.unit.test.ts +31 -0
- package/src/__tests__/morph-culling-reentry.dawn.test.ts +5 -5
- package/src/__tests__/morph-visual-evidence.integration.test.ts +8 -7
- package/src/__tests__/motion-blur-compute.dawn.test.ts +589 -0
- package/src/__tests__/motion-blur.pixel.integration.test.ts +2 -2
- package/src/__tests__/nineslice-handle-surface.unit.test.ts +4 -4
- package/src/__tests__/pbr-view-layout.unit.test.ts +9 -0
- package/src/__tests__/physical-clearcoat.integration.test.ts +58 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +21 -0
- package/src/__tests__/prepared-graphics-capability.unit.test.ts +66 -2
- package/src/__tests__/prepared-graphics-lifecycle.unit.test.ts +86 -0
- package/src/__tests__/probe-bindings.unit.test.ts +582 -1
- package/src/__tests__/probe-scene-dirty.integration.test.ts +28 -1
- package/src/__tests__/public-surface.test-d.ts +8 -0
- package/src/__tests__/receipt-observation-retirement.unit.test.ts +65 -0
- package/src/__tests__/recovery-candidate-prepare.contract.test.ts +69 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +9 -0
- package/src/__tests__/render-feature-diagnostics.unit.test.ts +15 -2
- package/src/__tests__/render-feature-error-reporting.unit.test.ts +44 -0
- package/src/__tests__/render-feature-prepared-diagnostics.unit.test.ts +10 -1
- package/src/__tests__/render-feature-retry.unit.test.ts +12 -1
- package/src/__tests__/render-feature-stage-fault-recovery.unit.test.ts +23 -0
- package/src/__tests__/render-scene-mixed-updates.integration.test.ts +145 -19
- package/src/__tests__/render-scene-projection.unit.test.ts +36 -11
- package/src/__tests__/render-scene-temporal-retry.unit.test.ts +37 -6
- package/src/__tests__/render-target-probe-soak.perf.test.ts +2 -2
- package/src/__tests__/render-temporal-environment-consumer.browser.test.ts +3 -3
- package/src/__tests__/render-temporal-environment-consumer.dawn.test.ts +5 -2
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +41 -7
- package/src/__tests__/renderer-frame-generation-fence.integration.test.ts +16 -0
- package/src/__tests__/renderer-frame-transaction.integration.test.ts +33 -11
- package/src/__tests__/resource-allocation.unit.test.ts +123 -0
- package/src/__tests__/shader-manifest-fixture.ts +4 -4
- package/src/__tests__/single-layer-medium-passes.unit.test.ts +275 -0
- package/src/__tests__/skin-motion-regression.unit.test.ts +70 -1
- package/src/__tests__/skin-palette-recycling.dawn.test.ts +97 -0
- package/src/__tests__/skinned-shadow-caster.test.ts +17 -0
- package/src/__tests__/ssr-carrier-public-contract.unit.test.ts +21 -0
- package/src/__tests__/ssr-gpu-dispatch.browser.test.ts +4 -4
- package/src/__tests__/ssr-gpu-dispatch.dawn.test.ts +2 -2
- package/src/__tests__/ssr-gpu-dispatch.ts +1 -1
- package/src/__tests__/ssr-receiver-coverage.dawn.test.ts +6 -2
- package/src/__tests__/standard-lighting-write.unit.test.ts +2 -1
- package/src/__tests__/standard-output-chain-contract.unit.test.ts +28 -0
- package/src/__tests__/standard-pbr-artifact-assembly.unit.test.ts +46 -1
- package/src/__tests__/standard-pipeline.dawn.test.ts +1 -1
- package/src/__tests__/standard-pipeline.integration.test.ts +200 -9
- package/src/__tests__/surface-dynamic-buffer-lifecycle.unit.test.ts +506 -0
- package/src/__tests__/surface-submission-observation.unit.test.ts +812 -0
- package/src/__tests__/temporal-history-lifecycle.unit.test.ts +32 -0
- package/src/__tests__/temporal-performance.integration.test.ts +3 -3
- package/src/__tests__/temporal-reset-matrix.unit.test.ts +10 -0
- package/src/__tests__/temporal-view.unit.test.ts +2 -1
- package/src/__tests__/typed-pipeline-topology.unit.test.ts +20 -4
- package/src/__tests__/visibility-instances.integration.test.ts +7 -19
- package/src/__tests__/visibility-producer-matrix.integration.test.ts +9 -20
- package/src/__tests__/volume-optics-oracle.unit.test.ts +7 -3
- package/src/__tests__/volumetric-fog-budget-recovery.integration.test.ts +189 -15
- package/src/__tests__/volumetric-fog-errors.unit.test.ts +4 -3
- package/src/__tests__/volumetric-fog-multiple.unit.test.ts +55 -0
- package/src/__tests__/volumetric-fog-spot-frame-optics.integration.test.ts +1 -1
- package/src/__tests__/volumetric-fog-stage-readback.dawn.test.ts +558 -68
- package/src/__tests__/volumetric-fog-temporal.unit.test.ts +27 -0
- package/src/__tests__/volumetric-fog-topology.unit.test.ts +23 -5
- package/src/assembly/analytic-fog-registration.ts +14 -0
- package/src/assembly/backend-contract.ts +30 -0
- package/src/assembly/barrel-distortion-inspection.ts +22 -0
- package/src/assembly/canvas-draw-guard.ts +11 -0
- package/src/assembly/cloud-shadow-entry.ts +22 -0
- package/src/assembly/dynamic-geometry-host.ts +65 -37
- package/src/assembly/dynamic-geometry-runtime.ts +7 -1
- package/src/assembly/factory.ts +2 -30
- package/src/assembly/fxaa-registration.ts +17 -0
- package/src/assembly/host-contract.ts +3 -3
- package/src/assembly/lod-observation.ts +12 -0
- package/src/assembly/material/assembly.ts +25 -13
- package/src/assembly/material/pipeline-helpers.ts +53 -12
- package/src/assembly/material-shader-policy.ts +55 -0
- package/src/assembly/material-shader-prewarm.ts +21 -10
- package/src/assembly/motion-blur-registration.ts +17 -0
- package/src/assembly/recovery/device-loss-fanout.ts +13 -0
- package/src/assembly/recovery/renderer-recover.ts +41 -18
- package/src/assembly/render-feature-post-processes.ts +54 -0
- package/src/assembly/renderer-facade.ts +6 -1
- package/src/assembly/renderer-feature-inspection.ts +8 -2
- package/src/assembly/renderer-frame-transaction.ts +23 -0
- package/src/assembly/renderer-inspection.ts +28 -0
- package/src/assembly/skin-palette-owner.ts +1 -1
- package/src/assembly/temporal-post-process-prewarm.ts +40 -0
- package/src/assembly/webgpu-pbr-ready.ts +9 -1
- package/src/assembly/webgpu-ready-contract.ts +8 -3
- package/src/assembly/webgpu-ready-per-pass.ts +104 -0
- package/src/assembly/webgpu-ready.ts +296 -306
- package/src/assembly/webgpu-renderer-bootstrap.ts +0 -12
- package/src/assembly/webgpu-renderer-observation-owner.ts +222 -0
- package/src/assembly/webgpu-renderer.ts +228 -281
- package/src/assembly/webgpu-vertex-layouts.ts +1 -1
- package/src/barrel-distortion.ts +247 -0
- package/src/bloom-admission.ts +21 -0
- package/src/cloud/__tests__/cloud-density-parity.dawn.test.ts +173 -0
- package/src/cloud/__tests__/cloud-layer-framebuffer-y.dawn.test.ts +265 -0
- package/src/cloud/__tests__/cloud-layer.browser.test.ts +432 -0
- package/src/cloud/__tests__/cloud-layer.unit.test.ts +634 -0
- package/src/cloud/density.ts +600 -0
- package/src/cloud/extract.ts +110 -0
- package/src/cloud/feature.ts +1810 -0
- package/src/cloud/frame-context.ts +42 -0
- package/src/cloud/inspection.ts +130 -0
- package/src/cloud/optics.ts +285 -0
- package/src/cloud/parameters.ts +255 -0
- package/src/cloud/resources.ts +122 -0
- package/src/cloud/shadow.ts +167 -0
- package/src/cloud/temporal.ts +226 -0
- package/src/components/__tests__/motion-blur.unit.test.ts +1 -0
- package/src/components/atmosphere.ts +4 -0
- package/src/components/barrel-distortion.ts +46 -0
- package/src/components/camera.ts +66 -10
- package/src/components/cloud-layer.ts +47 -0
- package/src/components/index.ts +2 -0
- package/src/components/instances.ts +18 -45
- package/src/components/mesh-filter.ts +11 -9
- package/src/components/motion-blur.ts +1 -0
- package/src/components/sprite-instances.ts +1 -1
- package/src/construct-renderer.ts +1 -1
- package/src/device/gpu-residency.ts +56 -12
- package/src/dynamic-geometry.ts +12 -1
- package/src/environment/analytic-fog.ts +44 -0
- package/src/environment/background.ts +2 -2
- package/src/errors/cloud.ts +103 -0
- package/src/errors/render.ts +58 -8
- package/src/examples/single-layer-medium-surface.ts +59 -0
- package/src/extract/camera.ts +35 -8
- package/src/extract/contracts.ts +12 -0
- package/src/extract/environment.ts +4 -0
- package/src/features/barrel-distortion.ts +172 -0
- package/src/features/error-reporting.ts +98 -0
- package/src/features/host.ts +138 -24
- package/src/features/motion-blur/__tests__/motion-blur-feature.unit.test.ts +111 -1
- package/src/features/motion-blur/__tests__/motion-blur-params.unit.test.ts +58 -3
- package/src/features/motion-blur/motion-blur-feature.ts +1519 -15
- package/src/features/motion-blur/motion-blur-params.ts +70 -2
- package/src/features/motion-blur/motion-blur-runtime.ts +176 -0
- package/src/features/plan.ts +33 -8
- package/src/features/prepared-gpu-work.ts +86 -35
- package/src/features/render-graph-compute.ts +13 -5
- package/src/features/render-graph-contribution.ts +11 -0
- package/src/features/render-graph-raster.ts +45 -3
- package/src/features/targets.ts +66 -0
- package/src/features/types.ts +47 -0
- package/src/fullscreen-post-process-pass.ts +41 -9
- package/src/gpu-dirty-ranges.ts +48 -0
- package/src/gpu-driven/batch-topology.ts +53 -0
- package/src/gpu-driven/material-artifacts.ts +35 -32
- package/src/gpu-driven/prepared-draw.ts +27 -14
- package/src/gpu-driven/production-raster-material.ts +1894 -0
- package/src/gpu-driven/production-raster.ts +904 -787
- package/src/gpu-driven/resource-allocation.ts +142 -0
- package/src/gpu-driven/shadow-ownership.ts +71 -0
- package/src/gpu-driven/view-gpu.ts +181 -10
- package/src/gpu-scene.ts +259 -101
- package/src/hdrp-buffers.ts +4 -3
- package/src/ibl/skylight-bind-group.ts +49 -7
- package/src/index.ts +228 -9
- package/src/inspection-types.ts +222 -2
- package/src/instance-buffer-cache.ts +4 -4
- package/src/instances.ts +151 -492
- package/src/pbr-pipeline.ts +219 -13
- package/src/pipeline/single-layer-medium-passes.ts +267 -0
- package/src/pipeline/standard-forward-lane.ts +313 -57
- package/src/pipeline/standard-output/graph.ts +8 -2
- package/src/pipeline/standard-output/types.ts +12 -1
- package/src/pipeline/standard-pipeline.ts +291 -18
- package/src/pipeline/standard-post.ts +397 -102
- package/src/pipeline-builder.ts +1 -1
- package/src/pipeline-spec.ts +5 -5
- package/src/plugin.ts +4 -0
- package/src/points-lines/__tests__/points-lines.bench.ts +17 -8
- package/src/points-lines/__tests__/view-ubo.unit.test.ts +2 -1
- package/src/prepare/prepared-graphics-resolver.ts +2 -0
- package/src/record/__tests__/main-pass-geometry.unit.test.ts +30 -0
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +1 -1
- package/src/record/__tests__/temporal-payload.unit.test.ts +3 -2
- package/src/record/__tests__/transparent-group2-selection.unit.test.ts +11 -0
- package/src/record/__tests__/typed-frame-graph-plan.unit.test.ts +1 -0
- package/src/record/__tests__/view-ubo-layout.unit.test.ts +4 -3
- package/src/record/barrel-distortion-frame.ts +110 -0
- package/src/record/dynamic-geometry-consumption.ts +39 -9
- package/src/record/fold-buckets.ts +852 -0
- package/src/record/fold-instance-buffer.ts +51 -0
- package/src/record/frame-lighting.ts +36 -2
- package/src/record/frame-snapshot.ts +44 -4
- package/src/record/frame-targets.ts +10 -6
- package/src/record/frame.ts +373 -1099
- package/src/record/gpu-draw-receipts.ts +38 -0
- package/src/record/gpu-timing.ts +48 -5
- package/src/record/main-pass-geometry.ts +281 -83
- package/src/record/main-pass-material.ts +66 -4
- package/src/record/main-pass-sprite-draws.ts +13 -66
- package/src/record/main-pass.ts +156 -20
- package/src/record/mesh-ssbo.ts +43 -6
- package/src/record/motion-blur-receipt.ts +91 -0
- package/src/record/probe-blend-buffer.ts +180 -0
- package/src/record/recovery-pipeline.ts +35 -3
- package/src/record/render-context.ts +51 -31
- package/src/record/shadow-pass.ts +36 -2
- package/src/record/skybox-post-pass.ts +150 -200
- package/src/record/typed-frame-graph.ts +824 -44
- package/src/record/view-ubo.ts +26 -3
- package/src/record/volume-params.ts +225 -0
- package/src/recovery/render-system-candidate.ts +257 -52
- package/src/reflection/record-owner.ts +7 -3
- package/src/render-contract.ts +71 -8
- package/src/render-graph-primitives.ts +7 -1
- package/src/render-pipeline.ts +136 -1
- package/src/render-system-extract-tail.ts +72 -60
- package/src/render-system-extract.ts +117 -87
- package/src/render-system-presentation.ts +56 -0
- package/src/render-system-producer-roots.ts +96 -0
- package/src/render-system-residency.ts +159 -0
- package/src/render-system.ts +601 -482
- package/src/scene/probe-blend.ts +96 -4
- package/src/scene/render-scene.ts +431 -281
- package/src/ssao-buffers.ts +95 -2
- package/src/surface/__tests__/dynamic-input.unit.test.ts +374 -0
- package/src/surface/__tests__/gpu-driven.unit.test.ts +87 -0
- package/src/surface/dynamic-input.ts +658 -0
- package/src/surface/gpu-driven.ts +147 -0
- package/src/surface/submission-observation.ts +517 -0
- package/src/systems/skin-palette-allocator.ts +4 -1
- package/src/temporal/__tests__/temporal-frame-transaction.unit.test.ts +36 -0
- package/src/temporal/frame-coordinator.ts +8 -1
- package/src/temporal/frame.ts +20 -0
- package/src/temporal/gpu.ts +101 -17
- package/src/temporal/inspection.ts +7 -1
- package/src/temporal/standard-scene-data.ts +5 -0
- package/src/temporal/target-coverage-attachment.ts +4 -0
- package/src/temporal/view.ts +13 -2
- package/src/transmission/__tests__/single-layer-medium.unit.test.ts +149 -0
- package/src/transmission/__tests__/standard-transmission.dawn.test.ts +12 -11
- package/src/transmission/single-layer-medium.ts +322 -0
- package/src/typed-render-graph-primitives.ts +191 -50
- package/src/volume/component.ts +10 -10
- package/src/volume/extract.ts +11 -5
- package/src/volume/inspection.ts +3 -0
- package/src/volume/passes.ts +95 -8
- package/src/volume/resources.ts +2 -1
- package/src/volume/temporal.ts +11 -0
- package/dist/chunk-4NNZQCL3.mjs.map +0 -1
- package/dist/chunk-6TFBXLRJ.mjs.map +0 -1
- package/dist/chunk-DRR7D3KX.mjs.map +0 -1
- package/dist/chunk-GWCEMDVR.mjs.map +0 -1
- package/dist/chunk-JCIRYQ4V.mjs.map +0 -1
- package/dist/chunk-JRIPCMYC.mjs.map +0 -1
- package/dist/chunk-LULCA3OF.mjs +0 -1713
- package/dist/chunk-LULCA3OF.mjs.map +0 -1
- package/dist/chunk-PA5DRJNI.mjs.map +0 -1
package/src/instances.ts
CHANGED
|
@@ -1,50 +1,26 @@
|
|
|
1
|
+
import type { World } from '@forgeax/engine-ecs';
|
|
2
|
+
import { InstanceTransformsStrideMismatchError } from '@forgeax/engine-ecs/projection';
|
|
1
3
|
import type { RhiErrorCode } from '@forgeax/engine-rhi';
|
|
2
|
-
import { err, ok, type Result } from '@forgeax/engine-types';
|
|
3
4
|
|
|
4
5
|
const MATRIX_STRIDE = 16;
|
|
5
|
-
const INITIAL_CAPACITY = 1;
|
|
6
6
|
|
|
7
|
+
/** Renderer projection identity; never stored in a World or SceneAsset. */
|
|
7
8
|
export type InstanceCollectionId = number & {
|
|
8
9
|
readonly __forgeaxInstanceCollectionId: unique symbol;
|
|
9
10
|
};
|
|
10
|
-
|
|
11
|
-
export interface InstanceCollectionData {
|
|
11
|
+
export interface InstanceCollectionInfo {
|
|
12
12
|
readonly collectionId: InstanceCollectionId;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface InstanceCollectionInfo extends InstanceCollectionData {
|
|
16
13
|
readonly count: number;
|
|
17
|
-
readonly capacity: number;
|
|
18
14
|
readonly revision: number;
|
|
19
15
|
}
|
|
20
|
-
|
|
21
16
|
export interface InstanceDirtyRange {
|
|
22
17
|
start: number;
|
|
23
18
|
end: number;
|
|
24
19
|
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Choose the ranges that initialize one resident GPU allocation.
|
|
28
|
-
*
|
|
29
|
-
* A cache miss is not a delta upload: recovery, reassociation, and any other
|
|
30
|
-
* new resident has uninitialized device memory. The canonical collection must
|
|
31
|
-
* therefore be copied in full even when the current authoring revision only
|
|
32
|
-
* records a partial dirty range. Existing residents keep the narrower ranges.
|
|
33
|
-
*/
|
|
34
|
-
export function instanceUploadRangesForResident(
|
|
35
|
-
activeIsNew: boolean,
|
|
36
|
-
dirtyRanges: readonly InstanceDirtyRange[],
|
|
37
|
-
fullRange: InstanceDirtyRange,
|
|
38
|
-
): readonly InstanceDirtyRange[] {
|
|
39
|
-
return activeIsNew ? [fullRange] : dirtyRanges;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
20
|
export interface InstanceCollectionSnapshot extends InstanceCollectionInfo {
|
|
43
21
|
readonly transforms: Float32Array;
|
|
44
|
-
readonly
|
|
22
|
+
readonly generations: Uint32Array;
|
|
45
23
|
}
|
|
46
|
-
|
|
47
|
-
/** The renderer-owned submission lane selected for one collection. */
|
|
48
24
|
export type InstanceSubmissionLane =
|
|
49
25
|
| 'unresident'
|
|
50
26
|
| 'direct-storage'
|
|
@@ -52,14 +28,8 @@ export type InstanceSubmissionLane =
|
|
|
52
28
|
| 'direct-uniform'
|
|
53
29
|
| 'chunked-uniform'
|
|
54
30
|
| 'unavailable';
|
|
55
|
-
|
|
56
|
-
/** Backend identity carried by collection residency and failure facts. */
|
|
57
31
|
export type InstanceBackendKind = 'webgpu' | 'wgpu-native' | 'wgpu-webgl2' | 'null' | 'unknown';
|
|
58
|
-
|
|
59
|
-
/** Closed record-stage failure vocabulary for collection residency. */
|
|
60
32
|
export type InstanceCollectionFailureCode = RhiErrorCode | 'queue-write-buffer-failed';
|
|
61
|
-
|
|
62
|
-
/** Typed producer facts retained when a collection cannot be admitted. */
|
|
63
33
|
export interface InstanceCollectionFailureFacts {
|
|
64
34
|
readonly requestedBytes: number;
|
|
65
35
|
readonly supportedBytes: number | undefined;
|
|
@@ -68,29 +38,9 @@ export interface InstanceCollectionFailureFacts {
|
|
|
68
38
|
readonly cause: string;
|
|
69
39
|
readonly recovery: string;
|
|
70
40
|
}
|
|
71
|
-
|
|
72
|
-
function instanceCollectionFailureFacts(
|
|
73
|
-
cause: string,
|
|
74
|
-
recovery: string,
|
|
75
|
-
requestedBytes = 0,
|
|
76
|
-
supportedBytes: number | undefined = undefined,
|
|
77
|
-
backend: InstanceBackendKind = 'unknown',
|
|
78
|
-
): InstanceCollectionFailureFacts {
|
|
79
|
-
return {
|
|
80
|
-
requestedBytes,
|
|
81
|
-
supportedBytes,
|
|
82
|
-
backend,
|
|
83
|
-
owner: 'renderer.instances',
|
|
84
|
-
cause,
|
|
85
|
-
recovery,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/** Detached, bounded collection evidence exposed by Renderer.inspect(). */
|
|
90
41
|
export interface InstanceCollectionInspection extends InstanceCollectionInfo {
|
|
91
42
|
readonly residentGeneration: number | undefined;
|
|
92
43
|
readonly lane: InstanceSubmissionLane;
|
|
93
|
-
readonly dirtyRanges: readonly InstanceDirtyRange[];
|
|
94
44
|
readonly uploadRanges: readonly InstanceDirtyRange[];
|
|
95
45
|
readonly uploadedBytes: number;
|
|
96
46
|
readonly requestedBytes: number;
|
|
@@ -107,81 +57,46 @@ export interface InstanceCollectionInspection extends InstanceCollectionInfo {
|
|
|
107
57
|
| undefined;
|
|
108
58
|
}
|
|
109
59
|
|
|
110
|
-
export
|
|
111
|
-
readonly transforms
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
export interface InstanceCollectionUpdateInput {
|
|
115
|
-
/** Matrix ordinal of the first matrix to replace. */
|
|
116
|
-
readonly start: number;
|
|
117
|
-
readonly transforms: Float32Array;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export interface InstanceCollectionInvalidDetail {
|
|
121
|
-
readonly collectionId?: number;
|
|
122
|
-
readonly operation: 'create' | 'replace' | 'update' | 'inspect' | 'release';
|
|
123
|
-
readonly expected: string;
|
|
124
|
-
readonly actual: number | string;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export type InstanceCollectionErrorCode =
|
|
128
|
-
| 'instance-collection-invalid'
|
|
129
|
-
| 'instance-collection-not-found'
|
|
130
|
-
| 'instance-collection-released';
|
|
131
|
-
|
|
132
|
-
export class InstanceCollectionError extends Error {
|
|
133
|
-
readonly code: InstanceCollectionErrorCode;
|
|
134
|
-
readonly expected: string;
|
|
135
|
-
readonly hint: string;
|
|
136
|
-
readonly detail: InstanceCollectionInvalidDetail | undefined;
|
|
137
|
-
readonly owner = 'renderer.instances' as const;
|
|
138
|
-
readonly recovery: string;
|
|
139
|
-
readonly facts: InstanceCollectionFailureFacts;
|
|
140
|
-
|
|
60
|
+
export class InstanceTransformsError extends Error {
|
|
61
|
+
readonly code = 'instance-transforms-invalid' as const;
|
|
62
|
+
readonly expected = 'finite column-major mat4 values, with transforms.length a multiple of 16';
|
|
63
|
+
readonly hint = 'repair Instances.transforms in the World or source SceneAsset and retry';
|
|
141
64
|
constructor(
|
|
142
|
-
|
|
143
|
-
expected: string,
|
|
144
|
-
hint: string,
|
|
145
|
-
detail?: InstanceCollectionInvalidDetail,
|
|
146
|
-
facts?: InstanceCollectionFailureFacts,
|
|
65
|
+
readonly detail: { readonly actualLength: number; readonly nonFiniteIndex?: number },
|
|
147
66
|
) {
|
|
148
|
-
super(
|
|
149
|
-
this.name = '
|
|
150
|
-
this.code = code;
|
|
151
|
-
this.expected = expected;
|
|
152
|
-
this.hint = hint;
|
|
153
|
-
this.detail = detail;
|
|
154
|
-
this.facts =
|
|
155
|
-
facts ??
|
|
156
|
-
instanceCollectionFailureFacts(
|
|
157
|
-
code,
|
|
158
|
-
hint,
|
|
159
|
-
detail?.operation === 'create' || detail?.operation === 'replace'
|
|
160
|
-
? typeof detail.actual === 'number' && Number.isFinite(detail.actual)
|
|
161
|
-
? detail.actual * Float32Array.BYTES_PER_ELEMENT
|
|
162
|
-
: 0
|
|
163
|
-
: 0,
|
|
164
|
-
);
|
|
165
|
-
this.recovery = this.facts.recovery;
|
|
67
|
+
super('Instances.transforms must contain complete finite matrices');
|
|
68
|
+
this.name = 'InstanceTransformsError';
|
|
166
69
|
}
|
|
167
70
|
}
|
|
71
|
+
export function validateInstanceTransforms(
|
|
72
|
+
transforms: ArrayLike<number>,
|
|
73
|
+
): InstanceTransformsError | InstanceTransformsStrideMismatchError | undefined {
|
|
74
|
+
if (transforms.length % MATRIX_STRIDE !== 0)
|
|
75
|
+
return new InstanceTransformsStrideMismatchError(transforms.length);
|
|
76
|
+
for (let index = 0; index < transforms.length; index++) {
|
|
77
|
+
if (!Number.isFinite(transforms[index]))
|
|
78
|
+
return new InstanceTransformsError({
|
|
79
|
+
actualLength: transforms.length,
|
|
80
|
+
nonFiniteIndex: index,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
168
85
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
readonly
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
revision: number;
|
|
177
|
-
dirtyRanges: InstanceDirtyRange[];
|
|
178
|
-
/** Last revision detached for extraction; repeated reads of that revision
|
|
179
|
-
* retain the same ranges for multiple entities sharing one collection. */
|
|
180
|
-
lastSnapshotRevision: number;
|
|
181
|
-
released: boolean;
|
|
86
|
+
/** A new allocation must receive the complete payload, including after recovery. */
|
|
87
|
+
export function instanceUploadRangesForResident(
|
|
88
|
+
activeIsNew: boolean,
|
|
89
|
+
dirtyRanges: readonly InstanceDirtyRange[],
|
|
90
|
+
fullRange: InstanceDirtyRange,
|
|
91
|
+
): readonly InstanceDirtyRange[] {
|
|
92
|
+
return activeIsNew ? [fullRange] : dirtyRanges;
|
|
182
93
|
}
|
|
183
94
|
|
|
184
|
-
interface
|
|
95
|
+
interface Projection extends InstanceCollectionSnapshot {
|
|
96
|
+
readonly world: World;
|
|
97
|
+
readonly entity: number;
|
|
98
|
+
}
|
|
99
|
+
interface Residency {
|
|
185
100
|
readonly frameNumber: number;
|
|
186
101
|
readonly residentGeneration: number | undefined;
|
|
187
102
|
readonly lane: InstanceSubmissionLane;
|
|
@@ -193,279 +108,120 @@ interface CollectionResidency {
|
|
|
193
108
|
readonly error: InstanceCollectionInspection['error'];
|
|
194
109
|
}
|
|
195
110
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
while (capacity < required) capacity *= 2;
|
|
199
|
-
return capacity;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function invalid(
|
|
203
|
-
operation: InstanceCollectionInvalidDetail['operation'],
|
|
204
|
-
expected: string,
|
|
205
|
-
actual: number | string,
|
|
206
|
-
collectionId?: number,
|
|
207
|
-
context?: {
|
|
208
|
-
readonly requestedBytes?: number;
|
|
209
|
-
readonly supportedBytes?: number;
|
|
210
|
-
readonly cause?: string;
|
|
211
|
-
readonly recovery?: string;
|
|
212
|
-
},
|
|
213
|
-
): InstanceCollectionError {
|
|
214
|
-
const hint = 'repair the collection payload and retry the same authoring operation';
|
|
215
|
-
return new InstanceCollectionError(
|
|
216
|
-
'instance-collection-invalid',
|
|
217
|
-
expected,
|
|
218
|
-
hint,
|
|
219
|
-
{ operation, expected, actual, ...(collectionId === undefined ? {} : { collectionId }) },
|
|
220
|
-
instanceCollectionFailureFacts(
|
|
221
|
-
context?.cause ?? `invalid-${operation}-authoring`,
|
|
222
|
-
context?.recovery ?? hint,
|
|
223
|
-
context?.requestedBytes ?? 0,
|
|
224
|
-
context?.supportedBytes,
|
|
225
|
-
),
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
function validateTransforms(
|
|
230
|
-
operation: InstanceCollectionInvalidDetail['operation'],
|
|
231
|
-
transforms: Float32Array,
|
|
232
|
-
collectionId?: number,
|
|
233
|
-
): InstanceCollectionError | undefined {
|
|
234
|
-
if (!(transforms instanceof Float32Array)) {
|
|
235
|
-
return invalid(operation, 'transforms is a Float32Array', typeof transforms, collectionId, {
|
|
236
|
-
cause: 'invalid-transform-type',
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
if (transforms.length % MATRIX_STRIDE !== 0) {
|
|
240
|
-
return invalid(
|
|
241
|
-
operation,
|
|
242
|
-
`transforms.length is a multiple of ${MATRIX_STRIDE}`,
|
|
243
|
-
transforms.length,
|
|
244
|
-
collectionId,
|
|
245
|
-
{
|
|
246
|
-
requestedBytes: transforms.byteLength,
|
|
247
|
-
cause: 'invalid-transform-stride',
|
|
248
|
-
},
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
for (const value of transforms) {
|
|
252
|
-
if (!Number.isFinite(value)) {
|
|
253
|
-
return invalid(operation, 'every transform value is finite', value, collectionId, {
|
|
254
|
-
requestedBytes: transforms.byteLength,
|
|
255
|
-
cause: 'invalid-transform-value',
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
return undefined;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
function appendRange(ranges: InstanceDirtyRange[], start: number, end: number): void {
|
|
263
|
-
if (start >= end) return;
|
|
264
|
-
// Updates are allowed to arrive in any order. Insert at the first range
|
|
265
|
-
// whose end reaches the new interval, then consume every range that starts
|
|
266
|
-
// before the merged end. This preserves the complete union for both
|
|
267
|
-
// adjacent and overlapping writes (for example [10, 12) then [8, 11)).
|
|
268
|
-
let index = 0;
|
|
269
|
-
while (index < ranges.length) {
|
|
270
|
-
const existing = ranges[index];
|
|
271
|
-
if (existing === undefined || existing.end >= start) break;
|
|
272
|
-
index += 1;
|
|
273
|
-
}
|
|
274
|
-
while (index < ranges.length) {
|
|
275
|
-
const existing = ranges[index];
|
|
276
|
-
if (existing === undefined || existing.start > end) break;
|
|
277
|
-
start = Math.min(start, existing.start);
|
|
278
|
-
end = Math.max(end, existing.end);
|
|
279
|
-
ranges.splice(index, 1);
|
|
280
|
-
}
|
|
281
|
-
ranges.splice(index, 0, { start, end });
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
function appendDirtyRange(record: CollectionRecord, start: number, end: number): void {
|
|
285
|
-
appendRange(record.dirtyRanges, start, end);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
function missing(
|
|
289
|
-
operation: InstanceCollectionInvalidDetail['operation'],
|
|
290
|
-
id: InstanceCollectionId,
|
|
291
|
-
): InstanceCollectionError {
|
|
292
|
-
return new InstanceCollectionError(
|
|
293
|
-
'instance-collection-not-found',
|
|
294
|
-
`instance collection ${Number(id)} is live and owned by this Renderer`,
|
|
295
|
-
'create a collection with renderer.instances.create or retain the original collection id',
|
|
296
|
-
{ operation, expected: 'a live instance collection id', actual: Number(id), collectionId: id },
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Renderer-owned canonical storage for explicit instance transforms.
|
|
302
|
-
*
|
|
303
|
-
* ECS carries only `Instances.collectionId`; this owner keeps the copied
|
|
304
|
-
* matrices, revision and dirty intervals independent of archetype capacity.
|
|
305
|
-
* Snapshots are detached before they cross into extraction, so callers cannot
|
|
306
|
-
* mutate the canonical source behind the revision protocol.
|
|
307
|
-
*/
|
|
308
|
-
export class InstanceCollectionStore {
|
|
111
|
+
/** Rebuildable renderer projection. All authoring and entity lifetime belong to World. */
|
|
112
|
+
export class InstanceProjectionStore {
|
|
309
113
|
private nextId = 1;
|
|
310
|
-
private
|
|
311
|
-
private
|
|
312
|
-
private readonly records = new Map<InstanceCollectionId,
|
|
313
|
-
private readonly residency = new Map<InstanceCollectionId,
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
114
|
+
private nextGeneration = 1;
|
|
115
|
+
private identities = new WeakMap<World, Map<number, InstanceCollectionId>>();
|
|
116
|
+
private readonly records = new Map<InstanceCollectionId, Projection>();
|
|
117
|
+
private readonly residency = new Map<InstanceCollectionId, Residency>();
|
|
118
|
+
|
|
119
|
+
project(world: World, entity: number, transforms: ArrayLike<number>): InstanceCollectionSnapshot {
|
|
120
|
+
const collectionId =
|
|
121
|
+
this.identities.get(world)?.get(entity) ?? (this.nextId++ as InstanceCollectionId);
|
|
122
|
+
const previous = this.records.get(collectionId);
|
|
123
|
+
if (
|
|
124
|
+
previous !== undefined &&
|
|
125
|
+
previous.transforms.length === transforms.length &&
|
|
126
|
+
previous.transforms.every((value, index) => Object.is(value, transforms[index]))
|
|
127
|
+
)
|
|
128
|
+
return previous;
|
|
129
|
+
const count = transforms.length / MATRIX_STRIDE;
|
|
130
|
+
// Ordinals are identities within the authored array. Pose edits retain them;
|
|
131
|
+
// resizing seeds topology anew so new instances cannot inherit old motion.
|
|
132
|
+
const generations =
|
|
133
|
+
previous?.count === count
|
|
134
|
+
? previous.generations
|
|
135
|
+
: Uint32Array.from({ length: count }, () => this.nextGeneration++);
|
|
136
|
+
const record: Projection = {
|
|
137
|
+
collectionId,
|
|
138
|
+
world,
|
|
139
|
+
entity,
|
|
140
|
+
transforms: new Float32Array(transforms),
|
|
141
|
+
generations,
|
|
336
142
|
count,
|
|
337
|
-
|
|
338
|
-
revision: 1,
|
|
339
|
-
dirtyRanges: count === 0 ? [] : [{ start: 0, end: count }],
|
|
340
|
-
lastSnapshotRevision: 0,
|
|
341
|
-
released: false,
|
|
143
|
+
revision: (previous?.revision ?? 0) + 1,
|
|
342
144
|
};
|
|
343
|
-
|
|
344
|
-
this.epochValue += 1;
|
|
345
|
-
return ok(this.info(record));
|
|
145
|
+
return record;
|
|
346
146
|
}
|
|
347
147
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
148
|
+
/** Called only after the owning RenderScene accepts its prepared changes. */
|
|
149
|
+
accept(
|
|
150
|
+
world: World,
|
|
151
|
+
entity: number,
|
|
152
|
+
snapshot: {
|
|
153
|
+
readonly collectionId?: InstanceCollectionId;
|
|
154
|
+
readonly revision?: number;
|
|
155
|
+
readonly transforms: Float32Array;
|
|
156
|
+
readonly generations?: Uint32Array;
|
|
157
|
+
},
|
|
158
|
+
): void {
|
|
159
|
+
const { collectionId, revision, transforms, generations } = snapshot;
|
|
160
|
+
if (collectionId === undefined || revision === undefined || generations === undefined) return;
|
|
161
|
+
let entities = this.identities.get(world);
|
|
162
|
+
if (entities === undefined) {
|
|
163
|
+
entities = new Map();
|
|
164
|
+
this.identities.set(world, entities);
|
|
165
|
+
}
|
|
166
|
+
entities.set(entity, collectionId);
|
|
167
|
+
this.records.set(collectionId, {
|
|
168
|
+
collectionId,
|
|
169
|
+
revision,
|
|
170
|
+
transforms,
|
|
171
|
+
generations,
|
|
172
|
+
count: transforms.length / MATRIX_STRIDE,
|
|
173
|
+
world,
|
|
174
|
+
entity,
|
|
175
|
+
});
|
|
365
176
|
}
|
|
366
177
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
requestedBytes: input.transforms.byteLength,
|
|
379
|
-
supportedBytes: record.value.capacity * MATRIX_STRIDE * Float32Array.BYTES_PER_ELEMENT,
|
|
380
|
-
cause: 'invalid-update-range-start',
|
|
381
|
-
}),
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
const span = input.transforms.length / MATRIX_STRIDE;
|
|
385
|
-
const attemptedEnd = input.start + span;
|
|
386
|
-
if (attemptedEnd > record.value.count) {
|
|
387
|
-
return err(
|
|
388
|
-
invalid(
|
|
389
|
-
'update',
|
|
390
|
-
`start + matrix count is <= collection count (${record.value.count})`,
|
|
391
|
-
attemptedEnd,
|
|
392
|
-
id,
|
|
393
|
-
{
|
|
394
|
-
requestedBytes: attemptedEnd * MATRIX_STRIDE * Float32Array.BYTES_PER_ELEMENT,
|
|
395
|
-
supportedBytes: record.value.count * MATRIX_STRIDE * Float32Array.BYTES_PER_ELEMENT,
|
|
396
|
-
cause: 'invalid-update-range-end',
|
|
397
|
-
},
|
|
398
|
-
),
|
|
399
|
-
);
|
|
400
|
-
}
|
|
401
|
-
if (record.value.lastSnapshotRevision === record.value.revision) {
|
|
402
|
-
record.value.dirtyRanges = [];
|
|
178
|
+
release(world: World, entity: number): void {
|
|
179
|
+
const entities = this.identities.get(world);
|
|
180
|
+
const id = entities?.get(entity);
|
|
181
|
+
if (id === undefined) return;
|
|
182
|
+
entities?.delete(entity);
|
|
183
|
+
this.records.delete(id);
|
|
184
|
+
this.residency.delete(id);
|
|
185
|
+
}
|
|
186
|
+
retain(ids: ReadonlySet<InstanceCollectionId>): void {
|
|
187
|
+
for (const record of this.records.values()) {
|
|
188
|
+
if (!ids.has(record.collectionId)) this.release(record.world, record.entity);
|
|
403
189
|
}
|
|
404
|
-
record.value.transforms.set(input.transforms, input.start * MATRIX_STRIDE);
|
|
405
|
-
record.value.revision += 1;
|
|
406
|
-
appendDirtyRange(record.value, input.start, input.start + span);
|
|
407
|
-
this.epochValue += 1;
|
|
408
|
-
return ok(this.info(record.value));
|
|
409
190
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
191
|
+
dispose(): void {
|
|
192
|
+
this.records.clear();
|
|
193
|
+
this.residency.clear();
|
|
194
|
+
this.identities = new WeakMap();
|
|
414
195
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
* Return detached residency facts for every live collection.
|
|
418
|
-
*
|
|
419
|
-
* @internal Record-stage evidence is reported through the two methods below;
|
|
420
|
-
* callers only receive immutable PODs and never GPU handles.
|
|
421
|
-
*/
|
|
422
|
-
_inspections(): readonly InstanceCollectionInspection[] {
|
|
423
|
-
return Object.freeze(
|
|
424
|
-
[...this.records.values()].map((record) => this.projectInspection(record)),
|
|
425
|
-
);
|
|
196
|
+
_resetResidency(): void {
|
|
197
|
+
this.residency.clear();
|
|
426
198
|
}
|
|
427
199
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
readonly uploadRanges: readonly InstanceDirtyRange[];
|
|
435
|
-
readonly uploadedBytes: number;
|
|
436
|
-
readonly requestedBytes: number;
|
|
437
|
-
readonly supportedBytes: number | undefined;
|
|
438
|
-
readonly backend: InstanceBackendKind;
|
|
439
|
-
}): void {
|
|
200
|
+
_reportResidency(
|
|
201
|
+
input: Omit<Residency, 'error' | 'lane'> & {
|
|
202
|
+
readonly collectionId: InstanceCollectionId;
|
|
203
|
+
readonly lane: Exclude<InstanceSubmissionLane, 'unresident' | 'unavailable'>;
|
|
204
|
+
},
|
|
205
|
+
): void {
|
|
440
206
|
if (!this.records.has(input.collectionId)) return;
|
|
441
207
|
const previous = this.residency.get(input.collectionId);
|
|
442
|
-
const sameFrame =
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
const uploadRanges =
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
input.uploadRanges.map((range) => ({ ...range })),
|
|
453
|
-
)
|
|
454
|
-
: input.uploadRanges.map((range) => ({ ...range }));
|
|
208
|
+
const sameFrame = previous?.frameNumber === input.frameNumber && previous.error === undefined;
|
|
209
|
+
const ranges = [...(sameFrame ? previous.uploadRanges : []), ...input.uploadRanges]
|
|
210
|
+
.map((range) => ({ ...range }))
|
|
211
|
+
.sort((a, b) => a.start - b.start);
|
|
212
|
+
const uploadRanges: InstanceDirtyRange[] = [];
|
|
213
|
+
for (const range of ranges) {
|
|
214
|
+
const last = uploadRanges.at(-1);
|
|
215
|
+
if (last !== undefined && range.start <= last.end) last.end = Math.max(last.end, range.end);
|
|
216
|
+
else uploadRanges.push(range);
|
|
217
|
+
}
|
|
455
218
|
this.residency.set(input.collectionId, {
|
|
456
|
-
|
|
457
|
-
residentGeneration: input.residentGeneration,
|
|
458
|
-
lane: input.lane,
|
|
219
|
+
...input,
|
|
459
220
|
uploadRanges,
|
|
460
|
-
uploadedBytes: sameFrame ? previous.uploadedBytes
|
|
461
|
-
requestedBytes: input.requestedBytes,
|
|
462
|
-
supportedBytes: input.supportedBytes,
|
|
463
|
-
backend: input.backend,
|
|
221
|
+
uploadedBytes: input.uploadedBytes + (sameFrame ? previous.uploadedBytes : 0),
|
|
464
222
|
error: undefined,
|
|
465
223
|
});
|
|
466
224
|
}
|
|
467
|
-
|
|
468
|
-
/** @internal Renderer record owner reports a typed admission failure. */
|
|
469
225
|
_reportFailure(input: {
|
|
470
226
|
readonly collectionId: InstanceCollectionId;
|
|
471
227
|
readonly code: InstanceCollectionFailureCode;
|
|
@@ -491,121 +247,24 @@ export class InstanceCollectionStore {
|
|
|
491
247
|
},
|
|
492
248
|
});
|
|
493
249
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
/**
|
|
513
|
-
* Read a detached matrix view without advancing the render-consumption
|
|
514
|
-
* cursor. Inspection and picking may call this between authoring updates;
|
|
515
|
-
* the next renderer snapshot must still receive the complete dirty union.
|
|
516
|
-
*/
|
|
517
|
-
peek(id: InstanceCollectionId): InstanceCollectionResult<InstanceCollectionSnapshot> {
|
|
518
|
-
const record = this.live('inspect', id);
|
|
519
|
-
return record.ok ? ok(this.detachedSnapshot(record.value)) : record;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
release(id: InstanceCollectionId): InstanceCollectionResult<void> {
|
|
523
|
-
const record = this.records.get(id);
|
|
524
|
-
if (record === undefined) return err(missing('release', id));
|
|
525
|
-
if (record.released) {
|
|
526
|
-
return err(
|
|
527
|
-
new InstanceCollectionError(
|
|
528
|
-
'instance-collection-released',
|
|
529
|
-
`instance collection ${Number(id)} has not already been released`,
|
|
530
|
-
'do not reuse a released collection id; create a new collection',
|
|
531
|
-
{
|
|
532
|
-
operation: 'release',
|
|
533
|
-
expected: 'a live instance collection id',
|
|
534
|
-
actual: Number(id),
|
|
535
|
-
collectionId: id,
|
|
536
|
-
},
|
|
537
|
-
),
|
|
538
|
-
);
|
|
539
|
-
}
|
|
540
|
-
record.released = true;
|
|
541
|
-
this.records.delete(id);
|
|
542
|
-
this.residency.delete(id);
|
|
543
|
-
this.epochValue += 1;
|
|
544
|
-
return ok(undefined);
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
/** Drop all canonical matrices during Renderer disposal. */
|
|
548
|
-
dispose(): void {
|
|
549
|
-
if (this.disposed) return;
|
|
550
|
-
this.disposed = true;
|
|
551
|
-
for (const record of this.records.values()) record.released = true;
|
|
552
|
-
this.records.clear();
|
|
553
|
-
this.residency.clear();
|
|
554
|
-
this.epochValue += 1;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
private live(
|
|
558
|
-
operation: InstanceCollectionInvalidDetail['operation'],
|
|
559
|
-
id: InstanceCollectionId,
|
|
560
|
-
): InstanceCollectionResult<CollectionRecord> {
|
|
561
|
-
if (!Number.isInteger(id) || id <= 0) {
|
|
562
|
-
return err(invalid(operation, 'collectionId is a positive integer', id, id));
|
|
563
|
-
}
|
|
564
|
-
if (this.disposed) {
|
|
565
|
-
return err(
|
|
566
|
-
new InstanceCollectionError(
|
|
567
|
-
'instance-collection-released',
|
|
568
|
-
'the Renderer-owned instance collection store is live',
|
|
569
|
-
'create a new Renderer before using instance collections',
|
|
570
|
-
{ operation, expected: 'a live collection store', actual: 'disposed', collectionId: id },
|
|
571
|
-
),
|
|
572
|
-
);
|
|
573
|
-
}
|
|
574
|
-
const record = this.records.get(id);
|
|
575
|
-
return record === undefined ? err(missing(operation, id)) : ok(record);
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
private detachedSnapshot(record: CollectionRecord): InstanceCollectionSnapshot {
|
|
579
|
-
return {
|
|
580
|
-
...this.info(record),
|
|
581
|
-
transforms: new Float32Array(record.transforms),
|
|
582
|
-
dirtyRanges: record.dirtyRanges.map((range) => ({ ...range })),
|
|
583
|
-
};
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
private info(record: CollectionRecord): InstanceCollectionInfo {
|
|
587
|
-
return Object.freeze({
|
|
588
|
-
collectionId: record.id,
|
|
589
|
-
count: record.count,
|
|
590
|
-
capacity: record.capacity,
|
|
591
|
-
revision: record.revision,
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
private projectInspection(record: CollectionRecord): InstanceCollectionInspection {
|
|
596
|
-
const residency = this.residency.get(record.id);
|
|
597
|
-
return Object.freeze({
|
|
598
|
-
...this.info(record),
|
|
599
|
-
residentGeneration: residency?.residentGeneration,
|
|
600
|
-
lane: residency?.lane ?? 'unresident',
|
|
601
|
-
dirtyRanges: Object.freeze(record.dirtyRanges.map((range) => ({ ...range }))),
|
|
602
|
-
uploadRanges: Object.freeze(residency?.uploadRanges.map((range) => ({ ...range })) ?? []),
|
|
603
|
-
uploadedBytes: residency?.uploadedBytes ?? 0,
|
|
604
|
-
requestedBytes: residency?.requestedBytes ?? record.count * MATRIX_STRIDE * 4,
|
|
605
|
-
supportedBytes: residency?.supportedBytes,
|
|
606
|
-
backend: residency?.backend ?? 'unknown',
|
|
607
|
-
owner: 'renderer.instances',
|
|
608
|
-
error: residency?.error,
|
|
250
|
+
_inspections(frameNumber: number): readonly InstanceCollectionInspection[] {
|
|
251
|
+
return [...this.records.values()].map((record) => {
|
|
252
|
+
const resident = this.residency.get(record.collectionId);
|
|
253
|
+
const current = resident?.frameNumber === frameNumber;
|
|
254
|
+
return {
|
|
255
|
+
collectionId: record.collectionId,
|
|
256
|
+
count: record.count,
|
|
257
|
+
revision: record.revision,
|
|
258
|
+
residentGeneration: resident?.residentGeneration,
|
|
259
|
+
lane: resident?.lane ?? 'unresident',
|
|
260
|
+
uploadRanges: current ? resident.uploadRanges.map((range) => ({ ...range })) : [],
|
|
261
|
+
uploadedBytes: current ? resident.uploadedBytes : 0,
|
|
262
|
+
requestedBytes: resident?.requestedBytes ?? record.transforms.byteLength,
|
|
263
|
+
supportedBytes: resident?.supportedBytes,
|
|
264
|
+
backend: resident?.backend ?? 'unknown',
|
|
265
|
+
owner: 'renderer.instances',
|
|
266
|
+
error: resident?.error,
|
|
267
|
+
};
|
|
609
268
|
});
|
|
610
269
|
}
|
|
611
270
|
}
|