From ef7c978d5b5b9407b45ba12ab78ac232ede94dce Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Sat, 7 Oct 2023 19:15:44 -0700 Subject: [PATCH] Add support for profiling using tracy --- Cargo.lock | 73 ++++++++++++++++++++++++++++-- Cargo.toml | 2 + src/backend/kms/mod.rs | 6 +++ src/backend/render/cursor.rs | 2 + src/backend/render/mod.rs | 4 ++ src/backend/winit.rs | 2 + src/main.rs | 10 ++++ src/shell/element/mod.rs | 1 + src/shell/element/surface.rs | 1 + src/shell/element/window.rs | 3 ++ src/shell/grabs/moving.rs | 1 + src/shell/layout/floating/mod.rs | 2 + src/shell/layout/tiling/mod.rs | 3 ++ src/shell/mod.rs | 1 + src/shell/workspace.rs | 2 + src/state.rs | 8 ++++ src/utils/iced.rs | 2 + src/wayland/handlers/screencopy.rs | 4 ++ 18 files changed, 122 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e8cc0abd..32f837cab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -761,6 +761,7 @@ dependencies = [ "once_cell", "ordered-float", "png", + "profiling", "puffin", "puffin_egui", "regex", @@ -1888,6 +1889,19 @@ dependencies = [ "libc", ] +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows 0.48.0", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -2038,7 +2052,7 @@ dependencies = [ "presser", "thiserror", "winapi", - "windows", + "windows 0.51.1", ] [[package]] @@ -2883,6 +2897,19 @@ dependencies = [ "log", ] +[[package]] +name = "loom" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e045d70ddfbc984eacfa964ded019534e8f6cbf36f6410aee0ed5cefa5a9175" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + [[package]] name = "lru" version = "0.12.1" @@ -3802,18 +3829,19 @@ dependencies = [ [[package]] name = "profiling" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d135ede8821cf6376eb7a64148901e1690b788c11ae94dc297ae917dbc91dc0e" +checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" dependencies = [ "profiling-procmacros", + "tracy-client", ] [[package]] name = "profiling-procmacros" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b322d7d65c1ab449be3c890fcbd0db6e1092d0dd05d79dba2dd28032cebeb05" +checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" dependencies = [ "quote", "syn 2.0.48", @@ -4220,6 +4248,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "rustybuzz" version = "0.12.1" @@ -5017,6 +5051,26 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "tracy-client" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59fb931a64ff88984f86d3e9bcd1ae8843aa7fe44dd0f8097527bc172351741d" +dependencies = [ + "loom", + "once_cell", + "tracy-client-sys", +] + +[[package]] +name = "tracy-client-sys" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d104d610dfa9dd154535102cc9c6164ae1fa37842bc2d9e83f9ac82b0ae0882" +dependencies = [ + "cc", +] + [[package]] name = "ttf-parser" version = "0.20.0" @@ -5710,6 +5764,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows" version = "0.51.1" diff --git a/Cargo.toml b/Cargo.toml index 0a020d7f9..968b72a12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,6 +58,7 @@ xdg = "^2.1" xdg-user = "0.2.1" xkbcommon = "0.7" zbus = "3.15.0" +profiling = { version = "1.0" } [dependencies.id_tree] branch = "feature/copy_clone" @@ -96,6 +97,7 @@ rev = "cdc652e0" debug = ["egui", "egui_plot", "smithay-egui", "renderdoc", "puffin", "puffin_egui", "anyhow/backtrace"] default = ["systemd"] systemd = ["libsystemd"] +profile-with-tracy = ["profiling/profile-with-tracy"] [profile.dev] lto = "thin" diff --git a/src/backend/kms/mod.rs b/src/backend/kms/mod.rs index 388266a15..e5e57e42b 100644 --- a/src/backend/kms/mod.rs +++ b/src/backend/kms/mod.rs @@ -1153,6 +1153,7 @@ fn get_surface_dmabuf_feedback( } impl Surface { + #[profiling::function] pub fn render_output( &mut self, api: &mut GpuManager>, @@ -1359,6 +1360,7 @@ impl KmsState { self.session.change_vt(num).map_err(Into::into) } + #[profiling::function] pub fn apply_config_for_output( &mut self, output: &Output, @@ -1587,6 +1589,7 @@ impl KmsState { Err(last_err) } + #[profiling::function] pub fn schedule_render( &mut self, loop_handle: &LoopHandle<'_, State>, @@ -1626,6 +1629,7 @@ impl KmsState { ) }, move |_time, _, state| { + profiling::scope!("render_timer"); let backend = state.backend.kms(); let (mut device, mut other) = backend .devices @@ -1666,6 +1670,8 @@ impl KmsState { ) }; + profiling::finish_frame!(); + match result { Ok(_) => { trace!(?crtc, "Frame pending"); diff --git a/src/backend/render/cursor.rs b/src/backend/render/cursor.rs index 72eb07783..2b62b412a 100644 --- a/src/backend/render/cursor.rs +++ b/src/backend/render/cursor.rs @@ -184,6 +184,7 @@ where ) } +#[profiling::function] pub fn draw_dnd_icon( renderer: &mut R, surface: &wl_surface::WlSurface, @@ -301,6 +302,7 @@ impl Default for CursorState { } } +#[profiling::function] pub fn draw_cursor( renderer: &mut R, seat: &Seat, diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index ee57e4249..df52ea12e 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -389,6 +389,7 @@ pub enum CursorMode { All, } +#[profiling::function] pub fn cursor_elements<'frame, E, R>( renderer: &mut R, state: &Common, @@ -464,6 +465,7 @@ where elements } +#[profiling::function] pub fn workspace_elements( _gpu: Option<&DrmNode>, renderer: &mut R, @@ -965,6 +967,7 @@ where } } +#[profiling::function] pub fn render_output( gpu: Option<&DrmNode>, renderer: &mut R, @@ -1020,6 +1023,7 @@ where result } +#[profiling::function] pub fn render_workspace( gpu: Option<&DrmNode>, renderer: &mut R, diff --git a/src/backend/winit.rs b/src/backend/winit.rs index 1e4134a4a..38adf37c1 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -51,6 +51,7 @@ pub struct WinitState { } impl WinitState { + #[profiling::function] pub fn render_output(&mut self, state: &mut Common) -> Result<()> { self.backend .bind() @@ -197,6 +198,7 @@ pub fn init_backend( error!(?err, "Failed to render frame."); render_ping.ping(); } + profiling::finish_frame!(); }) .map_err(|_| anyhow::anyhow!("Failed to init eventloop timer for winit"))?, ); diff --git a/src/main.rs b/src/main.rs index 66bdbe9a1..33424e686 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,6 +38,11 @@ pub mod utils; pub mod wayland; pub mod xwayland; +#[cfg(feature = "profile-with-tracy")] +#[global_allocator] +static GLOBAL: profiling::tracy_client::ProfiledAllocator = + profiling::tracy_client::ProfiledAllocator::new(std::alloc::System, 10); + fn main() -> Result<()> { // setup logger logger::init_logger()?; @@ -80,6 +85,11 @@ fn main() -> Result<()> { warn!(?err, "Failed to watch theme"); } + #[cfg(feature = "profile-with-tracy")] + profiling::tracy_client::Client::start(); + + profiling::register_thread!("Main Thread"); + // run the event loop event_loop.run(None, &mut state, |state| { // shall we shut down? diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 43de92747..37abe49f0 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -847,6 +847,7 @@ impl SpaceElement for CosmicMapped { fn z_index(&self) -> u8 { SpaceElement::z_index(&self.element) } + #[profiling::function] fn refresh(&self) { SpaceElement::refresh(&self.element) } diff --git a/src/shell/element/surface.rs b/src/shell/element/surface.rs index aa9452a86..b4072709e 100644 --- a/src/shell/element/surface.rs +++ b/src/shell/element/surface.rs @@ -641,6 +641,7 @@ impl SpaceElement for CosmicSurface { SpaceElement::output_leave(&self.0, output) } + #[profiling::function] fn refresh(&self) { SpaceElement::refresh(&self.0) } diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 46915f68f..0528fffc7 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -490,11 +490,13 @@ impl SpaceElement for CosmicWindow { }); } } + #[profiling::function] fn output_enter(&self, output: &Output, overlap: Rectangle) { SpaceElement::output_enter(&self.0, output, overlap); self.0 .with_program(|p| SpaceElement::output_enter(&p.window, output, overlap)); } + #[profiling::function] fn output_leave(&self, output: &Output) { SpaceElement::output_leave(&self.0, output); self.0 @@ -512,6 +514,7 @@ impl SpaceElement for CosmicWindow { fn z_index(&self) -> u8 { self.0.with_program(|p| SpaceElement::z_index(&p.window)) } + #[profiling::function] fn refresh(&self) { SpaceElement::refresh(&self.0); if self.0.with_program(|p| { diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index 1fa943138..a6e3434b3 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -61,6 +61,7 @@ pub struct MoveGrabState { } impl MoveGrabState { + #[profiling::function] pub fn render( &self, renderer: &mut R, diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index 6161e5f06..f09fb25a7 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -1095,6 +1095,7 @@ impl FloatingLayout { self.mapped().flat_map(|e| e.windows().map(|(w, _)| w)) } + #[profiling::function] pub fn refresh(&mut self) { #[cfg(feature = "debug")] puffin::profile_function!(); @@ -1150,6 +1151,7 @@ impl FloatingLayout { self.refresh(); //fixup any out of bounds elements } + #[profiling::function] pub fn render( &self, renderer: &mut R, diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 022c937e5..96ae33f45 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -2303,6 +2303,7 @@ impl TilingLayout { self.queue.push_tree(tree, ANIMATION_DURATION, blocker); } + #[profiling::function] pub fn refresh(&mut self) { #[cfg(feature = "debug")] puffin::profile_function!(); @@ -2934,6 +2935,7 @@ impl TilingLayout { } } + #[profiling::function] fn update_positions( output: &Output, tree: &mut Tree, @@ -3801,6 +3803,7 @@ impl TilingLayout { } } + #[profiling::function] pub fn render( &self, renderer: &mut R, diff --git a/src/shell/mod.rs b/src/shell/mod.rs index de90788d0..8a156a937 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1515,6 +1515,7 @@ impl Shell { } } + #[profiling::function] pub fn refresh(&mut self) { #[cfg(feature = "debug")] puffin::profile_function!(); diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 13e85dbb2..31262aa20 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -286,6 +286,7 @@ impl Workspace { } } + #[profiling::function] pub fn refresh(&mut self, xdg_activation_state: &XdgActivationState) { #[cfg(feature = "debug")] puffin::profile_function!(); @@ -1059,6 +1060,7 @@ impl Workspace { } } + #[profiling::function] pub fn render<'a, R>( &self, renderer: &mut R, diff --git a/src/state.rs b/src/state.rs index 1a492f0f9..3bc4c3145 100644 --- a/src/state.rs +++ b/src/state.rs @@ -353,7 +353,15 @@ impl State { .with_context(|| "Failed to load languages") .unwrap(); + #[cfg(feature = "profile-with-tracy")] + unsafe { + time::util::local_offset::set_soundness(time::util::local_offset::Soundness::Unsound); + } let local_offset = UtcOffset::current_local_offset().expect("No yet multithreaded"); + #[cfg(feature = "profile-with-tracy")] + unsafe { + time::util::local_offset::set_soundness(time::util::local_offset::Soundness::Sound); + } let clock = Clock::new(); let config = Config::load(&handle); let compositor_state = CompositorState::new::(dh); diff --git a/src/utils/iced.rs b/src/utils/iced.rs index 0a1dac995..23fb2bb2c 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced.rs @@ -358,6 +358,7 @@ impl IcedElement

{ } impl IcedElementInternal

{ + #[profiling::function] fn update(&mut self, mut force: bool) -> Vec::Message>> { while let Ok(message) = self.rx.try_recv() { self.state.queue_message(message); @@ -691,6 +692,7 @@ impl SpaceElement for IcedElement

{ RenderZindex::Shell as u8 } + #[profiling::function] fn refresh(&self) { let mut internal = self.0.lock().unwrap(); // makes partial borrows easier diff --git a/src/wayland/handlers/screencopy.rs b/src/wayland/handlers/screencopy.rs index b2ee3248b..8a122c1b2 100644 --- a/src/wayland/handlers/screencopy.rs +++ b/src/wayland/handlers/screencopy.rs @@ -593,6 +593,7 @@ where Ok(()) } +#[profiling::function] pub fn render_session( node: Option, renderer: &mut R, @@ -637,6 +638,7 @@ where } } +#[profiling::function] pub fn render_output_to_buffer( state: &mut State, session: &Session, @@ -767,6 +769,7 @@ pub fn render_output_to_buffer( } } +#[profiling::function] pub fn render_workspace_to_buffer( state: &mut State, session: &Session, @@ -916,6 +919,7 @@ smithay::render_elements! { CursorElement=cursor::CursorRenderElement, } +#[profiling::function] pub fn render_window_to_buffer( state: &mut State, session: &Session,