Commit 05ef5ef
4
files
+91
added
-1
deleted
@@ -135,6 +135,11 @@ fn main() -> Result<(), Box<dyn Error>> {
135
135
None
136
136
};
137
137
138
+ // Diagnostyka (SELENE_STATS=1): częstość aktualizacji kursora (tempo wejścia evdev).
139
+ let stats = std::env::var("SELENE_STATS").is_ok();
140
+ let mut cursor_updates = 0u64;
141
+ let mut stats_report = std::time::Instant::now();
142
+
138
143
loop {
139
144
let backend_fd = display.backend().poll_fd().as_raw_fd();
140
145
let wake_fd = wake_read.as_raw_fd();
@@ -173,6 +178,7 @@ fn main() -> Result<(), Box<dyn Error>> {
173
178
.unwrap_or((1280.0, 800.0));
174
179
let batch = input.read_events(bounds);
175
180
*state.cursor.lock_or_recover() = Some(input.cursor());
181
+ cursor_updates += 1;
176
182
for event in &batch {
177
183
seat::handle_input(&mut state, &handle, event);
178
184
}
@@ -213,6 +219,19 @@ fn main() -> Result<(), Box<dyn Error>> {
213
219
Ok(Err(e)) => return Err(e.into()),
214
220
Err(_) => eprintln!("{}", libluna_i18n::tr("client request panicked; ignoring")),
215
221
}
222
+
223
+ if stats && stats_report.elapsed().as_secs_f64() >= 2.0 {
224
+ let secs = stats_report.elapsed().as_secs_f64();
225
+ let windows = state.windows.lock_or_recover().len();
226
+ eprintln!(
227
+ "selene/input: {:.0} aktualizacji kursora/s | klienci={} okna={}",
228
+ cursor_updates as f64 / secs,
229
+ state.clients,
230
+ windows
231
+ );
232
+ cursor_updates = 0;
233
+ stats_report = std::time::Instant::now();
234
+ }
216
235
}
217
236
}
218
237
@@ -131,13 +131,19 @@ pub fn spawn_drm(model: WindowModel, cursor: CursorModel) {
131
131
.collect();
132
132
let bg = Color::from_rgba8(0x1e, 0x20, 0x28, 0xff);
133
133
134
- // Gdy page-flip zawodzi (np. sterownik/karta), ekran zostaje czarny — logujemy raz.
134
+ // Diagnostyka (SELENE_STATS=1): fps i rozbicie czasu na render/present/wait_flip.
135
+ let stats = std::env::var("SELENE_STATS").is_ok();
135
136
let mut flip_error_logged = false;
137
+ let mut frames = 0u64;
138
+ let (mut ms_render, mut ms_present, mut ms_wait) = (0.0f64, 0.0f64, 0.0f64);
139
+ let mut report = std::time::Instant::now();
136
140
loop {
137
141
for i in 0..sizes.len() {
138
142
let (w, h) = sizes[i];
139
143
let (ox, oy) = origins[i];
140
144
let cur = *cursor.lock_or_recover();
145
+
146
+ let t = std::time::Instant::now();
141
147
let mut scene = Scene::new();
142
148
build_scene(
143
149
&mut scene,
@@ -148,6 +154,9 @@ pub fn spawn_drm(model: WindowModel, cursor: CursorModel) {
148
154
cur,
149
155
);
150
156
renderers[i].draw(&scene, 1.0, bg);
157
+ ms_render += t.elapsed().as_secs_f64() * 1000.0;
158
+
159
+ let t = std::time::Instant::now();
151
160
if !backend.present(i, renderers[i].data()) && !flip_error_logged {
152
161
eprintln!(
153
162
"{}",
@@ -155,10 +164,32 @@ pub fn spawn_drm(model: WindowModel, cursor: CursorModel) {
155
164
);
156
165
flip_error_logged = true;
157
166
}
167
+ ms_present += t.elapsed().as_secs_f64() * 1000.0;
168
+
169
+ let t = std::time::Instant::now();
158
170
backend.wait_flip();
171
+ ms_wait += t.elapsed().as_secs_f64() * 1000.0;
159
172
}
160
173
// Bez wejścia w trybie DRM odświeżamy w stałym rytmie (~60 Hz).
161
174
std::thread::sleep(Duration::from_millis(16));
175
+ frames += 1;
176
+
177
+ if stats && report.elapsed().as_secs_f64() >= 2.0 {
178
+ let secs = report.elapsed().as_secs_f64();
179
+ let per_frame = (frames * sizes.len() as u64).max(1) as f64;
180
+ eprintln!(
181
+ "selene/drm: {:.1} fps | render {:.2} ms, present {:.2} ms, wait_flip {:.2} ms",
182
+ frames as f64 / secs,
183
+ ms_render / per_frame,
184
+ ms_present / per_frame,
185
+ ms_wait / per_frame
186
+ );
187
+ frames = 0;
188
+ ms_render = 0.0;
189
+ ms_present = 0.0;
190
+ ms_wait = 0.0;
191
+ report = std::time::Instant::now();
192
+ }
162
193
}
163
194
});
164
195
}
@@ -293,4 +324,32 @@ mod tests {
293
324
.any(|px| px[0] > 0 || px[1] > 0 || px[2] > 0);
294
325
assert!(painted, "kursor powinien zostawić niezerowe piksele");
295
326
}
327
+
328
+ #[test]
329
+ #[ignore = "benchmark reczny"]
330
+ fn bench_1080p_frame() {
331
+ use std::sync::{Arc, Mutex};
332
+ use std::time::Instant;
333
+ let model: WindowModel = Arc::new(Mutex::new(Vec::new()));
334
+ let bg = Color::from_rgba8(0x1e, 0x20, 0x28, 0xff);
335
+ let mut renderer = SoftwareRenderer::new(1920, 1080);
336
+ let n = 30;
337
+ let t = Instant::now();
338
+ for _ in 0..n {
339
+ let mut scene = Scene::new();
340
+ build_scene(
341
+ &mut scene,
342
+ Size::new(1920.0, 1080.0),
343
+ 0.0,
344
+ 0.0,
345
+ &model,
346
+ Some(Point::new(100.0, 100.0)),
347
+ );
348
+ renderer.draw(&scene, 1.0, bg);
349
+ }
350
+ println!(
351
+ "render 1920x1080: {:.2} ms/klatke",
352
+ t.elapsed().as_secs_f64() * 1000.0 / n as f64
353
+ );
354
+ }
296
355
}
@@ -28,6 +28,9 @@ if [ "$SELENE_BACKEND" = "drm" ]; then
28
28
export SELENE_INPUT
29
29
fi
30
30
31
+# Diagnostyka wydajności (fps DRM + tempo kursora) — tymczasowo włączona.
32
+export SELENE_STATS=1
33
+
31
34
# Trwały log sesji: LightDM trzyma tylko 2 pliki `.xsession-errors` i obraca je przy
32
35
# każdym starcie sesji, przez co logi Luny przepadają. Piszemy do stałego pliku w
33
36
# katalogu stanu użytkownika, żeby każdą próbę dało się obejrzeć po fakcie.
@@ -54,7 +57,10 @@ done
54
57
# Powłoka Luna (panel, launcher, OSD) — o ile jest zainstalowana.
55
58
if command -v luna-shell >/dev/null 2>&1; then
56
59
export WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}"
60
+ echo "luna-session: uruchamiam luna-shell ($(command -v luna-shell))"
57
61
luna-shell &
62
+else
63
+ echo "luna-session: brak luna-shell w PATH"
58
64
fi
59
65
60
66
# Sesja żyje, dopóki działa kompozytor.
@@ -28,6 +28,9 @@ if [ "$SELENE_BACKEND" = "drm" ]; then
28
28
export SELENE_INPUT
29
29
fi
30
30
31
+# Diagnostyka wydajności (fps DRM + tempo kursora) — tymczasowo włączona.
32
+export SELENE_STATS=1
33
+
31
34
# Trwały log sesji: LightDM trzyma tylko 2 pliki `.xsession-errors` i obraca je przy
32
35
# każdym starcie sesji, przez co logi Luny przepadają. Piszemy do stałego pliku w
33
36
# katalogu stanu użytkownika, żeby każdą próbę dało się obejrzeć po fakcie.
@@ -54,7 +57,10 @@ done
54
57
# Powłoka Luna (panel, launcher, OSD) — o ile jest zainstalowana.
55
58
if command -v luna-shell >/dev/null 2>&1; then
56
59
export WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}"
60
+ echo "luna-session: uruchamiam luna-shell ($(command -v luna-shell))"
57
61
luna-shell &
62
+else
63
+ echo "luna-session: brak luna-shell w PATH"
58
64
fi
59
65
60
66
# Sesja żyje, dopóki działa kompozytor.