mirror of
https://github.com/emilk/egui.git
synced 2026-08-30 05:10: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:
@@ -788,8 +788,7 @@ pub struct IntegrationInfo {
|
||||
///
|
||||
/// This includes [`App::update`] as well as rendering (except for vsync waiting).
|
||||
///
|
||||
/// For a more detailed view of cpu usage, use the [`puffin`](https://crates.io/crates/puffin)
|
||||
/// profiler together with the `puffin` feature of `eframe`.
|
||||
/// For a more detailed view of cpu usage, connect your preferred profiler by enabling it's feature in [`profiling`](https://crates.io/crates/profiling).
|
||||
///
|
||||
/// `None` if this is the first frame.
|
||||
pub cpu_usage: Option<f32>,
|
||||
@@ -831,7 +830,7 @@ impl Storage for DummyStorage {
|
||||
/// Get and deserialize the [RON](https://github.com/ron-rs/ron) stored at the given key.
|
||||
#[cfg(feature = "ron")]
|
||||
pub fn get_value<T: serde::de::DeserializeOwned>(storage: &dyn Storage, key: &str) -> Option<T> {
|
||||
crate::profile_function!(key);
|
||||
profiling::function_scope!(key);
|
||||
storage
|
||||
.get_string(key)
|
||||
.and_then(|value| match ron::from_str(&value) {
|
||||
@@ -847,7 +846,7 @@ pub fn get_value<T: serde::de::DeserializeOwned>(storage: &dyn Storage, key: &st
|
||||
/// Serialize the given value as [RON](https://github.com/ron-rs/ron) and store with the given key.
|
||||
#[cfg(feature = "ron")]
|
||||
pub fn set_value<T: serde::Serialize>(storage: &mut dyn Storage, key: &str, value: &T) {
|
||||
crate::profile_function!(key);
|
||||
profiling::function_scope!(key);
|
||||
match ron::ser::to_string(value) {
|
||||
Ok(string) => storage.set_string(key, string),
|
||||
Err(err) => log::error!("eframe failed to encode data using ron: {}", err),
|
||||
|
||||
@@ -22,7 +22,7 @@ pub trait IconDataExt {
|
||||
/// # Errors
|
||||
/// If this is not a valid png.
|
||||
pub fn from_png_bytes(png_bytes: &[u8]) -> Result<IconData, image::ImageError> {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
let image = image::load_from_memory(png_bytes)?;
|
||||
Ok(from_image(image))
|
||||
}
|
||||
@@ -38,7 +38,7 @@ fn from_image(image: image::DynamicImage) -> IconData {
|
||||
|
||||
impl IconDataExt for IconData {
|
||||
fn to_image(&self) -> Result<image::RgbaImage, String> {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
let Self {
|
||||
rgba,
|
||||
width,
|
||||
@@ -48,7 +48,7 @@ impl IconDataExt for IconData {
|
||||
}
|
||||
|
||||
fn to_png_bytes(&self) -> Result<Vec<u8>, String> {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
let image = self.to_image()?;
|
||||
let mut png_bytes: Vec<u8> = Vec::new();
|
||||
image
|
||||
|
||||
@@ -129,6 +129,17 @@
|
||||
//! ## Feature flags
|
||||
#![doc = document_features::document_features!()]
|
||||
//!
|
||||
//! ## Instrumentation
|
||||
//! This crate supports using the [profiling](https://crates.io/crates/profiling) crate for instrumentation.
|
||||
//! You can enable features on the profiling crates in your application to add instrumentation for all
|
||||
//! crates that support it, including egui. See the profiling crate docs for more information.
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! profiling = "1.0"
|
||||
//! [features]
|
||||
//! profile-with-puffin = ["profiling/profile-with-puffin"]
|
||||
//! ```
|
||||
//!
|
||||
|
||||
#![warn(missing_docs)] // let's keep eframe well-documented
|
||||
#![allow(clippy::needless_doctest_main)]
|
||||
@@ -445,33 +456,3 @@ impl std::fmt::Display for Error {
|
||||
|
||||
/// Short for `Result<T, eframe::Error>`.
|
||||
pub type Result<T = (), E = Error> = std::result::Result<T, E>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
mod profiling_scopes {
|
||||
#![allow(unused_macros)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
/// Profiling macro for feature "puffin"
|
||||
macro_rules! profile_function {
|
||||
($($arg: tt)*) => {
|
||||
#[cfg(feature = "puffin")]
|
||||
#[cfg(not(target_arch = "wasm32"))] // Disabled on web because of the coarse 1ms clock resolution there.
|
||||
puffin::profile_function!($($arg)*);
|
||||
};
|
||||
}
|
||||
pub(crate) use profile_function;
|
||||
|
||||
/// Profiling macro for feature "puffin"
|
||||
macro_rules! profile_scope {
|
||||
($($arg: tt)*) => {
|
||||
#[cfg(feature = "puffin")]
|
||||
#[cfg(not(target_arch = "wasm32"))] // Disabled on web because of the coarse 1ms clock resolution there.
|
||||
puffin::profile_scope!($($arg)*);
|
||||
};
|
||||
}
|
||||
pub(crate) use profile_scope;
|
||||
}
|
||||
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use profiling_scopes::{profile_function, profile_scope};
|
||||
|
||||
@@ -59,7 +59,7 @@ enum AppIconStatus {
|
||||
/// Since window creation can be lazy, call this every frame until it's either successfully or gave up.
|
||||
/// (See [`AppIconStatus`])
|
||||
fn set_title_and_icon(_title: &str, _icon_data: Option<&IconData>) -> AppIconStatus {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
@@ -201,7 +201,7 @@ fn set_app_icon_windows(icon_data: &IconData) -> AppIconStatus {
|
||||
#[allow(unsafe_code)]
|
||||
fn set_title_and_icon_mac(title: &str, icon_data: Option<&IconData>) -> AppIconStatus {
|
||||
use crate::icon_data::IconDataExt as _;
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
use objc2::ClassType;
|
||||
use objc2_app_kit::{NSApplication, NSImage};
|
||||
@@ -237,7 +237,7 @@ fn set_title_and_icon_mac(title: &str, icon_data: Option<&IconData>) -> AppIconS
|
||||
log::trace!("NSImage::initWithData…");
|
||||
let app_icon = NSImage::initWithData(NSImage::alloc(), &data);
|
||||
|
||||
crate::profile_scope!("setApplicationIconImage_");
|
||||
profiling::scope!("setApplicationIconImage_");
|
||||
log::trace!("setApplicationIconImage…");
|
||||
app.setApplicationIconImage(app_icon.as_deref());
|
||||
}
|
||||
@@ -246,7 +246,7 @@ fn set_title_and_icon_mac(title: &str, icon_data: Option<&IconData>) -> AppIconS
|
||||
if let Some(main_menu) = app.mainMenu() {
|
||||
if let Some(item) = main_menu.itemAtIndex(0) {
|
||||
if let Some(app_menu) = item.submenu() {
|
||||
crate::profile_scope!("setTitle_");
|
||||
profiling::scope!("setTitle_");
|
||||
app_menu.setTitle(&NSString::from_str(title));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ pub fn viewport_builder(
|
||||
native_options: &mut epi::NativeOptions,
|
||||
window_settings: Option<WindowSettings>,
|
||||
) -> ViewportBuilder {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
let mut viewport_builder = native_options.viewport.clone();
|
||||
|
||||
@@ -67,7 +67,7 @@ pub fn viewport_builder(
|
||||
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
if native_options.centered {
|
||||
crate::profile_scope!("center");
|
||||
profiling::scope!("center");
|
||||
if let Some(monitor) = event_loop
|
||||
.primary_monitor()
|
||||
.or_else(|| event_loop.available_monitors().next())
|
||||
@@ -94,8 +94,7 @@ pub fn apply_window_settings(
|
||||
window: &winit::window::Window,
|
||||
window_settings: Option<WindowSettings>,
|
||||
) {
|
||||
crate::profile_function!();
|
||||
|
||||
profiling::function_scope!();
|
||||
if let Some(window_settings) = window_settings {
|
||||
window_settings.initialize_window(window);
|
||||
}
|
||||
@@ -103,12 +102,11 @@ pub fn apply_window_settings(
|
||||
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
fn largest_monitor_point_size(egui_zoom_factor: f32, event_loop: &ActiveEventLoop) -> egui::Vec2 {
|
||||
crate::profile_function!();
|
||||
|
||||
profiling::function_scope!();
|
||||
let mut max_size = egui::Vec2::ZERO;
|
||||
|
||||
let available_monitors = {
|
||||
crate::profile_scope!("available_monitors");
|
||||
profiling::scope!("available_monitors");
|
||||
event_loop.available_monitors()
|
||||
};
|
||||
|
||||
@@ -238,7 +236,7 @@ impl EpiIntegration {
|
||||
egui_winit: &mut egui_winit::State,
|
||||
event: &winit::event::WindowEvent,
|
||||
) -> EventResponse {
|
||||
crate::profile_function!(egui_winit::short_window_event_description(event));
|
||||
profiling::function_scope!(egui_winit::short_window_event_description(event));
|
||||
|
||||
use winit::event::{ElementState, MouseButton, WindowEvent};
|
||||
|
||||
@@ -276,10 +274,10 @@ impl EpiIntegration {
|
||||
let full_output = self.egui_ctx.run(raw_input, |egui_ctx| {
|
||||
if let Some(viewport_ui_cb) = viewport_ui_cb {
|
||||
// Child viewport
|
||||
crate::profile_scope!("viewport_callback");
|
||||
profiling::scope!("viewport_callback");
|
||||
viewport_ui_cb(egui_ctx);
|
||||
} else {
|
||||
crate::profile_scope!("App::update");
|
||||
profiling::scope!("App::update");
|
||||
app.update(egui_ctx, &mut self.frame);
|
||||
}
|
||||
});
|
||||
@@ -306,7 +304,7 @@ impl EpiIntegration {
|
||||
}
|
||||
|
||||
pub fn post_rendering(&mut self, window: &winit::window::Window) {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
if std::mem::take(&mut self.is_first_frame) {
|
||||
// We keep hidden until we've painted something. See https://github.com/emilk/egui/pull/2279
|
||||
window.set_visible(true);
|
||||
@@ -332,11 +330,11 @@ impl EpiIntegration {
|
||||
pub fn save(&mut self, _app: &mut dyn epi::App, _window: Option<&winit::window::Window>) {
|
||||
#[cfg(feature = "persistence")]
|
||||
if let Some(storage) = self.frame.storage_mut() {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
if let Some(window) = _window {
|
||||
if self.persist_window {
|
||||
crate::profile_scope!("native_window");
|
||||
profiling::scope!("native_window");
|
||||
epi::set_value(
|
||||
storage,
|
||||
STORAGE_WINDOW_KEY,
|
||||
@@ -345,23 +343,23 @@ impl EpiIntegration {
|
||||
}
|
||||
}
|
||||
if _app.persist_egui_memory() {
|
||||
crate::profile_scope!("egui_memory");
|
||||
profiling::scope!("egui_memory");
|
||||
self.egui_ctx
|
||||
.memory(|mem| epi::set_value(storage, STORAGE_EGUI_MEMORY_KEY, mem));
|
||||
}
|
||||
{
|
||||
crate::profile_scope!("App::save");
|
||||
profiling::scope!("App::save");
|
||||
_app.save(storage);
|
||||
}
|
||||
|
||||
crate::profile_scope!("Storage::flush");
|
||||
profiling::scope!("Storage::flush");
|
||||
storage.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_default_egui_icon() -> egui::IconData {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
crate::icon_data::from_png_bytes(&include_bytes!("../../data/icon.png")[..]).unwrap()
|
||||
}
|
||||
|
||||
@@ -372,7 +370,7 @@ const STORAGE_EGUI_MEMORY_KEY: &str = "egui";
|
||||
const STORAGE_WINDOW_KEY: &str = "window";
|
||||
|
||||
pub fn load_window_settings(_storage: Option<&dyn epi::Storage>) -> Option<WindowSettings> {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
#[cfg(feature = "persistence")]
|
||||
{
|
||||
epi::get_value(_storage?, STORAGE_WINDOW_KEY)
|
||||
@@ -382,7 +380,7 @@ pub fn load_window_settings(_storage: Option<&dyn epi::Storage>) -> Option<Windo
|
||||
}
|
||||
|
||||
pub fn load_egui_memory(_storage: Option<&dyn epi::Storage>) -> Option<egui::Memory> {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
#[cfg(feature = "persistence")]
|
||||
{
|
||||
epi::get_value(_storage?, STORAGE_EGUI_MEMORY_KEY)
|
||||
|
||||
@@ -100,7 +100,7 @@ pub struct FileStorage {
|
||||
impl Drop for FileStorage {
|
||||
fn drop(&mut self) {
|
||||
if let Some(join_handle) = self.last_save_join_handle.take() {
|
||||
crate::profile_scope!("wait_for_save");
|
||||
profiling::scope!("wait_for_save");
|
||||
join_handle.join().ok();
|
||||
}
|
||||
}
|
||||
@@ -109,7 +109,7 @@ impl Drop for FileStorage {
|
||||
impl FileStorage {
|
||||
/// Store the state in this .ron file.
|
||||
pub(crate) fn from_ron_filepath(ron_filepath: impl Into<PathBuf>) -> Self {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
let ron_filepath: PathBuf = ron_filepath.into();
|
||||
log::debug!("Loading app state from {:?}…", ron_filepath);
|
||||
Self {
|
||||
@@ -122,7 +122,7 @@ impl FileStorage {
|
||||
|
||||
/// Find a good place to put the files that the OS likes.
|
||||
pub fn from_app_id(app_id: &str) -> Option<Self> {
|
||||
crate::profile_function!(app_id);
|
||||
profiling::function_scope!();
|
||||
if let Some(data_dir) = storage_dir(app_id) {
|
||||
if let Err(err) = std::fs::create_dir_all(&data_dir) {
|
||||
log::warn!(
|
||||
@@ -155,7 +155,7 @@ impl crate::Storage for FileStorage {
|
||||
|
||||
fn flush(&mut self) {
|
||||
if self.dirty {
|
||||
crate::profile_function!();
|
||||
profiling::scope!("FileStorage::flush");
|
||||
self.dirty = false;
|
||||
|
||||
let file_path = self.ron_filepath.clone();
|
||||
@@ -184,7 +184,7 @@ impl crate::Storage for FileStorage {
|
||||
}
|
||||
|
||||
fn save_to_disk(file_path: &PathBuf, kv: &HashMap<String, String>) {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
if let Some(parent_dir) = file_path.parent() {
|
||||
if !parent_dir.exists() {
|
||||
@@ -199,7 +199,7 @@ fn save_to_disk(file_path: &PathBuf, kv: &HashMap<String, String>) {
|
||||
let mut writer = std::io::BufWriter::new(file);
|
||||
let config = Default::default();
|
||||
|
||||
crate::profile_scope!("ron::serialize");
|
||||
profiling::scope!("ron::serialize");
|
||||
if let Err(err) = ron::ser::to_writer_pretty(&mut writer, &kv, config)
|
||||
.and_then(|_| writer.flush().map_err(|err| err.into()))
|
||||
{
|
||||
@@ -220,7 +220,7 @@ fn read_ron<T>(ron_path: impl AsRef<Path>) -> Option<T>
|
||||
where
|
||||
T: serde::de::DeserializeOwned,
|
||||
{
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
match std::fs::File::open(ron_path) {
|
||||
Ok(file) => {
|
||||
let reader = std::io::BufReader::new(file);
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ fn create_event_loop(native_options: &mut epi::NativeOptions) -> Result<EventLoo
|
||||
#[cfg(target_os = "android")]
|
||||
use winit::platform::android::EventLoopBuilderExtAndroid as _;
|
||||
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
let mut builder = winit::event_loop::EventLoop::with_user_event();
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
@@ -35,7 +35,7 @@ fn create_event_loop(native_options: &mut epi::NativeOptions) -> Result<EventLoo
|
||||
hook(&mut builder);
|
||||
}
|
||||
|
||||
crate::profile_scope!("EventLoopBuilder::build");
|
||||
profiling::scope!("EventLoopBuilder::build");
|
||||
Ok(builder.build()?)
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ impl<T: WinitApp> WinitAppWrapper<T> {
|
||||
|
||||
impl<T: WinitApp> ApplicationHandler<UserEvent> for WinitAppWrapper<T> {
|
||||
fn suspended(&mut self, event_loop: &ActiveEventLoop) {
|
||||
crate::profile_function!("Event::Suspended");
|
||||
profiling::scope!("Event::Suspended");
|
||||
|
||||
event_loop_context::with_event_loop_context(event_loop, move || {
|
||||
let event_result = self.winit_app.suspended(event_loop);
|
||||
@@ -195,7 +195,7 @@ impl<T: WinitApp> ApplicationHandler<UserEvent> for WinitAppWrapper<T> {
|
||||
}
|
||||
|
||||
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
||||
crate::profile_function!("Event::Resumed");
|
||||
profiling::scope!("Event::Resumed");
|
||||
|
||||
// Nb: Make sure this guard is dropped after this function returns.
|
||||
event_loop_context::with_event_loop_context(event_loop, move || {
|
||||
@@ -219,7 +219,7 @@ impl<T: WinitApp> ApplicationHandler<UserEvent> for WinitAppWrapper<T> {
|
||||
device_id: winit::event::DeviceId,
|
||||
event: winit::event::DeviceEvent,
|
||||
) {
|
||||
crate::profile_function!(egui_winit::short_device_event_description(&event));
|
||||
profiling::function_scope!(egui_winit::short_device_event_description(&event));
|
||||
|
||||
// Nb: Make sure this guard is dropped after this function returns.
|
||||
event_loop_context::with_event_loop_context(event_loop, move || {
|
||||
@@ -229,7 +229,7 @@ impl<T: WinitApp> ApplicationHandler<UserEvent> for WinitAppWrapper<T> {
|
||||
}
|
||||
|
||||
fn user_event(&mut self, event_loop: &ActiveEventLoop, event: UserEvent) {
|
||||
crate::profile_function!(match &event {
|
||||
profiling::function_scope!(match &event {
|
||||
UserEvent::RequestRepaint { .. } => "UserEvent::RequestRepaint",
|
||||
#[cfg(feature = "accesskit")]
|
||||
UserEvent::AccessKitActionRequest(_) => "UserEvent::AccessKitActionRequest",
|
||||
@@ -285,7 +285,7 @@ impl<T: WinitApp> ApplicationHandler<UserEvent> for WinitAppWrapper<T> {
|
||||
window_id: WindowId,
|
||||
event: winit::event::WindowEvent,
|
||||
) {
|
||||
crate::profile_function!(egui_winit::short_window_event_description(&event));
|
||||
profiling::function_scope!(egui_winit::short_window_event_description(&event));
|
||||
|
||||
// Nb: Make sure this guard is dropped after this function returns.
|
||||
event_loop_context::with_event_loop_context(event_loop, move || {
|
||||
|
||||
@@ -102,7 +102,7 @@ impl<'app> WgpuWinitApp<'app> {
|
||||
native_options: NativeOptions,
|
||||
app_creator: AppCreator<'app>,
|
||||
) -> Self {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
#[cfg(feature = "__screenshot")]
|
||||
assert!(
|
||||
@@ -181,8 +181,7 @@ impl<'app> WgpuWinitApp<'app> {
|
||||
window: Window,
|
||||
builder: ViewportBuilder,
|
||||
) -> crate::Result<&mut WgpuWinitRunning<'app>> {
|
||||
crate::profile_function!();
|
||||
|
||||
profiling::function_scope!();
|
||||
#[allow(unsafe_code, unused_mut, unused_unsafe)]
|
||||
let mut painter = egui_wgpu::winit::Painter::new(
|
||||
egui_ctx.clone(),
|
||||
@@ -199,7 +198,7 @@ impl<'app> WgpuWinitApp<'app> {
|
||||
let window = Arc::new(window);
|
||||
|
||||
{
|
||||
crate::profile_scope!("set_window");
|
||||
profiling::scope!("set_window");
|
||||
pollster::block_on(painter.set_window(ViewportId::ROOT, Some(window.clone())))?;
|
||||
}
|
||||
|
||||
@@ -268,7 +267,7 @@ impl<'app> WgpuWinitApp<'app> {
|
||||
raw_window_handle: window.window_handle().map(|h| h.as_raw()),
|
||||
};
|
||||
let app = {
|
||||
crate::profile_scope!("user_app_creator");
|
||||
profiling::scope!("user_app_creator");
|
||||
app_creator(&cc).map_err(crate::Error::AppCreation)?
|
||||
};
|
||||
|
||||
@@ -490,7 +489,7 @@ impl<'app> WinitApp for WgpuWinitApp<'app> {
|
||||
|
||||
impl<'app> WgpuWinitRunning<'app> {
|
||||
fn save_and_destroy(&mut self) {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
let mut shared = self.shared.borrow_mut();
|
||||
if let Some(Viewport { window, .. }) = shared.viewports.get(&ViewportId::ROOT) {
|
||||
@@ -508,7 +507,7 @@ impl<'app> WgpuWinitRunning<'app> {
|
||||
|
||||
/// This is called both for the root viewport, and all deferred viewports
|
||||
fn run_ui_and_paint(&mut self, window_id: WindowId) -> Result<EventResult> {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
let Some(viewport_id) = self
|
||||
.shared
|
||||
@@ -520,8 +519,7 @@ impl<'app> WgpuWinitRunning<'app> {
|
||||
return Ok(EventResult::Wait);
|
||||
};
|
||||
|
||||
#[cfg(feature = "puffin")]
|
||||
puffin::GlobalProfiler::lock().new_frame();
|
||||
profiling::finish_frame!();
|
||||
|
||||
let Self {
|
||||
app,
|
||||
@@ -533,7 +531,7 @@ impl<'app> WgpuWinitRunning<'app> {
|
||||
frame_timer.start();
|
||||
|
||||
let (viewport_ui_cb, raw_input) = {
|
||||
crate::profile_scope!("Prepare");
|
||||
profiling::scope!("Prepare");
|
||||
let mut shared_lock = shared.borrow_mut();
|
||||
|
||||
let SharedState {
|
||||
@@ -577,7 +575,7 @@ impl<'app> WgpuWinitRunning<'app> {
|
||||
egui_winit::update_viewport_info(info, &integration.egui_ctx, window, false);
|
||||
|
||||
{
|
||||
crate::profile_scope!("set_window");
|
||||
profiling::scope!("set_window");
|
||||
pollster::block_on(painter.set_window(viewport_id, Some(window.clone())))?;
|
||||
}
|
||||
|
||||
@@ -719,7 +717,7 @@ impl<'app> WgpuWinitRunning<'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));
|
||||
}
|
||||
}
|
||||
@@ -846,7 +844,7 @@ impl Viewport {
|
||||
return; // we already have one
|
||||
}
|
||||
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
let viewport_id = self.ids.this;
|
||||
|
||||
@@ -887,7 +885,7 @@ fn create_window(
|
||||
storage: Option<&dyn Storage>,
|
||||
native_options: &mut NativeOptions,
|
||||
) -> Result<(Window, ViewportBuilder), winit::error::OsError> {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
let window_settings = epi_integration::load_window_settings(storage);
|
||||
let viewport_builder = epi_integration::viewport_builder(
|
||||
@@ -908,7 +906,7 @@ fn render_immediate_viewport(
|
||||
shared: &RefCell<SharedState>,
|
||||
immediate_viewport: ImmediateViewport<'_>,
|
||||
) {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
let ImmediateViewport {
|
||||
ids,
|
||||
@@ -988,7 +986,7 @@ fn render_immediate_viewport(
|
||||
};
|
||||
|
||||
{
|
||||
crate::profile_scope!("set_window");
|
||||
profiling::scope!("set_window");
|
||||
if let Err(err) = pollster::block_on(painter.set_window(ids.this, Some(window.clone()))) {
|
||||
log::error!(
|
||||
"when rendering viewport_id={:?}, set_window Error {err}",
|
||||
@@ -1096,7 +1094,7 @@ fn initialize_or_update_viewport<'a>(
|
||||
viewport_ui_cb: Option<Arc<dyn Fn(&egui::Context) + Send + Sync>>,
|
||||
painter: &mut egui_wgpu::winit::Painter,
|
||||
) -> &'a mut Viewport {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
if builder.icon.is_none() {
|
||||
// Inherit icon from parent
|
||||
|
||||
@@ -11,7 +11,7 @@ use egui_winit::accesskit_winit;
|
||||
|
||||
/// Create an egui context, restoring it from storage if possible.
|
||||
pub fn create_egui_context(storage: Option<&dyn crate::Storage>) -> egui::Context {
|
||||
crate::profile_function!();
|
||||
profiling::function_scope!();
|
||||
|
||||
pub const IS_DESKTOP: bool = cfg!(any(
|
||||
target_os = "freebsd",
|
||||
|
||||
Reference in New Issue
Block a user