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

nordisk/facett

facett-graph3d/tests/gpu_offscreen.rs

//! **CONS-CORE Phase C (step 10) — the LogoRenderer offscreen fold.**
//!
//! Proves the GPU 3D logo now routes through the **shared
//! [`facett_core::render::gpu::OffscreenColorDepth`]** helper (colour+depth32 target +
//! blit) — the parity fold with `facett-map3d` — by driving the **live** GPU lane
//! through egui_kittest's wgpu backend and asserting the framebuffer is non-blank.
//!
//! Before the fold the logo drew straight into egui's colour-only pass (occlusion via
//! back-face cull only); now it renders into the offscreen colour+depth target with a
//! real `Less` Z-buffer and blits the result. This test installs the real
//! [`LogoRenderer`](facett_graph3d::logo3d::gpu::LogoRenderer), opts the logo into the
//! GPU path, and confirms the blitted result actually lit pixels.
//!
//! Run: `cargo test -p facett-graph3d --features wgpu --test gpu_offscreen`
//! (needs a GPU/`lavapipe`; degrades to a skip if no adapter — never a false fail.)
#![cfg(feature = "wgpu")]

use egui_kittest::Harness;
use egui_kittest::wgpu::{create_render_state, default_wgpu_setup, WgpuTestRenderer};
use facett_core::Facet;
use facett_graph3d::RabbitLogo3D;

/// Fraction of pixels far from the modal (≈background) colour — the "did real content
/// draw?" measure (a blank pane scores ~0).
fn content_ratio(img: &image::RgbaImage) -> f64 {
    let mut hist = std::collections::HashMap::<u32, u32>::new();
    for p in img.pixels() {
        let key = ((p.0[0] as u32 >> 3) << 10) | ((p.0[1] as u32 >> 3) << 5) | (p.0[2] as u32 >> 3);
        *hist.entry(key).or_default() += 1;
    }
    let (modal, _) = hist.iter().max_by_key(|(_, c)| **c).map(|(k, c)| (*k, *c)).unwrap();
    let (mr, mg, mb) = (((modal >> 10) & 0x1f) as i32, ((modal >> 5) & 0x1f) as i32, (modal & 0x1f) as i32);
    let total = (img.width() * img.height()) as usize;
    let mut content = 0usize;
    for p in img.pixels() {
        let (r, g, b) = ((p.0[0] >> 3) as i32, (p.0[1] >> 3) as i32, (p.0[2] >> 3) as i32);
        if (r - mr).abs() + (g - mg).abs() + (b - mb).abs() > 3 {
            content += 1;
        }
    }
    content as f64 / total as f64
}

/// INJECT-ASSERT: the GPU logo, opted into the depth-tested GPU lane, renders a
/// **non-blank** frame through the shared offscreen colour+depth+blit helper. The
/// renderer is the real `LogoRenderer` (installed into a live wgpu `RenderState`),
/// so a green result means the mesh actually drew into the offscreen target and the
/// blit composited it into egui's pass — the fold works end to end.
#[test]
fn gpu_logo_renders_nonblank_through_shared_offscreen_helper() {
    // A live GPU render state (the same one egui_kittest's wgpu backend uses).
    let rs = create_render_state(default_wgpu_setup(), Default::default());
    // Install the real folded LogoRenderer (owns a `core::OffscreenColorDepth`).
    facett_graph3d::logo3d::gpu::install_renderer(&rs);

    let mut view = RabbitLogo3D::new("rabbit3d-gpu").with_clock(1.2).with_gpu(true);
    // Inject-assert the mesh is real first (so a blank result can't be "empty mesh").
    let s = view.state_json();
    assert!(s["triangles"].as_u64().unwrap() > 50, "real extruded mesh feeds the GPU lane");

    let mut harness = Harness::builder()
        .with_size(egui::vec2(480.0, 480.0))
        .renderer(WgpuTestRenderer::from_render_state(rs))
        .build_ui(move |ui| {
            facett_core::set_theme(ui.ctx(), facett_core::Theme::sci_fi());
            view.ui(ui);
        });
    harness.run_steps(3);

    let img = harness.render().expect("wgpu render produced an image");
    let ratio = content_ratio(&img);
    eprintln!("[logo3d-gpu-offscreen] content ratio {ratio:.4}");
    // The blitted offscreen logo fills a visible region (well above blank).
    assert!(
        ratio > 0.02,
        "GPU logo must render non-blank via the shared offscreen+depth+blit helper (got {ratio:.4})"
    );
}