Compare commits
1 Commits
vim-syntax
...
linux/trac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ac6a2f5c2 |
@@ -193,6 +193,16 @@ impl TextInput {
|
||||
.find_map(|(idx, _)| (idx > offset).then_some(idx))
|
||||
.unwrap_or(self.content.len())
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
self.content = "".into();
|
||||
self.selected_range = 0..0;
|
||||
self.selection_reversed = false;
|
||||
self.marked_range = None;
|
||||
self.last_layout = None;
|
||||
self.last_bounds = None;
|
||||
self.is_selecting = false;
|
||||
}
|
||||
}
|
||||
|
||||
impl ViewInputHandler for TextInput {
|
||||
@@ -315,6 +325,7 @@ impl Element for TextElement {
|
||||
None
|
||||
}
|
||||
|
||||
#[profiling::function]
|
||||
fn request_layout(
|
||||
&mut self,
|
||||
_id: Option<&GlobalElementId>,
|
||||
@@ -326,6 +337,7 @@ impl Element for TextElement {
|
||||
(cx.request_layout(style, []), ())
|
||||
}
|
||||
|
||||
#[profiling::function]
|
||||
fn prepaint(
|
||||
&mut self,
|
||||
_id: Option<&GlobalElementId>,
|
||||
@@ -416,6 +428,7 @@ impl Element for TextElement {
|
||||
}
|
||||
}
|
||||
|
||||
#[profiling::function]
|
||||
fn paint(
|
||||
&mut self,
|
||||
_id: Option<&GlobalElementId>,
|
||||
@@ -430,12 +443,14 @@ impl Element for TextElement {
|
||||
ElementInputHandler::new(bounds, self.input.clone()),
|
||||
);
|
||||
if let Some(selection) = prepaint.selection.take() {
|
||||
profiling::scope!("paint_quad selection");
|
||||
cx.paint_quad(selection)
|
||||
}
|
||||
let line = prepaint.line.take().unwrap();
|
||||
line.paint(bounds.origin, cx.line_height(), cx).unwrap();
|
||||
|
||||
if let Some(cursor) = prepaint.cursor.take() {
|
||||
profiling::scope!("paint_quad cursor");
|
||||
cx.paint_quad(cursor);
|
||||
}
|
||||
self.input.update(cx, |input, _cx| {
|
||||
@@ -446,6 +461,7 @@ impl Element for TextElement {
|
||||
}
|
||||
|
||||
impl Render for TextInput {
|
||||
#[profiling::function]
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
div()
|
||||
.flex()
|
||||
@@ -494,13 +510,48 @@ struct InputExample {
|
||||
recent_keystrokes: Vec<Keystroke>,
|
||||
}
|
||||
|
||||
impl InputExample {
|
||||
fn on_reset_click(&mut self, _: &MouseUpEvent, cx: &mut ViewContext<Self>) {
|
||||
self.recent_keystrokes.clear();
|
||||
self.text_input
|
||||
.update(cx, |text_input, _cx| text_input.reset());
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for InputExample {
|
||||
fn render(&mut self, _: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
#[profiling::function]
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
let num_keystrokes = self.recent_keystrokes.len();
|
||||
div()
|
||||
.bg(rgb(0xaaaaaa))
|
||||
.flex()
|
||||
.flex_col()
|
||||
.size_full()
|
||||
.child(
|
||||
div()
|
||||
.bg(white())
|
||||
.border_b_1()
|
||||
.border_color(black())
|
||||
.flex()
|
||||
.flex_row()
|
||||
.justify_between()
|
||||
.child(format!("Keystrokes: {}", num_keystrokes))
|
||||
.child(
|
||||
div()
|
||||
.border_1()
|
||||
.border_color(black())
|
||||
.px_2()
|
||||
.bg(yellow())
|
||||
.child("Reset")
|
||||
.hover(|style| {
|
||||
style
|
||||
.bg(yellow().blend(opaque_grey(0.5, 0.5)))
|
||||
.cursor_pointer()
|
||||
})
|
||||
.on_mouse_up(MouseButton::Left, cx.listener(Self::on_reset_click)),
|
||||
),
|
||||
)
|
||||
.child(self.text_input.clone())
|
||||
.children(self.recent_keystrokes.iter().rev().map(|ks| {
|
||||
format!(
|
||||
|
||||
@@ -387,6 +387,7 @@ impl<E: Element> Drawable<E> {
|
||||
}
|
||||
}
|
||||
|
||||
#[profiling::function]
|
||||
pub(crate) fn layout_as_root(
|
||||
&mut self,
|
||||
available_space: Size<AvailableSpace>,
|
||||
@@ -503,6 +504,7 @@ impl AnyElement {
|
||||
}
|
||||
|
||||
/// Performs layout for this element within the given available space and returns its size.
|
||||
#[profiling::function]
|
||||
pub fn layout_as_root(
|
||||
&mut self,
|
||||
available_space: Size<AvailableSpace>,
|
||||
@@ -517,6 +519,7 @@ impl AnyElement {
|
||||
}
|
||||
|
||||
/// Performs layout on this element in the available space, then prepaints it at the given absolute origin.
|
||||
#[profiling::function]
|
||||
pub fn prepaint_as_root(
|
||||
&mut self,
|
||||
origin: Point<Pixels>,
|
||||
@@ -524,7 +527,10 @@ impl AnyElement {
|
||||
cx: &mut WindowContext,
|
||||
) {
|
||||
self.layout_as_root(available_space, cx);
|
||||
cx.with_absolute_element_offset(origin, |cx| self.0.prepaint(cx));
|
||||
cx.with_absolute_element_offset(origin, |cx| {
|
||||
profiling::scope!("with_absolute_element_offset prepaint");
|
||||
self.0.prepaint(cx)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -524,6 +524,7 @@ impl BladeRenderer {
|
||||
self.gpu.destroy_command_encoder(&mut self.command_encoder);
|
||||
}
|
||||
|
||||
#[profiling::function]
|
||||
pub fn draw(&mut self, scene: &Scene) {
|
||||
self.command_encoder.start();
|
||||
self.atlas.before_frame(&mut self.command_encoder);
|
||||
|
||||
@@ -38,6 +38,8 @@ impl LinuxDispatcher {
|
||||
.map(|i| {
|
||||
let receiver = background_receiver.clone();
|
||||
std::thread::spawn(move || {
|
||||
let thread_name = format!("background-{}", i);
|
||||
profiling::register_thread!(&thread_name);
|
||||
for runnable in receiver {
|
||||
let start = Instant::now();
|
||||
|
||||
@@ -55,6 +57,8 @@ impl LinuxDispatcher {
|
||||
|
||||
let (timer_sender, timer_channel) = calloop::channel::channel::<TimerAfter>();
|
||||
let timer_thread = std::thread::spawn(|| {
|
||||
profiling::register_thread!("timer-thread");
|
||||
|
||||
let mut event_loop: EventLoop<()> =
|
||||
EventLoop::try_new().expect("Failed to initialize timer loop!");
|
||||
|
||||
|
||||
@@ -1182,6 +1182,7 @@ impl PlatformWindow for X11Window {
|
||||
self.0.callbacks.borrow_mut().appearance_changed = Some(callback);
|
||||
}
|
||||
|
||||
#[profiling::function]
|
||||
fn draw(&self, scene: &Scene) {
|
||||
let mut inner = self.0.state.borrow_mut();
|
||||
inner.renderer.draw(scene);
|
||||
|
||||
@@ -142,6 +142,7 @@ impl TaffyLayoutEngine {
|
||||
Ok(edges)
|
||||
}
|
||||
|
||||
#[profiling::function]
|
||||
pub fn compute_layout(
|
||||
&mut self,
|
||||
id: LayoutId,
|
||||
@@ -161,6 +162,7 @@ impl TaffyLayoutEngine {
|
||||
//
|
||||
|
||||
if !self.computed_layouts.insert(id) {
|
||||
profiling::scope!("compute layout stack extension");
|
||||
let mut stack = SmallVec::<[LayoutId; 64]>::new();
|
||||
stack.push(id);
|
||||
while let Some(id) = stack.pop() {
|
||||
@@ -181,6 +183,8 @@ impl TaffyLayoutEngine {
|
||||
id.into(),
|
||||
available_space.into(),
|
||||
|known_dimensions, available_space, node_id, _context| {
|
||||
profiling::scope!("measure function");
|
||||
|
||||
let Some(measure) = self.nodes_to_measure.get_mut(&node_id.into()) else {
|
||||
return taffy::geometry::Size::default();
|
||||
};
|
||||
@@ -190,7 +194,10 @@ impl TaffyLayoutEngine {
|
||||
height: known_dimensions.height.map(Pixels),
|
||||
};
|
||||
|
||||
measure(known_dimensions, available_space.into(), cx).into()
|
||||
{
|
||||
profiling::scope!("calling measure");
|
||||
measure(known_dimensions, available_space.into(), cx).into()
|
||||
}
|
||||
},
|
||||
)
|
||||
.expect(EXPECT_MESSAGE);
|
||||
|
||||
@@ -453,17 +453,48 @@ impl Frame {
|
||||
}
|
||||
}
|
||||
|
||||
#[profiling::function]
|
||||
pub(crate) fn clear(&mut self) {
|
||||
self.element_states.clear();
|
||||
self.accessed_element_states.clear();
|
||||
self.mouse_listeners.clear();
|
||||
self.dispatch_tree.clear();
|
||||
self.scene.clear();
|
||||
self.input_handlers.clear();
|
||||
self.tooltip_requests.clear();
|
||||
self.cursor_styles.clear();
|
||||
self.hitboxes.clear();
|
||||
self.deferred_draws.clear();
|
||||
{
|
||||
profiling::scope!("element_states clear");
|
||||
self.element_states.clear();
|
||||
}
|
||||
{
|
||||
profiling::scope!("accessed_element_states clear");
|
||||
self.accessed_element_states.clear();
|
||||
}
|
||||
{
|
||||
profiling::scope!("mouse_listeners clear");
|
||||
self.mouse_listeners.clear();
|
||||
}
|
||||
{
|
||||
profiling::scope!("dispatch_tree clear");
|
||||
self.dispatch_tree.clear();
|
||||
}
|
||||
{
|
||||
profiling::scope!("scene clear");
|
||||
self.scene.clear();
|
||||
}
|
||||
{
|
||||
profiling::scope!("input handlers clear");
|
||||
self.input_handlers.clear();
|
||||
}
|
||||
{
|
||||
profiling::scope!("tooltip_requests clear");
|
||||
self.tooltip_requests.clear();
|
||||
}
|
||||
{
|
||||
profiling::scope!("cursor styles clear");
|
||||
self.cursor_styles.clear();
|
||||
}
|
||||
{
|
||||
profiling::scope!("hitboxes clear");
|
||||
self.hitboxes.clear();
|
||||
}
|
||||
{
|
||||
profiling::scope!("deferred draws clear");
|
||||
self.deferred_draws.clear();
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn hit_test(&self, position: Point<Pixels>) -> HitTest {
|
||||
@@ -695,6 +726,7 @@ impl Window {
|
||||
}
|
||||
}));
|
||||
platform_window.on_request_frame(Box::new({
|
||||
profiling::scope!("on_request_frame");
|
||||
let mut cx = cx.to_async();
|
||||
let dirty = dirty.clone();
|
||||
let active = active.clone();
|
||||
@@ -1429,6 +1461,7 @@ impl<'a> WindowContext<'a> {
|
||||
.next_frame
|
||||
.finish(&mut self.window.rendered_frame);
|
||||
ELEMENT_ARENA.with_borrow_mut(|element_arena| {
|
||||
profiling::scope!("element area clear");
|
||||
let percentage = (element_arena.len() as f32 / element_arena.capacity() as f32) * 100.;
|
||||
if percentage >= 80. {
|
||||
log::warn!("elevated element arena occupation: {}.", percentage);
|
||||
@@ -1439,37 +1472,47 @@ impl<'a> WindowContext<'a> {
|
||||
self.window.draw_phase = DrawPhase::Focus;
|
||||
let previous_focus_path = self.window.rendered_frame.focus_path();
|
||||
let previous_window_active = self.window.rendered_frame.window_active;
|
||||
mem::swap(&mut self.window.rendered_frame, &mut self.window.next_frame);
|
||||
self.window.next_frame.clear();
|
||||
let current_focus_path = self.window.rendered_frame.focus_path();
|
||||
let current_window_active = self.window.rendered_frame.window_active;
|
||||
|
||||
if previous_focus_path != current_focus_path
|
||||
|| previous_window_active != current_window_active
|
||||
{
|
||||
if !previous_focus_path.is_empty() && current_focus_path.is_empty() {
|
||||
self.window
|
||||
.focus_lost_listeners
|
||||
.clone()
|
||||
.retain(&(), |listener| listener(self));
|
||||
}
|
||||
profiling::scope!("swapping frames");
|
||||
mem::swap(&mut self.window.rendered_frame, &mut self.window.next_frame);
|
||||
}
|
||||
{
|
||||
profiling::scope!("clearing next frame");
|
||||
self.window.next_frame.clear();
|
||||
}
|
||||
|
||||
let event = WindowFocusEvent {
|
||||
previous_focus_path: if previous_window_active {
|
||||
previous_focus_path
|
||||
} else {
|
||||
Default::default()
|
||||
},
|
||||
current_focus_path: if current_window_active {
|
||||
current_focus_path
|
||||
} else {
|
||||
Default::default()
|
||||
},
|
||||
};
|
||||
self.window
|
||||
.focus_listeners
|
||||
.clone()
|
||||
.retain(&(), |listener| listener(&event, self));
|
||||
{
|
||||
profiling::scope!("updating focus path");
|
||||
let current_focus_path = self.window.rendered_frame.focus_path();
|
||||
let current_window_active = self.window.rendered_frame.window_active;
|
||||
|
||||
if previous_focus_path != current_focus_path
|
||||
|| previous_window_active != current_window_active
|
||||
{
|
||||
if !previous_focus_path.is_empty() && current_focus_path.is_empty() {
|
||||
self.window
|
||||
.focus_lost_listeners
|
||||
.clone()
|
||||
.retain(&(), |listener| listener(self));
|
||||
}
|
||||
|
||||
let event = WindowFocusEvent {
|
||||
previous_focus_path: if previous_window_active {
|
||||
previous_focus_path
|
||||
} else {
|
||||
Default::default()
|
||||
},
|
||||
current_focus_path: if current_window_active {
|
||||
current_focus_path
|
||||
} else {
|
||||
Default::default()
|
||||
},
|
||||
};
|
||||
self.window
|
||||
.focus_listeners
|
||||
.clone()
|
||||
.retain(&(), |listener| listener(&event, self));
|
||||
}
|
||||
}
|
||||
|
||||
self.reset_cursor_style();
|
||||
@@ -1487,6 +1530,7 @@ impl<'a> WindowContext<'a> {
|
||||
profiling::finish_frame!();
|
||||
}
|
||||
|
||||
#[profiling::function]
|
||||
fn draw_roots(&mut self) {
|
||||
self.window.draw_phase = DrawPhase::Prepaint;
|
||||
self.window.tooltip_bounds.take();
|
||||
@@ -1854,6 +1898,7 @@ impl<'a> WindowContext<'a> {
|
||||
/// Updates the global element offset based on the given offset. This is used to implement
|
||||
/// drag handles and other manual painting of elements. This method should only be called during
|
||||
/// the prepaint phase of element drawing.
|
||||
#[profiling::function]
|
||||
pub fn with_absolute_element_offset<R>(
|
||||
&mut self,
|
||||
offset: Point<Pixels>,
|
||||
@@ -2719,6 +2764,7 @@ impl<'a> WindowContext<'a> {
|
||||
/// After calling it, you can request the bounds of the given layout node id or any descendant.
|
||||
///
|
||||
/// This method should only be called as part of the prepaint phase of element drawing.
|
||||
#[profiling::function]
|
||||
pub fn compute_layout(&mut self, layout_id: LayoutId, available_space: Size<AvailableSpace>) {
|
||||
debug_assert_eq!(
|
||||
self.window.draw_phase,
|
||||
@@ -2727,7 +2773,10 @@ impl<'a> WindowContext<'a> {
|
||||
);
|
||||
|
||||
let mut layout_engine = self.window.layout_engine.take().unwrap();
|
||||
layout_engine.compute_layout(layout_id, available_space, self);
|
||||
{
|
||||
profiling::scope!("layout_engine compute_layout");
|
||||
layout_engine.compute_layout(layout_id, available_space, self);
|
||||
}
|
||||
self.window.layout_engine = Some(layout_engine);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user