From 6f7c305308d6034fe61684b05c8b2ee79d81419a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 5 Oct 2023 14:42:11 -0600 Subject: [PATCH] Checkpoint --- crates/gpui3/Cargo.toml | 3 +- crates/gpui3/src/elements/div.rs | 13 +- crates/gpui3/src/elements/img.rs | 4 +- crates/gpui3/src/geometry.rs | 46 +- .../gpui3/src/platform/mac/metal_renderer.rs | 71 +- crates/gpui3/src/scene.rs | 286 ++++-- crates/gpui3/src/style.rs | 64 +- crates/gpui3/src/style_helpers.rs | 2 +- crates/gpui3/src/window.rs | 42 +- crates/storybook2/src/collab_panel.rs | 4 +- crates/storybook2/src/themes.rs | 4 +- .../{rose_pine_dawn.rs => rose_pine.rs} | 843 +++++++++++++++++- crates/storybook2/src/workspace.rs | 2 +- 13 files changed, 1190 insertions(+), 194 deletions(-) rename crates/storybook2/src/themes/{rose_pine_dawn.rs => rose_pine.rs} (53%) diff --git a/crates/gpui3/Cargo.toml b/crates/gpui3/Cargo.toml index 855ce49d9d00f1b24e160aa637693a8b3c233a6e..e8ba5def502590a7ed830187b7a3b32618efc019 100644 --- a/crates/gpui3/Cargo.toml +++ b/crates/gpui3/Cargo.toml @@ -7,7 +7,7 @@ description = "The next version of Zed's GPU-accelerated UI framework" publish = false [features] -test = ["backtrace", "dhat", "env_logger", "collections/test-support"] +test = ["backtrace", "dhat", "env_logger", "collections/test-support", "util/test-support"] [lib] path = "src/gpui3.rs" @@ -66,6 +66,7 @@ dhat = "0.3" env_logger.workspace = true png = "0.16" simplelog = "0.9" +util = { path = "../util", features = ["test-support"] } [build-dependencies] bindgen = "0.65.1" diff --git a/crates/gpui3/src/elements/div.rs b/crates/gpui3/src/elements/div.rs index 535ccb995306a14252565f99ebb9eb130cb11230..ba006b13eeb63d3824586b877e7564019626c715 100644 --- a/crates/gpui3/src/elements/div.rs +++ b/crates/gpui3/src/elements/div.rs @@ -48,17 +48,14 @@ impl Element for Div { let Layout { order, bounds } = layout; let style = self.computed_style(); - style.paint(order, bounds, cx); + cx.stack(0, |cx| style.paint(order, bounds, cx)); - // // todo!("support only one dimension being hidden") let overflow = &style.overflow; - // if style.overflow.y != Overflow::Visible || style.overflow.x != Overflow::Visible { - // cx.clip(layout.bounds, style.corner_radii, || ) - // } - style.apply_text_style(cx, |cx| { - style.apply_overflow(layout.bounds, cx, |cx| { - self.paint_children(overflow, state, cx) + cx.stack(1, |cx| { + style.apply_overflow(layout.bounds, cx, |cx| { + self.paint_children(overflow, state, cx) + }) }) })?; self.handle_scroll(order, bounds, style.overflow.clone(), child_layouts, cx); diff --git a/crates/gpui3/src/elements/img.rs b/crates/gpui3/src/elements/img.rs index d4c0ac4373e0793a00ac0de569e04f4d18782c18..6b6ddc185f548b6e860ef5a5afe2b1b7a1df4e94 100644 --- a/crates/gpui3/src/elements/img.rs +++ b/crates/gpui3/src/elements/img.rs @@ -73,7 +73,9 @@ impl Element for Img { .and_then(ResultExt::log_err) { let corner_radii = style.corner_radii.to_pixels(bounds.size, cx.rem_size()); - cx.paint_image(bounds, corner_radii, order, data, self.grayscale)?; + cx.stack(1, |cx| { + cx.paint_image(bounds, corner_radii, order, data, self.grayscale) + })?; } else { cx.spawn(|_, mut cx| async move { if image_future.await.log_err().is_some() { diff --git a/crates/gpui3/src/geometry.rs b/crates/gpui3/src/geometry.rs index 98ccfd58c315f5a3deac15e79ca98ff631270ae4..93d7dd2a0804604e7bbe5886c22df1d91a2619f5 100644 --- a/crates/gpui3/src/geometry.rs +++ b/crates/gpui3/src/geometry.rs @@ -2,7 +2,7 @@ use core::fmt::Debug; use derive_more::{Add, AddAssign, Div, Mul, Sub, SubAssign}; use refineable::Refineable; use std::{ - cmp, + cmp, fmt, ops::{Add, AddAssign, Div, Mul, MulAssign, Sub, SubAssign}, }; @@ -128,7 +128,7 @@ impl Clone for Point { } } -#[derive(Refineable, Default, Clone, Copy, Debug, PartialEq, Div, Hash)] +#[derive(Refineable, Default, Clone, Copy, PartialEq, Div, Hash)] #[refineable(debug)] #[repr(C)] pub struct Size { @@ -199,14 +199,11 @@ impl, S: Clone> MulAssign for Size { impl Eq for Size {} -// impl From>> for Size> { -// fn from(size: Size>) -> Self { -// Size { -// width: size.width.map(|p| p.0 as f32), -// height: size.height.map(|p| p.0 as f32), -// } -// } -// } +impl Debug for Size { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Size {{ {:?} × {:?} }}", self.width, self.height) + } +} impl From> for Size { fn from(size: Size) -> Self { @@ -345,6 +342,13 @@ impl> Bounds { y: self.origin.y.clone() + self.size.height.clone(), } } + + pub fn lower_left(&self) -> Point { + Point { + x: self.origin.x.clone(), + y: self.origin.y.clone() + self.size.height.clone(), + } + } } impl> Bounds { @@ -627,7 +631,7 @@ impl From for Pixels { } impl Debug for Pixels { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{} px", self.0) } } @@ -662,8 +666,8 @@ impl DevicePixels { } } -impl std::fmt::Debug for DevicePixels { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl fmt::Debug for DevicePixels { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{} px (device)", self.0) } } @@ -721,7 +725,7 @@ impl ScaledPixels { impl Eq for ScaledPixels {} impl Debug for ScaledPixels { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{} px (scaled)", self.0) } } @@ -738,12 +742,18 @@ impl From for ScaledPixels { } } +impl From for f64 { + fn from(scaled_pixels: ScaledPixels) -> Self { + scaled_pixels.0 as f64 + } +} + #[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)] #[repr(transparent)] pub struct GlobalPixels(pub(crate) f32); impl Debug for GlobalPixels { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{} px (global coordinate space)", self.0) } } @@ -772,7 +782,7 @@ impl Mul for Rems { } impl Debug for Rems { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{} rem", self.0) } } @@ -840,7 +850,7 @@ impl DefiniteLength { } impl Debug for DefiniteLength { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { DefiniteLength::Absolute(length) => Debug::fmt(length, f), DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32), @@ -880,7 +890,7 @@ pub enum Length { } impl Debug for Length { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Length::Definite(definite_length) => write!(f, "{:?}", definite_length), Length::Auto => write!(f, "auto"), diff --git a/crates/gpui3/src/platform/mac/metal_renderer.rs b/crates/gpui3/src/platform/mac/metal_renderer.rs index f2e14a04319dfcf2348e3447d2c89172acba7ad6..a0c608abc6c738fa20362e38af195c78fa7d6ac6 100644 --- a/crates/gpui3/src/platform/mac/metal_renderer.rs +++ b/crates/gpui3/src/platform/mac/metal_renderer.rs @@ -182,49 +182,42 @@ impl MetalRenderer { }); let mut instance_offset = 0; - for layer in scene.layers() { - for batch in layer.batches() { - match batch { - crate::PrimitiveBatch::Quads(quads) => { - self.draw_quads( - quads, - &mut instance_offset, - viewport_size, - command_encoder, - ); - } - crate::PrimitiveBatch::Shadows(shadows) => { - self.draw_shadows( - shadows, - &mut instance_offset, - viewport_size, - command_encoder, - ); - } - crate::PrimitiveBatch::MonochromeSprites { + for batch in scene.batches() { + match batch { + crate::PrimitiveBatch::Quads(quads) => { + self.draw_quads(quads, &mut instance_offset, viewport_size, command_encoder); + } + crate::PrimitiveBatch::Shadows(shadows) => { + self.draw_shadows( + shadows, + &mut instance_offset, + viewport_size, + command_encoder, + ); + } + crate::PrimitiveBatch::MonochromeSprites { + texture_id, + sprites, + } => { + self.draw_monochrome_sprites( texture_id, sprites, - } => { - self.draw_monochrome_sprites( - texture_id, - sprites, - &mut instance_offset, - viewport_size, - command_encoder, - ); - } - crate::PrimitiveBatch::PolychromeSprites { + &mut instance_offset, + viewport_size, + command_encoder, + ); + } + crate::PrimitiveBatch::PolychromeSprites { + texture_id, + sprites, + } => { + self.draw_polychrome_sprites( texture_id, sprites, - } => { - self.draw_polychrome_sprites( - texture_id, - sprites, - &mut instance_offset, - viewport_size, - command_encoder, - ); - } + &mut instance_offset, + viewport_size, + command_encoder, + ); } } } diff --git a/crates/gpui3/src/scene.rs b/crates/gpui3/src/scene.rs index 0dad911383e4f88a4f51d945b10a10753a0e64d8..459d3e55f0a5124d1203af50fa6f8a75b110fd03 100644 --- a/crates/gpui3/src/scene.rs +++ b/crates/gpui3/src/scene.rs @@ -1,18 +1,26 @@ -use std::{iter::Peekable, mem, slice}; - -use super::{Bounds, Hsla, Point}; -use crate::{AtlasTextureId, AtlasTile, Corners, Edges, ScaledContentMask, ScaledPixels}; +use crate::{ + AtlasTextureId, AtlasTile, Bounds, Corners, Edges, Hsla, Point, ScaledContentMask, ScaledPixels, +}; use collections::BTreeMap; +use etagere::euclid::{Point3D, Vector3D}; +use plane_split::{BspSplitter, Polygon as BspPolygon}; use smallvec::SmallVec; +use std::{iter::Peekable, mem, slice}; // Exported to metal pub type PointF = Point; -pub type LayerId = SmallVec<[u32; 16]>; +pub type StackingOrder = SmallVec<[u32; 16]>; +pub type LayerId = u32; +pub type DrawOrder = u32; #[derive(Debug)] pub struct Scene { pub(crate) scale_factor: f32, - pub(crate) layers: BTreeMap, + pub(crate) layers: BTreeMap, + pub quads: Vec, + pub shadows: Vec, + pub monochrome_sprites: Vec, + pub polychrome_sprites: Vec, } impl Scene { @@ -20,6 +28,10 @@ impl Scene { Scene { scale_factor, layers: BTreeMap::new(), + quads: Vec::new(), + shadows: Vec::new(), + monochrome_sprites: Vec::new(), + polychrome_sprites: Vec::new(), } } @@ -27,47 +39,95 @@ impl Scene { Scene { scale_factor: self.scale_factor, layers: mem::take(&mut self.layers), + quads: mem::take(&mut self.quads), + shadows: mem::take(&mut self.shadows), + monochrome_sprites: mem::take(&mut self.monochrome_sprites), + polychrome_sprites: mem::take(&mut self.polychrome_sprites), } } - pub fn insert(&mut self, stacking_order: LayerId, primitive: impl Into) { - let layer = self.layers.entry(stacking_order).or_default(); - + pub fn insert(&mut self, layer_id: StackingOrder, primitive: impl Into) { + let next_id = self.layers.len() as LayerId; + let layer_id = *self.layers.entry(layer_id).or_insert(next_id); let primitive = primitive.into(); match primitive { - Primitive::Quad(quad) => { - layer.quads.push(quad); + Primitive::Quad(mut quad) => { + quad.order = layer_id; + self.quads.push(quad); } - Primitive::Shadow(shadow) => { - layer.shadows.push(shadow); + Primitive::Shadow(mut shadow) => { + shadow.order = layer_id; + self.shadows.push(shadow); } - Primitive::MonochromeSprite(sprite) => { - layer.monochrome_sprites.push(sprite); + Primitive::MonochromeSprite(mut sprite) => { + sprite.order = layer_id; + self.monochrome_sprites.push(sprite); } - Primitive::PolychromeSprite(sprite) => { - layer.polychrome_sprites.push(sprite); + Primitive::PolychromeSprite(mut sprite) => { + sprite.order = layer_id; + self.polychrome_sprites.push(sprite); } } } - pub(crate) fn layers(&mut self) -> impl Iterator { - self.layers.values_mut() - } -} + pub(crate) fn batches(&mut self) -> impl Iterator { + // Map each layer id to a float between 0. and 1., with 1. closer to the viewer. + let mut layer_z_values = vec![0.; self.layers.len()]; + for (ix, layer_id) in self.layers.values().enumerate() { + layer_z_values[*layer_id as usize] = ix as f32 / self.layers.len() as f32; + } -#[derive(Debug, Default)] -pub(crate) struct SceneLayer { - pub quads: Vec, - pub shadows: Vec, - pub monochrome_sprites: Vec, - pub polychrome_sprites: Vec, -} + // Add all primitives to the BSP splitter to determine draw order + let mut splitter = BspSplitter::new(); + for (ix, quad) in self.quads.iter().enumerate() { + let z = layer_z_values[quad.order as LayerId as usize]; + splitter.add(quad.bounds.to_bsp_polygon(z, (PrimitiveKind::Quad, ix))); + } + + for (ix, shadow) in self.shadows.iter().enumerate() { + let z = layer_z_values[shadow.order as LayerId as usize]; + splitter.add(shadow.bounds.to_bsp_polygon(z, (PrimitiveKind::Shadow, ix))); + } + + for (ix, monochrome_sprite) in self.monochrome_sprites.iter().enumerate() { + let z = layer_z_values[monochrome_sprite.order as LayerId as usize]; + splitter.add( + monochrome_sprite + .bounds + .to_bsp_polygon(z, (PrimitiveKind::MonochromeSprite, ix)), + ); + } -impl SceneLayer { - pub fn batches(&mut self) -> impl Iterator { + for (ix, polychrome_sprite) in self.polychrome_sprites.iter().enumerate() { + let z = layer_z_values[polychrome_sprite.order as LayerId as usize]; + splitter.add( + polychrome_sprite + .bounds + .to_bsp_polygon(z, (PrimitiveKind::PolychromeSprite, ix)), + ); + } + + // Sort all polygons, then reassign the order field of each primitive to `draw_order` + // We need primitives to be repr(C), hence the weird reuse of the order field for two different types. + for (draw_order, polygon) in splitter.sort(Vector3D::new(0., 0., 1.)).iter().enumerate() { + match polygon.anchor { + (PrimitiveKind::Quad, ix) => self.quads[ix].order = draw_order as DrawOrder, + (PrimitiveKind::Shadow, ix) => self.shadows[ix].order = draw_order as DrawOrder, + (PrimitiveKind::MonochromeSprite, ix) => { + self.monochrome_sprites[ix].order = draw_order as DrawOrder + } + (PrimitiveKind::PolychromeSprite, ix) => { + self.polychrome_sprites[ix].order = draw_order as DrawOrder + } + } + } + + // Sort the primitives self.quads.sort_unstable(); + self.shadows.sort_unstable(); self.monochrome_sprites.sort_unstable(); self.polychrome_sprites.sort_unstable(); + BatchIterator { quads: &self.quads, quads_start: 0, @@ -104,27 +164,27 @@ impl<'a> Iterator for BatchIterator<'a> { type Item = PrimitiveBatch<'a>; fn next(&mut self) -> Option { - let mut kinds_and_orders = [ - (PrimitiveKind::Quad, self.quads_iter.peek().map(|q| q.order)), + let mut orders_and_kinds = [ + (self.quads_iter.peek().map(|q| q.order), PrimitiveKind::Quad), ( - PrimitiveKind::Shadow, self.shadows_iter.peek().map(|s| s.order), + PrimitiveKind::Shadow, ), ( - PrimitiveKind::MonochromeSprite, self.monochrome_sprites_iter.peek().map(|s| s.order), + PrimitiveKind::MonochromeSprite, ), ( - PrimitiveKind::PolychromeSprite, self.polychrome_sprites_iter.peek().map(|s| s.order), + PrimitiveKind::PolychromeSprite, ), ]; - kinds_and_orders.sort_by_key(|(_, order)| order.unwrap_or(u32::MAX)); + orders_and_kinds.sort_by_key(|(order, kind)| (order.unwrap_or(u32::MAX), *kind)); - let first = kinds_and_orders[0]; - let second = kinds_and_orders[1]; - let (batch_kind, max_order) = if first.1.is_some() { - (first.0, second.1.unwrap_or(u32::MAX)) + let first = orders_and_kinds[0]; + let second = orders_and_kinds[1]; + let (batch_kind, max_order) = if first.0.is_some() { + (first.1, second.0.unwrap_or(u32::MAX)) } else { return None; }; @@ -132,23 +192,27 @@ impl<'a> Iterator for BatchIterator<'a> { match batch_kind { PrimitiveKind::Quad => { let quads_start = self.quads_start; - let quads_end = quads_start - + self - .quads_iter - .by_ref() - .take_while(|quad| quad.order <= max_order) - .count(); + let mut quads_end = quads_start; + while self + .quads_iter + .next_if(|quad| quad.order <= max_order) + .is_some() + { + quads_end += 1; + } self.quads_start = quads_end; Some(PrimitiveBatch::Quads(&self.quads[quads_start..quads_end])) } PrimitiveKind::Shadow => { let shadows_start = self.shadows_start; - let shadows_end = shadows_start - + self - .shadows_iter - .by_ref() - .take_while(|shadow| shadow.order <= max_order) - .count(); + let mut shadows_end = shadows_start; + while self + .shadows_iter + .next_if(|shadow| shadow.order <= max_order) + .is_some() + { + shadows_end += 1; + } self.shadows_start = shadows_end; Some(PrimitiveBatch::Shadows( &self.shadows[shadows_start..shadows_end], @@ -157,14 +221,16 @@ impl<'a> Iterator for BatchIterator<'a> { PrimitiveKind::MonochromeSprite => { let texture_id = self.monochrome_sprites_iter.peek().unwrap().tile.texture_id; let sprites_start = self.monochrome_sprites_start; - let sprites_end = sprites_start - + self - .monochrome_sprites_iter - .by_ref() - .take_while(|sprite| { - sprite.order <= max_order && sprite.tile.texture_id == texture_id - }) - .count(); + let mut sprites_end = sprites_start; + while self + .monochrome_sprites_iter + .next_if(|sprite| { + sprite.order <= max_order && sprite.tile.texture_id == texture_id + }) + .is_some() + { + sprites_end += 1; + } self.monochrome_sprites_start = sprites_end; Some(PrimitiveBatch::MonochromeSprites { texture_id, @@ -174,14 +240,16 @@ impl<'a> Iterator for BatchIterator<'a> { PrimitiveKind::PolychromeSprite => { let texture_id = self.polychrome_sprites_iter.peek().unwrap().tile.texture_id; let sprites_start = self.polychrome_sprites_start; - let sprites_end = sprites_start - + self - .polychrome_sprites_iter - .by_ref() - .take_while(|sprite| { - sprite.order <= max_order && sprite.tile.texture_id == texture_id - }) - .count(); + let mut sprites_end = self.polychrome_sprites_start; + while self + .polychrome_sprites_iter + .next_if(|sprite| { + sprite.order <= max_order && sprite.tile.texture_id == texture_id + }) + .is_some() + { + sprites_end += 1; + } self.polychrome_sprites_start = sprites_end; Some(PrimitiveBatch::PolychromeSprites { texture_id, @@ -192,10 +260,11 @@ impl<'a> Iterator for BatchIterator<'a> { } } -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Default)] pub enum PrimitiveKind { - Quad, Shadow, + #[default] + Quad, MonochromeSprite, PolychromeSprite, } @@ -222,10 +291,10 @@ pub(crate) enum PrimitiveBatch<'a> { }, } -#[derive(Debug, Clone, Eq, PartialEq)] +#[derive(Default, Debug, Clone, Eq, PartialEq)] #[repr(C)] pub struct Quad { - pub order: u32, + pub order: u32, // Initially a LayerId, then a DrawOrder. pub bounds: Bounds, pub content_mask: ScaledContentMask, pub background: Hsla, @@ -346,3 +415,76 @@ impl From for Primitive { #[derive(Copy, Clone, Debug)] pub struct AtlasId(pub(crate) usize); + +impl Bounds { + fn to_bsp_polygon(&self, z: f32, anchor: A) -> BspPolygon { + let upper_left = self.origin; + let upper_right = self.upper_right(); + let lower_right = self.lower_right(); + let lower_left = self.lower_left(); + + BspPolygon::from_points( + [ + Point3D::new(upper_left.x.into(), upper_left.y.into(), z as f64), + Point3D::new(upper_right.x.into(), upper_right.y.into(), z as f64), + Point3D::new(lower_right.x.into(), lower_right.y.into(), z as f64), + Point3D::new(lower_left.x.into(), lower_left.y.into(), z as f64), + ], + anchor, + ) + .expect("Polygon should not be empty") + } +} + +#[cfg(test)] +mod tests { + use crate::{point, size}; + + use super::*; + use smallvec::smallvec; + + #[test] + fn test_scene() { + let mut scene = Scene::new(1.0); + assert_eq!(scene.layers.len(), 0); + + scene.insert(smallvec![1], quad()); + scene.insert(smallvec![2], shadow()); + scene.insert(smallvec![3], quad()); + + let mut batches_count = 0; + for _ in scene.batches() { + batches_count += 1; + } + assert_eq!(batches_count, 3); + } + + fn quad() -> Quad { + Quad { + order: 0, + bounds: Bounds { + origin: point(ScaledPixels(0.), ScaledPixels(0.)), + size: size(ScaledPixels(100.), ScaledPixels(100.)), + }, + content_mask: Default::default(), + background: Default::default(), + border_color: Default::default(), + corner_radii: Default::default(), + border_widths: Default::default(), + } + } + + fn shadow() -> Shadow { + Shadow { + order: Default::default(), + bounds: Bounds { + origin: point(ScaledPixels(0.), ScaledPixels(0.)), + size: size(ScaledPixels(100.), ScaledPixels(100.)), + }, + corner_radii: Default::default(), + content_mask: Default::default(), + color: Default::default(), + blur_radius: Default::default(), + } + } +} diff --git a/crates/gpui3/src/style.rs b/crates/gpui3/src/style.rs index 3caaaf491d27288a224f5f12822be033a6dde066..50d9260e1f8d2133fa2931c29607818777fccb3c 100644 --- a/crates/gpui3/src/style.rs +++ b/crates/gpui3/src/style.rs @@ -246,46 +246,50 @@ impl Style { let scale = cx.scale_factor(); for shadow in &self.box_shadow { - let layer_id = cx.current_layer_id(); let content_mask = cx.content_mask(); let mut shadow_bounds = bounds; shadow_bounds.origin += shadow.offset; shadow_bounds.dilate(shadow.spread_radius); - cx.scene().insert( - layer_id, - Shadow { - order, - bounds: shadow_bounds.scale(scale), - content_mask: content_mask.scale(scale), - corner_radii: self - .corner_radii - .to_pixels(shadow_bounds.size, rem_size) - .scale(scale), - color: shadow.color, - blur_radius: shadow.blur_radius.scale(scale), - }, - ); + cx.stack(0, |cx| { + let layer_id = cx.current_stacking_order(); + cx.scene().insert( + layer_id, + Shadow { + order: 0, + bounds: shadow_bounds.scale(scale), + content_mask: content_mask.scale(scale), + corner_radii: self + .corner_radii + .to_pixels(shadow_bounds.size, rem_size) + .scale(scale), + color: shadow.color, + blur_radius: shadow.blur_radius.scale(scale), + }, + ); + }) } let background_color = self.fill.as_ref().and_then(Fill::color); if background_color.is_some() || self.is_border_visible() { - let layer_id = cx.current_layer_id(); let content_mask = cx.content_mask(); - cx.scene().insert( - layer_id, - Quad { + cx.stack(1, |cx| { + let order = cx.current_stacking_order(); + cx.scene().insert( order, - bounds: bounds.scale(scale), - content_mask: content_mask.scale(scale), - background: background_color.unwrap_or_default(), - border_color: self.border_color.unwrap_or_default(), - corner_radii: self - .corner_radii - .to_pixels(bounds.size, rem_size) - .scale(scale), - border_widths: self.border_widths.to_pixels(rem_size).scale(scale), - }, - ); + Quad { + order: 0, + bounds: bounds.scale(scale), + content_mask: content_mask.scale(scale), + background: background_color.unwrap_or_default(), + border_color: self.border_color.unwrap_or_default(), + corner_radii: self + .corner_radii + .to_pixels(bounds.size, rem_size) + .scale(scale), + border_widths: self.border_widths.to_pixels(rem_size).scale(scale), + }, + ); + }); } } diff --git a/crates/gpui3/src/style_helpers.rs b/crates/gpui3/src/style_helpers.rs index 6bcbc69df09e56457aeef220f3060c5170f6b206..148a12fc9c42f3fdac7f51c0d183cee3859cfe73 100644 --- a/crates/gpui3/src/style_helpers.rs +++ b/crates/gpui3/src/style_helpers.rs @@ -263,7 +263,7 @@ pub trait StyleHelpers: Styled