Checkpoint

Antonio Scandurra created

Change summary

crates/gpui3/src/elements/img.rs            | 16 ++---------
crates/gpui3/src/platform/mac/shaders.metal | 27 +++++++++++--------
crates/gpui3/src/scene.rs                   |  1 
crates/gpui3/src/style.rs                   |  7 ----
crates/gpui3/src/window.rs                  | 31 +++-------------------
5 files changed, 25 insertions(+), 57 deletions(-)

Detailed changes

crates/gpui3/src/elements/img.rs 🔗

@@ -1,6 +1,6 @@
 use crate::{
-    BorrowWindow, ContentMask, Element, IsZero, Layout, LayoutId, Result, SharedString, Style,
-    StyleHelpers, Styled, ViewContext,
+    BorrowWindow, Element, Layout, LayoutId, Result, SharedString, Style, StyleHelpers, Styled,
+    ViewContext,
 };
 use futures::FutureExt;
 use refineable::RefinementCascade;
@@ -73,17 +73,7 @@ impl<S: 'static> Element for Img<S> {
                 .and_then(ResultExt::log_err)
             {
                 let corner_radii = style.corner_radii.to_pixels(bounds, cx.rem_size());
-                if corner_radii.is_zero() {
-                    cx.paint_image(bounds, order, data, self.grayscale)?;
-                } else {
-                    cx.with_content_mask(
-                        ContentMask {
-                            bounds,
-                            corner_radii,
-                        },
-                        |cx| cx.paint_image(bounds, order, data, self.grayscale),
-                    )?;
-                }
+                cx.paint_image(bounds, corner_radii, order, data, self.grayscale)?;
             } else {
                 log::warn!("image not loaded yet");
                 // cx.spawn(|this, mut cx| async move {

crates/gpui3/src/platform/mac/shaders.metal 🔗

@@ -106,11 +106,7 @@ fragment float4 quad_fragment(QuadVertexOutput input [[stage_in]],
     color = float4(premultiplied_output_rgb, output_alpha);
   }
 
-  float clip_distance =
-      quad_sdf(input.position.xy, quad.clip_bounds, quad.clip_corner_radii);
-  return color *
-         float4(1., 1., 1.,
-                saturate(0.5 - distance) * saturate(0.5 - clip_distance));
+  return color * float4(1., 1., 1., saturate(0.5 - distance));
 }
 
 struct MonochromeSpriteVertexOutput {
@@ -131,8 +127,9 @@ vertex MonochromeSpriteVertexOutput monochrome_sprite_vertex(
 
   float2 unit_vertex = unit_vertices[unit_vertex_id];
   MonochromeSprite sprite = sprites[sprite_id];
+  // Don't apply content mask at the vertex level because we don't have time to make sampling from the texture match the mask.
   float4 device_position = to_device_position(
-      unit_vertex, sprite.bounds, sprite.content_mask.bounds, viewport_size);
+      unit_vertex, sprite.bounds, sprite.bounds, viewport_size);
   float2 tile_position = to_tile_position(unit_vertex, sprite.tile, atlas_size);
   float4 color = hsla_to_rgba(sprite.color);
   return MonochromeSpriteVertexOutput{device_position, tile_position, color,
@@ -148,8 +145,11 @@ fragment float4 monochrome_sprite_fragment(
                                           min_filter::linear);
   float4 sample =
       atlas_texture.sample(atlas_texture_sampler, input.tile_position);
-  float clip_distance = quad_sdf(input.position.xy, sprite.content_mask.bounds,
-                                 sprite.content_mask.corner_radii);
+  float clip_distance = quad_sdf(
+      input.position.xy,
+      sprite.content_mask.bounds,
+      Corners_ScaledPixels { 0., 0., 0., 0. }
+  );
   float4 color = input.color;
   color.a *= sample.a * saturate(0.5 - clip_distance);
   return color;
@@ -172,8 +172,9 @@ vertex PolychromeSpriteVertexOutput polychrome_sprite_vertex(
 
   float2 unit_vertex = unit_vertices[unit_vertex_id];
   PolychromeSprite sprite = sprites[sprite_id];
+  // Don't apply content mask at the vertex level because we don't have time to make sampling from the texture match the mask.
   float4 device_position = to_device_position(
-      unit_vertex, sprite.bounds, sprite.content_mask.bounds, viewport_size);
+      unit_vertex, sprite.bounds, sprite.bounds, viewport_size);
   float2 tile_position = to_tile_position(unit_vertex, sprite.tile, atlas_size);
   return PolychromeSpriteVertexOutput{device_position, tile_position,
                                       sprite_id};
@@ -188,8 +189,10 @@ fragment float4 polychrome_sprite_fragment(
                                           min_filter::linear);
   float4 sample =
       atlas_texture.sample(atlas_texture_sampler, input.tile_position);
-  float clip_distance = quad_sdf(input.position.xy, sprite.content_mask.bounds,
-                                 sprite.content_mask.corner_radii);
+  float quad_distance = quad_sdf(input.position.xy, sprite.bounds, sprite.corner_radii);
+  float clip_distance = quad_sdf(input.position.xy, sprite.content_mask.bounds, Corners_ScaledPixels { 0., 0., 0., 0. });
+  float distance = max(quad_distance, clip_distance);
+
   float4 color = sample;
   if (sprite.grayscale) {
     float grayscale = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
@@ -197,7 +200,7 @@ fragment float4 polychrome_sprite_fragment(
     color.g = grayscale;
     color.b = grayscale;
   }
-  color.a *= saturate(0.5 - clip_distance);
+  color.a *= saturate(0.5 - distance);
   return color;
 }
 

crates/gpui3/src/scene.rs 🔗

@@ -275,6 +275,7 @@ pub struct PolychromeSprite {
     pub order: u32,
     pub bounds: Bounds<ScaledPixels>,
     pub content_mask: ScaledContentMask,
+    pub corner_radii: Corners<ScaledPixels>,
     pub tile: AtlasTile,
     pub grayscale: bool,
 }

crates/gpui3/src/style.rs 🔗

@@ -202,7 +202,6 @@ impl Style {
         let min = current_mask.bounds.origin;
         let max = current_mask.bounds.lower_right();
 
-        let mut mask_corner_radii = Corners::default();
         let mask_bounds = match (
             self.overflow.x == Overflow::Visible,
             self.overflow.y == Overflow::Visible,
@@ -220,14 +219,10 @@ impl Style {
                 point(bounds.lower_right().x, max.y),
             ),
             // both hidden
-            (false, false) => {
-                mask_corner_radii = self.corner_radii.to_pixels(bounds, cx.rem_size());
-                bounds
-            }
+            (false, false) => bounds,
         };
         let mask = ContentMask {
             bounds: mask_bounds,
-            corner_radii: mask_corner_radii,
         };
 
         cx.with_content_mask(mask, f)

crates/gpui3/src/window.rs 🔗

@@ -76,24 +76,18 @@ impl Window {
 #[derive(Clone, Debug)]
 pub struct ContentMask {
     pub bounds: Bounds<Pixels>,
-    pub corner_radii: Corners<Pixels>,
 }
 
 impl ContentMask {
     pub fn scale(&self, factor: f32) -> ScaledContentMask {
         ScaledContentMask {
             bounds: self.bounds.scale(factor),
-            corner_radii: self.corner_radii.scale(factor),
         }
     }
 
     pub fn intersect(&self, other: &Self) -> Self {
         let bounds = self.bounds.intersect(&other.bounds);
-        // todo!("intersect corner radii")
-        ContentMask {
-            bounds,
-            corner_radii: self.corner_radii,
-        }
+        ContentMask { bounds }
     }
 }
 
@@ -101,7 +95,6 @@ impl ContentMask {
 #[repr(C)]
 pub struct ScaledContentMask {
     bounds: Bounds<ScaledPixels>,
-    corner_radii: Corners<ScaledPixels>,
 }
 
 pub struct WindowContext<'a, 'w> {
@@ -202,23 +195,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
         result
     }
 
-    pub fn clip<F, R>(
-        &mut self,
-        bounds: Bounds<Pixels>,
-        corner_radii: Corners<Pixels>,
-        f: impl FnOnce(&mut Self) -> R,
-    ) -> R {
-        let clip_mask = ContentMask {
-            bounds,
-            corner_radii,
-        };
-
-        self.window.content_mask_stack.push(clip_mask);
-        let result = f(self);
-        self.window.content_mask_stack.pop();
-        result
-    }
-
     pub fn current_layer_id(&self) -> LayerId {
         self.window.current_layer_id.clone()
     }
@@ -318,6 +294,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
                 PolychromeSprite {
                     order,
                     bounds,
+                    corner_radii: Default::default(),
                     content_mask,
                     tile,
                     grayscale: false,
@@ -371,6 +348,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
     pub fn paint_image(
         &mut self,
         bounds: Bounds<Pixels>,
+        corner_radii: Corners<Pixels>,
         order: u32,
         data: Arc<ImageData>,
         grayscale: bool,
@@ -387,6 +365,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
                 Ok((data.size(), Cow::Borrowed(data.as_bytes())))
             })?;
         let content_mask = self.content_mask().scale(scale_factor);
+        let corner_radii = corner_radii.scale(scale_factor);
 
         self.window.scene.insert(
             layer_id,
@@ -394,6 +373,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
                 order,
                 bounds,
                 content_mask,
+                corner_radii,
                 tile,
                 grayscale,
             },
@@ -505,7 +485,6 @@ pub trait BorrowWindow: BorrowAppContext {
                     origin: Point::default(),
                     size: self.window().content_size,
                 },
-                corner_radii: Default::default(),
             })
     }