Skip to content

Commit

Permalink
Add a basic frame profiler (lapce#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc authored Nov 10, 2023
1 parent 9d24307 commit 6215e92
Show file tree
Hide file tree
Showing 7 changed files with 461 additions and 26 deletions.
8 changes: 6 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use winit::{
};

use crate::{
action::Timer, app_handle::ApplicationHandle, inspector::Capture, view::View,
window::WindowConfig,
action::Timer, app_handle::ApplicationHandle, inspector::Capture, profiler::Profile,
view::View, window::WindowConfig,
};

type AppEventCallback = dyn Fn(AppEvent);
Expand Down Expand Up @@ -50,6 +50,10 @@ pub(crate) enum AppUpdateEvent {
window_id: WindowId,
capture: WriteSignal<Option<Rc<Capture>>>,
},
ProfileWindow {
window_id: WindowId,
end_profile: Option<WriteSignal<Option<Rc<Profile>>>>,
},
RequestTimer {
timer: Timer,
},
Expand Down
72 changes: 72 additions & 0 deletions src/app_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::{
app::{AppUpdateEvent, UserEvent, APP_UPDATE_EVENTS},
ext_event::EXT_EVENT_HANDLER,
inspector::Capture,
profiler::{Profile, ProfileEvent},
view::View,
window::WindowConfig,
window_handle::WindowHandle,
Expand Down Expand Up @@ -68,6 +69,22 @@ impl ApplicationHandle {
AppUpdateEvent::CaptureWindow { window_id, capture } => {
capture.set(self.capture_window(window_id).map(Rc::new));
}
AppUpdateEvent::ProfileWindow {
window_id,
end_profile,
} => {
let handle = self.window_handles.get_mut(&window_id);
if let Some(handle) = handle {
if let Some(profile) = end_profile {
profile.set(handle.profile.take().map(|mut profile| {
profile.next_frame();
Rc::new(profile)
}));
} else {
handle.profile = Some(Profile::default());
}
}
}
#[cfg(target_os = "linux")]
AppUpdateEvent::MenuAction {
window_id,
Expand All @@ -94,6 +111,44 @@ impl ApplicationHandle {
None => return,
};

let start = window_handle.profile.is_some().then(|| {
let name = match event {
WindowEvent::ActivationTokenDone { .. } => "ActivationTokenDone",
WindowEvent::Resized(..) => "Resized",
WindowEvent::Moved(..) => "Moved",
WindowEvent::CloseRequested => "CloseRequested",
WindowEvent::Destroyed => "Destroyed",
WindowEvent::DroppedFile(_) => "DroppedFile",
WindowEvent::HoveredFile(_) => "HoveredFile",
WindowEvent::HoveredFileCancelled => "HoveredFileCancelled",
WindowEvent::Focused(..) => "Focused",
WindowEvent::KeyboardInput { .. } => "KeyboardInput",
WindowEvent::ModifiersChanged(..) => "ModifiersChanged",
WindowEvent::Ime(..) => "Ime",
WindowEvent::CursorMoved { .. } => "CursorMoved",
WindowEvent::CursorEntered { .. } => "CursorEntered",
WindowEvent::CursorLeft { .. } => "CursorLeft",
WindowEvent::MouseWheel { .. } => "MouseWheel",
WindowEvent::MouseInput { .. } => "MouseInput",
WindowEvent::TouchpadMagnify { .. } => "TouchpadMagnify",
WindowEvent::SmartMagnify { .. } => "SmartMagnify",
WindowEvent::TouchpadRotate { .. } => "TouchpadRotate",
WindowEvent::TouchpadPressure { .. } => "TouchpadPressure",
WindowEvent::AxisMotion { .. } => "AxisMotion",
WindowEvent::Touch(_) => "Touch",
WindowEvent::ScaleFactorChanged { .. } => "ScaleFactorChanged",
WindowEvent::ThemeChanged(..) => "ThemeChanged",
WindowEvent::Occluded(..) => "Occluded",
WindowEvent::MenuAction(..) => "MenuAction",
WindowEvent::RedrawRequested => "RedrawRequested",
};
(
name,
Instant::now(),
matches!(event, WindowEvent::RedrawRequested),
)
});

match event {
WindowEvent::ActivationTokenDone { .. } => {}
WindowEvent::Resized(size) => {
Expand Down Expand Up @@ -162,6 +217,23 @@ impl ApplicationHandle {
window_handle.render_frame();
}
}

if let Some((name, start, new_frame)) = start {
let end = Instant::now();

if let Some(window_handle) = self.window_handles.get_mut(&window_id) {
let profile = window_handle.profile.as_mut().unwrap();

profile
.current
.events
.push(ProfileEvent { start, end, name });

if new_frame {
profile.next_frame();
}
}
}
}

pub(crate) fn new_window(
Expand Down
90 changes: 69 additions & 21 deletions src/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ use crate::app::{add_app_update_event, AppUpdateEvent};
use crate::context::{AppState, ChangeFlags, StyleCx};
use crate::event::{Event, EventListener};
use crate::id::Id;
use crate::profiler::profiler;
use crate::style::{Style, StyleMapValue};
use crate::view::{view_children, View};
use crate::views::{
container, dyn_container, empty, h_stack, img_dynamic, scroll, stack, static_label,
static_list, text, v_stack, Decorators, Label,
static_list, tab, text, v_stack, Decorators, Label,
};
use crate::widgets::button;
use crate::window::WindowConfig;
use crate::{new_window, style};
use floem_reactive::{create_effect, create_rw_signal, RwSignal, Scope};
use floem_reactive::{create_effect, create_rw_signal, create_signal, RwSignal, Scope};
use image::DynamicImage;
use kurbo::{Point, Rect, Size};
use peniko::Color;
Expand Down Expand Up @@ -361,7 +362,7 @@ fn captured_view(
}
}

fn header(label: impl Display) -> Label {
pub(crate) fn header(label: impl Display) -> Label {
text(label).style(|s| {
s.padding(5.0)
.background(Color::WHITE_SMOKE)
Expand Down Expand Up @@ -806,8 +807,7 @@ fn capture_view(capture: &Rc<Capture>) -> impl View {
.background(Color::BLACK.with_alpha_factor(0.2))
});

stack((left, seperator, tree))
.style(|s| s.flex_row().height_full().width_full().max_width_full())
h_stack((left, seperator, tree)).style(|s| s.height_full().width_full().max_width_full())
}

fn inspector_view(capture: &Option<Rc<Capture>>) -> impl View {
Expand All @@ -819,13 +819,8 @@ fn inspector_view(capture: &Option<Rc<Capture>>) -> impl View {

stack((view,))
.window_title(|| "Floem Inspector".to_owned())
.on_event(EventListener::WindowClosed, |_| {
RUNNING.set(false);
false
})
.style(|s| {
s.font_size(12.0)
.width_full()
s.width_full()
.height_full()
.background(Color::WHITE)
.class(scroll::Handle, |s| {
Expand Down Expand Up @@ -856,14 +851,64 @@ pub fn capture(window_id: WindowId) {
RUNNING.set(true);
new_window(
move |_| {
let view = dyn_container(
move || capture.get(),
|capture| Box::new(inspector_view(&capture)),
);
let id = view.id();
view.style(|s| s.width_full().height_full()).on_event(
EventListener::KeyUp,
move |e| {
let (selected, set_selected) = create_signal(0);

let tab_item = |name, index| {
text(name)
.on_click(move |_| {
set_selected.set(index);
true
})
.style(move |s| {
s.padding(5.0)
.border_right(1)
.border_color(Color::BLACK.with_alpha_factor(0.2))
.hover(move |s| {
s.background(Color::rgba8(228, 237, 216, 160))
.apply_if(selected.get() == index, |s| {
s.background(Color::rgb8(186, 180, 216))
})
})
.apply_if(selected.get() == index, |s| {
s.background(Color::rgb8(213, 208, 216))
})
})
};

let tabs = h_stack((tab_item("Views", 0), tab_item("Profiler", 1)))
.style(|s| s.background(Color::WHITE));

let tab = tab(
move || selected.get(),
move || [0, 1].into_iter(),
|it| *it,
move |it| -> Box<dyn View> {
match it {
0 => Box::new(
dyn_container(
move || capture.get(),
|capture| Box::new(inspector_view(&capture)),
)
.style(|s| s.width_full().height_full()),
),
1 => Box::new(profiler(window_id)),
_ => panic!(),
}
},
)
.style(|s| s.flex_basis(0.0).min_height(0.0).flex_grow(1.0));

let seperator = empty().style(move |s| {
s.width_full()
.min_height(1.0)
.background(Color::BLACK.with_alpha_factor(0.2))
});

let stack = v_stack((tabs, seperator, tab));
let id = stack.id();
stack
.style(|s| s.width_full().height_full())
.on_event(EventListener::KeyUp, move |e| {
if let Event::KeyUp(e) = e {
if e.key.logical_key == Key::Named(NamedKey::F11)
&& e.modifiers.shift_key()
Expand All @@ -873,8 +918,11 @@ pub fn capture(window_id: WindowId) {
}
}
false
},
)
})
.on_event(EventListener::WindowClosed, |_| {
RUNNING.set(false);
false
})
},
Some(WindowConfig {
size: Some(Size {
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub mod keyboard;
pub mod menu;
mod nav;
pub mod pointer;
mod profiler;
pub mod renderer;
pub mod responsive;
pub mod style;
Expand Down
Loading

0 comments on commit 6215e92

Please sign in to comment.