1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-30 05:10:03 -04:00

Much more accurate cpu_usage timing (#3913)

`frame.info.cpu_usage` now includes time for tessellation and rendering,
but excludes vsync and context switching.
This commit is contained in:
Emil Ernerfeldt
2024-01-29 19:12:16 +01:00
committed by GitHub
parent 6a94f4f5f0
commit ab39420c29
12 changed files with 123 additions and 63 deletions

View File

@@ -1,7 +1,6 @@
//! Common tools used by [`super::glow_integration`] and [`super::wgpu_integration`].
use std::time::Instant;
use web_time::Instant;
use winit::event_loop::EventLoopWindowTarget;
use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _};
@@ -259,7 +258,6 @@ impl EpiIntegration {
}
pub fn pre_update(&mut self) {
self.frame_start = Instant::now();
self.app_icon_setter.update();
}
@@ -304,9 +302,8 @@ impl EpiIntegration {
std::mem::take(&mut self.pending_full_output)
}
pub fn post_update(&mut self) {
let frame_time = self.frame_start.elapsed().as_secs_f64() as f32;
self.frame.info.cpu_usage = Some(frame_time);
pub fn report_frame_time(&mut self, seconds: f32) {
self.frame.info.cpu_usage = Some(seconds);
}
pub fn post_rendering(&mut self, window: &winit::window::Window) {

View File

@@ -493,6 +493,9 @@ impl GlowWinitRunning {
#[cfg(feature = "puffin")]
puffin::GlobalProfiler::lock().new_frame();
let mut frame_timer = crate::stopwatch::Stopwatch::new();
frame_timer.start();
{
let glutin = self.glutin.borrow();
let viewport = &glutin.viewports[&viewport_id];
@@ -556,7 +559,11 @@ impl GlowWinitRunning {
let screen_size_in_pixels: [u32; 2] = window.inner_size().into();
change_gl_context(current_gl_context, gl_surface);
{
frame_timer.pause();
change_gl_context(current_gl_context, gl_surface);
frame_timer.resume();
}
self.painter
.borrow()
@@ -600,17 +607,20 @@ impl GlowWinitRunning {
let viewport = viewports.get_mut(&viewport_id).unwrap();
viewport.info.events.clear(); // they should have been processed
let window = viewport.window.as_ref().unwrap();
let window = viewport.window.clone().unwrap();
let gl_surface = viewport.gl_surface.as_ref().unwrap();
let egui_winit = viewport.egui_winit.as_mut().unwrap();
integration.post_update();
egui_winit.handle_platform_output(window, platform_output);
egui_winit.handle_platform_output(&window, platform_output);
let clipped_primitives = integration.egui_ctx.tessellate(shapes, pixels_per_point);
// We may need to switch contexts again, because of immediate viewports:
change_gl_context(current_gl_context, gl_surface);
{
// We may need to switch contexts again, because of immediate viewports:
frame_timer.pause();
change_gl_context(current_gl_context, gl_surface);
frame_timer.resume();
}
let screen_size_in_pixels: [u32; 2] = window.inner_size().into();
@@ -637,10 +647,12 @@ impl GlowWinitRunning {
image: screenshot.into(),
});
}
integration.post_rendering(window);
integration.post_rendering(&window);
}
{
// vsync - don't count as frame-time:
frame_timer.pause();
crate::profile_scope!("swap_buffers");
if let Err(err) = gl_surface.swap_buffers(
current_gl_context
@@ -649,6 +661,7 @@ impl GlowWinitRunning {
) {
log::error!("swap_buffers failed: {err}");
}
frame_timer.resume();
}
// give it time to settle:
@@ -659,7 +672,11 @@ impl GlowWinitRunning {
}
}
integration.maybe_autosave(app.as_mut(), Some(window));
glutin.handle_viewport_output(event_loop, &integration.egui_ctx, viewport_output);
integration.report_frame_time(frame_timer.total_time_sec()); // don't count auto-save time as part of regular frame time
integration.maybe_autosave(app.as_mut(), Some(&window));
if window.is_minimized() == Some(true) {
// On Mac, a minimized Window uses up all CPU:
@@ -668,8 +685,6 @@ impl GlowWinitRunning {
std::thread::sleep(std::time::Duration::from_millis(10));
}
glutin.handle_viewport_output(event_loop, &integration.egui_ctx, viewport_output);
if integration.should_close() {
EventResult::Exit
} else {

View File

@@ -528,6 +528,9 @@ impl WgpuWinitRunning {
shared,
} = self;
let mut frame_timer = crate::stopwatch::Stopwatch::new();
frame_timer.start();
let (viewport_ui_cb, raw_input) = {
crate::profile_scope!("Prepare");
let mut shared_lock = shared.borrow_mut();
@@ -628,8 +631,6 @@ impl WgpuWinitRunning {
return EventResult::Wait;
};
integration.post_update();
let FullOutput {
platform_output,
textures_delta,
@@ -640,27 +641,25 @@ impl WgpuWinitRunning {
egui_winit.handle_platform_output(window, platform_output);
{
let clipped_primitives = egui_ctx.tessellate(shapes, pixels_per_point);
let clipped_primitives = egui_ctx.tessellate(shapes, pixels_per_point);
let screenshot_requested = std::mem::take(&mut viewport.screenshot_requested);
let (_vsync_secs, screenshot) = painter.paint_and_update_textures(
viewport_id,
pixels_per_point,
app.clear_color(&egui_ctx.style().visuals),
&clipped_primitives,
&textures_delta,
screenshot_requested,
);
if let Some(screenshot) = screenshot {
egui_winit
.egui_input_mut()
.events
.push(egui::Event::Screenshot {
viewport_id,
image: screenshot.into(),
});
}
let screenshot_requested = std::mem::take(&mut viewport.screenshot_requested);
let (vsync_secs, screenshot) = painter.paint_and_update_textures(
viewport_id,
pixels_per_point,
app.clear_color(&egui_ctx.style().visuals),
&clipped_primitives,
&textures_delta,
screenshot_requested,
);
if let Some(screenshot) = screenshot {
egui_winit
.egui_input_mut()
.events
.push(egui::Event::Screenshot {
viewport_id,
image: screenshot.into(),
});
}
integration.post_rendering(window);
@@ -684,6 +683,8 @@ impl WgpuWinitRunning {
.and_then(|id| viewports.get(id))
.and_then(|vp| vp.window.as_ref());
integration.report_frame_time(frame_timer.total_time_sec() - vsync_secs); // don't count auto-save time as part of regular frame time
integration.maybe_autosave(app.as_mut(), window.map(|w| w.as_ref()));
if let Some(window) = window {