Skip to content

Commit

Permalink
Add opt-in support for the 'puffin' profiler in eframe
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk committed Apr 12, 2022
1 parent 973c3f2 commit eff6117
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 5 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions eframe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 4 additions & 0 deletions egui-winit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand All @@ -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 }

Expand Down
12 changes: 11 additions & 1 deletion egui-winit/src/epi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,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);
Expand Down Expand Up @@ -274,17 +275,26 @@ 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,
&crate::WindowSettings::from_display(_window),
);
}
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();
}
}
Expand Down
22 changes: 22 additions & 0 deletions egui-winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,3 +646,25 @@ fn translate_cursor(cursor_icon: egui::CursorIcon) -> Option<winit::window::Curs
egui::CursorIcon::ZoomOut => 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)*);
};
}
4 changes: 2 additions & 2 deletions egui/src/containers/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl Frame {

pub(crate) fn central_panel(style: &Style) -> Self {
Self {
inner_margin: Margin::symmetric(8.0, 8.0),
inner_margin: Margin::same(8.0),
rounding: Rounding::none(),
fill: style.visuals.window_fill(),
stroke: Default::default(),
Expand Down Expand Up @@ -91,7 +91,7 @@ impl Frame {
/// and in dark mode this will be very dark.
pub fn canvas(style: &Style) -> Self {
Self {
inner_margin: Margin::symmetric(10.0, 10.0),
inner_margin: Margin::same(2.0),
rounding: style.visuals.widgets.noninteractive.rounding,
fill: style.visuals.extreme_bg_color,
stroke: style.visuals.window_stroke(),
Expand Down
4 changes: 4 additions & 0 deletions egui_glow/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand All @@ -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]
Expand Down
15 changes: 13 additions & 2 deletions egui_glow/src/epi_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,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());
Expand All @@ -99,7 +104,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,
Expand All @@ -108,7 +116,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() {
Expand Down
22 changes: 22 additions & 0 deletions egui_glow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)*);
};
}
5 changes: 5 additions & 0 deletions egui_glow/src/painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,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);
}
Expand Down Expand Up @@ -333,6 +334,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 {
Expand All @@ -355,6 +357,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;
Expand Down Expand Up @@ -456,6 +459,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
Expand Down

0 comments on commit eff6117

Please sign in to comment.