performance_benchmark/
performance_benchmark.rs1use astrelis_core::logging;
14use astrelis_render::{Color, GraphicsContext, RenderWindow, RenderWindowBuilder, wgpu};
15use astrelis_winit::{
16 FrameTime, WindowId,
17 app::{App, AppCtx, run_app},
18 event::{Event, EventBatch, HandleStatus, Key, NamedKey},
19 window::{WindowDescriptor, WinitPhysicalSize},
20};
21use std::sync::Arc;
22use std::time::Instant;
23
24struct PerformanceBenchmark {
25 _context: Arc<GraphicsContext>,
26 window: RenderWindow,
27 window_id: WindowId,
28 object_count: usize,
29 rendering: bool,
30 frame_count: u64,
31 last_fps_time: Instant,
32 fps: f32,
33 last_frame_time: f32,
34}
35
36fn main() {
37 logging::init();
38
39 run_app(|ctx| {
40 let graphics_ctx =
41 GraphicsContext::new_owned_sync().expect("Failed to create graphics context");
42
43 let window = ctx
44 .create_window(WindowDescriptor {
45 title: "Performance Benchmark - Render Stress Test".to_string(),
46 size: Some(WinitPhysicalSize::new(1280.0, 720.0)),
47 ..Default::default()
48 })
49 .expect("Failed to create window");
50
51 let window = RenderWindowBuilder::new()
52 .color_format(wgpu::TextureFormat::Bgra8UnormSrgb)
53 .with_depth_default()
54 .build(window, graphics_ctx.clone())
55 .expect("Failed to create render window");
56
57 let window_id = window.id();
58
59 println!("\n═══════════════════════════════════════════════════════");
60 println!(" ⚡ PERFORMANCE BENCHMARK - Render Stress Test");
61 println!("═══════════════════════════════════════════════════════");
62 println!(" CONTROLS:");
63 println!(" [Space] Toggle rendering on/off");
64 println!(" [+/-] Increase/decrease object count");
65 println!(" Starting with 1000 objects");
66 println!("═══════════════════════════════════════════════════════\n");
67
68 Box::new(PerformanceBenchmark {
69 _context: graphics_ctx,
70 window,
71 window_id,
72 object_count: 1000,
73 rendering: true,
74 frame_count: 0,
75 last_fps_time: Instant::now(),
76 fps: 0.0,
77 last_frame_time: 0.0,
78 })
79 });
80}
81
82impl App for PerformanceBenchmark {
83 fn update(&mut self, _ctx: &mut AppCtx, _time: &FrameTime) {
84 self.frame_count += 1;
85
86 let now = Instant::now();
87 if now.duration_since(self.last_fps_time).as_secs_f32() >= 1.0 {
88 self.fps = self.frame_count as f32;
89 self.frame_count = 0;
90 self.last_fps_time = now;
91 println!(
92 "FPS: {:.1} | Frame Time: {:.2}ms | Objects: {} | Rendering: {}",
93 self.fps, self.last_frame_time, self.object_count, self.rendering
94 );
95 }
96 }
97
98 fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
99 if window_id != self.window_id {
100 return;
101 }
102
103 let frame_start = Instant::now();
104
105 events.dispatch(|event| {
107 if let Event::WindowResized(size) = event {
108 self.window.resized(*size);
109 HandleStatus::consumed()
110 } else {
111 HandleStatus::ignored()
112 }
113 });
114
115 events.dispatch(|event| {
117 if let Event::KeyInput(key) = event
118 && key.state == astrelis_winit::event::ElementState::Pressed
119 {
120 match &key.logical_key {
121 Key::Named(NamedKey::Space) => {
122 self.rendering = !self.rendering;
123 println!("Rendering: {}", self.rendering);
124 return HandleStatus::consumed();
125 }
126 Key::Character(c) if c == "+" || c == "=" => {
127 self.object_count = (self.object_count + 500).min(50000);
128 println!("Object count: {}", self.object_count);
129 return HandleStatus::consumed();
130 }
131 Key::Character(c) if c == "-" => {
132 self.object_count = self.object_count.saturating_sub(500).max(100);
133 println!("Object count: {}", self.object_count);
134 return HandleStatus::consumed();
135 }
136 _ => {}
137 }
138 }
139 HandleStatus::ignored()
140 });
141
142 let Some(frame) = self.window.begin_frame() else {
144 return; };
146
147 if self.rendering {
148 let _pass = frame
156 .render_pass()
157 .clear_color(Color::from_rgb_u8(10, 10, 15))
158 .label("benchmark_pass")
159 .build();
160 } else {
164 let _pass = frame
165 .render_pass()
166 .clear_color(Color::from_rgb_u8(10, 10, 15))
167 .label("benchmark_pass")
168 .build();
169 }
170 let frame_end = Instant::now();
173 self.last_frame_time = frame_end.duration_since(frame_start).as_secs_f32() * 1000.0;
174 }
175}