Use `Vec` instead of `SmallVec` for `glyphs` field of `ShapedRun` (#30664)

Michael Sloan created

This glyphs field is usually larger than 8 elements, and SmallVec is not
efficient when it cannot store the value inline.

This change also adds precise glyphs run preallocation in some places
`ShapedRun` is constructed.

Release Notes:

- N/A

Change summary

crates/gpui/src/platform.rs                      | 2 +-
crates/gpui/src/platform/linux/text_system.rs    | 4 ++--
crates/gpui/src/platform/mac/text_system.rs      | 2 +-
crates/gpui/src/platform/windows/direct_write.rs | 3 +--
crates/gpui/src/text_system/line_layout.rs       | 2 +-
5 files changed, 6 insertions(+), 7 deletions(-)

Detailed changes

crates/gpui/src/platform.rs 🔗

@@ -595,7 +595,7 @@ impl PlatformTextSystem for NoopTextSystem {
                 .unwrap()
                 .width
             / metrics.units_per_em as f32;
-        let mut glyphs = SmallVec::default();
+        let mut glyphs = Vec::new();
         for (ix, c) in text.char_indices() {
             if let Some(glyph) = self.glyph_for_char(FontId(0), c) {
                 glyphs.push(ShapedGlyph {

crates/gpui/src/platform/linux/text_system.rs 🔗

@@ -16,7 +16,7 @@ use pathfinder_geometry::{
     rect::{RectF, RectI},
     vector::{Vector2F, Vector2I},
 };
-use smallvec::{SmallVec, smallvec};
+use smallvec::SmallVec;
 use std::{borrow::Cow, sync::Arc};
 
 pub(crate) struct CosmicTextSystem(RwLock<CosmicTextSystemState>);
@@ -443,7 +443,7 @@ impl CosmicTextSystemState {
             } else {
                 runs.push(ShapedRun {
                     font_id,
-                    glyphs: smallvec![shaped_glyph],
+                    glyphs: vec![shaped_glyph],
                 });
             }
         }

crates/gpui/src/platform/mac/text_system.rs 🔗

@@ -480,7 +480,7 @@ impl MacTextSystemState {
             };
             let font_id = self.id_for_native_font(font);
 
-            let mut glyphs = SmallVec::new();
+            let mut glyphs = Vec::with_capacity(run.glyph_count().try_into().unwrap_or(0));
             for ((glyph_id, position), glyph_utf16_ix) in run
                 .glyphs()
                 .iter()

crates/gpui/src/platform/windows/direct_write.rs 🔗

@@ -5,7 +5,6 @@ use anyhow::{Result, anyhow};
 use collections::HashMap;
 use itertools::Itertools;
 use parking_lot::{RwLock, RwLockUpgradableReadGuard};
-use smallvec::SmallVec;
 use windows::{
     Win32::{
         Foundation::*,
@@ -1089,7 +1088,7 @@ impl IDWriteTextRenderer_Impl for TextRenderer_Impl {
             } else {
                 context.text_system.select_font(&font_struct)
             };
-            let mut glyphs = SmallVec::new();
+            let mut glyphs = Vec::with_capacity(glyph_count);
             for index in 0..glyph_count {
                 let id = GlyphId(*glyphrun.glyphIndices.add(index) as u32);
                 context

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

@@ -34,7 +34,7 @@ pub struct ShapedRun {
     /// The font id for this run
     pub font_id: FontId,
     /// The glyphs that make up this run
-    pub glyphs: SmallVec<[ShapedGlyph; 8]>,
+    pub glyphs: Vec<ShapedGlyph>,
 }
 
 /// A single glyph, ready to paint.