debug: First iteration
- Flesh out FPS counters and graph - Add opacity slider - Add specialized views - Populate workspace state inspector (very basic)
This commit is contained in:
parent
c1484cdb02
commit
5315abb9f1
9 changed files with 234 additions and 115 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
|
@ -752,7 +752,7 @@ checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay"
|
name = "smithay"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/Smithay/smithay.git?branch=feature/egl_userdata#1edff977226474e25e0fe90cbfb91860978b80cc"
|
source = "git+https://github.com/Smithay/smithay.git?branch=feature/egl_userdata#5cbd4352b9043cf634fb0b950ef244d9aaa9e151"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"appendlist",
|
"appendlist",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
|
@ -773,6 +773,7 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"scan_fmt",
|
"scan_fmt",
|
||||||
"slog",
|
"slog",
|
||||||
|
"slog-stdlog",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wayland-commons",
|
"wayland-commons",
|
||||||
|
|
@ -786,7 +787,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay-egui"
|
name = "smithay-egui"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/Smithay/smithay-egui.git?rev=ad146d59#ad146d59cc35199ef68024cc04c0a6e0c40b0d91"
|
source = "git+https://github.com/Smithay/smithay-egui.git#baa131d77b2fc2e3c2e87e881bba3ee18b315d14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"egui",
|
"egui",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ authors = ["Victoria Brekenfeld"]
|
||||||
anyhow = { version = "1.0.51", features = ["backtrace"] }
|
anyhow = { version = "1.0.51", features = ["backtrace"] }
|
||||||
bitflags = "1.3.2"
|
bitflags = "1.3.2"
|
||||||
slog = "2.7"
|
slog = "2.7"
|
||||||
|
#slog = { version = "2.7", features = ["max_level_trace"] }
|
||||||
slog-term = "2.8"
|
slog-term = "2.8"
|
||||||
slog-async = "2.7"
|
slog-async = "2.7"
|
||||||
slog-scope = "4.4"
|
slog-scope = "4.4"
|
||||||
|
|
@ -20,13 +21,12 @@ version = "0.3"
|
||||||
git = "https://github.com/Smithay/smithay.git"
|
git = "https://github.com/Smithay/smithay.git"
|
||||||
branch = "feature/egl_userdata"
|
branch = "feature/egl_userdata"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["backend_x11", "backend_egl", "desktop", "use_system_lib", "renderer_gl", "wayland_frontend"]
|
features = ["backend_x11", "backend_egl", "desktop", "use_system_lib", "renderer_gl", "wayland_frontend", "slog-stdlog"]
|
||||||
|
|
||||||
[dependencies.smithay-egui]
|
[dependencies.smithay-egui]
|
||||||
git = "https://github.com/Smithay/smithay-egui.git"
|
git = "https://github.com/Smithay/smithay-egui.git"
|
||||||
rev = "ad146d59"
|
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["debug"]
|
default = []
|
||||||
debug = ["egui", "smithay-egui"]
|
debug = ["egui", "smithay-egui"]
|
||||||
|
|
@ -13,7 +13,7 @@ use smithay::{
|
||||||
drm::DrmNode,
|
drm::DrmNode,
|
||||||
egl::{EGLContext, EGLDisplay},
|
egl::{EGLContext, EGLDisplay},
|
||||||
input::{Event, InputEvent},
|
input::{Event, InputEvent},
|
||||||
renderer::{gles2::Gles2Renderer, Bind, ImportDma, ImportEgl, Unbind},
|
renderer::{gles2::Gles2Renderer, Bind, ImportDma, ImportEgl},
|
||||||
x11::{Window, WindowBuilder, X11Backend, X11Event, X11Handle, X11Input, X11Surface},
|
x11::{Window, WindowBuilder, X11Backend, X11Event, X11Handle, X11Input, X11Surface},
|
||||||
},
|
},
|
||||||
desktop::layer_map_for_output,
|
desktop::layer_map_for_output,
|
||||||
|
|
@ -37,7 +37,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
use crate::{rendering::debug_ui, state::Fps};
|
use crate::{debug::debug_ui, state::Fps};
|
||||||
|
|
||||||
pub struct X11State {
|
pub struct X11State {
|
||||||
allocator: Arc<Mutex<GbmDevice<DrmNode>>>,
|
allocator: Arc<Mutex<GbmDevice<DrmNode>>>,
|
||||||
|
|
@ -145,26 +145,19 @@ impl Surface {
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut custom_elements = Vec::new();
|
let mut custom_elements = Vec::new();
|
||||||
let space = state.spaces.active_space_mut(output);
|
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
if state.egui.active {
|
{
|
||||||
|
let space = state.spaces.active_space(output);
|
||||||
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 = debug_ui(state, &self.fps, size, scale, true);
|
||||||
|ctx| debug_ui(ctx, &self.fps, true),
|
|
||||||
size,
|
|
||||||
size.to_f64().to_physical(scale).to_i32_round().size,
|
|
||||||
scale,
|
|
||||||
state.egui.alpha,
|
|
||||||
&state.start_time,
|
|
||||||
state.egui.modifiers.clone(),
|
|
||||||
);
|
|
||||||
custom_elements.push(
|
custom_elements.push(
|
||||||
Box::new(frame) as smithay::desktop::space::DynamicRenderElements<Gles2Renderer>
|
Box::new(frame) as smithay::desktop::space::DynamicRenderElements<Gles2Renderer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let space = state.spaces.active_space_mut(output);
|
||||||
let (buffer, age) = self
|
let (buffer, age) = self
|
||||||
.surface
|
.surface
|
||||||
.buffer()
|
.buffer()
|
||||||
|
|
@ -179,8 +172,7 @@ impl Surface {
|
||||||
[0.153, 0.161, 0.165, 1.0],
|
[0.153, 0.161, 0.165, 1.0],
|
||||||
&*custom_elements,
|
&*custom_elements,
|
||||||
) {
|
) {
|
||||||
Ok(Some(_)) => {
|
Ok(_) => {
|
||||||
slog_scope::trace!("Finished rendering");
|
|
||||||
space.send_frames(false, state.start_time.elapsed().as_millis() as u32);
|
space.send_frames(false, state.start_time.elapsed().as_millis() as u32);
|
||||||
self.surface
|
self.surface
|
||||||
.submit()
|
.submit()
|
||||||
|
|
@ -190,10 +182,6 @@ impl Surface {
|
||||||
self.fps.tick();
|
self.fps.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
|
||||||
let _ = renderer.unbind();
|
|
||||||
self.render.ping();
|
|
||||||
}
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
self.surface.reset_buffers();
|
self.surface.reset_buffers();
|
||||||
anyhow::bail!("Rendering failed: {}", err);
|
anyhow::bail!("Rendering failed: {}", err);
|
||||||
|
|
|
||||||
174
src/debug.rs
Normal file
174
src/debug.rs
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
|
use crate::state::{Common, Fps};
|
||||||
|
use smithay_egui::EguiFrame;
|
||||||
|
use smithay::utils::{Rectangle, Logical};
|
||||||
|
|
||||||
|
pub fn debug_ui(state: &mut Common, fps: &Fps, area: Rectangle<i32, Logical>, scale: f64, primary: bool) -> EguiFrame {
|
||||||
|
let size = area.size;
|
||||||
|
let alpha = state.egui.alpha;
|
||||||
|
|
||||||
|
state.egui.state.run(
|
||||||
|
|ctx| {
|
||||||
|
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")
|
||||||
|
));
|
||||||
|
if let Some(hash) = std::option_env!("GIT_HASH").and_then(|x| x.get(0..8)) {
|
||||||
|
ui.label(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !state.egui.active {
|
||||||
|
ui.label("Press Mod+Escape for debug menu");
|
||||||
|
} else {
|
||||||
|
ui.set_max_width(label_res.rect.width());
|
||||||
|
ui.separator();
|
||||||
|
|
||||||
|
// FPS
|
||||||
|
|
||||||
|
let (max, min, avg, avg_fps) = (
|
||||||
|
fps.max_frametime().as_secs_f64(),
|
||||||
|
fps.min_frametime().as_secs_f64(),
|
||||||
|
fps.avg_frametime().as_secs_f64(),
|
||||||
|
fps.avg_fps(),
|
||||||
|
);
|
||||||
|
|
||||||
|
ui.label(egui::RichText::new(format!("FPS: {:>7.3}", avg_fps)).heading());
|
||||||
|
ui.label("Frame Times:");
|
||||||
|
ui.label(egui::RichText::new(format!("avg: {:>7.6}", avg)).code());
|
||||||
|
ui.label(egui::RichText::new(format!("min: {:>7.6}", min)).code());
|
||||||
|
ui.label(egui::RichText::new(format!("max: {:>7.6}", max)).code());
|
||||||
|
let fps_chart = BarChart::new(
|
||||||
|
fps.frames
|
||||||
|
.iter()
|
||||||
|
.rev().take(30).rev()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, d)| {
|
||||||
|
let value = d.as_secs_f64();
|
||||||
|
let transformed = ((value - min) / (max - min) * 255.0).round() as u8;
|
||||||
|
Bar::new(i as f64, value).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(30.0)
|
||||||
|
.include_y(0.0)
|
||||||
|
.include_y(max * 2.0)
|
||||||
|
.show_x(false)
|
||||||
|
.show(ui, |plot_ui| {
|
||||||
|
plot_ui.bar_chart(fps_chart);
|
||||||
|
plot_ui.hline(
|
||||||
|
HLine::new(avg)
|
||||||
|
.highlight()
|
||||||
|
.color(egui::Color32::LIGHT_BLUE),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.separator();
|
||||||
|
|
||||||
|
// Toggles and stuff
|
||||||
|
ui.add(egui::Slider::new(&mut state.egui.alpha, 0.1..=1.0).clamp_to_range(true).text("Opacity"));
|
||||||
|
ui.checkbox(&mut state.egui.spaces, "Workspace UI");
|
||||||
|
//TODO: ui.checkbox(&mut state.egui.outputs, "Outputs UI");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// don't show these one others then the primary monitor
|
||||||
|
if primary {
|
||||||
|
egui::Window::new("Workspaces")
|
||||||
|
.open(&mut state.egui.spaces)
|
||||||
|
.vscroll(true)
|
||||||
|
.show(ctx, |ui| {
|
||||||
|
use crate::shell::workspaces::{ActiveWorkspace, Mode, MAX_WORKSPACES};
|
||||||
|
|
||||||
|
ui.set_min_width(250.0);
|
||||||
|
|
||||||
|
// Mode
|
||||||
|
|
||||||
|
ui.label(egui::RichText::new("Mode").heading());
|
||||||
|
let mut mode = *state.spaces.mode();
|
||||||
|
let active = if let Mode::Global { active } = mode { active } else { 0 };
|
||||||
|
ui.radio_value(&mut mode, Mode::OutputBound, "Output bound");
|
||||||
|
ui.radio_value(&mut mode, Mode::Global { active }, "Global");
|
||||||
|
state.spaces.set_mode(mode);
|
||||||
|
|
||||||
|
match *state.spaces.mode() {
|
||||||
|
Mode::OutputBound => {
|
||||||
|
ui.label("Workspaces:");
|
||||||
|
for output in state.spaces.outputs().cloned().collect::<Vec<_>>() {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
let active = output
|
||||||
|
.user_data()
|
||||||
|
.get::<ActiveWorkspace>()
|
||||||
|
.unwrap()
|
||||||
|
.get()
|
||||||
|
.unwrap();
|
||||||
|
let mut active_val = active as f64;
|
||||||
|
ui.label(output.name());
|
||||||
|
ui.add(egui::DragValue::new(&mut active_val).clamp_range(0..=(MAX_WORKSPACES-1)).speed(1.0));
|
||||||
|
if active != active_val as usize {
|
||||||
|
state.spaces.activate(&output, active_val as usize);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Mode::Global { active } => {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
let mut active_val = active as f64;
|
||||||
|
ui.label("Workspace:");
|
||||||
|
ui.add(egui::DragValue::new(&mut active_val).clamp_range(0..=(MAX_WORKSPACES-1)).speed(1.0));
|
||||||
|
if active != active_val as usize {
|
||||||
|
let output = state.spaces.outputs().next().cloned().unwrap();
|
||||||
|
state.spaces.activate(&output, active_val as usize);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spaces
|
||||||
|
for (i, space) in state.spaces.spaces.iter().enumerate() {
|
||||||
|
ui.collapsing(format!("Space: {}", i), |ui| {
|
||||||
|
ui.collapsing(format!("Windows"), |ui| {
|
||||||
|
for window in space.windows() {
|
||||||
|
ui.collapsing(format!("{:?}", window.toplevel()), |ui| {
|
||||||
|
ui.label(format!("Rect: {:?}", space.window_geometry(window)));
|
||||||
|
ui.label(format!("Bounding box: {:?}", space.window_bbox(window)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
egui::Window::new("Outputs")
|
||||||
|
.open(&mut state.egui.outputs)
|
||||||
|
.hscroll(true)
|
||||||
|
.show(ctx, |ui| {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
area,
|
||||||
|
size.to_f64().to_physical(scale).to_i32_round(),
|
||||||
|
scale,
|
||||||
|
alpha,
|
||||||
|
&state.start_time,
|
||||||
|
state.egui.modifiers.clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -10,11 +10,13 @@ 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;
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
pub mod debug;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
// setup logger
|
// setup logger
|
||||||
let _guard = init_logger();
|
let _guard = init_logger();
|
||||||
|
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
// 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),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
|
||||||
mod debug;
|
|
||||||
#[cfg(feature = "debug")]
|
|
||||||
pub use debug::*;
|
|
||||||
|
|
@ -8,14 +8,14 @@ pub use smithay::{
|
||||||
};
|
};
|
||||||
use std::{cell::Cell, mem::MaybeUninit};
|
use std::{cell::Cell, mem::MaybeUninit};
|
||||||
|
|
||||||
const MAX_WORKSPACES: usize = 10; // TODO?
|
pub const MAX_WORKSPACES: usize = 10; // TODO?
|
||||||
|
|
||||||
pub struct ActiveWorkspace(Cell<Option<usize>>);
|
pub struct ActiveWorkspace(Cell<Option<usize>>);
|
||||||
impl ActiveWorkspace {
|
impl ActiveWorkspace {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
ActiveWorkspace(Cell::new(None))
|
ActiveWorkspace(Cell::new(None))
|
||||||
}
|
}
|
||||||
fn get(&self) -> Option<usize> {
|
pub fn get(&self) -> Option<usize> {
|
||||||
self.0.get()
|
self.0.get()
|
||||||
}
|
}
|
||||||
fn set(&self, active: usize) -> Option<usize> {
|
fn set(&self, active: usize) -> Option<usize> {
|
||||||
|
|
@ -26,6 +26,7 @@ impl ActiveWorkspace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
OutputBound,
|
OutputBound,
|
||||||
Global { active: usize },
|
Global { active: usize },
|
||||||
|
|
@ -44,7 +45,7 @@ impl Mode {
|
||||||
pub struct Workspaces {
|
pub struct Workspaces {
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
outputs: Vec<Output>,
|
outputs: Vec<Output>,
|
||||||
spaces: [Space; MAX_WORKSPACES],
|
pub spaces: [Space; MAX_WORKSPACES],
|
||||||
}
|
}
|
||||||
|
|
||||||
const UNINIT_SPACE: MaybeUninit<Space> = MaybeUninit::uninit();
|
const UNINIT_SPACE: MaybeUninit<Space> = MaybeUninit::uninit();
|
||||||
|
|
@ -166,6 +167,11 @@ impl Workspaces {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
pub fn mode(&self) -> &Mode {
|
||||||
|
&self.mode
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_mode(&mut self, mode: Mode) {
|
pub fn set_mode(&mut self, mode: Mode) {
|
||||||
match (&mut self.mode, mode) {
|
match (&mut self.mode, mode) {
|
||||||
(Mode::OutputBound, Mode::Global { .. }) => {
|
(Mode::OutputBound, Mode::Global { .. }) => {
|
||||||
|
|
|
||||||
50
src/state.rs
50
src/state.rs
|
|
@ -37,6 +37,7 @@ 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 +47,8 @@ pub struct Egui {
|
||||||
pub modifiers: smithay::wayland::seat::ModifiersState,
|
pub modifiers: smithay::wayland::seat::ModifiersState,
|
||||||
pub active: bool,
|
pub active: bool,
|
||||||
pub alpha: f32,
|
pub alpha: f32,
|
||||||
|
pub spaces: bool,
|
||||||
|
pub outputs: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
|
|
@ -54,15 +57,6 @@ pub struct Fps {
|
||||||
pub last: Instant,
|
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
|
||||||
|
|
@ -113,6 +107,8 @@ impl State {
|
||||||
modifiers: Default::default(),
|
modifiers: Default::default(),
|
||||||
active: false,
|
active: false,
|
||||||
alpha: 1.0,
|
alpha: 1.0,
|
||||||
|
outputs: false,
|
||||||
|
spaces: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
backend: BackendData::Unset,
|
backend: BackendData::Unset,
|
||||||
|
|
@ -122,31 +118,55 @@ impl State {
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
impl Fps {
|
impl Fps {
|
||||||
|
const WINDOW_SIZE: usize = 100;
|
||||||
|
|
||||||
pub fn tick(&mut self) {
|
pub fn tick(&mut self) {
|
||||||
let next = Instant::now();
|
let next = Instant::now();
|
||||||
let frame = next.duration_since(self.last);
|
let frame_time = next.duration_since(self.last);
|
||||||
|
|
||||||
self.frames.push_back(frame);
|
self.frames.push_back(frame_time);
|
||||||
if self.frames.len() > 100 {
|
if self.frames.len() > Fps::WINDOW_SIZE {
|
||||||
self.frames.pop_front();
|
self.frames.pop_front();
|
||||||
}
|
}
|
||||||
self.last = next;
|
self.last = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn max(&self) -> &Duration {
|
pub fn max_frametime(&self) -> &Duration {
|
||||||
self.frames.iter().max().unwrap_or(&Duration::ZERO)
|
self.frames.iter().max().unwrap_or(&Duration::ZERO)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn min(&self) -> &Duration {
|
pub fn min_frametime(&self) -> &Duration {
|
||||||
self.frames.iter().min().unwrap_or(&Duration::ZERO)
|
self.frames.iter().min().unwrap_or(&Duration::ZERO)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn avg(&self) -> Duration {
|
pub fn avg_frametime(&self) -> Duration {
|
||||||
|
if self.frames.is_empty() {
|
||||||
|
return Duration::ZERO;
|
||||||
|
}
|
||||||
self.frames.iter().cloned().sum::<Duration>() / (self.frames.len() as u32)
|
self.frames.iter().cloned().sum::<Duration>() / (self.frames.len() as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn avg_fps(&self) -> f64 {
|
pub fn avg_fps(&self) -> f64 {
|
||||||
|
if self.frames.is_empty() {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
let sum_secs = self.frames.iter().map(|d| d.as_secs_f64()).sum::<f64>();
|
let sum_secs = self.frames.iter().map(|d| d.as_secs_f64()).sum::<f64>();
|
||||||
1.0 / (sum_secs / self.frames.len() as f64)
|
1.0 / (sum_secs / self.frames.len() as f64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
impl Default for Fps {
|
||||||
|
fn default() -> Fps {
|
||||||
|
Fps {
|
||||||
|
frames: VecDeque::with_capacity(Fps::WINDOW_SIZE + 1),
|
||||||
|
last: Instant::now(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
pub fn avg_fps<'a>(iter: impl Iterator<Item=&'a Duration>) -> f64 {
|
||||||
|
let sum_secs = iter.map(|d| d.as_secs_f64()).sum::<f64>();
|
||||||
|
1.0 / (sum_secs / Fps::WINDOW_SIZE as f64)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue