gpui: Remove some unnecessay heap allocations and memcpies (#47858)

Lukas Wirth created

Release Notes:

- N/A *or* Added/Fixed/Improved ...

Change summary

crates/gpui/src/element.rs          | 10 +++++++---
crates/gpui/src/text_system.rs      |  2 +-
crates/gpui/src/text_system/line.rs |  4 ++--
crates/gpui/src/window.rs           | 24 ++++++++++++++++--------
4 files changed, 26 insertions(+), 14 deletions(-)

Detailed changes

crates/gpui/src/element.rs 🔗

@@ -220,7 +220,7 @@ impl<C: RenderOnce> Element for Component<C> {
         window: &mut Window,
         cx: &mut App,
     ) -> (LayoutId, Self::RequestLayoutState) {
-        window.with_global_id(ElementId::Name(type_name::<C>().into()), |_, window| {
+        window.with_id(ElementId::Name(type_name::<C>().into()), |window| {
             let mut element = self
                 .component
                 .take()
@@ -242,7 +242,7 @@ impl<C: RenderOnce> Element for Component<C> {
         window: &mut Window,
         cx: &mut App,
     ) {
-        window.with_global_id(ElementId::Name(type_name::<C>().into()), |_, window| {
+        window.with_id(ElementId::Name(type_name::<C>().into()), |window| {
             element.prepaint(window, cx);
         })
     }
@@ -257,7 +257,7 @@ impl<C: RenderOnce> Element for Component<C> {
         window: &mut Window,
         cx: &mut App,
     ) {
-        window.with_global_id(ElementId::Name(type_name::<C>().into()), |_, window| {
+        window.with_id(ElementId::Name(type_name::<C>().into()), |window| {
             element.paint(window, cx);
         })
     }
@@ -548,18 +548,22 @@ where
         &mut self.element
     }
 
+    #[inline]
     fn request_layout(&mut self, window: &mut Window, cx: &mut App) -> LayoutId {
         Drawable::request_layout(self, window, cx)
     }
 
+    #[inline]
     fn prepaint(&mut self, window: &mut Window, cx: &mut App) {
         Drawable::prepaint(self, window, cx);
     }
 
+    #[inline]
     fn paint(&mut self, window: &mut Window, cx: &mut App) {
         Drawable::paint(self, window, cx);
     }
 
+    #[inline]
     fn layout_as_root(
         &mut self,
         available_space: Size<AvailableSpace>,

crates/gpui/src/text_system.rs 🔗

@@ -435,7 +435,7 @@ impl WindowTextSystem {
         let mut process_line = |line_text: SharedString, line_start, line_end| {
             font_runs.clear();
 
-            let mut decoration_runs = SmallVec::<[DecorationRun; 32]>::new();
+            let mut decoration_runs = <Vec<DecorationRun>>::with_capacity(32);
             let mut run_start = line_start;
             while run_start < line_end {
                 let Some(run) = runs.peek_mut() else {

crates/gpui/src/text_system/line.rs 🔗

@@ -111,14 +111,14 @@ impl ShapedLine {
 }
 
 /// A line of text that has been shaped, decorated, and wrapped by the text layout system.
-#[derive(Clone, Default, Debug, Deref, DerefMut)]
+#[derive(Default, Debug, Deref, DerefMut)]
 pub struct WrappedLine {
     #[deref]
     #[deref_mut]
     pub(crate) layout: Arc<WrappedLineLayout>,
     /// The text that was shaped for this line.
     pub text: SharedString,
-    pub(crate) decoration_runs: SmallVec<[DecorationRun; 32]>,
+    pub(crate) decoration_runs: Vec<DecorationRun>,
 }
 
 impl WrappedLine {

crates/gpui/src/window.rs 🔗

@@ -2042,10 +2042,22 @@ impl Window {
         element_id: ElementId,
         f: impl FnOnce(&GlobalElementId, &mut Self) -> R,
     ) -> R {
-        self.element_id_stack.push(element_id);
-        let global_id = GlobalElementId(Arc::from(&*self.element_id_stack));
+        self.with_id(element_id, |this| {
+            let global_id = GlobalElementId(Arc::from(&*this.element_id_stack));
 
-        let result = f(&global_id, self);
+            f(&global_id, this)
+        })
+    }
+
+    /// Calls the provided closure with the element ID pushed on the stack.
+    #[inline]
+    pub fn with_id<R>(
+        &mut self,
+        element_id: impl Into<ElementId>,
+        f: impl FnOnce(&mut Self) -> R,
+    ) -> R {
+        self.element_id_stack.push(element_id.into());
+        let result = f(self);
         self.element_id_stack.pop();
         result
     }
@@ -2840,11 +2852,6 @@ impl Window {
         })
     }
 
-    /// Immediately push an element ID onto the stack. Useful for simplifying IDs in lists
-    pub fn with_id<R>(&mut self, id: impl Into<ElementId>, f: impl FnOnce(&mut Self) -> R) -> R {
-        self.with_global_id(id.into(), |_, window| f(window))
-    }
-
     /// Use a piece of state that exists as long this element is being rendered in consecutive frames, without needing to specify a key
     ///
     /// NOTE: This method uses the location of the caller to generate an ID for this state.
@@ -3638,6 +3645,7 @@ impl Window {
         self.rendered_entity_stack.last().copied().unwrap()
     }
 
+    #[inline]
     pub(crate) fn with_rendered_view<R>(
         &mut self,
         id: EntityId,