facett-core 0.1.17

facett — visual kernel: render a node/edge Scene into egui (wgpu fast path to come)
Documentation
//! **The L0 GPU lane** (feature `wgpu`) — the extracted shared scaffold the three
//! skin kernels (facett-map `GpuMapRenderer`, facett-map3d `Map3dRenderer`,
//! facett-graph3d `LogoRenderer`) will be re-pointed at in Phase C.
//!
//! All three share the identical `egui_wgpu::CallbackTrait` plumbing: a `*Renderer`
//! stored in `callback_resources`, **installed once** via an `install_renderer`,
//! driven by a paint callback. Phase A extracts:
//!
//! - [`types`] — the bytemuck `Vertex`/`Uniform`/`DrawIndirectArgs` structs +
//!   `color32_to_f32` (byte-identical to the skins' copies).
//! - [`buffer`] — the upload-once + **chunking** algorithm (fix #12), verbatim.
//! - [`install_renderer`] — the install-once lifecycle each kernel hand-rolls.
//! - [`CULL_WGSL`] / [`DRAW_WGSL`] — the cull + draw shaders, **byte-identical** to
//!   `facett-map/src/gpu/*.wgsl` (do not change their semantics).
//!
//! Nothing in the skins consumes this yet — it is the scaffold for Phase B/C.

/// **wgpu glue for the adapter-selection policy** — `wgpu::AdapterInfo` →
/// [`AdapterFacts`](crate::render::adapter::AdapterFacts), the live selector, the
/// `request_best_adapter` replacement for the naive headless probes, and the
/// `egui_wgpu::WgpuConfiguration` an eframe host installs. See [`adapter_wgpu`].
pub mod adapter_wgpu;
pub mod blur;
pub mod buffer;
/// **THE shared instanced graph-cloud renderer** — screen-space emissive node discs
/// + edge filaments as GPU instances, plus the live `egui_wgpu` paint callback and
/// its install-once lifecycle. Consumed by `facett-graph3d` (which re-exports it as
/// `graph_gpu`) AND by the 2-D graph family (`facett-graphpan` / `facett-graphview` /
/// `facett-graphnav`). See [`graphcloud`].
pub mod graphcloud;
/// **Final-look colour grade** (AgX tonemap + vignette + film grain + CAS sharpen +
/// blue-noise-style dither) as an optional post over the HDR offscreen colour — a
/// new, composable seam that does **not** touch the map3d ACES tonemap. See
/// [`colorgrade`].
pub mod colorgrade;
/// **GPU label collision + the indirect label draw** (GFX_V2 §3.B item 4) — three
/// compute passes over a fixed spatial grid whose third pass *produces the draw* by
/// `atomicAdd`ing onto a `DrawIndirectArgs`. The collision rule itself lives in
/// [`crate::label_grid`]; the WGSL here is its device transcription. See
/// [`label_collide`].
pub mod label_collide;
/// **MSDF text / label rendering** — crisp glowing labels at any zoom from a
/// multi-channel signed-distance-field atlas. See [`msdf`].
pub mod msdf;
pub mod offscreen;
/// **The in-GPU pass clock** — TIMESTAMP_QUERY around a lane's encoded passes,
/// resolved through a non-blocking readback ring into the per-lane clock stats
/// (`crate::render::lane::clock_stats_of`). Feature-detected; a device without the
/// feature reports `None`, never `0`. See [`pass_clock`].
pub mod pass_clock;
/// **OIT — order-independent transparency via per-pixel fragment linked lists**
/// (GFX_V2 §3.C item 7): gather every translucent fragment onto its pixel's list,
/// then sort and composite per pixel in one fullscreen resolve. See [`oit`].
pub mod oit;
/// **GPU picking — the colour-encoded ID pass** (GFX_V2 §7 item 8): render pickable
/// geometry into an `R32Uint` target where the value IS the [`PickId`](crate::engine::pick::PickId),
/// then read back the texel under the cursor. See [`picking`].
pub mod picking;
/// **The host lane for GPU picking** — install-once + the one `pick_at` entry point a
/// widget calls to turn a click into a `PickId`. See [`pick_host`].
pub mod pick_host;
/// **GPU compute particles** — storage-buffer boids stepped in a compute shader and
/// drawn as soft additive points into the HDR target. See [`particles`].
pub mod particles;
/// **THE one GPU→CPU readback** — the `map_async` + row-padding dance, spelled once
/// instead of in seventeen hand-rolled copies. See [`readback`].
pub mod readback;
pub mod sdf_pipeline;
/// **TAA — Halton jitter + a velocity-reprojecting temporal resolve** (GFX_V2 §5
/// item 7): the fix for sub-pixel vector lines shimmering under camera motion, which
/// MSAA cannot solve. See [`taa`].
pub mod taa;
pub mod types;

