facett-graphview/Cargo.toml
[package]
name = "facett-graphview"
description = "facett — a domain-agnostic 2D graph render engine: a GraphModel + Camera lowered to RGBA pixels by the vello_cpu rasterizer, plus a wgpu compute force-layout (feature `gpu`), a spatial pick index, and a legibility pass (label collision + edge ink budget). The intended home for every graph surface (dep/arch/release dashboards, korp, graph-DB browsing). Two rasterizer lanes share ONE geometry builder (`scene::build`): the default `vello_cpu` reference, and — behind feature `gpu` — a live `vello`-on-wgpu-29 path (`render_to_rgba`'s GpuVello arm renders the scene on a wgpu device and reads it back to RGBA), falling back to CPU when no adapter exists."
version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
# Development notes, agent instructions and machine-local tooling stay in the
# repository; they are not part of the published crate.
exclude = [
".nornir/",
]
[features]
default = []
# The GPU path (vello on wgpu 29 — the same wgpu the egui 0.34 stack already
# pins). OFF by default: the CPU path (vello_cpu, a transitive dep of epaint
# 0.34 already) is the reference and is always built. ON adds the wgpu device
# probe + GPU rasterizer seam (currently scaffolded — see lib::gpu).
#
# CONS-CORE Phase C: turning `gpu` on also lights up the L0 SDF kernel in
# facett-core (`facett-core/wgpu`) so the opt-in L0 Canvas path
# (`cpu_l0`/`render_to_rgba_l0`) can run on the GPU instead of the CPU lane.
gpu = ["dep:vello", "dep:wgpu29", "dep:wgpu", "dep:pollster", "dep:bytemuck", "dep:resvg", "facett-core/wgpu"]
# Stream a GPU-layout CSR straight from an Arrow edge batch (Int64 src/dst + an
# optional Float64 weight column) — the `gpu_layout::GraphCsr::from_arrow` front door.
# arrow-array already builds transitively in this workspace, so ON adds no new crate.
arrow = ["dep:arrow-array"]
# The SHARED instanced graph-cloud GPU lane (facett-core's `graphcloud` — the same
# renderer facett-graph3d installs and facett-graphpan paints through). Separate from
# `gpu` (which is the vello rasterizer seam) because they answer different questions and
# a host may want one without the other. OFF by default: `legible::draw_gpu_cloud` then
# compiles to a `false` and the CPU painter always runs, so every golden is unchanged.
gpu-cloud = ["facett-core/wgpu"]
# L4: functional-status emitter passthrough (see facett-core::testmatrix). When
# OFF (the release default) every `facett_core::testmatrix::emit(...)` call in the
# render-call-chain coverage tests compiles to a no-op; ON appends one functional
# row per real check to the `nornir test` matrix. ADDITIVE: no source path changes.
testmatrix = ["facett-core/testmatrix"]
[dependencies]
# CONS-CORE L0 kernel: the shared render seam (Backend/GpuProbe/decide are
# re-pointed here; nodes lower to L0 SDF QuadInstances + edges to LineInstances,
# rastered through the core CpuCanvas). graphview re-exports the backend types
# for back-compat. The CPU `cpu::render` reference path is untouched + default.
facett-core = { path = "../facett-core", version = "0.3.0" }
# CPU rasterizer — already in the workspace lock as a transitive dep of
# epaint 0.34 (egui's own paint layer pulls vello_cpu). Guaranteed to build.
vello_cpu = "0.0.6"
# egui only for the color-compat seam (Color32 <-> vello color) so callers that
# already speak egui (nornir's draw_graph) drop straight in. No render path here.
egui = { workspace = true }
# state_json() for the clip-render report — the observable the EMIT-DOCTRINE asserts
# on (counts per stage) instead of an emit row. Same dep map3d's state_json uses.
serde_json = { workspace = true }
# The Elm `Model` (FC-3) must be Serialize + DeserializeOwned so the harness can
# round-trip observable state; the metro/graph model structs derive it.
serde = { version = "1", features = ["derive"] }
# GPU path deps — only compiled with `gpu`. Versions match the egui 0.34 stack
# (vello 0.9 → wgpu 29.0.3, exactly egui-wgpu 0.34's wgpu). No version war.
# `default-features = false` + `wgpu` WITHOUT `wgpu_default` (LAW 4 / GFX_V2 Decision 0).
# vello's default set is `["wgpu", "wgpu_default"]`, and `wgpu_default` is exactly what
# its name says — it turns on wgpu's OWN defaults, which include `wgpu-hal/default` and
# therefore **glow**, the GL backend this constellation dropped. `wgpu` alone gives the
# renderer (`dep:wgpu` + `vello_shaders` + `futures-intrusive`) and nothing else; the
# backends come from the workspace `wgpu` entry, which lists vulkan/dx12/metal/webgpu and
# no GL. This was the SHIPPED edge `facett-core/tests/webgl_free_law.rs` red-fired on.
vello = { version = "0.9", optional = true, default-features = false, features = ["wgpu"] }
# vello renders on its OWN wgpu 29 device (`src/gpu.rs` imports this as `wgpu`):
# vello 0.9/0.10 need wgpu 29, egui 0.36 is on wgpu 30. Drop when vello ships on 30.
wgpu29 = { workspace = true, optional = true }
wgpu = { workspace = true, optional = true }
pollster = { version = "1", optional = true }
bytemuck = { version = "1", optional = true }
# The MEGA-still text layer: rasterise the crisp vector <text>/legend SVG overlay and
# burn it OVER the GPU raster — PURE RUST (resvg re-exports usvg + tiny_skia, the same
# stack facett-docview uses; no pdfium/inkscape/native libs). Only compiled with `gpu`
# (the mega composite is a gpu-feature capability). Pinned to the workspace's 0.47.
resvg = { version = "0.47", optional = true }
# Arrow edge-batch ingestion for the GPU layout (feature `arrow`). Pinned to the
# workspace's existing arrow-array major (58) so no second version enters the lock.
arrow-array = { version = "59", optional = true }
[dev-dependencies]
# `tests/resident_lane.rs` opens the installed-renderer gate without a device
# (`cloud-test-gate`) to count what the resident lane uploads over plain egui frames.
facett-core = { path = "../facett-core", features = ["cloud-test-gate"] }
# Benchmark: vello_cpu raster vs egui's epaint tessellation on a synthetic graph.
criterion = { version = "0.8", default-features = false }
# PNG out for the headless render proof + the demo example.
image = { version = "0.25", default-features = false, features = ["png"] }
# epaint tessellation baseline for the benchmark.
egui = { workspace = true }
[[bench]]
name = "raster"
harness = false
# The world-graph STILL: converge a galaxy layout and render it once, headless, on the
# GPU into a PNG (the 100k+ "mega tier"). Needs the `gpu` feature (wgpu offscreen cloud).
[[example]]
name = "world_still"
required-features = ["gpu"]
# The MEGA composite still: a dense tiled GPU raster of the whole world-graph universe
# (100k–1M nodes) with a crisp vector TEXT/label layer (repo labels at cluster centroids,
# title, legend, counts) burned OVER it into ONE huge image. Needs `gpu` (wgpu offscreen
# cloud + resvg). Raster format: PNG (no pure-Rust JPEG2000 encoder exists — see the docs).
[[example]]
name = "world_mega_still"
required-features = ["gpu"]
# Times the GPU force layout on every hardware adapter (discrete AND integrated).
[[example]]
name = "gpu_layout_adapters"
required-features = ["gpu"]
# The bench matrix: force layout 1k/10k/100k × {gpu, gpu-grid, cpu-1, cpu-all}, FDEB
# gpu vs cpu, point cloud 100k/1M — the rows `.nornir/facett-benchmarks.md` quotes.
[[example]]
name = "layout_matrix"
required-features = ["gpu"]