From 0efc30ebfd7e28666a5da72f1a3f64113cda7fd6 Mon Sep 17 00:00:00 2001 From: Alex Bates Date: Tue, 24 Feb 2026 02:32:56 +0000 Subject: [PATCH] integrate puffin profiling for dev builds --- Cargo.lock | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 7 +++++++ crates/kammy/Cargo.toml | 6 ++++++ crates/kammy/src/app.rs | 8 ++++++++ crates/kammy/src/main.rs | 5 +++++ justfile | 3 +++ 6 file(s) changed, 198 insertion(s)(+), 0 deletion(s)(-) diff --git a/Cargo.lock b/Cargo.lock --- a/Cargo.lock +++ b/Cargo.lock @@ -508,6 +508,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] name = "bindgen" version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -977,6 +986,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" [[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "powerfmt", +] + +[[package]] name = "derive_arbitrary" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1222,6 +1240,20 @@ "winit", ] [[package]] +name = "egui_extras" +version = "0.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d01d34e845f01c62e3fded726961092e70417d66570c499b9817ab24674ca4ed" +dependencies = [ + "ahash", + "egui", + "enum-map", + "log", + "profiling", + "serde", +] + +[[package]] name = "egui_kittest" version = "0.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1309,6 +1341,27 @@ "syn 2.0.117", ] [[package]] +name = "enum-map" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +dependencies = [ + "enum-map-derive", + "serde", +] + +[[package]] +name = "enum-map-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] name = "enum_dispatch" version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2037,6 +2090,8 @@ checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", + "serde", + "serde_core", ] [[package]] @@ -2131,7 +2186,10 @@ "loro", "loroscope", "parallel_rdp", "pm64", + "profiling", "project", + "puffin", + "puffin_egui", "raw-window-handle", "rfd", "star_rod_interop", @@ -2255,6 +2313,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] +name = "log-once" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d8a05e3879b317b1b6dbf353e5bba7062bedcc59815267bb23eaa0c576cebf0" +dependencies = [ + "log", +] + +[[package]] name = "longest-increasing-subsequence" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2565,6 +2632,12 @@ "unicode-ident", ] [[package]] +name = "natord" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308d96db8debc727c3fd9744aac51751243420e46edf401010908da7f8d5e57c" + +[[package]] name = "ndk" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2657,6 +2730,12 @@ checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] + +[[package]] +name = "num-conv" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-integer" @@ -3260,6 +3339,12 @@ checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" @@ -3319,6 +3404,20 @@ name = "profiling" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" +dependencies = [ + "profiling-procmacros", + "puffin", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" +dependencies = [ + "quote", + "syn 2.0.117", +] [[package]] name = "project" @@ -3326,6 +3425,39 @@ version = "0.1.0" dependencies = [ "loro", "loroscope", +] + +[[package]] +name = "puffin" +version = "0.19.1" +source = "git+https://github.com/blip-radar/puffin?branch=egui-0.33#4a51e9f504f584e2e68a404cf24812bbb1be2300" +dependencies = [ + "anyhow", + "bincode", + "byteorder", + "cfg-if", + "itertools 0.14.0", + "lz4_flex", + "parking_lot", + "serde", +] + +[[package]] +name = "puffin_egui" +version = "0.29.0" +source = "git+https://github.com/blip-radar/puffin?branch=egui-0.33#4a51e9f504f584e2e68a404cf24812bbb1be2300" +dependencies = [ + "egui", + "egui_extras", + "indexmap", + "log", + "log-once", + "natord", + "parking_lot", + "puffin", + "time", + "vec1", + "web-time", ] [[package]] @@ -4092,6 +4224,37 @@ "zune-jpeg", ] [[package]] +name = "time" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "time-macros" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] name = "tiny-skia" version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4350,6 +4513,12 @@ name = "valuable" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vec1" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab68b56840f69efb0fefbe3ab6661499217ffdc58e2eef7c3f6f69835386322" [[package]] name = "version_check" diff --git a/Cargo.toml b/Cargo.toml --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,13 @@ rfd = "0.15" log = "0.4" thiserror = "2" anyhow = "1" +profiling = "1.0" +puffin = { git = "https://github.com/blip-radar/puffin", branch = "egui-0.33" } +puffin_egui = { git = "https://github.com/blip-radar/puffin", branch = "egui-0.33" } + +[patch.crates-io] +puffin = { git = "https://github.com/blip-radar/puffin", branch = "egui-0.33" } +puffin_egui = { git = "https://github.com/blip-radar/puffin", branch = "egui-0.33" } [workspace.lints.rust] missing_debug_implementations = "warn" diff --git a/crates/kammy/Cargo.toml b/crates/kammy/Cargo.toml --- a/crates/kammy/Cargo.toml +++ b/crates/kammy/Cargo.toml @@ -7,7 +7,13 @@ name = "kammy" version = "0.1.0" edition = "2024" +[features] +profile = ["dep:puffin", "dep:puffin_egui", "profiling/profile-with-puffin"] + [dependencies] +profiling = { workspace = true } +puffin = { workspace = true, optional = true } +puffin_egui = { workspace = true, optional = true } parallel_rdp = { path = "../parallel_rdp" } pm64 = { path = "../pm64" } project = { path = "../project" } diff --git a/crates/kammy/src/app.rs b/crates/kammy/src/app.rs --- a/crates/kammy/src/app.rs +++ b/crates/kammy/src/app.rs @@ -344,6 +344,7 @@ self.active_undo(true); } } + #[profiling::function] fn toolbar_ui(&mut self, ctx: &egui::Context) { egui::TopBottomPanel::top("toolbar").show(ctx, |ui| { ui.horizontal(|ui| { @@ -374,6 +375,7 @@ }); }); } + #[profiling::function] fn status_bar_ui(&mut self, ctx: &egui::Context) { egui::TopBottomPanel::bottom("status_bar").show(ctx, |ui| { ui.horizontal(|ui| { @@ -392,6 +394,7 @@ }); }); } + #[profiling::function] fn render_docks(&mut self, ctx: &egui::Context) { // Determine commit origin from the active editor so tool edits // are attributed to the correct undo stack. @@ -429,6 +432,7 @@ project.doc().commit(); } } + #[profiling::function] fn content_ui(&mut self, ctx: &egui::Context, gpu: Option<&mut GpuState>) { egui::CentralPanel::default().show(ctx, |ui| { // Snapshot each tabs container's children and active tab so we can @@ -522,7 +526,11 @@ impl KammyApp { /// Main UI update, called each frame from the winit event loop. /// /// `gpu` is `None` only in headless test environments. + #[profiling::function] pub fn update(&mut self, ctx: &egui::Context, gpu: Option<&mut GpuState>) { + #[cfg(feature = "profile")] + puffin_egui::profiler_window(ctx); + self.handle_keyboard(ctx); subsecond::call(|| self.toolbar_ui(ctx)); subsecond::call(|| self.status_bar_ui(ctx)); diff --git a/crates/kammy/src/main.rs b/crates/kammy/src/main.rs --- a/crates/kammy/src/main.rs +++ b/crates/kammy/src/main.rs @@ -125,6 +125,8 @@ state.gpu.resize(size.width, size.height); state.window.request_redraw(); } WindowEvent::RedrawRequested => { + profiling::finish_frame!(); + let raw_input = state.egui_state.take_egui_input(&state.window); let full_output = state.egui_ctx.run(raw_input, |ctx| { subsecond::call(|| state.app.update(ctx, Some(&mut state.gpu))); @@ -172,6 +174,9 @@ })) .init(); dioxus_devtools::connect_subsecond(); + + #[cfg(feature = "profile")] + puffin::set_scopes_on(true); subsecond::call(|| { let event_loop = EventLoop::new().expect("failed to create event loop"); diff --git a/justfile b/justfile --- a/justfile +++ b/justfile @@ -1,6 +1,9 @@ run: dx serve --hot-patch -p kammy +profile: + dx serve --hot-patch -p kammy --features profile + fmt: nix fmt -- tangled.sh