diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index 6dcf32832b44ccceba72fa8554b8634373294bd6..db7aacb1efff9f27888e3705f96744381806d902 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -114,6 +114,7 @@ use std::{ borrow::BorrowMut, future::Future, sync::{Arc, LazyLock, atomic::AtomicUsize}, + time::Instant, }; use taffy::TaffyLayoutEngine; @@ -326,6 +327,8 @@ pub struct FrameTimings { pub frame_time: f64, /// A pub timings: HashMap<&'static core::panic::Location<'static>, f64>, + /// A + pub end_time: Option, } /// TESTING @@ -336,6 +339,7 @@ pub(crate) static FRAME_BUF: LazyLock<[Arc>; FRAME_RING]> = Arc::new(Mutex::new(FrameTimings { frame_time: 0.0, timings: HashMap::default(), + end_time: None, })) }) }); diff --git a/crates/gpui/src/platform/windows/events.rs b/crates/gpui/src/platform/windows/events.rs index c1b4e5d6b798a04d545bb3cd2ad4cb5410803845..442db4298d11c9d2158026818aacbd980a3c7bb6 100644 --- a/crates/gpui/src/platform/windows/events.rs +++ b/crates/gpui/src/platform/windows/events.rs @@ -1,4 +1,7 @@ -use std::{rc::Rc, time::Instant}; +use std::{ + rc::Rc, + time::{Duration, Instant}, +}; use ::util::ResultExt; use anyhow::Context as _; @@ -1192,28 +1195,25 @@ impl WindowsWindowInner { #[inline] fn draw_window(&self, handle: HWND, force_render: bool) -> Option { - let cur_frame = FRAME_INDEX - .fetch_add(1, std::sync::atomic::Ordering::SeqCst) - .overflowing_add(1) - .0 - % FRAME_RING; + let last_frame = FRAME_INDEX.fetch_add(1, std::sync::atomic::Ordering::SeqCst) % FRAME_RING; + let cur_frame = (last_frame + 1) % FRAME_RING; + + let start = Instant::now(); + let prev_frame_start = self.frame_start.replace(start); + FRAME_BUF[last_frame].lock().frame_time = + start.duration_since(prev_frame_start).as_secs_f64(); FRAME_BUF[cur_frame].lock().timings.clear(); let mut request_frame = self.state.borrow_mut().callbacks.request_frame.take()?; - let start = Instant::now(); request_frame(RequestFrameOptions { require_presentation: false, force_render, }); - let end = Instant::now(); - let duration = end.duration_since(start).as_secs_f64(); self.state.borrow_mut().callbacks.request_frame = Some(request_frame); unsafe { ValidateRect(Some(handle), None).ok().log_err() }; - FRAME_BUF[cur_frame].lock().frame_time = duration; - Some(0) } diff --git a/crates/gpui/src/platform/windows/platform.rs b/crates/gpui/src/platform/windows/platform.rs index 9cc34cdae468abb5e6cb422254295291604c062e..c4dd10fb0dac2ec1e1b04e8181c353f0731f9551 100644 --- a/crates/gpui/src/platform/windows/platform.rs +++ b/crates/gpui/src/platform/windows/platform.rs @@ -800,19 +800,22 @@ impl WindowsPlatformInner { pub(crate) fn drain_main_receiver(main_receiver: &flume::Receiver>) { let mut timings = HashMap::default(); + let frame_buf = { + let index = FRAME_INDEX.load(std::sync::atomic::Ordering::Acquire) % FRAME_RING; + FRAME_BUF[index].clone() + }; + + let end_time = frame_buf.lock().end_time; + for runnable in main_receiver.drain() { let name = runnable.metadata().location; let start = Instant::now(); runnable.run(); let end = Instant::now(); + *timings.entry(name).or_insert(0f64) += end.duration_since(start).as_secs_f64(); } - let frame_buf = { - let index = FRAME_INDEX.load(std::sync::atomic::Ordering::Acquire) % FRAME_RING; - let mut frame_buf = &*FRAME_BUF; - frame_buf[index].clone() - }; let mut frame_buf = frame_buf.lock(); frame_buf.timings.extend(timings); } diff --git a/crates/gpui/src/platform/windows/window.rs b/crates/gpui/src/platform/windows/window.rs index 40fb6af18004bafefe2288abf9feff1990e0fbbf..5ee47a4e0b0e53143dda1d46edf935910fa8842b 100644 --- a/crates/gpui/src/platform/windows/window.rs +++ b/crates/gpui/src/platform/windows/window.rs @@ -74,6 +74,7 @@ pub(crate) struct WindowsWindowInner { pub(crate) validation_number: usize, pub(crate) main_receiver: flume::Receiver>, pub(crate) platform_window_handle: HWND, + pub(crate) frame_start: RefCell, } impl WindowsWindowState { @@ -232,6 +233,7 @@ impl WindowsWindowInner { main_receiver: context.main_receiver.clone(), platform_window_handle: context.platform_window_handle, system_settings: RefCell::new(WindowsSystemSettings::new(context.display)), + frame_start: RefCell::new(Instant::now()), })) } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index df42e8faf115509f66ae97c857a8beec2e027259..9122c50b7fa00c44d6d715c3592e737a5b4c05d2 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -681,7 +681,7 @@ impl TimingsPanel { .min_w(px(60.0)) .flex_shrink_0() .text_right() - .child(format!("{:.1}", fill_width)), + .child(format!("{:.1} {}", fill_width, item.value)), ) } } @@ -810,8 +810,11 @@ impl Panel for TimingsPanel { impl Render for TimingsPanel { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { v_flex() + .id("timings") .w_full() + .h_full() .gap_2() + .overflow_scroll() .child( Button::new( "switch-mode",