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