debug: Add basic debug interface
This commit is contained in:
parent
928ce9c6f6
commit
bbeb51cbce
5 changed files with 134 additions and 9 deletions
|
|
@ -36,6 +36,9 @@ use std::{
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
use crate::{rendering::debug_ui, state::Fps};
|
||||||
|
|
||||||
pub struct X11State {
|
pub struct X11State {
|
||||||
allocator: Arc<Mutex<GbmDevice<DrmNode>>>,
|
allocator: Arc<Mutex<GbmDevice<DrmNode>>>,
|
||||||
_egl: EGLDisplay,
|
_egl: EGLDisplay,
|
||||||
|
|
@ -112,6 +115,8 @@ impl X11State {
|
||||||
surface,
|
surface,
|
||||||
output: output.clone(),
|
output: output.clone(),
|
||||||
render: ping.clone(),
|
render: ping.clone(),
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
fps: Fps::default(),
|
||||||
_global,
|
_global,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -126,6 +131,8 @@ pub struct Surface {
|
||||||
surface: X11Surface,
|
surface: X11Surface,
|
||||||
output: Output,
|
output: Output,
|
||||||
render: ping::Ping,
|
render: ping::Ping,
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
fps: Fps,
|
||||||
_global: GlobalDrop<WlOutput>,
|
_global: GlobalDrop<WlOutput>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,14 +152,7 @@ impl Surface {
|
||||||
let size = space.output_geometry(&self.output).unwrap();
|
let size = space.output_geometry(&self.output).unwrap();
|
||||||
let scale = space.output_scale(&self.output).unwrap();
|
let scale = space.output_scale(&self.output).unwrap();
|
||||||
let frame = state.egui.state.run(
|
let frame = state.egui.state.run(
|
||||||
|ctx| {
|
|ctx| debug_ui(ctx, &self.fps, true),
|
||||||
egui::SidePanel::left("my_left_panel").show(ctx, |ui| {
|
|
||||||
ui.label(format!(
|
|
||||||
"cosmic-comp version {}",
|
|
||||||
std::env!("CARGO_PKG_VERSION")
|
|
||||||
));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
size,
|
size,
|
||||||
size.to_f64().to_physical(scale).to_i32_round().size,
|
size.to_f64().to_physical(scale).to_i32_round().size,
|
||||||
scale,
|
scale,
|
||||||
|
|
@ -185,6 +185,10 @@ impl Surface {
|
||||||
self.surface
|
self.surface
|
||||||
.submit()
|
.submit()
|
||||||
.with_context(|| "Failed to submit buffer for display")?;
|
.with_context(|| "Failed to submit buffer for display")?;
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
{
|
||||||
|
self.fps.tick();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
let _ = renderer.unbind();
|
let _ = renderer.unbind();
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ use slog::Drain;
|
||||||
|
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
|
pub mod rendering;
|
||||||
pub mod shell;
|
pub mod shell;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
|
use crate::state::{Common, Fps};
|
||||||
|
use egui::CtxRef;
|
||||||
|
|
||||||
|
pub fn debug_ui(ctx: &CtxRef, fps: &Fps, primary: bool) {
|
||||||
|
egui::Area::new("main")
|
||||||
|
.anchor(egui::Align2::LEFT_TOP, (10.0, 10.0))
|
||||||
|
.show(ctx, |ui| {
|
||||||
|
use egui::widgets::plot::{Bar, BarChart, HLine, Legend, Plot};
|
||||||
|
|
||||||
|
// Basics
|
||||||
|
|
||||||
|
let label_res = ui.label(format!(
|
||||||
|
"cosmic-comp version {}",
|
||||||
|
std::env!("CARGO_PKG_VERSION")
|
||||||
|
));
|
||||||
|
ui.set_max_width(label_res.rect.width());
|
||||||
|
if let Some(hash) = std::option_env!("GIT_HASH").and_then(|x| x.get(0..8)) {
|
||||||
|
ui.label(hash);
|
||||||
|
}
|
||||||
|
ui.separator();
|
||||||
|
|
||||||
|
// FPS
|
||||||
|
|
||||||
|
let (max, min, avg) = (
|
||||||
|
fps.max().as_secs_f64(),
|
||||||
|
fps.min().as_secs_f64(),
|
||||||
|
fps.avg_fps(),
|
||||||
|
);
|
||||||
|
let fps_chart = BarChart::new(
|
||||||
|
fps.frames
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, duration)| {
|
||||||
|
let value = duration.as_secs_f64();
|
||||||
|
let transformed = ((value - min) / (max - min) * 255.0).round() as u8;
|
||||||
|
Bar::new(i as f64, value + 1.0).fill(egui::Color32::from_rgb(
|
||||||
|
transformed,
|
||||||
|
255 - transformed,
|
||||||
|
0,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
.vertical();
|
||||||
|
|
||||||
|
Plot::new("FPS")
|
||||||
|
.legend(Legend::default())
|
||||||
|
.view_aspect(33.0)
|
||||||
|
.include_x(0.0)
|
||||||
|
.include_x(100.0)
|
||||||
|
.include_y(0.0)
|
||||||
|
.include_y(max + 1.0)
|
||||||
|
.show_x(false)
|
||||||
|
.show(ui, |plot_ui| {
|
||||||
|
plot_ui.bar_chart(fps_chart);
|
||||||
|
plot_ui.hline(
|
||||||
|
HLine::new(avg)
|
||||||
|
.highlight()
|
||||||
|
.name(format!("AVG {}", avg.round() as i32))
|
||||||
|
.color(egui::Color32::DARK_BLUE),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
6
src/rendering/mod.rs
Normal file
6
src/rendering/mod.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
mod debug;
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
pub use debug::*;
|
||||||
50
src/state.rs
50
src/state.rs
|
|
@ -14,7 +14,10 @@ use smithay::{
|
||||||
shm::init_shm_global,
|
shm::init_shm_global,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::{cell::RefCell, rc::Rc, time::Instant};
|
use std::{cell::RefCell, rc::Rc, time::Instant};
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
use std::{collections::VecDeque, time::Duration};
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub common: Common,
|
pub common: Common,
|
||||||
|
|
@ -34,7 +37,6 @@ pub struct Common {
|
||||||
pub start_time: Instant,
|
pub start_time: Instant,
|
||||||
pub should_stop: bool,
|
pub should_stop: bool,
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
|
||||||
pub egui: Egui,
|
pub egui: Egui,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,6 +48,21 @@ pub struct Egui {
|
||||||
pub alpha: f32,
|
pub alpha: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
pub struct Fps {
|
||||||
|
pub frames: VecDeque<Duration>,
|
||||||
|
pub last: Instant,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Fps {
|
||||||
|
fn default() -> Fps {
|
||||||
|
Fps {
|
||||||
|
frames: VecDeque::with_capacity(101),
|
||||||
|
last: Instant::now(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum BackendData {
|
pub enum BackendData {
|
||||||
X11(X11State),
|
X11(X11State),
|
||||||
// TODO
|
// TODO
|
||||||
|
|
@ -102,3 +119,34 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
impl Fps {
|
||||||
|
pub fn tick(&mut self) {
|
||||||
|
let next = Instant::now();
|
||||||
|
let frame = next.duration_since(self.last);
|
||||||
|
|
||||||
|
self.frames.push_back(frame);
|
||||||
|
if self.frames.len() > 100 {
|
||||||
|
self.frames.pop_front();
|
||||||
|
}
|
||||||
|
self.last = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max(&self) -> &Duration {
|
||||||
|
self.frames.iter().max().unwrap_or(&Duration::ZERO)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn min(&self) -> &Duration {
|
||||||
|
self.frames.iter().min().unwrap_or(&Duration::ZERO)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn avg(&self) -> Duration {
|
||||||
|
self.frames.iter().cloned().sum::<Duration>() / (self.frames.len() as u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn avg_fps(&self) -> f64 {
|
||||||
|
let sum_secs = self.frames.iter().map(|d| d.as_secs_f64()).sum::<f64>();
|
||||||
|
1.0 / (sum_secs / self.frames.len() as f64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue