Render sprited icons at 2x resolution since we don't align to pixel grid

Nathan Sobo and Antonio Scandurra created

This provides the sampler with a bit more data when positioning sprites at subpixel positions.

Co-Authored-By: Antonio Scandurra <me@as-cii.com>

Change summary

gpui/src/platform/mac/renderer.rs     | 24 +++++++++++++-----------
gpui/src/platform/mac/sprite_cache.rs | 19 +------------------
2 files changed, 14 insertions(+), 29 deletions(-)

Detailed changes

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

@@ -153,7 +153,8 @@ impl Renderer {
                     atlas_id,
                     shader_data: shaders::GPUISprite {
                         origin: origin.floor().to_float2(),
-                        size: size.to_float2(),
+                        target_size: size.to_float2(),
+                        source_size: size.to_float2(),
                         atlas_origin: atlas_origin.to_float2(),
                         color: path.color.to_uchar4(),
                         compute_winding: 1,
@@ -493,7 +494,8 @@ impl Renderer {
                     .or_insert_with(Vec::new)
                     .push(shaders::GPUISprite {
                         origin: origin.to_float2(),
-                        size: sprite.size.to_float2(),
+                        target_size: sprite.size.to_float2(),
+                        source_size: sprite.size.to_float2(),
                         atlas_origin: sprite.atlas_origin.to_float2(),
                         color: glyph.color.to_uchar4(),
                         compute_winding: 0,
@@ -502,21 +504,21 @@ impl Renderer {
         }
 
         for icon in layer.icons() {
-            let sprite = self.sprite_cache.render_icon(
-                icon.bounds.size(),
-                icon.path.clone(),
-                icon.svg.clone(),
-                scene.scale_factor(),
-            );
+            let origin = icon.bounds.origin() * scene.scale_factor();
+            let target_size = icon.bounds.size() * scene.scale_factor();
+            let source_size = (target_size * 2.).ceil().to_i32();
+
+            let sprite =
+                self.sprite_cache
+                    .render_icon(source_size, icon.path.clone(), icon.svg.clone());
 
-            // Snap sprite to pixel grid.
-            let origin = (icon.bounds.origin() * scene.scale_factor()); //.floor();
             sprites_by_atlas
                 .entry(sprite.atlas_id)
                 .or_insert_with(Vec::new)
                 .push(shaders::GPUISprite {
                     origin: origin.to_float2(),
-                    size: sprite.size.to_float2(),
+                    target_size: target_size.to_float2(),
+                    source_size: sprite.size.to_float2(),
                     atlas_origin: sprite.atlas_origin.to_float2(),
                     color: icon.color.to_uchar4(),
                     compute_winding: 0,

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

@@ -137,30 +137,13 @@ impl SpriteCache {
 
     pub fn render_icon(
         &mut self,
-        size: Vector2F,
+        size: Vector2I,
         path: Cow<'static, str>,
         svg: usvg::Tree,
-        target_position: Vector2F,
-        scale_factor: f32,
     ) -> IconSprite {
-        const SUBPIXEL_VARIANTS: u8 = 4;
-
-        let target_position = target_position * scale_factor;
-        let subpixel_variant = (
-            (target_position.x().fract() * SUBPIXEL_VARIANTS as f32).round() as u8
-                % SUBPIXEL_VARIANTS,
-            (target_position.y().fract() * SUBPIXEL_VARIANTS as f32).round() as u8
-                % SUBPIXEL_VARIANTS,
-        );
-        let subpixel_shift = vec2f(
-            subpixel_variant.0 as f32 / SUBPIXEL_VARIANTS as f32,
-            subpixel_variant.1 as f32 / SUBPIXEL_VARIANTS as f32,
-        );
-
         let atlases = &mut self.atlases;
         let atlas_size = self.atlas_size;
         let device = &self.device;
-        let size = (size * scale_factor).round().to_i32();
         assert!(size.x() < atlas_size.x());
         assert!(size.y() < atlas_size.y());
         self.icons