Detailed changes
@@ -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<Instant>,
}
/// TESTING
@@ -336,6 +339,7 @@ pub(crate) static FRAME_BUF: LazyLock<[Arc<Mutex<FrameTimings>>; FRAME_RING]> =
Arc::new(Mutex::new(FrameTimings {
frame_time: 0.0,
timings: HashMap::default(),
+ end_time: None,
}))
})
});
@@ -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<isize> {
- 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)
}
@@ -800,19 +800,22 @@ impl WindowsPlatformInner {
pub(crate) fn drain_main_receiver(main_receiver: &flume::Receiver<Runnable<Bigus>>) {
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);
}
@@ -74,6 +74,7 @@ pub(crate) struct WindowsWindowInner {
pub(crate) validation_number: usize,
pub(crate) main_receiver: flume::Receiver<Runnable<Bigus>>,
pub(crate) platform_window_handle: HWND,
+ pub(crate) frame_start: RefCell<Instant>,
}
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()),
}))
}
@@ -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<Self>) -> impl IntoElement {
v_flex()
+ .id("timings")
.w_full()
+ .h_full()
.gap_2()
+ .overflow_scroll()
.child(
Button::new(
"switch-mode",