use uzor_urx_core::math::{Color, Rect};
use uzor_urx_core::region::RegionId;
use uzor_urx_core::scene::Scene;
use uzor_urx_cpu::Pixmap;
use uzor_urx_engine::cadence::RenderCadence;
use uzor_urx_engine::engine::{Backend, RenderTarget, UrxEngine, WorkloadHint};
const W: u32 = 800;
const H: u32 = 600;
const N_REGIONS: usize = 16;
const FRAMES: usize = 30;
fn main() {
println!("=== URX backend auto-switch demo ===");
println!();
let scenarios: &[(&str, WorkloadHint)] = &[
("headless / no GPU",
WorkloadHint { gpu_available: false, region_count: 16, total_pixels: 480_000,
..Default::default() }),
("tiny low-pixel scene",
WorkloadHint { gpu_available: true, region_count: 2, total_pixels: 50_000,
..Default::default() }),
("dashboard, 16 regions, GPU available",
WorkloadHint { gpu_available: true, region_count: 16, total_pixels: 480_000,
retained: true, ..Default::default() }),
];
println!("{:<40} │ {:<10} │ {:<14}", "scenario", "backend", "render ms/frame");
println!("{}", "─".repeat(72));
for (label, hint) in scenarios {
let backend = Backend::auto(*hint);
let ms = run_scene_with_backend(backend);
println!("{:<40} │ {:<10} │ {:>10.3}", label, format!("{:?}", backend), ms);
}
println!();
println!("Notes:");
println!(" - Same 16-region scene rendered through whichever backend");
println!(" `Backend::auto(hint)` returned");
println!(" - With default features (wgpu-backend only) Hybrid falls through");
println!(" to Wgpu; rebuild with `--features hybrid-backend` to see Hybrid");
println!(" paths");
println!(" - CPU path is real (renders into Pixmap); Wgpu/Hybrid paths");
println!(" require a wgpu surface — this demo measures Cpu and reports");
println!(" Wgpu/Hybrid choice only (the engine returns the same chosen");
println!(" backend regardless of whether we actually render through it)");
}
fn run_scene_with_backend(backend: Backend) -> f64 {
if backend != Backend::Cpu {
return f64::NAN;
}
let mut engine = UrxEngine::new_cpu(W, H);
let mut pixmap = Pixmap::new(W, H);
for i in 0..N_REGIONS {
let col = (i % 4) as f64;
let row = (i / 4) as f64;
let x0 = 40.0 + col * 180.0;
let y0 = 40.0 + row * 130.0;
let mut scene = Scene::new();
scene.fill_rect_solid(
Rect::new(0.0, 0.0, 160.0, 110.0),
Color::rgba8(
((i * 37) & 0xff) as u8,
((i * 71) & 0xff) as u8,
((i * 113) & 0xff) as u8,
255,
),
);
engine.upsert_region(
RegionId(i as u64),
scene,
Rect::new(x0, y0, x0 + 160.0, y0 + 110.0),
RenderCadence::Static,
);
}
let _ = engine.render(RenderTarget::Cpu(&mut pixmap));
let t = std::time::Instant::now();
for _ in 0..FRAMES {
for i in 0..N_REGIONS {
engine.mark_dirty(RegionId(i as u64));
}
let _ = engine.render(RenderTarget::Cpu(&mut pixmap));
}
let elapsed_ms = t.elapsed().as_secs_f64() * 1000.0;
elapsed_ms / FRAMES as f64
}