diff --git a/Cargo.lock b/Cargo.lock
index 4a8c133a616..6e03615ed82 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -81,6 +81,12 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "anyhow"
+version = "1.0.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
+
[[package]]
name = "approx"
version = "0.4.0"
@@ -423,6 +429,9 @@ name = "cc"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
+dependencies = [
+ "jobserver",
+]
[[package]]
name = "cesu8"
@@ -1018,6 +1027,8 @@ dependencies = [
"glow",
"image",
"poll-promise",
+ "puffin",
+ "puffin_http",
"rfd",
"three-d",
]
@@ -1044,6 +1055,7 @@ dependencies = [
"epi",
"glow",
"instant",
+ "puffin",
"serde",
"tracing",
"tts",
@@ -1118,6 +1130,7 @@ dependencies = [
"glow",
"glutin",
"memoffset",
+ "puffin",
"tracing",
"wasm-bindgen",
"web-sys",
@@ -1806,6 +1819,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
+[[package]]
+name = "jobserver"
+version = "0.1.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "jpeg-decoder"
version = "0.2.2"
@@ -2529,6 +2551,43 @@ dependencies = [
"unicode-xid",
]
+[[package]]
+name = "puffin"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78cc1dc2f2e3e4787201dd9404c9b097967fd74b9013ba41e62448b617cb7ac2"
+dependencies = [
+ "anyhow",
+ "bincode",
+ "byteorder",
+ "once_cell",
+ "parking_lot 0.12.0",
+ "ruzstd",
+ "serde",
+ "zstd",
+]
+
+[[package]]
+name = "puffin_http"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "784f1952bda562ec8b76651f0c879b61eb02eaf20fe9acd2a8ca69b4898b13fd"
+dependencies = [
+ "anyhow",
+ "crossbeam-channel",
+ "log",
+ "puffin",
+]
+
+[[package]]
+name = "puffin_profiler"
+version = "0.1.0"
+dependencies = [
+ "eframe",
+ "puffin",
+ "puffin_http",
+]
+
[[package]]
name = "quote"
version = "1.0.15"
@@ -2795,6 +2854,16 @@ dependencies = [
"unicode-script",
]
+[[package]]
+name = "ruzstd"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cada0ef59efa6a5f4dc5e491f93d9f31e3fc7758df421ff1de8a706338e1100"
+dependencies = [
+ "byteorder",
+ "twox-hash",
+]
+
[[package]]
name = "ryu"
version = "1.0.9"
@@ -3374,6 +3443,16 @@ dependencies = [
"windows",
]
+[[package]]
+name = "twox-hash"
+version = "1.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ee73e6e4924fe940354b8d4d98cad5231175d615cd855b758adc658c0aac6a0"
+dependencies = [
+ "cfg-if 1.0.0",
+ "static_assertions",
+]
+
[[package]]
name = "unicode-bidi"
version = "0.3.7"
@@ -4051,6 +4130,35 @@ dependencies = [
"synstructure",
]
+[[package]]
+name = "zstd"
+version = "0.10.0+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b1365becbe415f3f0fcd024e2f7b45bacfb5bdd055f0dc113571394114e7bdd"
+dependencies = [
+ "zstd-safe",
+]
+
+[[package]]
+name = "zstd-safe"
+version = "4.1.4+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f7cd17c9af1a4d6c24beb1cc54b17e2ef7b593dc92f19e9d9acad8b182bbaee"
+dependencies = [
+ "libc",
+ "zstd-sys",
+]
+
+[[package]]
+name = "zstd-sys"
+version = "1.6.3+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc49afa5c8d634e75761feda8c592051e7eeb4683ba827211eb0d731d3402ea8"
+dependencies = [
+ "cc",
+ "libc",
+]
+
[[package]]
name = "zvariant"
version = "3.1.2"
diff --git a/Cargo.toml b/Cargo.toml
index a8113833166..bb600940a9d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,6 +12,8 @@ members = [
"emath",
"epaint",
"epi",
+
+ "examples/puffin_profiler",
]
[profile.dev]
diff --git a/eframe/CHANGELOG.md b/eframe/CHANGELOG.md
index 1646e51f9f7..8deb782ff8b 100644
--- a/eframe/CHANGELOG.md
+++ b/eframe/CHANGELOG.md
@@ -22,6 +22,7 @@ NOTE: [`egui_web`](../egui_web/CHANGELOG.md), [`egui-winit`](../egui-winit/CHANG
* `dark-light` (dark mode detection) is now an opt-in feature ([#1437](https://github.com/emilk/egui/pull/1437)).
* Fixed potential scale bug when DPI scaling changes (e.g. when dragging a window between different displays) ([#1441](https://github.com/emilk/egui/pull/1441)).
* MSRV (Minimum Supported Rust Version) is now `1.60.0` ([#1467](https://github.com/emilk/egui/pull/1467)).
+* Added new feature `puffin` to add [`puffin profiler`](https://github.com/EmbarkStudios/puffin) scopes ([#1483](https://github.com/emilk/egui/pull/1483)).
## 0.17.0 - 2022-02-22
diff --git a/eframe/Cargo.toml b/eframe/Cargo.toml
index 07413163204..4b1f4569a49 100644
--- a/eframe/Cargo.toml
+++ b/eframe/Cargo.toml
@@ -37,6 +37,11 @@ persistence = [
"epi/persistence",
]
+# Enable profiling with the puffin crate: https://github.com/EmbarkStudios/puffin
+# Only enabled on native, because of the low resolution (1ms) of time keeping in browsers.
+# eframe will call `puffin::GlobalProfiler::lock().new_frame()` for you
+puffin = ["egui_glow/puffin"]
+
# enable screen reader support (requires `ctx.options().screen_reader = true;`)
screen_reader = [
"egui-winit/screen_reader",
@@ -74,5 +79,7 @@ image = { version = "0.24", default-features = false, features = [
"png",
] }
poll-promise = "0.1"
+puffin = "0.13"
+puffin_http = "0.10"
rfd = "0.8"
three-d = { version = "0.11", default-features = false }
diff --git a/eframe/README.md b/eframe/README.md
index 68581dc9284..b38e0c0b71c 100644
--- a/eframe/README.md
+++ b/eframe/README.md
@@ -8,9 +8,10 @@
`eframe` is the official framework library for writing apps using [`egui`](https://github.com/emilk/egui). The app can be compiled both to run natively (cross platform) or be compiled to a web app (using WASM).
-To get started, go to and follow the instructions there!
+To get started, see the [crate examples](https://github.com/emilk/egui/tree/master/examples) and [single-file examples](https://github.com/emilk/egui/tree/master/eframe/examples).
+To learn how to set up `eframe` for web and native, go to and follow the instructions there!
-You can also take a look at [the `eframe` examples folder](https://github.com/emilk/egui/tree/master/eframe/examples). There is also an excellent tutorial video at .
+There is also a tutorial video at .
For how to use `egui`, see [the egui docs](https://docs.rs/egui).
@@ -37,6 +38,7 @@ Not all rust crates work when compiled to WASM, but here are some useful crates
* Audio: [`cpal`](https://github.com/RustAudio/cpal).
* HTTP client: [`ehttp`](https://github.com/emilk/ehttp).
* Time: [`chrono`](https://github.com/chronotope/chrono).
+* WebSockets: [`ewebsock`](https://github.com/rerun-io/ewebsock).
## Name
diff --git a/eframe/src/lib.rs b/eframe/src/lib.rs
index 6e7a318f738..45ff0f7385f 100644
--- a/eframe/src/lib.rs
+++ b/eframe/src/lib.rs
@@ -4,9 +4,8 @@
//! and are happy with just using egui for all visuals,
//! Then `eframe` is for you!
//!
-//! To get started, look at .
-//!
-//! You can also take a look at [the `eframe` examples folder](https://github.com/emilk/egui/tree/master/eframe/examples).
+//! To get started, see the [crate examples](https://github.com/emilk/egui/tree/master/examples) and [single-file examples](https://github.com/emilk/egui/tree/master/eframe/examples).
+//! To learn how to set up `eframe` for web and native, go to and follow the instructions there!
//!
//! You write your application code for [`epi`] (implementing [`epi::App`]) and then
//! call from [`crate::run_native`] your `main.rs`, and/or call `eframe::start_web` from your `lib.rs`.
diff --git a/egui-winit/CHANGELOG.md b/egui-winit/CHANGELOG.md
index 296191f13eb..b7c711f635c 100644
--- a/egui-winit/CHANGELOG.md
+++ b/egui-winit/CHANGELOG.md
@@ -7,6 +7,7 @@ All notable changes to the `egui-winit` integration will be noted in this file.
* Renamed the feature `convert_bytemuck` to `bytemuck` ([#1467](https://github.com/emilk/egui/pull/1467)).
* Renamed the feature `serialize` to `serde` ([#1467](https://github.com/emilk/egui/pull/1467)).
* MSRV (Minimum Supported Rust Version) is now `1.60.0` ([#1467](https://github.com/emilk/egui/pull/1467)).
+* Added new feature `puffin` to add [`puffin profiler`](https://github.com/EmbarkStudios/puffin) scopes ([#1483](https://github.com/emilk/egui/pull/1483)).
## 0.17.0 - 2022-02-22
diff --git a/egui-winit/Cargo.toml b/egui-winit/Cargo.toml
index 578e1a390fc..aa835295317 100644
--- a/egui-winit/Cargo.toml
+++ b/egui-winit/Cargo.toml
@@ -36,6 +36,9 @@ epi_backend = ["epi", "glow"]
# enable opening links in a browser when an egui hyperlink is clicked.
links = ["webbrowser"]
+# Enable profiling with the puffin crate: https://github.com/EmbarkStudios/puffin
+puffin = ["dep:puffin"]
+
# experimental support for a screen reader
screen_reader = ["tts"]
@@ -57,6 +60,7 @@ epi = { version = "0.17.0", path = "../epi", optional = true }
arboard = { version = "2.1", optional = true, default-features = false }
dark-light = { version = "0.2.1", optional = true }
glow = { version = "0.11", optional = true }
+puffin = { version = "0.13", optional = true }
serde = { version = "1.0", optional = true, features = ["derive"] }
webbrowser = { version = "0.6", optional = true }
diff --git a/egui-winit/src/epi.rs b/egui-winit/src/epi.rs
index b34d3a5d124..349349c9af6 100644
--- a/egui-winit/src/epi.rs
+++ b/egui-winit/src/epi.rs
@@ -191,6 +191,7 @@ impl EpiIntegration {
}
pub fn warm_up(&mut self, app: &mut dyn epi::App, window: &winit::window::Window) {
+ crate::profile_function!();
let saved_memory: egui::Memory = self.egui_ctx.memory().clone();
self.egui_ctx.memory().set_everything_is_visible(true);
let full_output = self.update(app, window);
@@ -230,6 +231,7 @@ impl EpiIntegration {
let raw_input = self.egui_winit.take_egui_input(window);
let full_output = self.egui_ctx.run(raw_input, |egui_ctx| {
+ crate::profile_scope!("App::update");
app.update(egui_ctx, &mut self.frame);
});
self.pending_full_output.append(full_output);
@@ -274,7 +276,10 @@ impl EpiIntegration {
pub fn save(&mut self, _app: &mut dyn epi::App, _window: &winit::window::Window) {
#[cfg(feature = "persistence")]
if let Some(storage) = self.frame.storage_mut() {
+ crate::profile_function!();
+
if _app.persist_native_window() {
+ crate::profile_scope!("native_window");
epi::set_value(
storage,
STORAGE_WINDOW_KEY,
@@ -282,9 +287,15 @@ impl EpiIntegration {
);
}
if _app.persist_egui_memory() {
+ crate::profile_scope!("egui_memory");
epi::set_value(storage, STORAGE_EGUI_MEMORY_KEY, &*self.egui_ctx.memory());
}
- _app.save(storage);
+ {
+ crate::profile_scope!("App::save");
+ _app.save(storage);
+ }
+
+ crate::profile_scope!("Storage::flush");
storage.flush();
}
}
diff --git a/egui-winit/src/lib.rs b/egui-winit/src/lib.rs
index 4a3ec05df9d..e0893a40c17 100644
--- a/egui-winit/src/lib.rs
+++ b/egui-winit/src/lib.rs
@@ -646,3 +646,25 @@ fn translate_cursor(cursor_icon: egui::CursorIcon) -> Option Some(winit::window::CursorIcon::ZoomOut),
}
}
+
+// ---------------------------------------------------------------------------
+
+/// Profiling macro for feature "puffin"
+#[doc(hidden)]
+#[macro_export]
+macro_rules! profile_function {
+ ($($arg: tt)*) => {
+ #[cfg(feature = "puffin")]
+ puffin::profile_function!($($arg)*);
+ };
+}
+
+/// Profiling macro for feature "puffin"
+#[doc(hidden)]
+#[macro_export]
+macro_rules! profile_scope {
+ ($($arg: tt)*) => {
+ #[cfg(feature = "puffin")]
+ puffin::profile_scope!($($arg)*);
+ };
+}
diff --git a/egui/examples/README.md b/egui/examples/README.md
index 33da866cca6..cdc7a211dad 100644
--- a/egui/examples/README.md
+++ b/egui/examples/README.md
@@ -2,4 +2,5 @@ There are no stand-alone egui examples, because egui is not stand-alone!
There are plenty of examples in [the online demo](https://www.egui.rs/#demo). You can find the source code for it at .
-If you are using `eframe`, check out [the `eframe` examples](https://github.com/emilk/egui/tree/master/eframe/examples) and [the `eframe` template repository](https://github.com/emilk/eframe_template/).
+If you are using `eframe`, the [crate examples](https://github.com/emilk/egui/tree/master/examples) and [single-file examples](https://github.com/emilk/egui/tree/master/eframe/examples).
+To learn how to set up `eframe` for web and native, go to and follow the instructions there!
diff --git a/egui_glow/CHANGELOG.md b/egui_glow/CHANGELOG.md
index a2852125860..70b62a7e024 100644
--- a/egui_glow/CHANGELOG.md
+++ b/egui_glow/CHANGELOG.md
@@ -9,6 +9,7 @@ All notable changes to the `egui_glow` integration will be noted in this file.
* Fixed potential scale bug when DPI scaling changes (e.g. when dragging a window between different displays) ([#1441](https://github.com/emilk/egui/pull/1441)).
* MSRV (Minimum Supported Rust Version) is now `1.60.0` ([#1467](https://github.com/emilk/egui/pull/1467)).
* `clipboard`, `links`, `persistence`, `winit` are now all opt-in features ([#1467](https://github.com/emilk/egui/pull/1467)).
+* Added new feature `puffin` to add [`puffin profiler`](https://github.com/EmbarkStudios/puffin) scopes ([#1483](https://github.com/emilk/egui/pull/1483)).
## 0.17.0 - 2022-02-22
diff --git a/egui_glow/Cargo.toml b/egui_glow/Cargo.toml
index b2b3c48c5b6..5889477f6e5 100644
--- a/egui_glow/Cargo.toml
+++ b/egui_glow/Cargo.toml
@@ -47,6 +47,9 @@ persistence = [
"epi?/persistence",
]
+# Enable profiling with the puffin crate: https://github.com/EmbarkStudios/puffin
+puffin = ["dep:puffin", "egui-winit?/puffin"]
+
# experimental support for a screen reader
screen_reader = ["egui-winit?/screen_reader"]
@@ -72,6 +75,7 @@ egui-winit = { version = "0.17.0", path = "../egui-winit", optional = true, defa
"epi_backend",
] }
glutin = { version = "0.28.0", optional = true }
+puffin = { version = "0.13", optional = true }
# Web:
[target.'cfg(target_arch = "wasm32")'.dependencies]
diff --git a/egui_glow/src/epi_backend.rs b/egui_glow/src/epi_backend.rs
index 9c891ea3278..4f50cebda89 100644
--- a/egui_glow/src/epi_backend.rs
+++ b/egui_glow/src/epi_backend.rs
@@ -11,6 +11,7 @@ fn create_display(
glutin::WindowedContext,
glow::Context,
) {
+ crate::profile_function!();
let gl_window = unsafe {
glutin::ContextBuilder::new()
.with_depth_buffer(native_options.depth_buffer)
@@ -77,15 +78,20 @@ pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi
event_loop.run(move |event, _, control_flow| {
let mut redraw = || {
+ #[cfg(feature = "puffin")]
+ puffin::GlobalProfiler::lock().new_frame();
+
if !is_focused {
// On Mac, a minimized Window uses up all CPU: https://github.com/emilk/egui/issues/325
// We can't know if we are minimized: https://github.com/rust-windowing/winit/issues/208
// But we know if we are focused (in foreground). When minimized, we are not focused.
// However, a user may want an egui with an animation in the background,
// so we still need to repaint quite fast.
+ crate::profile_scope!("bg_sleep");
std::thread::sleep(std::time::Duration::from_millis(10));
}
+ crate::profile_scope!("frame");
let screen_size_in_pixels: [u32; 2] = gl_window.window().inner_size().into();
crate::painter::clear(&gl, screen_size_in_pixels, app.clear_color());
@@ -99,7 +105,10 @@ pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi
integration.handle_platform_output(gl_window.window(), platform_output);
- let clipped_primitives = integration.egui_ctx.tessellate(shapes);
+ let clipped_primitives = {
+ crate::profile_scope!("tessellate");
+ integration.egui_ctx.tessellate(shapes)
+ };
painter.paint_and_update_textures(
screen_size_in_pixels,
@@ -108,7 +117,10 @@ pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi
&textures_delta,
);
- gl_window.swap_buffers().unwrap();
+ {
+ crate::profile_scope!("swap_buffers");
+ gl_window.swap_buffers().unwrap();
+ }
{
*control_flow = if integration.should_quit() {
diff --git a/egui_glow/src/lib.rs b/egui_glow/src/lib.rs
index 29a6cf2bf2d..94d155af719 100644
--- a/egui_glow/src/lib.rs
+++ b/egui_glow/src/lib.rs
@@ -85,3 +85,25 @@ pub fn check_for_gl_error_impl(gl: &glow::Context, file: &str, line: u32, contex
}
}
}
+
+// ---------------------------------------------------------------------------
+
+/// Profiling macro for feature "puffin"
+#[doc(hidden)]
+#[macro_export]
+macro_rules! profile_function {
+ ($($arg: tt)*) => {
+ #[cfg(feature = "puffin")]
+ puffin::profile_function!($($arg)*);
+ };
+}
+
+/// Profiling macro for feature "puffin"
+#[doc(hidden)]
+#[macro_export]
+macro_rules! profile_scope {
+ ($($arg: tt)*) => {
+ #[cfg(feature = "puffin")]
+ puffin::profile_scope!($($arg)*);
+ };
+}
diff --git a/egui_glow/src/painter.rs b/egui_glow/src/painter.rs
index 35b2ff40197..078c028e766 100644
--- a/egui_glow/src/painter.rs
+++ b/egui_glow/src/painter.rs
@@ -96,6 +96,7 @@ impl Painter {
pp_fb_extent: Option<[i32; 2]>,
shader_prefix: &str,
) -> Result {
+ crate::profile_function!();
check_for_gl_error!(&gl, "before Painter::new");
let max_texture_side = unsafe { gl.get_parameter_i32(glow::MAX_TEXTURE_SIZE) } as usize;
@@ -297,6 +298,7 @@ impl Painter {
clipped_primitives: &[egui::ClippedPrimitive],
textures_delta: &egui::TexturesDelta,
) {
+ crate::profile_function!();
for (id, image_delta) in &textures_delta.set {
self.set_texture(*id, image_delta);
}
@@ -333,6 +335,7 @@ impl Painter {
pixels_per_point: f32,
clipped_primitives: &[egui::ClippedPrimitive],
) {
+ crate::profile_function!();
self.assert_not_destroyed();
if let Some(ref mut post_process) = self.post_process {
@@ -355,6 +358,7 @@ impl Painter {
}
Primitive::Callback(callback) => {
if callback.rect.is_positive() {
+ crate::profile_scope!("callback");
// Transform callback rect to physical pixels:
let rect_min_x = pixels_per_point * callback.rect.min.x;
let rect_min_y = pixels_per_point * callback.rect.min.y;
@@ -456,6 +460,8 @@ impl Painter {
// ------------------------------------------------------------------------
pub fn set_texture(&mut self, tex_id: egui::TextureId, delta: &egui::epaint::ImageDelta) {
+ crate::profile_function!();
+
self.assert_not_destroyed();
let glow_texture = *self
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 00000000000..7bde00f6116
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1 @@
+Examples of how to use [`eframe`](https://github.com/emilk/egui/tree/master/eframe) and [`egui`](https://github.com/emilk/egui/).
diff --git a/examples/puffin_profiler/Cargo.toml b/examples/puffin_profiler/Cargo.toml
new file mode 100644
index 00000000000..2acf172ff10
--- /dev/null
+++ b/examples/puffin_profiler/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "puffin_profiler"
+version = "0.1.0"
+authors = ["Emil Ernerfeldt "]
+license = "MIT OR Apache-2.0"
+edition = "2021"
+rust-version = "1.60"
+publish = false
+
+
+[dependencies]
+eframe = { path = "../../eframe", features = ["puffin"] }
+puffin = "0.13"
+puffin_http = "0.10"
diff --git a/examples/puffin_profiler/README.md b/examples/puffin_profiler/README.md
new file mode 100644
index 00000000000..a2c5085b39f
--- /dev/null
+++ b/examples/puffin_profiler/README.md
@@ -0,0 +1,9 @@
+Example how to use the [puffin profiler](https://github.com/EmbarkStudios/puffin) with an `eframe` app.
+
+
+```sh
+cargo run -p puffin_profiler &
+
+cargo install puffin_viewer
+puffin_viewer --url 127.0.0.1:8585
+```
diff --git a/examples/puffin_profiler/src/main.rs b/examples/puffin_profiler/src/main.rs
new file mode 100644
index 00000000000..26f7252a1ce
--- /dev/null
+++ b/examples/puffin_profiler/src/main.rs
@@ -0,0 +1,68 @@
+#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
+
+use eframe::egui;
+
+fn main() {
+ start_puffin_server(); // NOTE: you may only want to call this if the users specifies some flag or clicks a button!
+
+ let options = eframe::NativeOptions::default();
+ eframe::run_native(
+ "My egui App",
+ options,
+ Box::new(|_cc| Box::new(MyApp::default())),
+ );
+}
+
+#[derive(Default)]
+struct MyApp {}
+
+impl eframe::App for MyApp {
+ fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
+ egui::CentralPanel::default().show(ctx, |ui| {
+ ui.heading("Example of how to use the puffin profiler with egui");
+ ui.separator();
+
+ let cmd = "cargo install puffin_viewer && puffin_viewer --url 127.0.0.1:8585";
+
+ ui.label("To connect, run this:");
+ ui.horizontal(|ui| {
+ ui.monospace(cmd);
+ if ui.small_button("📋").clicked() {
+ ui.output().copied_text = cmd.into();
+ }
+ });
+
+ ui.separator();
+
+ ui.label("Note that this app runs in 'reactive' mode, so you must interact with the app for new profile events to be sent. Waving the mouse over this window is enough.");
+
+ if ui
+ .button(
+ "Click to sleep a bit. That should be visible as a spike in the profiler view!",
+ )
+ .clicked()
+ {
+ puffin::profile_scope!("sleep");
+ std::thread::sleep(std::time::Duration::from_millis(50));
+ }
+ });
+ }
+}
+
+fn start_puffin_server() {
+ puffin::set_scopes_on(true); // tell puffin to collect data
+
+ match puffin_http::Server::new("0.0.0.0:8585") {
+ Ok(puffin_server) => {
+ eprintln!("Run: cargo install puffin_viewer && puffin_viewer --url 127.0.0.1:8585");
+
+ // We can store the server if we want, but in this case we just want
+ // it to keep running. Dropping it closes the server, so let's not drop it!
+ #[allow(clippy::mem_forget)]
+ std::mem::forget(puffin_server);
+ }
+ Err(err) => {
+ eprintln!("Failed to start puffin server: {}", err);
+ }
+ };
+}