Checkpoint

Antonio Scandurra created

Change summary

crates/gpui3/src/geometry.rs                    | 66 +++++++++++---
crates/gpui3/src/platform/mac/metal_renderer.rs |  6 -
crates/gpui3/src/platform/mac/shaders.metal     | 63 +-------------
crates/gpui3/src/platform/mac/window.rs         |  6 
crates/gpui3/src/scene.rs                       | 81 +++++-------------
5 files changed, 83 insertions(+), 139 deletions(-)

Detailed changes

crates/gpui3/src/geometry.rs 🔗

@@ -2,7 +2,7 @@ use bytemuck::{Pod, Zeroable};
 use core::fmt::Debug;
 use derive_more::{Add, AddAssign, Div, Mul, Sub, SubAssign};
 use refineable::Refineable;
-use std::ops::{Add, AddAssign, Mul, Sub, SubAssign};
+use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
 
 #[derive(
     Refineable, Default, Add, AddAssign, Sub, SubAssign, Mul, Div, Copy, Debug, PartialEq, Eq, Hash,
@@ -31,6 +31,13 @@ impl<T: Clone + Debug> Point<T> {
     }
 }
 
+impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Point<T> {
+    fn mul_assign(&mut self, rhs: S) {
+        self.x = self.x.clone() * rhs.clone();
+        self.y = self.y.clone() * rhs;
+    }
+}
+
 impl<T: Clone + Debug + Sub<Output = T>> SubAssign<Size<T>> for Point<T> {
     fn sub_assign(&mut self, rhs: Size<T>) {
         self.x = self.x.clone() - rhs.width;
@@ -98,6 +105,13 @@ impl<T: Clone + Debug> Size<T> {
     }
 }
 
+impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Size<T> {
+    fn mul_assign(&mut self, rhs: S) {
+        self.width = self.width.clone() * rhs.clone();
+        self.height = self.height.clone() * rhs;
+    }
+}
+
 impl From<Size<Option<Pixels>>> for Size<Option<f32>> {
     fn from(val: Size<Option<Pixels>>) -> Self {
         Size {
@@ -145,28 +159,28 @@ pub struct Bounds<T: Clone + Debug> {
 unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Bounds<T> {}
 unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Bounds<T> {}
 
-impl<T: Clone + Debug + Copy + Add<T, Output = T>> Bounds<T> {
+impl<T: Clone + Debug + Add<T, Output = T>> Bounds<T> {
     pub fn upper_right(&self) -> Point<T> {
         Point {
-            x: self.origin.x + self.size.width,
-            y: self.origin.y,
+            x: self.origin.x.clone() + self.size.width.clone(),
+            y: self.origin.y.clone(),
         }
     }
 
     pub fn lower_right(&self) -> Point<T> {
         Point {
-            x: self.origin.x + self.size.width,
-            y: self.origin.y + self.size.height,
+            x: self.origin.x.clone() + self.size.width.clone(),
+            y: self.origin.y.clone() + self.size.height.clone(),
         }
     }
 }
 
-impl<T: Clone + Debug + Copy + PartialOrd + Add<T, Output = T>> Bounds<T> {
+impl<T: Clone + Debug + PartialOrd + Add<T, Output = T>> Bounds<T> {
     pub fn contains_point(&self, point: Point<T>) -> bool {
         point.x >= self.origin.x
-            && point.x <= self.origin.x + self.size.width
+            && point.x <= self.origin.x.clone() + self.size.width.clone()
             && point.y >= self.origin.y
-            && point.y <= self.origin.y + self.size.height
+            && point.y <= self.origin.y.clone() + self.size.height.clone()
     }
 }
 
@@ -182,6 +196,15 @@ pub struct Edges<T: Clone + Debug> {
     pub left: T,
 }
 
+impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Edges<T> {
+    fn mul_assign(&mut self, rhs: S) {
+        self.top = self.top.clone() * rhs.clone();
+        self.right = self.right.clone() * rhs.clone();
+        self.bottom = self.bottom.clone() * rhs.clone();
+        self.left = self.left.clone() * rhs.clone();
+    }
+}
+
 impl<T: Clone + Debug + Copy> Copy for Edges<T> {}
 
 unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Edges<T> {}
@@ -255,6 +278,15 @@ pub struct Corners<T: Clone + Debug> {
     pub bottom_left: T,
 }
 
+impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Corners<T> {
+    fn mul_assign(&mut self, rhs: S) {
+        self.top_left = self.top_left.clone() * rhs.clone();
+        self.top_right = self.top_right.clone() * rhs.clone();
+        self.bottom_right = self.bottom_right.clone() * rhs.clone();
+        self.bottom_left = self.bottom_left.clone() * rhs;
+    }
+}
+
 impl<T: Clone + Debug + Copy> Copy for Corners<T> {}
 
 unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Corners<T> {}
@@ -265,6 +297,14 @@ unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Corners<T> {}
 #[repr(transparent)]
 pub struct Pixels(pub(crate) f32);
 
+impl Mul<f32> for Pixels {
+    type Output = Pixels;
+
+    fn mul(self, other: f32) -> Pixels {
+        Pixels(self.0 * other)
+    }
+}
+
 #[derive(
     Clone, Copy, Debug, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd,
 )]
@@ -287,14 +327,6 @@ impl Pixels {
     }
 }
 
-impl Mul<f32> for Pixels {
-    type Output = Pixels;
-
-    fn mul(self, other: f32) -> Pixels {
-        Pixels(self.0 * other)
-    }
-}
-
 impl Mul<Pixels> for Pixels {
     type Output = Pixels;
 

crates/gpui3/src/platform/mac/metal_renderer.rs 🔗

@@ -99,7 +99,7 @@ impl MetalRenderer {
         &*self.layer
     }
 
-    pub fn draw(&mut self, scene: &Scene, scale_factor: f32) {
+    pub fn draw(&mut self, scene: &Scene) {
         let layer = self.layer.clone();
         let viewport_size = layer.drawable_size();
         let viewport_size: Size<Pixels> =
@@ -140,7 +140,6 @@ impl MetalRenderer {
         self.draw_quads(
             &scene.opaque_primitives().quads,
             &mut buffer_offset,
-            scale_factor,
             viewport_size,
             scene.max_order(),
             command_encoder,
@@ -161,7 +160,6 @@ impl MetalRenderer {
         &mut self,
         quads: &[Quad],
         offset: &mut usize,
-        scale_factor: f32,
         viewport_size: Size<Pixels>,
         max_order: u32,
         command_encoder: &metal::RenderCommandEncoderRef,
@@ -184,7 +182,6 @@ impl MetalRenderer {
         );
         let quad_uniforms = QuadUniforms {
             viewport_size,
-            scale_factor,
             max_order,
         };
 
@@ -268,6 +265,5 @@ enum QuadInputIndex {
 #[repr(C)]
 pub(crate) struct QuadUniforms {
     viewport_size: Size<Pixels>,
-    scale_factor: f32,
     max_order: u32,
 }

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

@@ -35,9 +35,13 @@ vertex QuadVertexOutput quad_vertex(
     };
 }
 
-fragment float4 quad_fragment(QuadVertexOutput input [[stage_in]], constant Quad *quads [[buffer(QuadInputIndex_Quads)]]) {
+fragment float4 quad_fragment(
+    QuadVertexOutput input [[stage_in]],
+    constant Quad *quads [[buffer(QuadInputIndex_Quads)]],
+    constant QuadUniforms *uniforms [[buffer(QuadInputIndex_Uniforms)]]
+) {
     Quad quad = quads[input.quad_id];
-    float2 half_size = float2( quad.bounds.size.width, quad.bounds.size.height ) / 2.;
+    float2 half_size = float2(quad.bounds.size.width, quad.bounds.size.height) / 2.;
     float2 center = float2( quad.bounds.origin.x, quad.bounds.origin.y ) + half_size;
     float2 center_to_point = input.position.xy - center;
     float corner_radius;
@@ -142,58 +146,3 @@ float4 hsla_to_rgba(Hsla hsla) {
 float4 to_device_position(float2 pixel_position, uint order, uint max_order, float2 viewport_size) {
     return float4(pixel_position / viewport_size * float2(2., -2.) + float2(-1., 1.), (1. - order / max_order), 1.);
 }
-
-// fragment float4 quad_fragment(QuadVertexOutput input [[stage_in]]) {
-//     float2 half_size = input.size / 2.;
-//     float2 center = input.origin + half_size;
-//     float2 center_to_point = input.position.xy - center;
-//     float corner_radius;
-//     if (center_to_point.x < 0.) {
-//         if (center_to_point.y < 0.) {
-//             corner_radius = input.corner_radius_top_left;
-//         } else {
-//             corner_radius = input.corner_radius_bottom_left;
-//         }
-//     } else {
-//         if (center_to_point.y < 0.) {
-//             corner_radius = input.corner_radius_top_right;
-//         } else {
-//             corner_radius = input.corner_radius_bottom_right;
-//         }
-//     }
-
-//     float2 rounded_edge_to_point = fabs(center_to_point) - half_size + corner_radius;
-//     float distance = length(max(0., rounded_edge_to_point)) + min(0., max(rounded_edge_to_point.x, rounded_edge_to_point.y)) - corner_radius;
-
-//     float vertical_border = center_to_point.x <= 0. ? input.border_left : input.border_right;
-//     float horizontal_border = center_to_point.y <= 0. ? input.border_top : input.border_bottom;
-//     float2 inset_size = half_size - corner_radius - float2(vertical_border, horizontal_border);
-//     float2 point_to_inset_corner = fabs(center_to_point) - inset_size;
-//     float border_width;
-//     if (point_to_inset_corner.x < 0. && point_to_inset_corner.y < 0.) {
-//         border_width = 0.;
-//     } else if (point_to_inset_corner.y > point_to_inset_corner.x) {
-//         border_width = horizontal_border;
-//     } else {
-//         border_width = vertical_border;
-//     }
-
-//     float4 color;
-//     if (border_width == 0.) {
-//         color = input.background_color;
-//     } else {
-//         float inset_distance = distance + border_width;
-
-//         // Decrease border's opacity as we move inside the background.
-//         input.border_color.a *= 1. - saturate(0.5 - inset_distance);
-
-//         // Alpha-blend the border and the background.
-//         float output_alpha = input.border_color.a + input.background_color.a * (1. - input.border_color.a);
-//         float3 premultiplied_border_rgb = input.border_color.rgb * input.border_color.a;
-//         float3 premultiplied_background_rgb = input.background_color.rgb * input.background_color.a;
-//         float3 premultiplied_output_rgb = premultiplied_border_rgb + premultiplied_background_rgb * (1. - input.border_color.a);
-//         color = float4(premultiplied_output_rgb / output_alpha, output_alpha);
-//     }
-
-//     return color * float4(1., 1., 1., saturate(0.5 - distance));
-// }

crates/gpui3/src/platform/mac/window.rs 🔗

@@ -1348,7 +1348,8 @@ extern "C" fn display_layer(this: &Object, _: Sel, _: id) {
         let window_state = get_window_state(this);
         let mut window_state = window_state.as_ref().lock();
 
-        let mut scene = crate::Scene::new();
+        let scale_factor = window_state.scale_factor();
+        let mut scene = crate::Scene::new(scale_factor);
         scene.insert(crate::Quad {
             order: 0,
             bounds: Bounds {
@@ -1366,8 +1367,7 @@ extern "C" fn display_layer(this: &Object, _: Sel, _: id) {
             border_widths: Default::default(),
         });
         dbg!("!!!!!!!!!");
-        let scale_factor = window_state.scale_factor();
-        window_state.renderer.draw(&scene, scale_factor);
+        window_state.renderer.draw(&scene);
     }
 }
 

crates/gpui3/src/scene.rs 🔗

@@ -13,25 +13,26 @@ pub struct Scene {
     transparent_primitives: slotmap::SlotMap<slotmap::DefaultKey, Primitive>,
     splitter: BspSplitter<slotmap::DefaultKey>,
     max_order: u32,
+    scale_factor: f32,
 }
 
 impl Scene {
-    pub fn new() -> Scene {
+    pub fn new(scale_factor: f32) -> Scene {
         Scene {
             opaque_primitives: PrimitiveBatch::default(),
             transparent_primitives: slotmap::SlotMap::new(),
             splitter: BspSplitter::new(),
             max_order: 0,
+            scale_factor,
         }
     }
 
     pub fn insert(&mut self, primitive: impl Into<Primitive>) {
-        let primitive = primitive.into();
+        let mut primitive = primitive.into();
+        primitive.scale(self.scale_factor);
         self.max_order = cmp::max(self.max_order, primitive.order());
         match primitive {
             Primitive::Quad(quad) => self.opaque_primitives.quads.push(quad),
-            Primitive::Glyph(glyph) => self.opaque_primitives.glyphs.push(glyph),
-            Primitive::Underline(underline) => self.opaque_primitives.underlines.push(underline),
         }
     }
 
@@ -47,16 +48,12 @@ impl Scene {
 #[derive(Clone, Debug)]
 pub enum Primitive {
     Quad(Quad),
-    Glyph(RenderedGlyph),
-    Underline(Underline),
 }
 
 impl Primitive {
     pub fn order(&self) -> u32 {
         match self {
             Primitive::Quad(quad) => quad.order,
-            Primitive::Glyph(glyph) => glyph.order,
-            Primitive::Underline(underline) => underline.order,
         }
     }
 
@@ -65,8 +62,14 @@ impl Primitive {
             Primitive::Quad(quad) => {
                 quad.background.is_transparent() && quad.border_color.is_transparent()
             }
-            Primitive::Glyph(glyph) => glyph.color.is_transparent(),
-            Primitive::Underline(underline) => underline.color.is_transparent(),
+        }
+    }
+
+    pub fn scale(&mut self, factor: f32) {
+        match self {
+            Primitive::Quad(quad) => {
+                quad.scale(factor);
+            }
         }
     }
 }
@@ -74,8 +77,6 @@ impl Primitive {
 #[derive(Default)]
 pub struct PrimitiveBatch {
     pub quads: Vec<Quad>,
-    pub glyphs: Vec<RenderedGlyph>,
-    pub underlines: Vec<Underline>,
 }
 
 #[derive(Debug, Clone, Copy, Zeroable, Pod)]
@@ -107,53 +108,19 @@ impl Quad {
     }
 }
 
-impl From<Quad> for Primitive {
-    fn from(quad: Quad) -> Self {
-        Primitive::Quad(quad)
-    }
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct RenderedGlyph {
-    pub order: u32,
-    pub font_id: FontId,
-    pub font_size: f32,
-    pub id: GlyphId,
-    pub origin: Point<Pixels>,
-    pub color: Hsla,
-}
-
-impl From<RenderedGlyph> for Primitive {
-    fn from(glyph: RenderedGlyph) -> Self {
-        Primitive::Glyph(glyph)
+impl Quad {
+    pub fn scale(&mut self, factor: f32) {
+        self.bounds.origin *= factor;
+        self.bounds.size *= factor;
+        self.clip_bounds.origin *= factor;
+        self.clip_corner_radii *= factor;
+        self.corner_radii *= factor;
+        self.border_widths *= factor;
     }
 }
 
-#[derive(Copy, Clone, Default, Debug, Zeroable, Pod)]
-#[repr(C)]
-pub struct Underline {
-    pub order: u32,
-    pub origin: Point<Pixels>,
-    pub width: Pixels,
-    pub thickness: Pixels,
-    pub color: Hsla,
-    pub style: LineStyle,
-}
-
-#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
-#[repr(C)]
-pub enum LineStyle {
-    #[default]
-    Solid = 0,
-    Squiggly = 1,
-}
-
-unsafe impl Zeroable for LineStyle {}
-unsafe impl Pod for LineStyle {}
-
-impl From<Underline> for Primitive {
-    fn from(underline: Underline) -> Self {
-        Primitive::Underline(underline)
+impl From<Quad> for Primitive {
+    fn from(quad: Quad) -> Self {
+        Primitive::Quad(quad)
     }
 }