From 5aa45607eb9f1b23d3857754867ed40fd5e9c04a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 4 Oct 2023 18:38:08 +0200 Subject: [PATCH] Checkpoint --- 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(-) diff --git a/crates/gpui3/src/elements/img.rs b/crates/gpui3/src/elements/img.rs index 81164f1bdc17a1fd78dd3ec304826feeea6d700a..1932045885ce0e30f3f4c6c18d652638c65d775f 100644 --- a/crates/gpui3/src/elements/img.rs +++ b/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 Element for Img { .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 { diff --git a/crates/gpui3/src/platform/mac/shaders.metal b/crates/gpui3/src/platform/mac/shaders.metal index 313feec7f11902c430a8861e379643b0c9fe62a5..b4614bef4d58fc08f8f8a24008e0ae79b86e8f02 100644 --- a/crates/gpui3/src/platform/mac/shaders.metal +++ b/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; } diff --git a/crates/gpui3/src/scene.rs b/crates/gpui3/src/scene.rs index fb6111b0391e85cc2e3077e4c7eec883445603ee..3426eefc9ea306ab530e7082b6ad16880d080c30 100644 --- a/crates/gpui3/src/scene.rs +++ b/crates/gpui3/src/scene.rs @@ -275,6 +275,7 @@ pub struct PolychromeSprite { pub order: u32, pub bounds: Bounds, pub content_mask: ScaledContentMask, + pub corner_radii: Corners, pub tile: AtlasTile, pub grayscale: bool, } diff --git a/crates/gpui3/src/style.rs b/crates/gpui3/src/style.rs index 33da5e3602a945f8873b973ae8e1ee4a57d0e603..1f874807488b01374f4517273518127f9460d787 100644 --- a/crates/gpui3/src/style.rs +++ b/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) diff --git a/crates/gpui3/src/window.rs b/crates/gpui3/src/window.rs index b92edb8ecefee09c1a89934b0ad45eef7b615dcb..e1a75791e4590733f721bb0b346f12d2baafacd4 100644 --- a/crates/gpui3/src/window.rs +++ b/crates/gpui3/src/window.rs @@ -76,24 +76,18 @@ impl Window { #[derive(Clone, Debug)] pub struct ContentMask { pub bounds: Bounds, - pub corner_radii: Corners, } 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, - corner_radii: Corners, } pub struct WindowContext<'a, 'w> { @@ -202,23 +195,6 @@ impl<'a, 'w> WindowContext<'a, 'w> { result } - pub fn clip( - &mut self, - bounds: Bounds, - corner_radii: Corners, - 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, + corner_radii: Corners, order: u32, data: Arc, 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(), }) }