pub use adapter_wgpu::{
    decide_for, facett_wgpu_options, facts_of, facts_of_all, kind_of, preferred_backends,
    request_best_adapter, select_adapter,
};
pub use blur::{gaussian_taps, GaussianBlur, BLUR_WGSL};
pub use graphcloud::{
    render_graph_offscreen, BloomParams, EdgeInstance, GraphGpu, GraphRender, GraphScene,
    NodeInstance,
};
pub use buffer::{
    ChunkSpan, chunk_budget, chunk_budget_stride, partition_chunks, partition_chunks_stride,
    rebase_chunk_meta,
};
pub use colorgrade::{
    agx_tonemap, ign, srgb_oetf, vignette_factor, ColorGrade, ColorGradeParams, COLORGRADE_WGSL,
};
pub use label_collide::{
    LabelCollider, LabelStats, LABEL_COLLIDE_WGSL, LABEL_DRAW_WGSL, LABEL_GLYPH_CAPACITY,
};
pub use msdf::{
    coverage, disk_msdf_atlas, median3, screen_px_range, GlyphInstance, MsdfText, MSDF_WGSL,
};
pub use particles::{
    advect_cpu, step_cpu, DrawParams, FlowGeometry, GpuParticles, Particle, ParticleBuffers,
    SimParams, PARTICLES_WGSL,
};
pub use offscreen::{
    gpu_scissor_px, scissor_intersection, OffscreenColorDepth, ScissorPx, BLIT_WGSL, DEPTH_FORMAT,
    OFFSCREEN_FORMAT,
};
pub use oit::{
    OitBatch, OitPass, OitVertex, OIT_DEFAULT_LAYERS, OIT_MAX_LAYERS, OIT_NODE_SIZE,
    OIT_VERTEX_STRIDE, OIT_WGSL,
};
pub use pass_clock::{PassClock, PassClockSlot, PASS_CLOCK_FEATURES};
pub use pick_host::{install_pick_host, pick_at, pick_host_installed, pick_passes_run, PickHost};
pub use readback::{map_read_all, read_buffer_range, read_texture_region, strip_row_padding};
pub use taa::{
    halton, history_weight, jitter_px, TaaPass, TAA_FEEDBACK_CAP, TAA_PHASES, TAA_WGSL,
};
pub use picking::{
    logical_to_texel, painter_depth, PickBatch, PickPass, PickTarget, PickVertex,
    PICK_DEPTH_FORMAT, PICK_FORMAT, PICK_VERTEX_STRIDE, PICK_WGSL,
};
pub use sdf_pipeline::{
    GpuSdfHeadless, GpuSdfRenderer, SdfUniforms, offscreen_render, LINE_WGSL, SDF_WGSL,
};
pub use types::{
    DrawIndirectArgs, DrawUniforms, GPU_WAY_FLAG_FILL, GpuWayMeta, Vertex, ViewportCull,
    color32_to_f32, rebase_vertex_origin,
};

/// **The shader TEXT lives in [`crate::render::wgsl`]**, which is NOT behind this
/// feature — a `.wgsl` source string needs `include_str!` and nothing else, and
/// keeping it here put the shader-CONTRACT guards (`cull.wgsl` is the shader every
/// road on the map goes through) out of reach of a default `cargo test`. Re-exported
/// so every existing `facett_core::render::gpu::*_WGSL` path still resolves.
pub use crate::render::wgsl::{COMMON_WGSL, CULL_WGSL, DRAW_WGSL, wgsl};

/// **Install-once** lifecycle, generic over the renderer type — the pattern all
/// three skin kernels hand-roll (`install_renderer` in facett-map / facett-map3d /
/// facett-graph3d). If a renderer of type `R` is already in the egui-wgpu
/// `RenderState`'s `callback_resources`, this is a no-op; otherwise `make` builds
/// one (from the device + target format) and inserts it. Hosts call this once at
/// startup so the paint callback can `resources.get::<R>()`.
///
/// Returns `true` if a renderer was newly installed, `false` if one already existed.
///
/// It also **registers the lane** with [`crate::render::lane`] under
/// `std::any::type_name::<R>()`, whether or not this call did the inserting. That is
/// how an About box can say "a GPU lane is installed" without every lane wiring
/// itself up: the one install writer is the one place that knows. A lane that also
/// counts frames declares it next to its own install
/// ([`lane::note_reports_frames`](crate::render::lane::note_reports_frames)).
pub fn install_renderer<R, F>(render_state: &egui_wgpu::RenderState, make: F) -> bool
where
    R: 'static + Send + Sync,
    F: FnOnce(&wgpu::Device, wgpu::TextureFormat) -> R,
{
    crate::render::lane::note_installed(std::any::type_name::<R>());
    if render_state.renderer.read().callback_resources.get::<R>().is_some() {
        return false; // already installed
    }
    let renderer = make(&render_state.device, render_state.target_format);
    render_state.renderer.write().callback_resources.insert(renderer);
    true
}