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