Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

facett-map3d/tests/gpu_lane_before_the_first_frame.rs

//! **A lane that has not been measured must not report the CPU painter.**
//!
//! # The defect, and how long it cost
//!
//! `Map3D::used_gpu()` read a `Cell<bool>` seeded `false` and written only inside
//! [`Map3D::view`]. Any host reading it OUTSIDE a paint therefore got `false` — the same
//! value the genuine failure produces. korp's `rebuild_map3d` logs one line per 3D
//! rebuild and that line runs *before the first frame*, so on the owner's session of
//! 2026-08-06 it printed:
//!
//! ```text
//! rebuild: … gpu=false building_ways=2 scene_ways=34965 …
//! rebuild: … gpu=false building_ways=0 scene_ways=86 …
//! ```
//!
//! on a build where the feature was compiled in (`map3d-gpu = ["facett-map3d/wgpu"]`),
//! the adapter had come up (`AMD Radeon 890M (RADV STRIX1)`), the renderer was installed
//! (`korp/src/main.rs`, `facett_map3d::gpu::install_renderer`) and the backend swap had
//! run (`with_gpu(true)`). Three separate people read that `false` as the root cause and
//! went looking for a broken install. There was none. The number was an artefact of WHERE
//! it was read.
//!
//! # What is asserted, and in which direction it goes red
//!
//! Two states that a `bool` cannot tell apart, asserted to be distinct:
//!
//! * **before any paint** — [`Map3D::used_gpu_observed`] is `None`. Restore the old
//!   `Cell<bool>` (or make `used_gpu_observed` return `Some(self.used_gpu())`) and
//!   `never_measured_is_not_the_cpu_painter` fails on this line, because `Some(false)`
//!   is then indistinguishable from a real CPU-painter frame.
//! * **after a paint** — it is `Some(_)`, and `Some(false)` on the CPU lane. Delete the
//!   `set(Some(..))` in `view` and `a_painted_frame_reports_its_lane` fails: the
//!   observation never appears.
//!
//! And the question a host CAN answer early: [`Map3D::gpu_lane_selected`] is decided by
//! the constructor, so it is `true` the instant `with_gpu(true)` has run — which is the
//! half that separates "the lane was never chosen" from "the lane was chosen and
//! something fell back". Neutralise the swap in `with_gpu` and
//! `the_selected_lane_is_known_before_the_first_frame` goes red.
//!
//! Everything here is measured on APPLIED OUTPUT: the observation left behind by a real
//! `view()` call through a real egui pass, never a setter read back.

use facett_core::{Facet, Theme};
use facett_map::Way;
use facett_map3d::Map3D;

/// A tiny scene — this file is about the observation, not the geometry.
fn scene() -> Map3D {
    let theme = Theme::default();
    let ring = |lon: f64, lat: f64, h: f64| {
        vec![(lon - h, lat - h), (lon + h, lat - h), (lon + h, lat + h), (lon - h, lat + h), (lon - h, lat - h)]
    };
    let mut ways: Vec<Way> = Vec::new();
    for i in 0..6 {
        let d = f64::from(i) * 0.0004;
        ways.extend(Way::from_lonlat(
            100 + i64::from(i),
            &ring(18.0686 + d, 59.3293 + d, 0.00008),
            &[("building", "yes")],
            &theme,
        ));
    }
    Map3D::from_geometry("lane probe", &ways)
}

/// Run one real egui pass over `map` and hand back what it observed.
fn paint_once(mut map: Map3D) -> Option<bool> {
    let seen = std::rc::Rc::new(std::cell::Cell::new(Some(true)));
    let cell = seen.clone();
    let mut harness = egui_kittest::Harness::builder()
        .with_size(egui::vec2(320.0, 240.0))
        .build_ui(move |ui| {
            facett_core::set_theme(ui.ctx(), Theme::default());
            map.ui(ui);
            cell.set(map.used_gpu_observed());
        });
    harness.run_steps(2);
    seen.get()
}

/// **THE RED LINE.** A freshly built scene has never been painted, so no lane has been
/// observed — and that is a different fact from "the CPU painter drew it".
#[test]
fn never_measured_is_not_the_cpu_painter() {
    let map = scene();
    assert_eq!(
        map.used_gpu_observed(),
        None,
        "a scene that has not been painted must report NO observation, not Some(false) — \
         `Some(false)` is the spelling of the actual defect and korp's log printed it as \
         `gpu=false` for a working GPU build"
    );
    // The old signature is kept, and it is exactly as blind as it was — which is why the
    // rule is that out-of-paint readers must not use it. Pinned so a future change that
    // makes `used_gpu()` panic or diverge is caught here rather than in a host's log.
    assert!(!map.used_gpu(), "the lossy spelling still collapses `None` to false");
}

/// After a real egui pass the observation EXISTS, and on the CPU lane it is `false`.
/// This is what makes the `None` above meaningful: the field is not simply always `None`.
#[test]
fn a_painted_frame_reports_its_lane() {
    let observed = paint_once(scene());
    assert_eq!(
        observed,
        Some(false),
        "one real paint through the CPU painter must leave Some(false) behind — \
         got {observed:?}"
    );
}

/// The half that IS answerable before the first frame. Without the `wgpu` feature there
/// is only one backend, so the assertion is that the selected lane is reported honestly
/// as the CPU one — not that a GPU lane exists.
#[test]
fn the_selected_lane_is_known_before_the_first_frame() {
    let map = scene();
    assert!(!map.gpu_lane_selected(), "the default backend is the CPU painter");
    assert_eq!(map.backend_name(), "cpu-painter", "and it says so by name");
    assert_eq!(map.used_gpu_observed(), None, "…while nothing has been observed yet");

    #[cfg(feature = "wgpu")]
    {
        let g = scene().with_gpu(true);
        assert!(
            g.gpu_lane_selected(),
            "with_gpu(true) selects the wgpu lane, and that is knowable at construction"
        );
        assert_eq!(g.backend_name(), "wgpu-vello");
        // **The owner's exact state, and the reason this file exists.** Selected, and not
        // yet observed. A host printing `false` here is printing an artefact.
        assert_eq!(
            g.used_gpu_observed(),
            None,
            "the lane is selected but no frame has run — the two facts are independent"
        );
    }
}

/// **`Some(true)` on a REAL wgpu device, read AFTER the paint.** The other half of the
/// pair: without it, every assertion above is consistent with a lane that can only ever
/// report `false`, which is the shape of the very defect this file is about.
///
/// The adapter is printed, because "the GPU lane ran" on a llvmpipe/lavapipe software
/// adapter is a different claim from the same words on a real card, and korp has been
/// burned by not saying which.
///
/// Self-skipping when no adapter comes up (the honest CI answer), and it says so loudly
/// rather than passing quietly.
#[cfg(feature = "wgpu")]
#[test]
fn a_real_gpu_paint_reports_some_true() {
    use egui_kittest::wgpu::{WgpuTestRenderer, create_render_state};
    // **facett's OWN adapter policy, not egui_kittest's default.** `default_wgpu_setup()`
    // lets wgpu's internal preference order answer, and on this box that hands back
    // `llvmpipe [Cpu/Vulkan]` while an RTX 4090 sits beside it — so a green here would have
    // said "the GPU lane ran" about a software rasteriser. `facett_wgpu_options` installs
    // the same `native_adapter_selector` korp's `NativeOptions` does (discrete first,
    // llvmpipe/lavapipe and BMC consoles LAST), which is the policy the shipped binary
    // actually runs under.
    let setup = facett_core::render::gpu::adapter_wgpu::facett_wgpu_options().wgpu_setup;
    let rs = create_render_state(setup, Default::default());
    let info = rs.adapter.get_info();
    println!("  adapter: {} [{:?}/{:?}]", info.name, info.device_type, info.backend);
    facett_map3d::gpu::install_renderer(&rs);

    let mut map = scene().with_gpu(true);
    assert!(map.gpu_lane_selected(), "the wgpu lane is selected before any frame");
    assert_eq!(map.used_gpu_observed(), None, "…and nothing has been observed yet");

    let seen = std::rc::Rc::new(std::cell::Cell::new(None));
    let cell = seen.clone();
    let mut harness = egui_kittest::Harness::builder()
        .with_size(egui::vec2(640.0, 480.0))
        .renderer(WgpuTestRenderer::from_render_state(rs))
        .build_ui(move |ui| {
            facett_core::set_theme(ui.ctx(), Theme::default());
            map.ui(ui);
            cell.set(map.used_gpu_observed());
        });
    harness.run_steps(3);
    let _img = harness.render().expect("wgpu render");
    assert_eq!(
        seen.get(),
        Some(true),
        "a real wgpu paint through the installed renderer must observe the GPU lane — \
         got {:?} on adapter {} [{:?}/{:?}]",
        seen.get(),
        info.name,
        info.device_type,
        info.backend,
    );
    println!(
        "  used_gpu AFTER paint = Some(true) on {} [{:?}/{:?}]",
        info.name, info.device_type, info.backend
    );
}

/// **`used_gpu` must mean "the GPU lane DISPATCHED", not "this backend ran".**
///
/// The two halves of the GPU path are useless apart — korp's own comment at the install
/// site says so — and the field that exists to separate them could not see the second one
/// missing. MEASURED 2026-08-06, RTX 4090 [DiscreteGpu/Vulkan]: `with_gpu(true)` with **no**
/// `install_renderer` reported `used_gpu = Some(true)`. "The install is not reaching" was
/// the leading theory for a flat 3D pane for most of that day, and the number everyone was
/// reading would have said `true` either way.
///
/// Asserted as an EQUALITY against `renderer_installed()` rather than against a constant,
/// because the lane registry is per-process and test order is not fixed: whichever state
/// this binary happens to be in, the two must agree. Restore the literal `true` in
/// `WgpuVelloBackend::paint` and this fails on any run where no renderer is installed.
#[cfg(feature = "wgpu")]
#[test]
fn used_gpu_means_the_lane_dispatched_not_that_the_backend_ran() {
    use egui_kittest::wgpu::{WgpuTestRenderer, create_render_state};
    let setup = facett_core::render::gpu::adapter_wgpu::facett_wgpu_options().wgpu_setup;
    let rs = create_render_state(setup, Default::default());
    let info = rs.adapter.get_info();
    // DELIBERATELY no `install_renderer` — that is the whole experiment.
    let mut map = scene().with_gpu(true);
    let seen = std::rc::Rc::new(std::cell::Cell::new(None));
    let cell = seen.clone();
    let mut harness = egui_kittest::Harness::builder()
        .with_size(egui::vec2(640.0, 480.0))
        .renderer(WgpuTestRenderer::from_render_state(rs))
        .build_ui(move |ui| {
            facett_core::set_theme(ui.ctx(), Theme::default());
            map.ui(ui);
            cell.set(map.used_gpu_observed());
        });
    harness.run_steps(3);
    let _ = harness.render();
    let installed = facett_map3d::gpu::renderer_installed();
    println!(
        "  with_gpu(true), renderer_installed={installed}, adapter {} [{:?}]: used_gpu = {:?}",
        info.name,
        info.device_type,
        seen.get()
    );
    assert_eq!(
        seen.get(),
        Some(installed),
        "`used_gpu` must equal `a Map3dRenderer is installed` — a `true` with no renderer \
         is a claim about pixels nothing drew (adapter {} [{:?}])",
        info.name,
        info.device_type,
    );
}

/// `state_json` must carry the same three-way answer, because that is the surface a robot
/// and korp's `$KORP_STATE` read. `used_gpu: null` before the first frame; the selected
/// lane beside it.
#[test]
fn state_json_publishes_pending_rather_than_false() {
    let map = scene();
    let js = Facet::state_json(&map);
    assert!(
        js["used_gpu"].is_null(),
        "state_json says `null` (pending) before the first paint, got {}",
        js["used_gpu"]
    );
    assert_eq!(js["gpu_lane_selected"], serde_json::json!(false));
    assert_eq!(js["backend"], serde_json::json!("cpu-painter"));
}