Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add opt-in puffin feature to egui #3298

Merged
merged 3 commits into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions crates/eframe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ persistence = [

## Enable profiling with the [`puffin`](https://docs.rs/puffin) crate.
##
## Only enabled on native, because of the low resolution (1ms) of time keeping in browsers.
## Only enabled on native, because of the low resolution (1ms) of clocks in browsers.
## `eframe` will call `puffin::GlobalProfiler::lock().new_frame()` for you
puffin = ["dep:puffin", "egui_glow?/puffin", "egui-wgpu?/puffin"]
puffin = ["dep:puffin", "egui/puffin", "egui_glow?/puffin", "egui-wgpu?/puffin"]

## Enable screen reader support (requires `ctx.options_mut(|o| o.screen_reader = true);`) on web.
##
Expand Down
2 changes: 1 addition & 1 deletion crates/egui-winit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ clipboard = ["arboard", "smithay-clipboard"]
links = ["webbrowser"]

## Enable profiling with the [`puffin`](https://docs.rs/puffin) crate.
puffin = ["dep:puffin"]
puffin = ["dep:puffin", "egui/puffin"]

## Allow serialization of [`WindowSettings`] using [`serde`](https://docs.rs/serde).
serde = ["egui/serde", "dep:serde"]
Expand Down
6 changes: 6 additions & 0 deletions crates/egui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ mint = ["epaint/mint"]
## Enable persistence of memory (window positions etc).
persistence = ["serde", "epaint/serde", "ron"]

## Enable profiling with the [`puffin`](https://docs.rs/puffin) crate.
##
## Only enabled on native, because of the low resolution (1ms) of clocks in browsers.
puffin = ["dep:puffin"]

## Allow serialization using [`serde`](https://docs.rs/serde).
serde = ["dep:serde", "epaint/serde", "accesskit?/serde"]

Expand All @@ -79,5 +84,6 @@ accesskit = { version = "0.11", optional = true }
document-features = { version = "0.2", optional = true }

log = { version = "0.4", optional = true, features = ["std"] }
puffin = { version = "0.16", optional = true }
ron = { version = "0.8", optional = true }
serde = { version = "1", optional = true, features = ["derive", "rc"] }
36 changes: 27 additions & 9 deletions crates/egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ impl ContextImpl {

#[cfg(feature = "accesskit")]
if self.is_accesskit_enabled {
crate::profile_scope!("accesskit");
use crate::frame_state::AccessKitFrameState;
let id = crate::accesskit_root_id();
let mut builder = accesskit::NodeBuilder::new(accesskit::Role::Window);
Expand All @@ -224,24 +225,32 @@ impl ContextImpl {

/// Load fonts unless already loaded.
fn update_fonts_mut(&mut self) {
crate::profile_function!();

let pixels_per_point = self.input.pixels_per_point();
let max_texture_side = self.input.max_texture_side;

if let Some(font_definitions) = self.memory.new_font_definitions.take() {
crate::profile_scope!("Fonts::new");
let fonts = Fonts::new(pixels_per_point, max_texture_side, font_definitions);
self.fonts = Some(fonts);
}

let fonts = self.fonts.get_or_insert_with(|| {
let font_definitions = FontDefinitions::default();
crate::profile_scope!("Fonts::new");
Fonts::new(pixels_per_point, max_texture_side, font_definitions)
});

fonts.begin_frame(pixels_per_point, max_texture_side);
{
crate::profile_scope!("Fonts::begin_frame");
fonts.begin_frame(pixels_per_point, max_texture_side);
}

if self.memory.options.preload_font_glyphs {
crate::profile_scope!("preload_font_glyphs");
// Preload the most common characters for the most common fonts.
// This is not very important to do, but may a few GPU operations.
// This is not very important to do, but may save a few GPU operations.
for font_id in self.memory.options.style.text_styles.values() {
fonts.lock().fonts.font(font_id).preload_common_characters();
}
Expand Down Expand Up @@ -370,6 +379,7 @@ impl Context {
/// ```
#[must_use]
pub fn run(&self, new_input: RawInput, run_ui: impl FnOnce(&Context)) -> FullOutput {
crate::profile_function!();
self.begin_frame(new_input);
run_ui(self);
self.end_frame()
Expand All @@ -393,6 +403,7 @@ impl Context {
/// // handle full_output
/// ```
pub fn begin_frame(&self, new_input: RawInput) {
crate::profile_function!();
self.write(|ctx| ctx.begin_frame_mut(new_input));
}
}
Expand Down Expand Up @@ -1207,6 +1218,7 @@ impl Context {
/// Call at the end of each frame.
#[must_use]
pub fn end_frame(&self) -> FullOutput {
crate::profile_function!();
if self.input(|i| i.wants_repaint()) {
self.request_repaint();
}
Expand All @@ -1230,6 +1242,7 @@ impl Context {

#[cfg(feature = "accesskit")]
{
crate::profile_scope!("accesskit");
let state = self.frame_state_mut(|fs| fs.accesskit_state.take());
if let Some(state) = state {
let has_focus = self.input(|i| i.raw.focused);
Expand Down Expand Up @@ -1269,11 +1282,13 @@ impl Context {
}

fn drain_paint_lists(&self) -> Vec<ClippedShape> {
crate::profile_function!();
self.write(|ctx| ctx.graphics.drain(ctx.memory.areas.order()).collect())
}

/// Tessellate the given shapes into triangle meshes.
pub fn tessellate(&self, shapes: Vec<ClippedShape>) -> Vec<ClippedPrimitive> {
crate::profile_function!();
// A tempting optimization is to reuse the tessellation from last frame if the
// shapes are the same, but just comparing the shapes takes about 50% of the time
// it takes to tessellate them, so it is not a worth optimization.
Expand All @@ -1293,13 +1308,16 @@ impl Context {
};

let paint_stats = PaintStats::from_shapes(&shapes);
let clipped_primitives = tessellator::tessellate_shapes(
pixels_per_point,
tessellation_options,
font_tex_size,
prepared_discs,
shapes,
);
let clipped_primitives = {
crate::profile_scope!("tessellator::tessellate_shapes");
tessellator::tessellate_shapes(
pixels_per_point,
tessellation_options,
font_tex_size,
prepared_discs,
shapes,
)
};
ctx.paint_stats = paint_stats.with_clipped_primitives(&clipped_primitives);
clipped_primitives
})
Expand Down
1 change: 1 addition & 0 deletions crates/egui/src/frame_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ impl Default for FrameState {

impl FrameState {
pub(crate) fn begin_frame(&mut self, input: &InputState) {
crate::profile_function!();
let Self {
used_ids,
available_rect,
Expand Down
1 change: 1 addition & 0 deletions crates/egui/src/input_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ impl InputState {
mut new: RawInput,
requested_repaint_last_frame: bool,
) -> InputState {
crate::profile_function!();
let time = new.time.unwrap_or(self.time + new.predicted_dt as f64);
let unstable_dt = (time - self.time) as f32;

Expand Down
29 changes: 29 additions & 0 deletions crates/egui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,3 +579,32 @@ pub fn __run_test_ui(mut add_contents: impl FnMut(&mut Ui)) {
pub fn accesskit_root_id() -> Id {
Id::new("accesskit_root")
}

// ---------------------------------------------------------------------------

mod profiling_scopes {
#![allow(unused_macros)]
#![allow(unused_imports)]

/// Profiling macro for feature "puffin"
macro_rules! profile_function {
($($arg: tt)*) => {
#[cfg(not(target_arch = "wasm32"))] // Disabled on web because of the coarse 1ms clock resolution there.
#[cfg(feature = "puffin")]
puffin::profile_function!($($arg)*);
};
}
pub(crate) use profile_function;

/// Profiling macro for feature "puffin"
macro_rules! profile_scope {
($($arg: tt)*) => {
#[cfg(not(target_arch = "wasm32"))] // Disabled on web because of the coarse 1ms clock resolution there.
#[cfg(feature = "puffin")]
puffin::profile_scope!($($arg)*);
};
}
pub(crate) use profile_scope;
}

pub(crate) use profiling_scopes::*;
1 change: 1 addition & 0 deletions crates/egui/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ impl Memory {
prev_input: &crate::input_state::InputState,
new_input: &crate::data::input::RawInput,
) {
crate::profile_function!();
self.interaction.begin_frame(prev_input, new_input);

if !prev_input.pointer.any_down() {
Expand Down
4 changes: 4 additions & 0 deletions crates/egui/src/util/id_type_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ struct PersistedMap(Vec<(u64, SerializedElement)>);
#[cfg(feature = "persistence")]
impl PersistedMap {
fn from_map(map: &IdTypeMap) -> Self {
crate::profile_function!();
// filter out the elements which cannot be serialized:
Self(
map.0
Expand All @@ -525,6 +526,7 @@ impl PersistedMap {
}

fn into_map(self) -> IdTypeMap {
crate::profile_function!();
IdTypeMap(
self.0
.into_iter()
Expand All @@ -542,6 +544,7 @@ impl serde::Serialize for IdTypeMap {
where
S: serde::Serializer,
{
crate::profile_scope!("IdTypeMap::serialize");
PersistedMap::from_map(self).serialize(serializer)
}
}
Expand All @@ -552,6 +555,7 @@ impl<'de> serde::Deserialize<'de> for IdTypeMap {
where
D: serde::Deserializer<'de>,
{
crate::profile_scope!("IdTypeMap::deserialize");
<PersistedMap>::deserialize(deserializer).map(PersistedMap::into_map)
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/egui_glow/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ clipboard = ["egui-winit?/clipboard"]
links = ["egui-winit?/links"]

## Enable profiling with the [`puffin`](https://docs.rs/puffin) crate.
puffin = ["dep:puffin", "egui-winit?/puffin"]
puffin = ["dep:puffin", "egui-winit?/puffin", "egui/puffin"]

## Enable [`winit`](https://docs.rs/winit) integration.
winit = ["egui-winit"]
Expand Down