Revert recent anti-aliasing improvements (#24289)

Kirill Bulatov created

This reverts commit 31fa4144226fcbd140bb4f26d80001f0abd6facd.
This reverts commit b9e0aae49fad996ddb0ce55225873e5c1d5abecd.

`lyon` commit revert:

![image](https://github.com/user-attachments/assets/0243f61c-0713-416d-b8db-47372e04abaa)

`MSAA` commit revert:

![image](https://github.com/user-attachments/assets/b1a4a9fe-0192-47ef-be6f-52e03c025724)

cc @huacnlee , @\as-cii had decided to revert this PR due to a selection
right corner rendering bug.
Not sure what to propose for a fix from my side

Release Notes:

- N/A

Change summary

Cargo.lock                                       |  76 -----
Cargo.toml                                       |   6 
crates/editor/src/element.rs                     |  48 +-
crates/gpui/Cargo.toml                           |   2 
crates/gpui/examples/gradient.rs                 |  14 
crates/gpui/examples/painting.rs                 | 141 +++------
crates/gpui/src/gpui.rs                          |   2 
crates/gpui/src/path_builder.rs                  | 241 ------------------
crates/gpui/src/platform/blade/blade_atlas.rs    |  49 ---
crates/gpui/src/platform/blade/blade_renderer.rs |  60 +--
crates/gpui/src/platform/mac/metal_atlas.rs      |  22 -
crates/gpui/src/platform/mac/metal_renderer.rs   |  27 -
crates/gpui/src/scene.rs                         |  10 
13 files changed, 113 insertions(+), 585 deletions(-)

Detailed changes

Cargo.lock πŸ”—

@@ -1821,7 +1821,7 @@ dependencies = [
 [[package]]
 name = "blade-graphics"
 version = "0.6.0"
-source = "git+https://github.com/kvark/blade?rev=b16f5c7bd873c7126f48c82c39e7ae64602ae74f#b16f5c7bd873c7126f48c82c39e7ae64602ae74f"
+source = "git+https://github.com/kvark/blade?rev=091a8401033847bb9b6ace3fcf70448d069621c5#091a8401033847bb9b6ace3fcf70448d069621c5"
 dependencies = [
  "ash",
  "ash-window",
@@ -1853,7 +1853,7 @@ dependencies = [
 [[package]]
 name = "blade-macros"
 version = "0.3.0"
-source = "git+https://github.com/kvark/blade?rev=b16f5c7bd873c7126f48c82c39e7ae64602ae74f#b16f5c7bd873c7126f48c82c39e7ae64602ae74f"
+source = "git+https://github.com/kvark/blade?rev=091a8401033847bb9b6ace3fcf70448d069621c5#091a8401033847bb9b6ace3fcf70448d069621c5"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1863,7 +1863,7 @@ dependencies = [
 [[package]]
 name = "blade-util"
 version = "0.2.0"
-source = "git+https://github.com/kvark/blade?rev=b16f5c7bd873c7126f48c82c39e7ae64602ae74f#b16f5c7bd873c7126f48c82c39e7ae64602ae74f"
+source = "git+https://github.com/kvark/blade?rev=091a8401033847bb9b6ace3fcf70448d069621c5#091a8401033847bb9b6ace3fcf70448d069621c5"
 dependencies = [
  "blade-graphics",
  "bytemuck",
@@ -4668,12 +4668,6 @@ version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ce81f49ae8a0482e4c55ea62ebbd7e5a686af544c00b9d090bba3ff9be97b3d"
 
-[[package]]
-name = "float_next_after"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8"
-
 [[package]]
 name = "flume"
 version = "0.11.1"
@@ -5418,7 +5412,6 @@ dependencies = [
  "inventory",
  "itertools 0.14.0",
  "log",
- "lyon",
  "media",
  "metal",
  "naga",
@@ -7435,69 +7428,6 @@ dependencies = [
  "url",
 ]
 
-[[package]]
-name = "lyon"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91e7f9cda98b5430809e63ca5197b06c7d191bf7e26dfc467d5a3f0290e2a74f"
-dependencies = [
- "lyon_algorithms",
- "lyon_extra",
- "lyon_tessellation",
-]
-
-[[package]]
-name = "lyon_algorithms"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f13c9be19d257c7d37e70608ed858e8eab4b2afcea2e3c9a622e892acbf43c08"
-dependencies = [
- "lyon_path",
- "num-traits",
-]
-
-[[package]]
-name = "lyon_extra"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ca94c7bf1e2557c2798989c43416822c12fc5dcc5e17cc3307ef0e71894a955"
-dependencies = [
- "lyon_path",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "lyon_geom"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8af69edc087272df438b3ee436c4bb6d7c04aa8af665cfd398feae627dbd8570"
-dependencies = [
- "arrayvec",
- "euclid",
- "num-traits",
-]
-
-[[package]]
-name = "lyon_path"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e0b8aec2f58586f6eef237985b9a9b7cb3a3aff4417c575075cf95bf925252e"
-dependencies = [
- "lyon_geom",
- "num-traits",
-]
-
-[[package]]
-name = "lyon_tessellation"
-version = "1.0.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "579d42360a4b09846eff2feef28f538696c7d6c7439bfa65874ff3cbe0951b2c"
-dependencies = [
- "float_next_after",
- "lyon_path",
- "num-traits",
-]
-
 [[package]]
 name = "mac"
 version = "0.1.1"

Cargo.toml πŸ”—

@@ -375,9 +375,9 @@ async-watch = "0.3.1"
 async_zip = { version = "0.0.17", features = ["deflate", "deflate64"] }
 base64 = "0.22"
 bitflags = "2.6.0"
-blade-graphics = { git = "https://github.com/kvark/blade", rev = "b16f5c7bd873c7126f48c82c39e7ae64602ae74f" }
-blade-macros = { git = "https://github.com/kvark/blade", rev = "b16f5c7bd873c7126f48c82c39e7ae64602ae74f" }
-blade-util = { git = "https://github.com/kvark/blade", rev = "b16f5c7bd873c7126f48c82c39e7ae64602ae74f" }
+blade-graphics = { git = "https://github.com/kvark/blade", rev = "091a8401033847bb9b6ace3fcf70448d069621c5" }
+blade-macros = { git = "https://github.com/kvark/blade", rev = "091a8401033847bb9b6ace3fcf70448d069621c5" }
+blade-util = { git = "https://github.com/kvark/blade", rev = "091a8401033847bb9b6ace3fcf70448d069621c5" }
 naga = { version = "23.1.0", features = ["wgsl-in"] }
 blake3 = "1.5.3"
 bytes = "1.0"

crates/editor/src/element.rs πŸ”—

@@ -8197,8 +8197,8 @@ impl HighlightedRange {
         };
 
         let top_curve_width = curve_width(first_line.start_x, first_line.end_x);
-        let mut builder = gpui::PathBuilder::fill();
-        builder.curve_to(first_top_right + curve_height, first_top_right);
+        let mut path = gpui::Path::new(first_top_right - top_curve_width);
+        path.curve_to(first_top_right + curve_height, first_top_right);
 
         let mut iter = lines.iter().enumerate().peekable();
         while let Some((ix, line)) = iter.next() {
@@ -8209,42 +8209,42 @@ impl HighlightedRange {
 
                 match next_top_right.x.partial_cmp(&bottom_right.x).unwrap() {
                     Ordering::Equal => {
-                        builder.line_to(bottom_right);
+                        path.line_to(bottom_right);
                     }
                     Ordering::Less => {
                         let curve_width = curve_width(next_top_right.x, bottom_right.x);
-                        builder.line_to(bottom_right - curve_height);
+                        path.line_to(bottom_right - curve_height);
                         if self.corner_radius > Pixels::ZERO {
-                            builder.curve_to(bottom_right - curve_width, bottom_right);
+                            path.curve_to(bottom_right - curve_width, bottom_right);
                         }
-                        builder.line_to(next_top_right + curve_width);
+                        path.line_to(next_top_right + curve_width);
                         if self.corner_radius > Pixels::ZERO {
-                            builder.curve_to(next_top_right + curve_height, next_top_right);
+                            path.curve_to(next_top_right + curve_height, next_top_right);
                         }
                     }
                     Ordering::Greater => {
                         let curve_width = curve_width(bottom_right.x, next_top_right.x);
-                        builder.line_to(bottom_right - curve_height);
+                        path.line_to(bottom_right - curve_height);
                         if self.corner_radius > Pixels::ZERO {
-                            builder.curve_to(bottom_right + curve_width, bottom_right);
+                            path.curve_to(bottom_right + curve_width, bottom_right);
                         }
-                        builder.line_to(next_top_right - curve_width);
+                        path.line_to(next_top_right - curve_width);
                         if self.corner_radius > Pixels::ZERO {
-                            builder.curve_to(next_top_right + curve_height, next_top_right);
+                            path.curve_to(next_top_right + curve_height, next_top_right);
                         }
                     }
                 }
             } else {
                 let curve_width = curve_width(line.start_x, line.end_x);
-                builder.line_to(bottom_right - curve_height);
+                path.line_to(bottom_right - curve_height);
                 if self.corner_radius > Pixels::ZERO {
-                    builder.curve_to(bottom_right - curve_width, bottom_right);
+                    path.curve_to(bottom_right - curve_width, bottom_right);
                 }
 
                 let bottom_left = point(line.start_x, bottom_right.y);
-                builder.line_to(bottom_left + curve_width);
+                path.line_to(bottom_left + curve_width);
                 if self.corner_radius > Pixels::ZERO {
-                    builder.curve_to(bottom_left - curve_height, bottom_left);
+                    path.curve_to(bottom_left - curve_height, bottom_left);
                 }
             }
         }
@@ -8252,26 +8252,24 @@ impl HighlightedRange {
         if first_line.start_x > last_line.start_x {
             let curve_width = curve_width(last_line.start_x, first_line.start_x);
             let second_top_left = point(last_line.start_x, start_y + self.line_height);
-            builder.line_to(second_top_left + curve_height);
+            path.line_to(second_top_left + curve_height);
             if self.corner_radius > Pixels::ZERO {
-                builder.curve_to(second_top_left + curve_width, second_top_left);
+                path.curve_to(second_top_left + curve_width, second_top_left);
             }
             let first_bottom_left = point(first_line.start_x, second_top_left.y);
-            builder.line_to(first_bottom_left - curve_width);
+            path.line_to(first_bottom_left - curve_width);
             if self.corner_radius > Pixels::ZERO {
-                builder.curve_to(first_bottom_left - curve_height, first_bottom_left);
+                path.curve_to(first_bottom_left - curve_height, first_bottom_left);
             }
         }
 
-        builder.line_to(first_top_left + curve_height);
+        path.line_to(first_top_left + curve_height);
         if self.corner_radius > Pixels::ZERO {
-            builder.curve_to(first_top_left + top_curve_width, first_top_left);
+            path.curve_to(first_top_left + top_curve_width, first_top_left);
         }
-        builder.line_to(first_top_right - top_curve_width);
+        path.line_to(first_top_right - top_curve_width);
 
-        if let Ok(path) = builder.build() {
-            window.paint_path(path, self.color);
-        }
+        window.paint_path(path, self.color);
     }
 }
 

crates/gpui/Cargo.toml πŸ”—

@@ -108,7 +108,6 @@ thiserror.workspace = true
 util.workspace = true
 uuid.workspace = true
 waker-fn = "1.2.0"
-lyon = "1.0"
 
 [target.'cfg(target_os = "macos")'.dependencies]
 block = "0.1"
@@ -206,7 +205,6 @@ rand.workspace = true
 util = { workspace = true, features = ["test-support"] }
 http_client = { workspace = true, features = ["test-support"] }
 unicode-segmentation.workspace = true
-lyon = { version = "1.0", features = ["extra"] }
 
 [target.'cfg(target_os = "windows")'.build-dependencies]
 embed-resource = "3.0"

crates/gpui/examples/gradient.rs πŸ”—

@@ -218,17 +218,13 @@ impl Render for GradientViewer {
                     let height = square_bounds.size.height;
                     let horizontal_offset = height;
                     let vertical_offset = px(30.);
-                    let mut builder = gpui::PathBuilder::fill();
-                    builder.move_to(square_bounds.bottom_left());
-                    builder
-                        .line_to(square_bounds.origin + point(horizontal_offset, vertical_offset));
-                    builder.line_to(
+                    let mut path = gpui::Path::new(square_bounds.bottom_left());
+                    path.line_to(square_bounds.origin + point(horizontal_offset, vertical_offset));
+                    path.line_to(
                         square_bounds.top_right() + point(-horizontal_offset, vertical_offset),
                     );
-
-                    builder.line_to(square_bounds.bottom_right());
-                    builder.line_to(square_bounds.bottom_left());
-                    let path = builder.build().unwrap();
+                    path.line_to(square_bounds.bottom_right());
+                    path.line_to(square_bounds.bottom_left());
                     window.paint_path(
                         path,
                         linear_gradient(

crates/gpui/examples/painting.rs πŸ”—

@@ -1,62 +1,46 @@
 use gpui::{
-    canvas, div, linear_color_stop, linear_gradient, point, prelude::*, px, rgb, size, Application,
-    Background, Bounds, ColorSpace, Context, MouseDownEvent, Path, PathBuilder, PathStyle, Pixels,
-    Point, Render, StrokeOptions, Window, WindowOptions,
+    canvas, div, point, prelude::*, px, size, App, Application, Bounds, Context, MouseDownEvent,
+    Path, Pixels, Point, Render, Window, WindowOptions,
 };
-
 struct PaintingViewer {
-    default_lines: Vec<(Path<Pixels>, Background)>,
+    default_lines: Vec<Path<Pixels>>,
     lines: Vec<Vec<Point<Pixels>>>,
     start: Point<Pixels>,
     _painting: bool,
 }
 
 impl PaintingViewer {
-    fn new(_window: &mut Window, _cx: &mut Context<Self>) -> Self {
+    fn new() -> Self {
         let mut lines = vec![];
 
-        // draw a Rust logo
-        let mut builder = lyon::path::Path::svg_builder();
-        lyon::extra::rust_logo::build_logo_path(&mut builder);
-        // move down the Path
-        let mut builder: PathBuilder = builder.into();
-        builder.translate(point(px(10.), px(100.)));
-        builder.scale(0.9);
-        let path = builder.build().unwrap();
-        lines.push((path, gpui::black().into()));
+        // draw a line
+        let mut path = Path::new(point(px(50.), px(180.)));
+        path.line_to(point(px(100.), px(120.)));
+        // go back to close the path
+        path.line_to(point(px(100.), px(121.)));
+        path.line_to(point(px(50.), px(181.)));
+        lines.push(path);
 
         // draw a lightening bolt ⚑
-        let mut builder = PathBuilder::fill();
-        builder.move_to(point(px(150.), px(200.)));
-        builder.line_to(point(px(200.), px(125.)));
-        builder.line_to(point(px(200.), px(175.)));
-        builder.line_to(point(px(250.), px(100.)));
-        let path = builder.build().unwrap();
-        lines.push((path, rgb(0x1d4ed8).into()));
+        let mut path = Path::new(point(px(150.), px(200.)));
+        path.line_to(point(px(200.), px(125.)));
+        path.line_to(point(px(200.), px(175.)));
+        path.line_to(point(px(250.), px(100.)));
+        lines.push(path);
 
         // draw a ⭐
-        let mut builder = PathBuilder::fill();
-        builder.move_to(point(px(350.), px(100.)));
-        builder.line_to(point(px(370.), px(160.)));
-        builder.line_to(point(px(430.), px(160.)));
-        builder.line_to(point(px(380.), px(200.)));
-        builder.line_to(point(px(400.), px(260.)));
-        builder.line_to(point(px(350.), px(220.)));
-        builder.line_to(point(px(300.), px(260.)));
-        builder.line_to(point(px(320.), px(200.)));
-        builder.line_to(point(px(270.), px(160.)));
-        builder.line_to(point(px(330.), px(160.)));
-        builder.line_to(point(px(350.), px(100.)));
-        let path = builder.build().unwrap();
-        lines.push((
-            path,
-            linear_gradient(
-                180.,
-                linear_color_stop(rgb(0xFACC15), 0.7),
-                linear_color_stop(rgb(0xD56D0C), 1.),
-            )
-            .color_space(ColorSpace::Oklab),
-        ));
+        let mut path = Path::new(point(px(350.), px(100.)));
+        path.line_to(point(px(370.), px(160.)));
+        path.line_to(point(px(430.), px(160.)));
+        path.line_to(point(px(380.), px(200.)));
+        path.line_to(point(px(400.), px(260.)));
+        path.line_to(point(px(350.), px(220.)));
+        path.line_to(point(px(300.), px(260.)));
+        path.line_to(point(px(320.), px(200.)));
+        path.line_to(point(px(270.), px(160.)));
+        path.line_to(point(px(330.), px(160.)));
+        path.line_to(point(px(350.), px(100.)));
+        lines.push(path);
 
         let square_bounds = Bounds {
             origin: point(px(450.), px(100.)),
@@ -65,42 +49,18 @@ impl PaintingViewer {
         let height = square_bounds.size.height;
         let horizontal_offset = height;
         let vertical_offset = px(30.);
-        let mut builder = PathBuilder::fill();
-        builder.move_to(square_bounds.bottom_left());
-        builder.curve_to(
+        let mut path = Path::new(square_bounds.bottom_left());
+        path.curve_to(
             square_bounds.origin + point(horizontal_offset, vertical_offset),
             square_bounds.origin + point(px(0.0), vertical_offset),
         );
-        builder.line_to(square_bounds.top_right() + point(-horizontal_offset, vertical_offset));
-        builder.curve_to(
+        path.line_to(square_bounds.top_right() + point(-horizontal_offset, vertical_offset));
+        path.curve_to(
             square_bounds.bottom_right(),
             square_bounds.top_right() + point(px(0.0), vertical_offset),
         );
-        builder.line_to(square_bounds.bottom_left());
-        let path = builder.build().unwrap();
-        lines.push((
-            path,
-            linear_gradient(
-                180.,
-                linear_color_stop(gpui::blue(), 0.4),
-                linear_color_stop(gpui::red(), 1.),
-            ),
-        ));
-
-        // draw a wave
-        let options = StrokeOptions::default()
-            .with_line_width(1.)
-            .with_line_join(lyon::path::LineJoin::Bevel);
-        let mut builder = PathBuilder::stroke(px(1.)).with_style(PathStyle::Stroke(options));
-        builder.move_to(point(px(40.), px(320.)));
-        for i in 0..50 {
-            builder.line_to(point(
-                px(40.0 + i as f32 * 10.0),
-                px(320.0 + (i as f32 * 10.0).sin() * 40.0),
-            ));
-        }
-        let path = builder.build().unwrap();
-        lines.push((path, gpui::green().into()));
+        path.line_to(square_bounds.bottom_left());
+        lines.push(path);
 
         Self {
             default_lines: lines.clone(),
@@ -155,28 +115,27 @@ impl Render for PaintingViewer {
                         canvas(
                             move |_, _, _| {},
                             move |_, _, window, _| {
-
-                                for (path, color) in default_lines {
-                                    window.paint_path(path, color);
+                                const STROKE_WIDTH: Pixels = px(2.0);
+                                for path in default_lines {
+                                    window.paint_path(path, gpui::black());
                                 }
-
                                 for points in lines {
-                                    if points.len() < 2 {
-                                        continue;
+                                    let mut path = Path::new(points[0]);
+                                    for p in points.iter().skip(1) {
+                                        path.line_to(*p);
                                     }
 
-                                    let mut builder = PathBuilder::stroke(px(1.));
-                                    for (i, p) in points.into_iter().enumerate() {
-                                        if i == 0 {
-                                            builder.move_to(p);
-                                        } else {
-                                            builder.line_to(p);
+                                    let mut last = points.last().unwrap();
+                                    for p in points.iter().rev() {
+                                        let mut offset_x = px(0.);
+                                        if last.x == p.x {
+                                            offset_x = STROKE_WIDTH;
                                         }
+                                        path.line_to(point(p.x + offset_x, p.y  + STROKE_WIDTH));
+                                        last = p;
                                     }
 
-                                    if let Ok(path) = builder.build() {
-                                        window.paint_path(path, gpui::black());
-                                    }
+                                    window.paint_path(path, gpui::black());
                                 }
                             },
                         )
@@ -226,13 +185,13 @@ impl Render for PaintingViewer {
 }
 
 fn main() {
-    Application::new().run(|cx| {
+    Application::new().run(|cx: &mut App| {
         cx.open_window(
             WindowOptions {
                 focus: true,
                 ..Default::default()
             },
-            |window, cx| cx.new(|cx| PaintingViewer::new(window, cx)),
+            |_, cx| cx.new(|_| PaintingViewer::new()),
         )
         .unwrap();
         cx.activate(true);

crates/gpui/src/gpui.rs πŸ”—

@@ -82,7 +82,6 @@ mod input;
 mod interactive;
 mod key_dispatch;
 mod keymap;
-mod path_builder;
 mod platform;
 pub mod prelude;
 mod scene;
@@ -136,7 +135,6 @@ pub use input::*;
 pub use interactive::*;
 use key_dispatch::*;
 pub use keymap::*;
-pub use path_builder::*;
 pub use platform::*;
 pub use refineable::*;
 pub use scene::*;

crates/gpui/src/path_builder.rs πŸ”—

@@ -1,241 +0,0 @@
-use anyhow::Error;
-use etagere::euclid::Vector2D;
-use lyon::geom::Angle;
-use lyon::tessellation::{
-    BuffersBuilder, FillTessellator, FillVertex, StrokeTessellator, StrokeVertex, VertexBuffers,
-};
-
-pub use lyon::math::Transform;
-pub use lyon::tessellation::{FillOptions, FillRule, StrokeOptions};
-
-use crate::{point, px, Path, Pixels, Point};
-
-/// Style of the PathBuilder
-pub enum PathStyle {
-    /// Stroke style
-    Stroke(StrokeOptions),
-    /// Fill style
-    Fill(FillOptions),
-}
-
-/// A [`Path`] builder.
-pub struct PathBuilder {
-    raw: lyon::path::builder::WithSvg<lyon::path::BuilderImpl>,
-    transform: Option<lyon::math::Transform>,
-    /// PathStyle of the PathBuilder
-    pub style: PathStyle,
-}
-
-impl From<lyon::path::Builder> for PathBuilder {
-    fn from(builder: lyon::path::Builder) -> Self {
-        Self {
-            raw: builder.with_svg(),
-            ..Default::default()
-        }
-    }
-}
-
-impl From<lyon::path::builder::WithSvg<lyon::path::BuilderImpl>> for PathBuilder {
-    fn from(raw: lyon::path::builder::WithSvg<lyon::path::BuilderImpl>) -> Self {
-        Self {
-            raw,
-            ..Default::default()
-        }
-    }
-}
-
-impl From<lyon::math::Point> for Point<Pixels> {
-    fn from(p: lyon::math::Point) -> Self {
-        point(px(p.x), px(p.y))
-    }
-}
-
-impl From<Point<Pixels>> for lyon::math::Point {
-    fn from(p: Point<Pixels>) -> Self {
-        lyon::math::point(p.x.0, p.y.0)
-    }
-}
-
-impl Default for PathBuilder {
-    fn default() -> Self {
-        Self {
-            raw: lyon::path::Path::builder().with_svg(),
-            style: PathStyle::Fill(FillOptions::default()),
-            transform: None,
-        }
-    }
-}
-
-impl PathBuilder {
-    /// Creates a new [`PathBuilder`] to build a Stroke path.
-    pub fn stroke(width: Pixels) -> Self {
-        Self {
-            style: PathStyle::Stroke(StrokeOptions::default().with_line_width(width.0)),
-            ..Self::default()
-        }
-    }
-
-    /// Creates a new [`PathBuilder`] to build a Fill path.
-    pub fn fill() -> Self {
-        Self::default()
-    }
-
-    /// Sets the style of the [`PathBuilder`].
-    pub fn with_style(self, style: PathStyle) -> Self {
-        Self { style, ..self }
-    }
-
-    /// Move the current point to the given point.
-    #[inline]
-    pub fn move_to(&mut self, to: Point<Pixels>) {
-        self.raw.move_to(to.into());
-    }
-
-    /// Draw a straight line from the current point to the given point.
-    #[inline]
-    pub fn line_to(&mut self, to: Point<Pixels>) {
-        self.raw.line_to(to.into());
-    }
-
-    /// Draw a curve from the current point to the given point, using the given control point.
-    #[inline]
-    pub fn curve_to(&mut self, to: Point<Pixels>, ctrl: Point<Pixels>) {
-        self.raw.quadratic_bezier_to(ctrl.into(), to.into());
-    }
-
-    /// Adds a cubic BΓ©zier to the [`Path`] given its two control points
-    /// and its end point.
-    #[inline]
-    pub fn cubic_bezier_to(
-        &mut self,
-        to: Point<Pixels>,
-        control_a: Point<Pixels>,
-        control_b: Point<Pixels>,
-    ) {
-        self.raw
-            .cubic_bezier_to(control_a.into(), control_b.into(), to.into());
-    }
-
-    /// Close the current sub-path.
-    #[inline]
-    pub fn close(&mut self) {
-        self.raw.close();
-    }
-
-    /// Applies a transform to the path.
-    #[inline]
-    pub fn transform(&mut self, transform: Transform) {
-        self.transform = Some(transform);
-    }
-
-    /// Applies a translation to the path.
-    #[inline]
-    pub fn translate(&mut self, to: Point<Pixels>) {
-        if let Some(transform) = self.transform {
-            self.transform = Some(transform.then_translate(Vector2D::new(to.x.0, to.y.0)));
-        } else {
-            self.transform = Some(Transform::translation(to.x.0, to.y.0))
-        }
-    }
-
-    /// Applies a scale to the path.
-    #[inline]
-    pub fn scale(&mut self, scale: f32) {
-        if let Some(transform) = self.transform {
-            self.transform = Some(transform.then_scale(scale, scale));
-        } else {
-            self.transform = Some(Transform::scale(scale, scale));
-        }
-    }
-
-    /// Applies a rotation to the path.
-    ///
-    /// The `angle` is in degrees value in the range 0.0 to 360.0.
-    #[inline]
-    pub fn rotate(&mut self, angle: f32) {
-        let radians = angle.to_radians();
-        if let Some(transform) = self.transform {
-            self.transform = Some(transform.then_rotate(Angle::radians(radians)));
-        } else {
-            self.transform = Some(Transform::rotation(Angle::radians(radians)));
-        }
-    }
-
-    /// Builds into a [`Path`].
-    #[inline]
-    pub fn build(self) -> Result<Path<Pixels>, Error> {
-        let path = if let Some(transform) = self.transform {
-            self.raw.build().transformed(&transform)
-        } else {
-            self.raw.build()
-        };
-
-        match self.style {
-            PathStyle::Stroke(options) => Self::tessellate_stroke(&path, &options),
-            PathStyle::Fill(options) => Self::tessellate_fill(&path, &options),
-        }
-    }
-
-    fn tessellate_fill(
-        path: &lyon::path::Path,
-        options: &FillOptions,
-    ) -> Result<Path<Pixels>, Error> {
-        // Will contain the result of the tessellation.
-        let mut buf: VertexBuffers<lyon::math::Point, u16> = VertexBuffers::new();
-        let mut tessellator = FillTessellator::new();
-
-        // Compute the tessellation.
-        tessellator.tessellate_path(
-            path,
-            options,
-            &mut BuffersBuilder::new(&mut buf, |vertex: FillVertex| vertex.position()),
-        )?;
-
-        Ok(Self::build_path(buf))
-    }
-
-    fn tessellate_stroke(
-        path: &lyon::path::Path,
-        options: &StrokeOptions,
-    ) -> Result<Path<Pixels>, Error> {
-        // Will contain the result of the tessellation.
-        let mut buf: VertexBuffers<lyon::math::Point, u16> = VertexBuffers::new();
-        let mut tessellator = StrokeTessellator::new();
-
-        // Compute the tessellation.
-        tessellator.tessellate_path(
-            path,
-            options,
-            &mut BuffersBuilder::new(&mut buf, |vertex: StrokeVertex| vertex.position()),
-        )?;
-
-        Ok(Self::build_path(buf))
-    }
-
-    /// Builds a [`Path`] from a [`lyon::VertexBuffers`].
-    pub fn build_path(buf: VertexBuffers<lyon::math::Point, u16>) -> Path<Pixels> {
-        if buf.vertices.is_empty() {
-            return Path::new(Point::default());
-        }
-
-        let first_point = buf.vertices[0];
-
-        let mut path = Path::new(first_point.into());
-        for i in 0..buf.indices.len() / 3 {
-            let i0 = buf.indices[i * 3] as usize;
-            let i1 = buf.indices[i * 3 + 1] as usize;
-            let i2 = buf.indices[i * 3 + 2] as usize;
-
-            let v0 = buf.vertices[i0];
-            let v1 = buf.vertices[i1];
-            let v2 = buf.vertices[i2];
-
-            path.push_triangle(
-                (v0.into(), v1.into(), v2.into()),
-                (point(0., 1.), point(0., 1.), point(0., 1.)),
-            );
-        }
-
-        path
-    }
-}

crates/gpui/src/platform/blade/blade_atlas.rs πŸ”—

@@ -27,7 +27,6 @@ struct BladeAtlasState {
     tiles_by_key: FxHashMap<AtlasKey, AtlasTile>,
     initializations: Vec<AtlasTextureId>,
     uploads: Vec<PendingUpload>,
-    path_sample_count: u32,
 }
 
 #[cfg(gles)]
@@ -43,11 +42,10 @@ impl BladeAtlasState {
 pub struct BladeTextureInfo {
     pub size: gpu::Extent,
     pub raw_view: gpu::TextureView,
-    pub msaa_view: Option<gpu::TextureView>,
 }
 
 impl BladeAtlas {
-    pub(crate) fn new(gpu: &Arc<gpu::Context>, path_sample_count: u32) -> Self {
+    pub(crate) fn new(gpu: &Arc<gpu::Context>) -> Self {
         BladeAtlas(Mutex::new(BladeAtlasState {
             gpu: Arc::clone(gpu),
             upload_belt: BufferBelt::new(BufferBeltDescriptor {
@@ -59,7 +57,6 @@ impl BladeAtlas {
             tiles_by_key: Default::default(),
             initializations: Vec::new(),
             uploads: Vec::new(),
-            path_sample_count,
         }))
     }
 
@@ -109,7 +106,6 @@ impl BladeAtlas {
                 depth: 1,
             },
             raw_view: texture.raw_view,
-            msaa_view: texture.msaa_view,
         }
     }
 }
@@ -208,39 +204,6 @@ impl BladeAtlasState {
             }
         }
 
-        // We currently only enable MSAA for path textures.
-        let (msaa, msaa_view) = if self.path_sample_count > 1 && kind == AtlasTextureKind::Path {
-            let msaa = self.gpu.create_texture(gpu::TextureDesc {
-                name: "msaa path texture",
-                format,
-                size: gpu::Extent {
-                    width: size.width.into(),
-                    height: size.height.into(),
-                    depth: 1,
-                },
-                array_layer_count: 1,
-                mip_level_count: 1,
-                sample_count: self.path_sample_count,
-                dimension: gpu::TextureDimension::D2,
-                usage: gpu::TextureUsage::TARGET,
-            });
-
-            (
-                Some(msaa),
-                Some(self.gpu.create_texture_view(
-                    msaa,
-                    gpu::TextureViewDesc {
-                        name: "msaa texture view",
-                        format,
-                        dimension: gpu::ViewDimension::D2,
-                        subresources: &Default::default(),
-                    },
-                )),
-            )
-        } else {
-            (None, None)
-        };
-
         let raw = self.gpu.create_texture(gpu::TextureDesc {
             name: "atlas",
             format,
@@ -277,8 +240,6 @@ impl BladeAtlasState {
             format,
             raw,
             raw_view,
-            msaa,
-            msaa_view,
             live_atlas_keys: 0,
         };
 
@@ -393,8 +354,6 @@ struct BladeAtlasTexture {
     allocator: BucketedAtlasAllocator,
     raw: gpu::Texture,
     raw_view: gpu::TextureView,
-    msaa: Option<gpu::Texture>,
-    msaa_view: Option<gpu::TextureView>,
     format: gpu::TextureFormat,
     live_atlas_keys: u32,
 }
@@ -422,12 +381,6 @@ impl BladeAtlasTexture {
     fn destroy(&mut self, gpu: &gpu::Context) {
         gpu.destroy_texture(self.raw);
         gpu.destroy_texture_view(self.raw_view);
-        if let Some(msaa) = self.msaa {
-            gpu.destroy_texture(msaa);
-        }
-        if let Some(msaa_view) = self.msaa_view {
-            gpu.destroy_texture_view(msaa_view);
-        }
     }
 
     fn bytes_per_pixel(&self) -> u8 {

crates/gpui/src/platform/blade/blade_renderer.rs πŸ”—

@@ -7,18 +7,16 @@ use crate::{
     MonochromeSprite, Path, PathId, PathVertex, PolychromeSprite, PrimitiveBatch, Quad,
     ScaledPixels, Scene, Shadow, Size, Underline,
 };
-use blade_graphics as gpu;
-use blade_util::{BufferBelt, BufferBeltDescriptor};
 use bytemuck::{Pod, Zeroable};
 use collections::HashMap;
 #[cfg(target_os = "macos")]
 use media::core_video::CVMetalTextureCache;
+
+use blade_graphics as gpu;
+use blade_util::{BufferBelt, BufferBeltDescriptor};
 use std::{mem, sync::Arc};
 
 const MAX_FRAME_TIME_MS: u32 = 10000;
-// Use 4x MSAA, all devices support it.
-// https://developer.apple.com/documentation/metal/mtldevice/1433355-supportstexturesamplecount
-const PATH_SAMPLE_COUNT: u32 = 4;
 
 #[repr(C)]
 #[derive(Clone, Copy, Pod, Zeroable)]
@@ -210,10 +208,7 @@ impl BladePipelines {
                     blend: Some(gpu::BlendState::ADDITIVE),
                     write_mask: gpu::ColorWrites::default(),
                 }],
-                multisample_state: gpu::MultisampleState {
-                    sample_count: PATH_SAMPLE_COUNT,
-                    ..Default::default()
-                },
+                multisample_state: gpu::MultisampleState::default(),
             }),
             paths: gpu.create_render_pipeline(gpu::RenderPipelineDesc {
                 name: "paths",
@@ -353,7 +348,7 @@ impl BladeRenderer {
             min_chunk_size: 0x1000,
             alignment: 0x40, // Vulkan `minStorageBufferOffsetAlignment` on Intel Xe
         });
-        let atlas = Arc::new(BladeAtlas::new(&context.gpu, PATH_SAMPLE_COUNT));
+        let atlas = Arc::new(BladeAtlas::new(&context.gpu));
         let atlas_sampler = context.gpu.create_sampler(gpu::SamplerDesc {
             name: "atlas",
             mag_filter: gpu::FilterMode::Linear,
@@ -502,38 +497,27 @@ impl BladeRenderer {
             };
 
             let vertex_buf = unsafe { self.instance_belt.alloc_typed(&vertices, &self.gpu) };
-            let frame_view = tex_info.raw_view;
-            let color_target = if let Some(msaa_view) = tex_info.msaa_view {
-                gpu::RenderTarget {
-                    view: msaa_view,
-                    init_op: gpu::InitOp::Clear(gpu::TextureColor::OpaqueBlack),
-                    finish_op: gpu::FinishOp::ResolveTo(frame_view),
-                }
-            } else {
-                gpu::RenderTarget {
-                    view: frame_view,
-                    init_op: gpu::InitOp::Clear(gpu::TextureColor::OpaqueBlack),
-                    finish_op: gpu::FinishOp::Store,
-                }
-            };
-
-            if let mut pass = self.command_encoder.render(
+            let mut pass = self.command_encoder.render(
                 "paths",
                 gpu::RenderTargetSet {
-                    colors: &[color_target],
+                    colors: &[gpu::RenderTarget {
+                        view: tex_info.raw_view,
+                        init_op: gpu::InitOp::Clear(gpu::TextureColor::OpaqueBlack),
+                        finish_op: gpu::FinishOp::Store,
+                    }],
                     depth_stencil: None,
                 },
-            ) {
-                let mut encoder = pass.with(&self.pipelines.path_rasterization);
-                encoder.bind(
-                    0,
-                    &ShaderPathRasterizationData {
-                        globals,
-                        b_path_vertices: vertex_buf,
-                    },
-                );
-                encoder.draw(0, vertices.len() as u32, 0, 1);
-            }
+            );
+
+            let mut encoder = pass.with(&self.pipelines.path_rasterization);
+            encoder.bind(
+                0,
+                &ShaderPathRasterizationData {
+                    globals,
+                    b_path_vertices: vertex_buf,
+                },
+            );
+            encoder.draw(0, vertices.len() as u32, 0, 1);
         }
     }
 

crates/gpui/src/platform/mac/metal_atlas.rs πŸ”—

@@ -13,14 +13,13 @@ use std::borrow::Cow;
 pub(crate) struct MetalAtlas(Mutex<MetalAtlasState>);
 
 impl MetalAtlas {
-    pub(crate) fn new(device: Device, path_sample_count: u32) -> Self {
+    pub(crate) fn new(device: Device) -> Self {
         MetalAtlas(Mutex::new(MetalAtlasState {
             device: AssertSend(device),
             monochrome_textures: Default::default(),
             polychrome_textures: Default::default(),
             path_textures: Default::default(),
             tiles_by_key: Default::default(),
-            path_sample_count,
         }))
     }
 
@@ -28,10 +27,6 @@ impl MetalAtlas {
         self.0.lock().texture(id).metal_texture.clone()
     }
 
-    pub(crate) fn msaa_texture(&self, id: AtlasTextureId) -> Option<metal::Texture> {
-        self.0.lock().texture(id).msaa_texture.clone()
-    }
-
     pub(crate) fn allocate(
         &self,
         size: Size<DevicePixels>,
@@ -59,7 +54,6 @@ struct MetalAtlasState {
     polychrome_textures: AtlasTextureList<MetalAtlasTexture>,
     path_textures: AtlasTextureList<MetalAtlasTexture>,
     tiles_by_key: FxHashMap<AtlasKey, AtlasTile>,
-    path_sample_count: u32,
 }
 
 impl PlatformAtlas for MetalAtlas {
@@ -182,18 +176,6 @@ impl MetalAtlasState {
         texture_descriptor.set_usage(usage);
         let metal_texture = self.device.new_texture(&texture_descriptor);
 
-        // We currently only enable MSAA for path textures.
-        let msaa_texture = if self.path_sample_count > 1 && kind == AtlasTextureKind::Path {
-            let mut descriptor = texture_descriptor.clone();
-            descriptor.set_texture_type(metal::MTLTextureType::D2Multisample);
-            descriptor.set_storage_mode(metal::MTLStorageMode::Private);
-            descriptor.set_sample_count(self.path_sample_count as _);
-            let msaa_texture = self.device.new_texture(&descriptor);
-            Some(msaa_texture)
-        } else {
-            None
-        };
-
         let texture_list = match kind {
             AtlasTextureKind::Monochrome => &mut self.monochrome_textures,
             AtlasTextureKind::Polychrome => &mut self.polychrome_textures,
@@ -209,7 +191,6 @@ impl MetalAtlasState {
             },
             allocator: etagere::BucketedAtlasAllocator::new(size.into()),
             metal_texture: AssertSend(metal_texture),
-            msaa_texture: AssertSend(msaa_texture),
             live_atlas_keys: 0,
         };
 
@@ -236,7 +217,6 @@ struct MetalAtlasTexture {
     id: AtlasTextureId,
     allocator: BucketedAtlasAllocator,
     metal_texture: AssertSend<metal::Texture>,
-    msaa_texture: AssertSend<Option<metal::Texture>>,
     live_atlas_keys: u32,
 }
 

crates/gpui/src/platform/mac/metal_renderer.rs πŸ”—

@@ -28,9 +28,6 @@ pub(crate) type PointF = crate::Point<f32>;
 const SHADERS_METALLIB: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/shaders.metallib"));
 #[cfg(feature = "runtime_shaders")]
 const SHADERS_SOURCE_FILE: &str = include_str!(concat!(env!("OUT_DIR"), "/stitched_shaders.metal"));
-// Use 4x MSAA, all devices support it.
-// https://developer.apple.com/documentation/metal/mtldevice/1433355-supportstexturesamplecount
-const PATH_SAMPLE_COUNT: u32 = 4;
 
 pub type Context = Arc<Mutex<InstanceBufferPool>>;
 pub type Renderer = MetalRenderer;
@@ -173,7 +170,6 @@ impl MetalRenderer {
             "path_rasterization_vertex",
             "path_rasterization_fragment",
             MTLPixelFormat::R16Float,
-            PATH_SAMPLE_COUNT,
         );
         let path_sprites_pipeline_state = build_pipeline_state(
             &device,
@@ -233,7 +229,7 @@ impl MetalRenderer {
         );
 
         let command_queue = device.new_command_queue();
-        let sprite_atlas = Arc::new(MetalAtlas::new(device.clone(), PATH_SAMPLE_COUNT));
+        let sprite_atlas = Arc::new(MetalAtlas::new(device.clone()));
         let core_video_texture_cache =
             unsafe { CVMetalTextureCache::new(device.as_ptr()).unwrap() };
 
@@ -535,20 +531,10 @@ impl MetalRenderer {
                 .unwrap();
 
             let texture = self.sprite_atlas.metal_texture(texture_id);
-            let msaa_texture = self.sprite_atlas.msaa_texture(texture_id);
-
-            if let Some(msaa_texture) = msaa_texture {
-                color_attachment.set_texture(Some(&msaa_texture));
-                color_attachment.set_resolve_texture(Some(&texture));
-                color_attachment.set_load_action(metal::MTLLoadAction::Clear);
-                color_attachment.set_store_action(metal::MTLStoreAction::MultisampleResolve);
-            } else {
-                color_attachment.set_texture(Some(&texture));
-                color_attachment.set_load_action(metal::MTLLoadAction::Clear);
-                color_attachment.set_store_action(metal::MTLStoreAction::Store);
-            }
+            color_attachment.set_texture(Some(&texture));
+            color_attachment.set_load_action(metal::MTLLoadAction::Clear);
+            color_attachment.set_store_action(metal::MTLStoreAction::Store);
             color_attachment.set_clear_color(metal::MTLClearColor::new(0., 0., 0., 1.));
-
             let command_encoder = command_buffer.new_render_command_encoder(render_pass_descriptor);
             command_encoder.set_render_pipeline_state(&self.paths_rasterization_pipeline_state);
             command_encoder.set_vertex_buffer(
@@ -1174,7 +1160,6 @@ fn build_path_rasterization_pipeline_state(
     vertex_fn_name: &str,
     fragment_fn_name: &str,
     pixel_format: metal::MTLPixelFormat,
-    path_sample_count: u32,
 ) -> metal::RenderPipelineState {
     let vertex_fn = library
         .get_function(vertex_fn_name, None)
@@ -1187,10 +1172,6 @@ fn build_path_rasterization_pipeline_state(
     descriptor.set_label(label);
     descriptor.set_vertex_function(Some(vertex_fn.as_ref()));
     descriptor.set_fragment_function(Some(fragment_fn.as_ref()));
-    if path_sample_count > 1 {
-        descriptor.set_raster_sample_count(path_sample_count as _);
-        descriptor.set_alpha_to_coverage_enabled(true);
-    }
     let color_attachment = descriptor.color_attachments().object_at(0).unwrap();
     color_attachment.set_pixel_format(pixel_format);
     color_attachment.set_blending_enabled(true);

crates/gpui/src/scene.rs πŸ”—

@@ -715,13 +715,6 @@ impl Path<Pixels> {
         }
     }
 
-    /// Move the start, current point to the given point.
-    pub fn move_to(&mut self, to: Point<Pixels>) {
-        self.contour_count += 1;
-        self.start = to;
-        self.current = to;
-    }
-
     /// Draw a straight line from the current point to the given point.
     pub fn line_to(&mut self, to: Point<Pixels>) {
         self.contour_count += 1;
@@ -751,8 +744,7 @@ impl Path<Pixels> {
         self.current = to;
     }
 
-    /// Push a triangle to the Path.
-    pub fn push_triangle(
+    fn push_triangle(
         &mut self,
         xy: (Point<Pixels>, Point<Pixels>, Point<Pixels>),
         st: (Point<f32>, Point<f32>, Point<f32>),