#![cfg(all(feature = "export", target_os = "windows"))]
mod common;
use std::time::{Duration, Instant};
use common::engine_with_frame;
const DXGI_FORMAT_B8G8R8A8_UNORM: u32 = 87;
#[test]
fn exported_frames_carry_correctly_oriented_bgra_pixels() {
let Some((engine, frame, _rx)) = engine_with_frame() else {
return;
};
assert_eq!((frame.width(), frame.height()), (64, 64));
assert!(!frame.shared_handle().is_null());
assert_eq!(
frame.dxgi_format(),
DXGI_FORMAT_B8G8R8A8_UNORM,
"backend promises BGRA8"
);
let px = frame.copy_pixels();
assert_eq!(px.len(), 64 * 64 * 4);
let pixel = |x: usize, y: usize| {
let i = (y * 64 + x) * 4;
(px[i], px[i + 1], px[i + 2]) };
let (top_b, _top_g, top_r) = pixel(32, 8);
assert!(
top_r > 150 && top_b < 100,
"top should be red in BGRA order, got B={top_b} R={top_r}"
);
let (bot_b, bot_g, bot_r) = pixel(32, 56);
assert!(
bot_b < 60 && bot_g < 60 && bot_r < 60,
"bottom should be black, got ({bot_b},{bot_g},{bot_r})"
);
frame.presented();
engine.detach_render();
}
#[test]
fn resize_rerenders_at_new_size_without_playback() {
let Some((engine, first, rx)) = engine_with_frame() else {
return;
};
drop(first);
engine.set_export_size(32, 32).expect("resize");
let deadline = Instant::now() + Duration::from_secs(10);
loop {
assert!(Instant::now() < deadline, "no 32x32 frame within 10s");
let _ = rx.recv_timeout(Duration::from_millis(200));
match engine.acquire_frame().expect("acquire") {
Some(frame) if (frame.width(), frame.height()) == (32, 32) => {
assert_eq!(frame.copy_pixels().len(), 32 * 32 * 4);
break;
}
_ => {}
}
}
engine.detach_render();
}
#[test]
fn outstanding_frame_survives_detach() {
let Some((engine, frame, _rx)) = engine_with_frame() else {
return;
};
engine.detach_render();
let px = frame.copy_pixels();
assert_eq!(px.len(), 64 * 64 * 4);
drop(engine);
drop(frame);
}