From cc0bbb61e3eb368b4627a5a72a3e39356500c8e7 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 7 Jun 2024 20:07:16 +0200 Subject: [PATCH] debug: Drop FPS struct for kms timings --- src/backend/render/mod.rs | 39 ++-- src/backend/winit.rs | 18 +- src/backend/x11.rs | 15 +- src/debug.rs | 47 ++--- src/state.rs | 207 ---------------------- src/wayland/handlers/screencopy/render.rs | 2 - 6 files changed, 44 insertions(+), 284 deletions(-) diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 4ac42ff2..953de063 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only use std::{ - borrow::{Borrow, BorrowMut}, + borrow::Borrow, cell::RefCell, collections::HashMap, sync::{Arc, RwLock, Weak}, @@ -66,12 +66,17 @@ use smithay::{ }, }; +#[cfg(feature = "debug")] +use smithay_egui::EguiState; + pub mod animations; pub mod cursor; pub mod element; use self::element::{AsGlowRenderer, CosmicElement}; +use super::kms::Timings; + pub type GlMultiRenderer<'a> = MultiRenderer<'a, 'a, GbmGlowBackend, GbmGlowBackend>; pub type GlMultiFrame<'a, 'frame> = @@ -456,6 +461,9 @@ where elements } +#[cfg(not(feature = "debug"))] +pub type EguiState = (); + #[profiling::function] pub fn workspace_elements( _gpu: Option<&DrmNode>, @@ -466,8 +474,8 @@ pub fn workspace_elements( previous: Option<(WorkspaceHandle, usize, WorkspaceDelta)>, current: (WorkspaceHandle, usize), cursor_mode: CursorMode, - _fps: &mut Option<&mut Fps>, exclude_workspace_overview: bool, + _fps: Option<(&EguiState, &Timings)>, ) -> Result>, RenderError> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, @@ -500,13 +508,15 @@ where let output_geo = output.geometry(); let scale = output.current_scale().fractional_scale(); - if let Some(fps) = _fps.as_mut() { + if let Some((state, timings)) = _fps.as_mut() { + let debug_active = shell.read().unwrap().debug_active; let fps_overlay = fps_ui( _gpu, - shell, - theme, + debug_active, + seats.iter(), renderer.glow_renderer_mut(), - *fps, + state, + timings, Rectangle::from_loc_and_size( (0, 0), (output_geo.size.w.min(400), output_geo.size.h.min(800)), @@ -954,7 +964,6 @@ pub fn render_output<'d, R, Target, OffTarget>( now: Time, output: &Output, cursor_mode: CursorMode, - fps: Option<&mut Fps>, ) -> Result, RenderError> where R: Renderer @@ -995,7 +1004,6 @@ where previous_workspace, workspace, cursor_mode, - fps, false, ); @@ -1108,7 +1116,6 @@ pub fn render_workspace<'d, R, Target, OffTarget>( previous: Option<(WorkspaceHandle, usize, WorkspaceDelta)>, current: (WorkspaceHandle, usize), cursor_mode: CursorMode, - mut fps: Option<&mut Fps>, exclude_workspace_overview: bool, ) -> Result<(RenderOutputResult<'d>, Vec>), RenderError> where @@ -1126,10 +1133,6 @@ where CosmicMappedRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { - if let Some(ref mut fps) = fps { - fps.start(); - } - let mut elements: Vec> = workspace_elements( gpu, renderer, @@ -1139,8 +1142,8 @@ where previous, current, cursor_mode, - &mut fps, exclude_workspace_overview, + None, )?; if let Some(additional_damage) = additional_damage { @@ -1154,10 +1157,6 @@ where ); } - if let Some(fps) = fps.as_mut() { - fps.elements(); - } - renderer.bind(target).map_err(RenderError::Rendering)?; let res = damage_tracker.render_output( renderer, @@ -1166,9 +1165,5 @@ where CLEAR_COLOR, // TODO use a theme neutral color ); - if let Some(fps) = fps.as_mut() { - fps.render(); - } - res.map(|res| (res, elements)) } diff --git a/src/backend/winit.rs b/src/backend/winit.rs index 3201e297..f080f4cc 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -31,12 +31,9 @@ use smithay::{ utils::Transform, wayland::dmabuf::DmabufFeedbackBuilder, }; -use std::{cell::RefCell, time::Duration}; +use std::{borrow::BorrowMut, cell::RefCell, time::Duration}; use tracing::{error, info, warn}; -#[cfg(feature = "debug")] -use crate::state::Fps; - use super::render::{init_shaders, CursorMode}; #[derive(Debug)] @@ -45,8 +42,6 @@ pub struct WinitState { pub backend: WinitGraphicsBackend, output: Output, damage_tracker: OutputDamageTracker, - #[cfg(feature = "debug")] - fps: Fps, } impl WinitState { @@ -68,10 +63,6 @@ impl WinitState { state.clock.now(), &self.output, CursorMode::NotDefault, - #[cfg(not(feature = "debug"))] - None, - #[cfg(feature = "debug")] - Some(&mut self.fps), ) { Ok(RenderOutputResult { damage, states, .. }) => { self.backend @@ -80,8 +71,6 @@ impl WinitState { self.backend .submit(damage.map(|x| x.as_slice())) .with_context(|| "Failed to submit buffer for display")?; - #[cfg(feature = "debug")] - self.fps.displayed(); state.send_frames(&self.output); state.update_primary_output(&self.output, &states); state.send_dmabuf_feedback(&self.output, &states, |_| None); @@ -215,15 +204,10 @@ pub fn init_backend( .map_err(|_| anyhow::anyhow!("Failed to init eventloop timer for winit"))?; event_ping.ping(); - #[cfg(feature = "debug")] - let fps = Fps::new(backend.renderer()); - state.backend = BackendData::Winit(WinitState { backend, output: output.clone(), damage_tracker: OutputDamageTracker::from_output(&output), - #[cfg(feature = "debug")] - fps, }); state diff --git a/src/backend/x11.rs b/src/backend/x11.rs index a3e61565..b5918a2f 100644 --- a/src/backend/x11.rs +++ b/src/backend/x11.rs @@ -38,12 +38,9 @@ use smithay::{ utils::{DeviceFd, Transform}, wayland::dmabuf::DmabufFeedbackBuilder, }; -use std::{cell::RefCell, os::unix::io::OwnedFd, time::Duration}; +use std::{borrow::BorrowMut, cell::RefCell, os::unix::io::OwnedFd, time::Duration}; use tracing::{debug, error, info, warn}; -#[cfg(feature = "debug")] -use crate::state::Fps; - use super::render::init_shaders; #[derive(Debug)] @@ -149,8 +146,6 @@ impl X11State { render: ping.clone(), dirty: false, pending: true, - #[cfg(feature = "debug")] - fps: Fps::new(&mut self.renderer), }); // schedule first render @@ -203,8 +198,6 @@ pub struct Surface { render: ping::Ping, dirty: bool, pending: bool, - #[cfg(feature = "debug")] - fps: Fps, } impl Surface { @@ -223,17 +216,11 @@ impl Surface { state.clock.now(), &self.output, render::CursorMode::NotDefault, - #[cfg(not(feature = "debug"))] - None, - #[cfg(feature = "debug")] - Some(&mut self.fps), ) { Ok(RenderOutputResult { damage, states, .. }) => { self.surface .submit() .with_context(|| "Failed to submit buffer for display")?; - #[cfg(feature = "debug")] - self.fps.displayed(); state.send_frames(&self.output); state.update_primary_output(&self.output, &states); state.send_dmabuf_feedback(&self.output, &states, |_| None); diff --git a/src/debug.rs b/src/debug.rs index 6a46fa8d..7660bcf2 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use crate::{ + backend::kms::Timings, shell::focus::target::{KeyboardFocusTarget, PointerFocusTarget}, state::{Common, Fps}, }; @@ -24,46 +25,48 @@ use smithay::{ pub const ELEMENTS_COLOR: Color32 = Color32::from_rgb(70, 198, 115); pub const RENDER_COLOR: Color32 = Color32::from_rgb(29, 114, 58); -pub const SCREENCOPY_COLOR: Color32 = Color32::from_rgb(253, 178, 39); +pub const SUBMITTED_COLOR: Color32 = Color32::from_rgb(253, 178, 39); pub const DISPLAY_COLOR: Color32 = Color32::from_rgb(41, 184, 209); -pub fn fps_ui( +pub fn fps_ui<'a>( gpu: Option<&DrmNode>, - state: &Common, + debug_active: bool, + seats: impl Iterator>, renderer: &mut GlowRenderer, - fps: &mut Fps, + state: &EguiState, + timings: &Timings, area: Rectangle, scale: f64, ) -> Result, GlesError> { use egui_plot::{Bar, BarChart, Legend, Plot}; 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(), + timings.max_frametime().as_secs_f64(), + timings.min_frametime().as_secs_f64(), + timings.avg_frametime().as_secs_f64(), + timings.avg_fps(), ); let (max_disp, min_disp) = ( - fps.max_time_to_display().as_secs_f64(), - fps.min_time_to_display().as_secs_f64(), + timings.max_time_to_display().as_secs_f64(), + timings.min_time_to_display().as_secs_f64(), ); let amount = avg_fps.round() as usize * 2; let ((bars_elements, bars_render), (bars_screencopy, bars_displayed)): ( (Vec, Vec), (Vec, Vec), - ) = fps - .frames + ) = timings + .previous_frames .iter() .rev() .take(amount) .rev() .enumerate() .map(|(i, frame)| { - let elements_val = frame.duration_elements.as_secs_f64(); - let render_val = frame.duration_render.as_secs_f64(); - let screencopy_val = frame - .duration_screencopy + let elements_val = frame.render_duration_elements.as_secs_f64(); + let render_val = frame.render_duration_draw.as_secs_f64(); + let submitted_val = frame + .presentation_submitted .as_ref() .map(|val| val.as_secs_f64()) .unwrap_or(0.0); @@ -93,7 +96,7 @@ pub fn fps_ui( let vendors = HashMap::from([ ( "0x10de", - fps.state + state .with_image(renderer, "nvidia", |image, ctx| { (image.texture_id(ctx), image.size_vec2()) }) @@ -101,7 +104,7 @@ pub fn fps_ui( ), ( "0x1002", - fps.state + state .with_image(renderer, "amd", |image, ctx| { (image.texture_id(ctx), image.size_vec2()) }) @@ -109,7 +112,7 @@ pub fn fps_ui( ), ( "0x8086", - fps.state + state .with_image(renderer, "intel", |image, ctx| { (image.texture_id(ctx), image.size_vec2()) }) @@ -117,7 +120,7 @@ pub fn fps_ui( ), ]); - fps.state.render( + state.render( |ctx| { egui::Area::new("main") .anchor(egui::Align2::LEFT_TOP, (10.0, 10.0)) @@ -130,7 +133,7 @@ pub fn fps_ui( ui.label(format!(": {hash}")); } - if !state.egui.active { + if !debug_active { ui.label("Press Super+Escape for debug overlay"); } else { ui.set_max_width(300.0); @@ -187,7 +190,7 @@ pub fn fps_ui( ui.separator(); ui.label(egui::RichText::new("Input States").heading()); - for seat in state.seats() { + for seat in seats { ui.label(egui::RichText::new(format!("\t{}", seat.name())).strong()); if let Some(ptr) = seat.get_pointer() { egui::Frame::none() diff --git a/src/state.rs b/src/state.rs index b5fa273f..5337c3e0 100644 --- a/src/state.rs +++ b/src/state.rs @@ -24,8 +24,6 @@ use i18n_embed::{ }; use once_cell::sync::Lazy; use rust_embed::RustEmbed; -#[cfg(feature = "debug")] -use smithay::utils::Rectangle; use smithay::{ backend::{ allocator::dmabuf::Dmabuf, @@ -35,7 +33,6 @@ use smithay::{ default_primary_scanout_output_compare, utils::select_dmabuf_feedback, RenderElementStates, }, - glow::GlowRenderer, ImportDma, }, }, @@ -98,7 +95,6 @@ use smithay::{ xwayland::XWaylandClientData, }; use time::UtcOffset; -use tracing::error; use std::{ cell::RefCell, @@ -954,206 +950,3 @@ impl Common { } } } - -#[derive(Debug)] -pub struct Fps { - #[cfg(feature = "debug")] - pub rd: Option>, - #[cfg(feature = "debug")] - pub state: smithay_egui::EguiState, - pending_frame: Option, - pub frames: VecDeque, -} - -#[derive(Debug)] -struct PendingFrame { - start: Instant, - duration_elements: Option, - duration_render: Option, - duration_displayed: Option, -} - -#[derive(Debug)] -pub struct Frame { - pub start: Instant, - pub duration_elements: Duration, - pub duration_render: Duration, - pub duration_displayed: Duration, -} - -impl Frame { - fn _render_time(&self) -> Duration { - self.duration_elements + self.duration_render - } - - fn frame_time(&self) -> Duration { - self.duration_elements + self.duration_render - } - - fn time_to_display(&self) -> Duration { - self.duration_elements + self.duration_render + self.duration_displayed - } -} - -impl From for Frame { - fn from(pending: PendingFrame) -> Self { - Frame { - start: pending.start, - duration_elements: pending.duration_elements.unwrap_or(Duration::ZERO), - duration_render: pending.duration_render.unwrap_or(Duration::ZERO), - duration_displayed: pending.duration_displayed.unwrap_or(Duration::ZERO), - } - } -} - -impl Fps { - const WINDOW_SIZE: usize = 360; - - pub fn start(&mut self) { - self.pending_frame = Some(PendingFrame { - start: Instant::now(), - duration_elements: None, - duration_render: None, - duration_displayed: None, - }); - } - - pub fn elements(&mut self) { - if let Some(frame) = self.pending_frame.as_mut() { - frame.duration_elements = Some(Instant::now().duration_since(frame.start)); - } - } - - pub fn render(&mut self) { - if let Some(frame) = self.pending_frame.as_mut() { - frame.duration_render = Some( - Instant::now().duration_since(frame.start) - - frame.duration_elements.clone().unwrap_or(Duration::ZERO), - ); - } - } - - pub fn displayed(&mut self) { - if let Some(mut frame) = self.pending_frame.take() { - frame.duration_displayed = Some( - Instant::now().duration_since(frame.start) - - frame.duration_elements.clone().unwrap_or(Duration::ZERO) - - frame.duration_render.clone().unwrap_or(Duration::ZERO), - ); - - self.frames.push_back(frame.into()); - while self.frames.len() > Fps::WINDOW_SIZE { - self.frames.pop_front(); - } - } - } - - pub fn max_frametime(&self) -> Duration { - self.frames - .iter() - .map(|f| f.frame_time()) - .max() - .unwrap_or(Duration::ZERO) - } - - pub fn min_frametime(&self) -> Duration { - self.frames - .iter() - .map(|f| f.frame_time()) - .min() - .unwrap_or(Duration::ZERO) - } - - pub fn max_time_to_display(&self) -> Duration { - self.frames - .iter() - .map(|f| f.time_to_display()) - .max() - .unwrap_or(Duration::ZERO) - } - - pub fn min_time_to_display(&self) -> Duration { - self.frames - .iter() - .map(|f| f.time_to_display()) - .min() - .unwrap_or(Duration::ZERO) - } - - pub fn avg_frametime(&self) -> Duration { - if self.frames.is_empty() { - return Duration::ZERO; - } - self.frames.iter().map(|f| f.frame_time()).sum::() / (self.frames.len() as u32) - } - - pub fn avg_time_to_display(&self, window: usize) -> Duration { - self.frames - .iter() - .rev() - .take(window) - .map(|f| f.time_to_display()) - .sum::() - / window as u32 - } - - pub fn avg_fps(&self) -> f64 { - if self.frames.is_empty() { - return 0.0; - } - let secs = match (self.frames.front(), self.frames.back()) { - (Some(Frame { start, .. }), Some(end_frame)) => { - end_frame.start.duration_since(*start) + end_frame.frame_time() - } - _ => Duration::ZERO, - } - .as_secs_f64(); - 1.0 / (secs / self.frames.len() as f64) - } -} - -#[cfg(feature = "debug")] -static INTEL_LOGO: &'static [u8] = include_bytes!("../resources/icons/intel.svg"); -#[cfg(feature = "debug")] -static AMD_LOGO: &'static [u8] = include_bytes!("../resources/icons/amd.svg"); -#[cfg(feature = "debug")] -static NVIDIA_LOGO: &'static [u8] = include_bytes!("../resources/icons/nvidia.svg"); - -impl Fps { - pub fn new(_renderer: &mut GlowRenderer) -> Fps { - #[cfg(feature = "debug")] - let state = { - let state = smithay_egui::EguiState::new(smithay::utils::Rectangle::from_loc_and_size( - (0, 0), - (400, 800), - )); - let mut visuals: egui::style::Visuals = Default::default(); - visuals.window_shadow.extrusion = 0.0; - state.context().set_visuals(visuals); - state - .load_svg(_renderer, String::from("intel"), INTEL_LOGO) - .unwrap(); - state - .load_svg(_renderer, String::from("amd"), AMD_LOGO) - .unwrap(); - state - .load_svg(_renderer, String::from("nvidia"), NVIDIA_LOGO) - .unwrap(); - state - }; - - Fps { - #[cfg(feature = "debug")] - state, - #[cfg(feature = "debug")] - rd: renderdoc::RenderDoc::new().ok(), - pending_frame: None, - frames: VecDeque::with_capacity(Fps::WINDOW_SIZE + 1), - } - } -} - -pub fn avg_fps<'a>(iter: impl Iterator) -> f64 { - let sum_secs = iter.map(|d| d.as_secs_f64()).sum::(); - 1.0 / (sum_secs / Fps::WINDOW_SIZE as f64) -} diff --git a/src/wayland/handlers/screencopy/render.rs b/src/wayland/handlers/screencopy/render.rs index b8f0c875..652acb5c 100644 --- a/src/wayland/handlers/screencopy/render.rs +++ b/src/wayland/handlers/screencopy/render.rs @@ -284,7 +284,6 @@ pub fn render_workspace_to_buffer( None, handle, cursor_mode, - None, true, ) .map(|res| res.0) @@ -310,7 +309,6 @@ pub fn render_workspace_to_buffer( None, handle, cursor_mode, - None, true, ) .map(|res| res.0)