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

nordisk/facett

facett-demo/tests/velo_l1.rs

//! **Velo L1 render-proof** — inject the synthetic scene, render BOTH lanes (L0
//! SDF only + L0 + L1 vello overlay), and assert REAL output (not "didn't
//! panic"): each lane lit pixels, the L1 lane differs from L0, the L1 overlay is
//! contained in the rect, and the composited final picture is emitted as a **PNG
//! blob** the test reads back (so an agent can inspect the rendered image).
//!
//! Run: `cargo test -p facett-demo --no-default-features --features l1-vello,testmatrix --test velo_l1 -- --nocapture`
//!
//! The L1 lane needs the `l1-vello` feature **and** a GPU adapter; when either is
//! absent the L1 assertions are skipped gracefully (the lane degrades, it never
//! fails) and the test still proves the L0 lane + the PNG-blob round-trip.

use facett_demo::velo_l1_tab::{self, VeloL1Tab, HEIGHT, WIDTH};
use image::{Rgba, RgbaImage};

/// Write a straight-RGBA8 [`facett_core::render::Frame`] as a PNG and return its
/// path — the **final-picture blob** the EMIT-DOCTRINE asks for (a real image the
/// agent reads back, not a number).
fn save_png(name: &str, frame: &facett_core::render::Frame) -> std::path::PathBuf {
    let mut img = RgbaImage::new(frame.width, frame.height);
    for (i, px) in frame.rgba.as_chunks::<4>().0.iter().enumerate() {
        let x = (i as u32) % frame.width;
        let y = (i as u32) / frame.width;
        img.put_pixel(x, y, Rgba([px[0], px[1], px[2], px[3]]));
    }
    let dir = std::env::temp_dir().join("facett-demo");
    std::fs::create_dir_all(&dir).ok();
    let png = dir.join(format!("velo_l1_{name}.png"));
    img.save(&png).expect("write velo_l1 PNG blob");
    png
}

#[test]
fn velo_l1_renders_both_lanes_and_emits_a_png_blob() {
    let tab = VeloL1Tab::new(velo_l1_tab::TITLE);

    // ── L0 lane: the SDF base alone (always available, zero vello). ────────────
    let f0 = tab.render_l0(WIDTH, HEIGHT);
    assert_eq!(f0.rgba.len(), (WIDTH * HEIGHT * 4) as usize);
    let lit0 = f0.lit_px();
    assert!(lit0 > 5_000, "L0 SDF lane lit real pixels, got {lit0}");

    // ── L0 + L1 lane: the same frame with the vello overlay composited over it. ─
    let (f1, l1_ran) = tab.render_l0_l1(WIDTH, HEIGHT);
    assert_eq!(f1.rgba.len(), (WIDTH * HEIGHT * 4) as usize);
    let lit1 = f1.lit_px();
    assert!(lit1 > 5_000, "L0+L1 lane lit real pixels, got {lit1}");

    // ── The final-picture PNG blobs (read back the bytes to prove they wrote). ─
    let p0 = save_png("l0", &f0);
    let p1 = save_png("l0_l1", &f1);
    let b0 = std::fs::read(&p0).expect("read L0 PNG blob");
    let b1 = std::fs::read(&p1).expect("read L0+L1 PNG blob");
    assert!(b0.starts_with(b"\x89PNG"), "L0 blob is a real PNG ({} bytes)", b0.len());
    assert!(b1.starts_with(b"\x89PNG"), "L0+L1 blob is a real PNG ({} bytes)", b1.len());
    eprintln!("velo_l1 PNG blobs: {} , {}", p0.display(), p1.display());

    let diff = velo_l1_tab::frame_diff_px(&f0, &f1);

    if l1_ran {
        // The L1 lane ran (feature on + a GPU). It must have ADDED beauty: the
        // composited frame differs from L0 in a real number of pixels (the
        // gradient banner + curve + glow the SDF base can't draw), and lights at
        // least as many pixels as L0 (the overlay only adds, never erases L0).
        assert!(diff > 500, "L1 overlay changed the picture in real pixels, got {diff}");
        assert!(lit1 >= lit0, "L1 composited over L0 (added, didn't erase): lit {lit1} vs {lit0}");

        // Containment: the L1 overlay (rendered on its own transparent frame) must
        // not light the 1-px border ring — nothing escapes the rect (the clip
        // oracle, asserted on the overlay-only frame).
        #[cfg(feature = "l1-vello")]
        {
            let overlay = velo_l1_tab::beauty_overlay(WIDTH, HEIGHT);
            let ov = facett_core::render::l1::render_overlay(&overlay, WIDTH, HEIGHT)
                .expect("L1 ran above, so render_overlay yields a frame");
            let at = |x: u32, y: u32| ov.rgba[((y * WIDTH + x) * 4 + 3) as usize];
            for x in 0..WIDTH {
                assert_eq!(at(x, 0), 0, "L1 top edge clear (contained in rect)");
                assert_eq!(at(x, HEIGHT - 1), 0, "L1 bottom edge clear");
            }
            for y in 0..HEIGHT {
                assert_eq!(at(0, y), 0, "L1 left edge clear");
                assert_eq!(at(WIDTH - 1, y), 0, "L1 right edge clear");
            }
        }

        // Emit a functional-status row: the L1 lane drew + differed from L0.
        #[cfg(feature = "testmatrix")]
        facett_core::testmatrix::emit(
            "facett-demo::velo_l1",
            "l0_plus_l1_render",
            lit0 > 0 && lit1 > 0 && diff > 500 && lit1 >= lit0,
            &format!("lit_l0={lit0} lit_l1={lit1} l1_diff_px={diff} blob={}", p1.display()),
        );
    } else {
        // No GPU / feature off: the L1 lane degraded to the L0 frame — the two
        // sides are identical (the honest no-op the tab reports as
        // `l1_available = false`).
        assert_eq!(diff, 0, "with L1 unavailable both lanes are the identical L0 frame");
        eprintln!("L1 vello unavailable (feature off / no GPU) — L0-only proof + PNG blob still emitted");

        #[cfg(feature = "testmatrix")]
        facett_core::testmatrix::emit(
            "facett-demo::velo_l1",
            "l0_only_render",
            lit0 > 0,
            &format!("lit_l0={lit0} l1_available=false blob={}", p0.display()),
        );
    }
}

/// INJECT-ASSERT: the 2-category auto-select decision is real + observable in the
/// tab's `state_json` (the CPU / CPU+GPU pick the engine hinges on), and the L0
/// instance counts prove the scene lowered to real SDF content.
#[test]
fn velo_l1_state_exposes_the_two_category_decision() {
    let tab = VeloL1Tab::new(velo_l1_tab::TITLE);
    let s = facett::Facet::state_json(&tab);
    assert_eq!(s["category"], "CPU", "cpu_only probe → CPU category");
    assert_eq!(s["gpu_probe"]["usable_gpu"], false);
    assert_eq!(s["gpu_probe"]["force_cpu"], false);
    assert_eq!(s["nodes"].as_u64(), Some(velo_l1_tab::NODES as u64));
    assert!(s["l0_quads"].as_u64().unwrap() > velo_l1_tab::NODES as u64);
    assert_eq!(s["l1_feature"], cfg!(feature = "l1-vello"));
}