#[cfg(all(feature = "render", feature = "demux"))]
mod tests {
use vtome::{
Compositor, Output, OutputLayer, Frame, PixelFormat, ColorSpace, render::{Gpu, Renderer},
geometry::Rect,
};
use std::time::Duration;
fn test_frame(width: u32, height: u32, frame_num: u32, color: (u8, u8, u8)) -> Frame {
let (r, g, b) = color;
let mut data = vec![0u8; (width * height * 4) as usize];
for i in 0..(width * height) {
let idx = (i * 4) as usize;
data[idx] = r;
data[idx + 1] = g;
data[idx + 2] = b;
data[idx + 3] = 255;
}
Frame::packed(
width,
height,
PixelFormat::Rgba8,
ColorSpace::srgb(),
Duration::from_millis(frame_num as u64 * 41),
data,
)
.expect("valid frame")
}
#[test]
fn gpu_initialization() {
let result = Gpu::new();
match result {
Ok(gpu) => {
let adapter_info = gpu.describe();
println!("GPU available: {}", adapter_info);
assert!(!adapter_info.is_empty());
}
Err(_) => {
println!("No GPU available (headless environment)");
}
}
}
#[test]
fn renderer_creation_and_upload() {
let gpu = match Gpu::new() {
Ok(g) => g,
Err(_) => {
println!("Skipping: no GPU available");
return;
}
};
let mut renderer = match Renderer::new(&gpu, wgpu::TextureFormat::Rgba8Unorm) {
Ok(r) => r,
Err(e) => {
println!("Skipping: renderer creation failed: {}", e);
return;
}
};
let frame = test_frame(64, 64, 0, (255, 0, 0));
let result = renderer.upload(&gpu, &frame);
assert!(
result.is_ok(),
"Frame upload should succeed: {:?}",
result.err()
);
}
#[test]
fn compositor_gpu_infrastructure() {
let mut comp = Compositor::new();
let mut output = Output::new(640, 480);
let layer = OutputLayer::new("test_video", Rect::new(0.0, 0.0, 640.0, 480.0));
output.add_layer(layer);
comp.add_output(output);
let stats = comp.stats();
assert_eq!(stats.output_count, 1);
assert_eq!(stats.total_visible_layers, 1);
println!("Compositor stats: {}", stats);
}
#[test]
fn multi_layer_composition_setup() {
let mut comp = Compositor::new();
let mut output = Output::new(1920, 1080);
let layer1 = OutputLayer::new("video_bg", Rect::new(0.0, 0.0, 1920.0, 1080.0))
.with_z_index(2)
.with_opacity(1.0);
let layer2 = OutputLayer::new("video_main", Rect::new(0.0, 0.0, 960.0, 1080.0))
.with_z_index(1)
.with_opacity(1.0);
let layer3 = OutputLayer::new("video_overlay", Rect::new(1400.0, 750.0, 400.0, 300.0))
.with_z_index(0)
.with_opacity(0.8);
output.add_layers(vec![layer1, layer2, layer3]);
comp.add_output(output);
let stats = comp.stats();
assert_eq!(stats.total_layers, 3);
assert_eq!(stats.total_visible_layers, 3);
println!("Multi-layer composition: {}", stats);
}
#[test]
fn full_rendering_pipeline_validation() {
let mut comp = Compositor::new();
let mut output = Output::new(1920, 1080)
.with_background_rgb(0.1, 0.1, 0.1);
let layer = OutputLayer::new("video", Rect::new(100.0, 100.0, 800.0, 600.0))
.with_z_index(0)
.with_opacity(1.0);
output.add_layer(layer);
comp.add_output(output);
let result = comp.advance(Duration::from_millis(41));
assert!(result.is_ok(), "Advance should succeed");
let result = comp.render_output(0);
assert!(result.is_ok(), "Render should succeed");
let stats = comp.stats();
assert_eq!(stats.output_count, 1);
assert_eq!(stats.total_visible_layers, 1);
println!("Pipeline validation: {}", stats);
}
#[test]
fn single_frame_gpu_rendering() {
let gpu = match Gpu::new() {
Ok(g) => g,
Err(_) => {
println!("Skipping GPU rendering test: no GPU available");
return;
}
};
let mut renderer = match Renderer::new(&gpu, wgpu::TextureFormat::Rgba8Unorm) {
Ok(r) => r,
Err(_) => {
println!("Skipping GPU rendering test: renderer creation failed");
return;
}
};
let frame = test_frame(320, 240, 0, (255, 0, 0));
let result = renderer.render_to_rgba(
&gpu,
&frame,
320,
240,
vtome::geometry::Quad::from_rect(Rect::new(0.0, 0.0, 320.0, 240.0)),
1.0,
);
match result {
Ok(pixels) => {
assert_eq!(pixels.len(), 320 * 240 * 4);
println!("Rendered {} pixels successfully", pixels.len() / 4);
}
Err(e) => {
println!("Rendering failed (may be unavailable in CI): {}", e);
}
}
}
}
#[cfg(not(all(feature = "render", feature = "demux")))]
fn main() {
eprintln!("GPU rendering tests require --features render with demux");
}