use oximedia_virtual::math::{Point3, UnitQuaternion};
use oximedia_virtual::{
led::{
render::{LedRenderer, LedRendererConfig},
LedPanel, LedWall,
},
metrics::MetricsCollector,
tracking::{
camera::{CameraTracker, CameraTrackerConfig},
CameraPose,
},
QualityMode, VirtualProduction, VirtualProductionConfig, WorkflowType,
};
use std::time::Instant;
const TEST_W: usize = 64;
const TEST_H: usize = 64;
#[test]
fn test_camera_tracking_performance() {
let config = CameraTrackerConfig {
update_rate: 120.0,
optical_tracking: false, imu_tracking: true,
fusion_weight: 0.5,
smoothing_window: 3,
max_latency_ms: 10.0,
};
let mut tracker = CameraTracker::new(config).expect("test expectation failed");
let mut total_time = std::time::Duration::ZERO;
let iterations = 100u64;
for i in 0..iterations {
let timestamp_ns = i * 8_333_333;
let start = Instant::now();
let _ = tracker.update(timestamp_ns).expect("_ should be valid");
total_time += start.elapsed();
}
let avg_time = total_time / iterations as u32;
println!("Average tracking time: {avg_time:?}");
assert!(
avg_time.as_millis() < 100,
"tracking update too slow: {avg_time:?}"
);
}
#[test]
fn test_led_rendering_performance() {
let mut led_wall = LedWall::new("Perf Test".to_string());
led_wall.add_panel(LedPanel::new(
Point3::origin(),
5.0,
3.0,
(TEST_W, TEST_H),
2.5,
));
let config = LedRendererConfig {
target_fps: 60.0,
perspective_correction: false, color_correction: false,
quality: 0.5,
motion_blur: false,
};
let mut renderer = LedRenderer::new(config).expect("test expectation failed");
renderer.set_led_wall(led_wall);
let camera_pose = CameraPose::new(Point3::new(0.0, 1.5, 5.0), UnitQuaternion::identity(), 0);
let source_frame = vec![128u8; TEST_W * TEST_H * 3];
let mut total_time = std::time::Duration::ZERO;
for i in 0..3u64 {
let timestamp_ns = i * 16_666_667;
let start = Instant::now();
let _ = renderer
.render(&camera_pose, &source_frame, TEST_W, TEST_H, timestamp_ns)
.expect("test expectation failed");
total_time += start.elapsed();
}
let avg_time = total_time / 3;
println!("Average render time (64×64): {avg_time:?}");
}
#[test]
fn test_compositing_performance() {
use oximedia_virtual::icvfx::composite::{CompositorConfig, IcvfxCompositor};
let config = CompositorConfig {
resolution: (TEST_W, TEST_H),
depth_compositing: false, motion_blur: false,
quality: 0.5,
};
let mut compositor = IcvfxCompositor::new(config).expect("test expectation failed");
let foreground = vec![255u8; TEST_W * TEST_H * 3];
let background = vec![0u8; TEST_W * TEST_H * 3];
let mut total_time = std::time::Duration::ZERO;
for i in 0..3u64 {
let timestamp_ns = i * 16_666_667;
let start = Instant::now();
let _ = compositor
.composite(&foreground, &background, None, timestamp_ns)
.expect("test expectation failed");
total_time += start.elapsed();
}
let avg_time = total_time / 3;
println!("Average composite time (64×64): {avg_time:?}");
}
#[test]
fn test_full_pipeline_performance() {
let config = VirtualProductionConfig {
workflow: WorkflowType::LedWall,
target_fps: 60.0,
sync_accuracy_ms: 1.0,
quality: QualityMode::Preview,
color_calibration: false,
lens_correction: false,
num_cameras: 1,
motion_capture: false,
unreal_integration: false,
};
let mut vp = VirtualProduction::new(config).expect("test expectation failed");
let mut led_wall = LedWall::new("Pipeline Test".to_string());
led_wall.add_panel(LedPanel::new(
Point3::origin(),
5.0,
3.0,
(TEST_W, TEST_H),
2.5,
));
vp.led_renderer_mut().set_led_wall(led_wall);
vp.set_compositor_resolution(TEST_W, TEST_H)
.expect("set_compositor_resolution should succeed");
let mut metrics = MetricsCollector::new(60);
for i in 0..2u64 {
let timestamp_ns = i * 16_666_667;
let start = Instant::now();
let _ = vp
.camera_tracker_mut()
.update(timestamp_ns)
.expect("_ should be valid");
let camera_pose = *vp.camera_tracker().current_pose();
let source_frame = vec![128u8; TEST_W * TEST_H * 3];
let led_output = vp
.led_renderer_mut()
.render(&camera_pose, &source_frame, TEST_W, TEST_H, timestamp_ns)
.expect("test expectation failed");
let foreground = vec![64u8; TEST_W * TEST_H * 3];
let _ = vp
.compositor_mut()
.composite(&foreground, &led_output.pixels, None, timestamp_ns)
.expect("test expectation failed");
let frame_time = start.elapsed();
metrics.record_frame();
println!("Frame time (64×64): {frame_time:?}");
}
let perf = metrics.performance();
println!("Pipeline performance:");
println!(" Avg FPS: {:.2}", perf.avg_fps);
println!(" Avg frame time: {:.2}ms", perf.avg_frame_time_ms);
assert!(perf.total_frames > 0);
}
#[test]
fn test_metrics_overhead() {
let mut metrics = MetricsCollector::new(60);
let start = Instant::now();
for _ in 0..10_000 {
metrics.record_frame();
}
let total_time = start.elapsed();
let avg_time = total_time / 10_000;
println!("Average metrics overhead: {avg_time:?}");
assert!(
avg_time.as_millis() < 1,
"metrics record_frame too slow: {avg_time:?}"
);
}
#[test]
fn test_high_resolution_performance() {
let mut led_wall = LedWall::new("High-Res Test".to_string());
led_wall.add_panel(LedPanel::new(
Point3::origin(),
10.0,
6.0,
(TEST_W, TEST_H),
1.8,
));
let config = LedRendererConfig {
target_fps: 60.0,
perspective_correction: false,
color_correction: false,
quality: 0.5,
motion_blur: false,
};
let mut renderer = LedRenderer::new(config).expect("test expectation failed");
renderer.set_led_wall(led_wall);
let camera_pose = CameraPose::new(Point3::new(0.0, 1.5, 10.0), UnitQuaternion::identity(), 0);
let source_frame = vec![128u8; TEST_W * TEST_H * 3];
let start = Instant::now();
let _ = renderer
.render(&camera_pose, &source_frame, TEST_W, TEST_H, 0)
.expect("test expectation failed");
let render_time = start.elapsed();
println!("Render time (64×64): {render_time:?}");
}
#[test]
fn test_multi_camera_performance() {
let config = VirtualProductionConfig::default().with_num_cameras(4);
let mut vp = VirtualProduction::new(config).expect("test expectation failed");
let start = Instant::now();
for i in 0..100u64 {
let timestamp_ns = i * 16_666_667;
let _ = vp
.camera_tracker_mut()
.update(timestamp_ns)
.expect("_ should be valid");
}
let total_time = start.elapsed();
let avg_time = total_time / 100;
println!("Multi-camera tracking time: {avg_time:?}");
assert!(avg_time.as_millis() < 2000);
}
#[test]
fn test_sustained_performance() {
let config = VirtualProductionConfig {
workflow: WorkflowType::LedWall,
target_fps: 60.0,
sync_accuracy_ms: 1.0,
quality: QualityMode::Preview,
color_calibration: false,
lens_correction: false,
num_cameras: 1,
motion_capture: false,
unreal_integration: false,
};
let mut vp = VirtualProduction::new(config).expect("test expectation failed");
let mut led_wall = LedWall::new("Sustained Test".to_string());
led_wall.add_panel(LedPanel::new(
Point3::origin(),
5.0,
3.0,
(TEST_W, TEST_H),
2.5,
));
vp.led_renderer_mut().set_led_wall(led_wall);
let mut dropped_frames = 0;
let frame_budget = std::time::Duration::from_millis(16);
for i in 0..2u64 {
let timestamp_ns = i * 16_666_667;
let start = Instant::now();
let _ = vp
.camera_tracker_mut()
.update(timestamp_ns)
.expect("_ should be valid");
let camera_pose = *vp.camera_tracker().current_pose();
let source_frame = vec![128u8; TEST_W * TEST_H * 3];
let _ = vp
.led_renderer_mut()
.render(&camera_pose, &source_frame, TEST_W, TEST_H, timestamp_ns)
.expect("test expectation failed");
if start.elapsed() > frame_budget {
dropped_frames += 1;
}
}
println!("Dropped frames: {dropped_frames}/2");
assert!(dropped_frames <= 2);
}