mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 04:40:03 -04:00
Use profiling crate to support more profiler backends (#5150)
Hey! I am not sure if this is something that's been considered before and decided against (I couldn't find any PR's or issues). This change removes the internal profiling macros in library crates and the `puffin` feature and replaces it with similar functions in the [profiling](https://github.com/aclysma/profiling) crate. This crate provides a layer of abstraction over various profiler instrumentation crates and allows library users to pick their favorite (supported) profiler. An additional benefit for puffin users is that dependencies of egui are included in the instrumentation output too (mainly wgpu which uses the profiling crate), so more details might be available when profiling. A breaking change is that instead of using the `puffin` feature on egui, users that want to profile the crate with puffin instead have to enable the `profile-with-puffin` feature on the profiling crate. Similarly they could instead choose to use `profile-with-tracy` etc. I tried to add a 'tracy' feature to egui_demo_app in order to showcase , however the /scripts/check.sh currently breaks on mutually exclusive features (which this introduces), so I decided against including it for the initial PR. I'm happy to iterate more on this if there is interest in taking this PR though. Screenshot showing the additional info for wgpu now available when using puffin 
This commit is contained in:
@@ -129,7 +129,7 @@ impl<'app> GlowWinitApp<'app> {
|
||||
native_options: NativeOptions,
|
||||
app_creator: AppCreator<'app>,
|
||||
) -> Self {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
Self {
|
||||
repaint_proxy: Arc::new(egui::mutex::Mutex::new(event_loop.create_proxy())),
|
||||
app_name: app_name.to_owned(),
|
||||
@@ -146,8 +146,7 @@ impl<'app> GlowWinitApp<'app> {
|
||||
storage: Option<&dyn Storage>,
|
||||
native_options: &mut NativeOptions,
|
||||
) -> Result<(GlutinWindowContext, egui_glow::Painter)> {
|
||||
crate::profile_function!();
|
||||
|
||||
profiling::function_scope!();
|
||||
let window_settings = epi_integration::load_window_settings(storage);
|
||||
|
||||
let winit_window_builder = epi_integration::viewport_builder(
|
||||
@@ -172,7 +171,7 @@ impl<'app> GlowWinitApp<'app> {
|
||||
}
|
||||
|
||||
let gl = unsafe {
|
||||
crate::profile_scope!("glow::Context::from_loader_function");
|
||||
profiling::scope!("glow::Context::from_loader_function");
|
||||
Arc::new(glow::Context::from_loader_function(|s| {
|
||||
let s = std::ffi::CString::new(s)
|
||||
.expect("failed to construct C string from string for gl proc address");
|
||||
@@ -195,7 +194,7 @@ impl<'app> GlowWinitApp<'app> {
|
||||
&mut self,
|
||||
event_loop: &ActiveEventLoop,
|
||||
) -> Result<&mut GlowWinitRunning<'app>> {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
let storage = if let Some(file) = &self.native_options.persistence_path {
|
||||
epi_integration::create_storage_with_file(file)
|
||||
@@ -308,7 +307,7 @@ impl<'app> GlowWinitApp<'app> {
|
||||
raw_display_handle: window.display_handle().map(|h| h.as_raw()),
|
||||
raw_window_handle: window.window_handle().map(|h| h.as_raw()),
|
||||
};
|
||||
crate::profile_scope!("app_creator");
|
||||
profiling::scope!("app_creator");
|
||||
app_creator(&cc).map_err(crate::Error::AppCreation)?
|
||||
};
|
||||
|
||||
@@ -369,7 +368,7 @@ impl<'app> WinitApp for GlowWinitApp<'app> {
|
||||
|
||||
fn save_and_destroy(&mut self) {
|
||||
if let Some(mut running) = self.running.take() {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
running.integration.save(
|
||||
running.app.as_mut(),
|
||||
@@ -486,7 +485,7 @@ impl<'app> GlowWinitRunning<'app> {
|
||||
event_loop: &ActiveEventLoop,
|
||||
window_id: WindowId,
|
||||
) -> Result<EventResult> {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
let Some(viewport_id) = self
|
||||
.glutin
|
||||
@@ -498,8 +497,7 @@ impl<'app> GlowWinitRunning<'app> {
|
||||
return Ok(EventResult::Wait);
|
||||
};
|
||||
|
||||
#[cfg(feature = "puffin")]
|
||||
puffin::GlobalProfiler::lock().new_frame();
|
||||
profiling::finish_frame!();
|
||||
|
||||
let mut frame_timer = crate::stopwatch::Stopwatch::new();
|
||||
frame_timer.start();
|
||||
@@ -698,7 +696,7 @@ impl<'app> GlowWinitRunning<'app> {
|
||||
{
|
||||
// vsync - don't count as frame-time:
|
||||
frame_timer.pause();
|
||||
crate::profile_scope!("swap_buffers");
|
||||
profiling::scope!("swap_buffers");
|
||||
let context = current_gl_context
|
||||
.as_ref()
|
||||
.ok_or(egui_glow::PainterError::from(
|
||||
@@ -726,7 +724,7 @@ impl<'app> GlowWinitRunning<'app> {
|
||||
if window.is_minimized() == Some(true) {
|
||||
// On Mac, a minimized Window uses up all CPU:
|
||||
// https://github.com/emilk/egui/issues/325
|
||||
crate::profile_scope!("minimized_sleep");
|
||||
profiling::scope!("minimized_sleep");
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
}
|
||||
|
||||
@@ -857,7 +855,7 @@ fn change_gl_context(
|
||||
not_current_gl_context: &mut Option<glutin::context::NotCurrentContext>,
|
||||
gl_surface: &glutin::surface::Surface<glutin::surface::WindowSurface>,
|
||||
) {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
if !cfg!(target_os = "windows") {
|
||||
// According to https://github.com/emilk/egui/issues/4289
|
||||
@@ -866,7 +864,7 @@ fn change_gl_context(
|
||||
// See https://github.com/emilk/egui/issues/4173
|
||||
|
||||
if let Some(current_gl_context) = current_gl_context {
|
||||
crate::profile_scope!("is_current");
|
||||
profiling::scope!("is_current");
|
||||
if gl_surface.is_current(current_gl_context) {
|
||||
return; // Early-out to save a lot of time.
|
||||
}
|
||||
@@ -876,7 +874,7 @@ fn change_gl_context(
|
||||
let not_current = if let Some(not_current_context) = not_current_gl_context.take() {
|
||||
not_current_context
|
||||
} else {
|
||||
crate::profile_scope!("make_not_current");
|
||||
profiling::scope!("make_not_current");
|
||||
current_gl_context
|
||||
.take()
|
||||
.unwrap()
|
||||
@@ -884,7 +882,7 @@ fn change_gl_context(
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
crate::profile_scope!("make_current");
|
||||
profiling::scope!("make_current");
|
||||
*current_gl_context = Some(not_current.make_current(gl_surface).unwrap());
|
||||
}
|
||||
|
||||
@@ -896,7 +894,7 @@ impl GlutinWindowContext {
|
||||
native_options: &NativeOptions,
|
||||
event_loop: &ActiveEventLoop,
|
||||
) -> Result<Self> {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
// There is a lot of complexity with opengl creation,
|
||||
// so prefer extensive logging to get all the help we can to debug issues.
|
||||
@@ -952,7 +950,7 @@ impl GlutinWindowContext {
|
||||
)));
|
||||
|
||||
let (window, gl_config) = {
|
||||
crate::profile_scope!("DisplayBuilder::build");
|
||||
profiling::scope!("DisplayBuilder::build");
|
||||
|
||||
display_builder
|
||||
.build(
|
||||
@@ -995,7 +993,7 @@ impl GlutinWindowContext {
|
||||
.build(glutin_raw_window_handle);
|
||||
|
||||
let gl_context_result = unsafe {
|
||||
crate::profile_scope!("create_context");
|
||||
profiling::scope!("create_context");
|
||||
gl_config
|
||||
.display()
|
||||
.create_context(&gl_config, &context_attributes)
|
||||
@@ -1070,7 +1068,7 @@ impl GlutinWindowContext {
|
||||
///
|
||||
/// Errors will be logged.
|
||||
fn initialize_all_windows(&mut self, event_loop: &ActiveEventLoop) {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
let viewports: Vec<ViewportId> = self.viewports.keys().copied().collect();
|
||||
|
||||
@@ -1088,7 +1086,7 @@ impl GlutinWindowContext {
|
||||
viewport_id: ViewportId,
|
||||
event_loop: &ActiveEventLoop,
|
||||
) -> Result {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
let viewport = self
|
||||
.viewports
|
||||
@@ -1268,7 +1266,7 @@ impl GlutinWindowContext {
|
||||
egui_ctx: &egui::Context,
|
||||
viewport_output: &ViewportIdMap<ViewportOutput>,
|
||||
) {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
for (
|
||||
viewport_id,
|
||||
@@ -1329,7 +1327,7 @@ fn initialize_or_update_viewport(
|
||||
mut builder: ViewportBuilder,
|
||||
viewport_ui_cb: Option<Arc<dyn Fn(&egui::Context) + Send + Sync>>,
|
||||
) -> &mut Viewport {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
if builder.icon.is_none() {
|
||||
// Inherit icon from parent
|
||||
@@ -1393,7 +1391,7 @@ fn render_immediate_viewport(
|
||||
beginning: Instant,
|
||||
immediate_viewport: ImmediateViewport<'_>,
|
||||
) {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
let ImmediateViewport {
|
||||
ids,
|
||||
@@ -1516,7 +1514,7 @@ fn render_immediate_viewport(
|
||||
);
|
||||
|
||||
{
|
||||
crate::profile_scope!("swap_buffers");
|
||||
profiling::scope!("swap_buffers");
|
||||
if let Err(err) = gl_surface.swap_buffers(current_gl_context) {
|
||||
log::error!("swap_buffers failed: {err}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user