WIP: Try rendering underlines after all other quads

Nathan Sobo created

I thought this would allow underlines to show up in tabs, but it doesn't seem to be working.

Change summary

gpui/src/platform/mac/renderer.rs | 10 ++++++----
gpui/src/scene.rs                 | 14 ++++++++++++++
gpui/src/text_layout.rs           |  5 +++--
3 files changed, 23 insertions(+), 6 deletions(-)

Detailed changes

gpui/src/platform/mac/renderer.rs 🔗

@@ -396,11 +396,13 @@ impl Renderer {
         drawable_size: Vector2F,
         command_encoder: &metal::RenderCommandEncoderRef,
     ) {
-        if layer.quads().is_empty() {
+        if layer.quads().is_empty() && layer.underlines().is_empty() {
             return;
         }
         align_offset(offset);
-        let next_offset = *offset + layer.quads().len() * mem::size_of::<shaders::GPUIQuad>();
+        let next_offset = *offset
+            + (layer.quads().len() + layer.underlines().len())
+                * mem::size_of::<shaders::GPUIQuad>();
         assert!(
             next_offset <= INSTANCE_BUFFER_SIZE,
             "instance buffer exhausted"
@@ -430,7 +432,7 @@ impl Renderer {
             (self.instances.contents() as *mut u8).offset(*offset as isize)
                 as *mut shaders::GPUIQuad
         };
-        for (ix, quad) in layer.quads().iter().enumerate() {
+        for (ix, quad) in layer.quads().iter().chain(layer.underlines()).enumerate() {
             let bounds = quad.bounds * scene.scale_factor();
             let border_width = quad.border.width * scene.scale_factor();
             let shader_quad = shaders::GPUIQuad {
@@ -456,7 +458,7 @@ impl Renderer {
             metal::MTLPrimitiveType::Triangle,
             0,
             6,
-            layer.quads().len() as u64,
+            (layer.quads().len() + layer.underlines().len()) as u64,
         );
         *offset = next_offset;
     }

gpui/src/scene.rs 🔗

@@ -24,6 +24,7 @@ struct StackingContext {
 pub struct Layer {
     clip_bounds: Option<RectF>,
     quads: Vec<Quad>,
+    underlines: Vec<Quad>,
     shadows: Vec<Shadow>,
     glyphs: Vec<Glyph>,
     icons: Vec<Icon>,
@@ -165,6 +166,10 @@ impl Scene {
         self.active_layer().push_quad(quad)
     }
 
+    pub fn push_underline(&mut self, underline: Quad) {
+        self.active_layer().push_underline(underline)
+    }
+
     pub fn push_shadow(&mut self, shadow: Shadow) {
         self.active_layer().push_shadow(shadow)
     }
@@ -234,6 +239,7 @@ impl Layer {
         Self {
             clip_bounds,
             quads: Vec::new(),
+            underlines: Vec::new(),
             shadows: Vec::new(),
             glyphs: Vec::new(),
             icons: Vec::new(),
@@ -253,6 +259,14 @@ impl Layer {
         self.quads.as_slice()
     }
 
+    fn push_underline(&mut self, underline: Quad) {
+        self.underlines.push(underline);
+    }
+
+    pub fn underlines(&self) -> &[Quad] {
+        self.underlines.as_slice()
+    }
+
     fn push_shadow(&mut self, shadow: Shadow) {
         self.shadows.push(shadow);
     }

gpui/src/text_layout.rs 🔗

@@ -271,7 +271,7 @@ impl Line {
                     if let Some((run_len, run_color, run_underlined)) = style_runs.next() {
                         if let Some(underline_origin) = underline_start {
                             if !*run_underlined || *run_color != color {
-                                cx.scene.push_quad(scene::Quad {
+                                cx.scene.push_underline(scene::Quad {
                                     bounds: RectF::from_points(
                                         underline_origin,
                                         glyph_origin + vec2f(0., 1.),
@@ -307,7 +307,8 @@ impl Line {
 
             if let Some(underline_start) = underline_start.take() {
                 let line_end = origin + baseline_offset + vec2f(self.layout.width, 0.);
-                cx.scene.push_quad(scene::Quad {
+
+                cx.scene.push_underline(scene::Quad {
                     bounds: RectF::from_points(underline_start, line_end + vec2f(0., 1.)),
                     background: Some(color),
                     border: Default::default(),