From f6d31917c15d1328991ccae317964190b309f1ff Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 19 Dec 2023 17:05:39 +0200 Subject: [PATCH] Optimize stack id in-memory layout --- crates/gpui2/src/scene.rs | 212 ++++++++++++++++++------------------- crates/gpui2/src/window.rs | 66 ++++-------- 2 files changed, 129 insertions(+), 149 deletions(-) diff --git a/crates/gpui2/src/scene.rs b/crates/gpui2/src/scene.rs index 15a4a37d5b..517632ed79 100644 --- a/crates/gpui2/src/scene.rs +++ b/crates/gpui2/src/scene.rs @@ -857,116 +857,116 @@ impl Bounds { } } -#[cfg(test)] -mod tests { - use super::*; - use crate::{point, px, size, Size}; - use smallvec::smallvec; +// todo!() +// #[cfg(test)] +// mod tests { +// use super::*; +// use crate::{point, px, size, Size}; +// use smallvec::smallvec; - // todo!() - // #[test] - // fn test_scene() { - // let mut scene = SceneBuilder::default(); - // assert_eq!(scene.layers_by_order.len(), 0); +// #[test] +// fn test_scene() { +// let mut scene = SceneBuilder::default(); +// assert_eq!(scene.layers_by_order.len(), 0); - // // div with z_index(1) - // // glyph with z_index(1) - // // div with z_index(1) - // // glyph with z_index(1) +// // div with z_index(1) +// // glyph with z_index(1) +// // div with z_index(1) +// // glyph with z_index(1) - // scene.insert( - // &smallvec![1].into(), - // quad( - // point(px(0.), px(0.)), - // size(px(100.), px(100.)), - // crate::black(), - // ), - // ); - // scene.insert( - // &smallvec![1, 1].into(), - // sprite( - // point(px(0.), px(0.)), - // size(px(10.), px(10.)), - // crate::white(), - // ), - // ); - // scene.insert( - // &smallvec![1].into(), - // quad( - // point(px(10.), px(10.)), - // size(px(20.), px(20.)), - // crate::green(), - // ), - // ); - // scene.insert( - // &smallvec![1, 1].into(), - // sprite(point(px(15.), px(15.)), size(px(5.), px(5.)), crate::blue()), - // ); +// scene.insert( +// &smallvec![1].into(), +// quad( +// point(px(0.), px(0.)), +// size(px(100.), px(100.)), +// crate::black(), +// ), +// ); +// scene.insert( +// &smallvec![1, 1].into(), +// sprite( +// point(px(0.), px(0.)), +// size(px(10.), px(10.)), +// crate::white(), +// ), +// ); +// scene.insert( +// &smallvec![1].into(), +// quad( +// point(px(10.), px(10.)), +// size(px(20.), px(20.)), +// crate::green(), +// ), +// ); +// scene.insert( +// &smallvec![1, 1].into(), +// sprite(point(px(15.), px(15.)), size(px(5.), px(5.)), crate::blue()), +// ); - // assert!(!scene.layers_by_order.is_empty()); +// assert!(!scene.layers_by_order.is_empty()); - // for batch in scene.build().batches() { - // println!("new batch"); - // match batch { - // PrimitiveBatch::Quads(quads) => { - // for quad in quads { - // if quad.background == crate::black() { - // println!(" black quad"); - // } else if quad.background == crate::green() { - // println!(" green quad"); - // } else { - // todo!(" ((( bad quad"); - // } - // } - // } - // PrimitiveBatch::MonochromeSprites { sprites, .. } => { - // for sprite in sprites { - // if sprite.color == crate::white() { - // println!(" white sprite"); - // } else if sprite.color == crate::blue() { - // println!(" blue sprite"); - // } else { - // todo!(" ((( bad sprite") - // } - // } - // } - // _ => todo!(), - // } - // } - // } +// for batch in scene.build().batches() { +// println!("new batch"); +// match batch { +// PrimitiveBatch::Quads(quads) => { +// for quad in quads { +// if quad.background == crate::black() { +// println!(" black quad"); +// } else if quad.background == crate::green() { +// println!(" green quad"); +// } else { +// todo!(" ((( bad quad"); +// } +// } +// } +// PrimitiveBatch::MonochromeSprites { sprites, .. } => { +// for sprite in sprites { +// if sprite.color == crate::white() { +// println!(" white sprite"); +// } else if sprite.color == crate::blue() { +// println!(" blue sprite"); +// } else { +// todo!(" ((( bad sprite") +// } +// } +// } +// _ => todo!(), +// } +// } +// } - fn quad(origin: Point, size: Size, background: Hsla) -> Quad { - Quad { - order: 0, - bounds: Bounds { origin, size }.scale(1.), - background, - content_mask: ContentMask { - bounds: Bounds { origin, size }, - } - .scale(1.), - border_color: Default::default(), - corner_radii: Default::default(), - border_widths: Default::default(), - } - } +// fn quad(origin: Point, size: Size, background: Hsla) -> Quad { +// Quad { +// order: 0, +// bounds: Bounds { origin, size }.scale(1.), +// background, +// content_mask: ContentMask { +// bounds: Bounds { origin, size }, +// } +// .scale(1.), +// border_color: Default::default(), +// corner_radii: Default::default(), +// border_widths: Default::default(), +// } +// } - fn sprite(origin: Point, size: Size, color: Hsla) -> MonochromeSprite { - MonochromeSprite { - order: 0, - bounds: Bounds { origin, size }.scale(1.), - content_mask: ContentMask { - bounds: Bounds { origin, size }, - } - .scale(1.), - color, - tile: AtlasTile { - texture_id: AtlasTextureId { - index: 0, - kind: crate::AtlasTextureKind::Monochrome, - }, - tile_id: crate::TileId(0), - bounds: Default::default(), - }, - } - } -} +// fn sprite(origin: Point, size: Size, color: Hsla) -> MonochromeSprite { +// MonochromeSprite { +// order: 0, +// bounds: Bounds { origin, size }.scale(1.), +// content_mask: ContentMask { +// bounds: Bounds { origin, size }, +// } +// .scale(1.), +// color, +// tile: AtlasTile { +// texture_id: AtlasTextureId { +// index: 0, +// kind: crate::AtlasTextureKind::Monochrome, +// }, +// tile_id: crate::TileId(0), +// bounds: Default::default(), +// }, +// } +// } +// } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 5d06cfe1a5..ddda9f0302 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -39,7 +39,7 @@ use std::{ Arc, }, }; -use util::{post_inc, ResultExt}; +use util::ResultExt; const ACTIVE_DRAG_Z_INDEX: u8 = 1; @@ -49,25 +49,21 @@ const ACTIVE_DRAG_Z_INDEX: u8 = 1; pub struct StackingOrder { #[deref] #[deref_mut] - context_stack: SmallVec<[StackingContext; 64]>, -} - -#[derive(Clone, Ord, PartialOrd, PartialEq, Eq)] -pub struct StackingContext { - // TODO kb use u16 and/or try to push the `id` above into the stacking order - z_index: u8, - id: u16, + context_stack: SmallVec<[u8; 64]>, + id: u32, } impl std::fmt::Debug for StackingOrder { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut stacks = self.context_stack.iter().peekable(); + write!(f, "[({}): ", self.id)?; while let Some(z_index) = stacks.next() { - write!(f, "{}.{}", z_index.z_index, z_index.id)?; + write!(f, "{z_index}")?; if stacks.peek().is_some() { write!(f, "->")?; } } + write!(f, "]")?; Ok(()) } } @@ -296,7 +292,7 @@ pub(crate) struct Frame { pub(crate) scene_builder: SceneBuilder, pub(crate) depth_map: Vec<(StackingOrder, Bounds)>, pub(crate) z_index_stack: StackingOrder, - pub(crate) stacking_context_id_stack: Vec, + pub(crate) next_stacking_order_id: u32, content_mask_stack: Vec>, element_offset_stack: Vec>, } @@ -310,7 +306,7 @@ impl Frame { dispatch_tree, scene_builder: SceneBuilder::default(), z_index_stack: StackingOrder::default(), - stacking_context_id_stack: vec![0], + next_stacking_order_id: 0, depth_map: Default::default(), content_mask_stack: Vec::new(), element_offset_stack: Vec::new(), @@ -322,8 +318,7 @@ impl Frame { self.mouse_listeners.values_mut().for_each(Vec::clear); self.dispatch_tree.clear(); self.depth_map.clear(); - self.stacking_context_id_stack.clear(); - self.stacking_context_id_stack.push(0); + self.next_stacking_order_id = 0; } fn focus_path(&self) -> SmallVec<[FocusId; 8]> { @@ -947,20 +942,14 @@ impl<'a> WindowContext<'a> { /// Called during painting to invoke the given closure in a new stacking context. The given /// z-index is interpreted relative to the previous call to `stack`. pub fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { - let id = post_inc( - self.window - .next_frame - .stacking_context_id_stack - .last_mut() - .unwrap(), - ); - self.window.next_frame.stacking_context_id_stack.push(0); - self.window - .next_frame - .z_index_stack - .push(StackingContext { z_index, id }); + let new_stacking_order_id = self.window.next_frame.next_stacking_order_id; + let new_next_stacking_order_id = new_stacking_order_id + 1; + + self.window.next_frame.next_stacking_order_id = 0; + self.window.next_frame.z_index_stack.id = new_stacking_order_id; + self.window.next_frame.z_index_stack.push(z_index); let result = f(self); - self.window.next_frame.stacking_context_id_stack.pop(); + self.window.next_frame.next_stacking_order_id = new_next_stacking_order_id; self.window.next_frame.z_index_stack.pop(); result } @@ -2077,23 +2066,14 @@ pub trait BorrowWindow: BorrowMut + BorrowMut { /// Called during painting to invoke the given closure in a new stacking context. The given /// z-index is interpreted relative to the previous call to `stack`. fn with_z_index(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R { - let id = post_inc( - self.window_mut() - .next_frame - .stacking_context_id_stack - .last_mut() - .unwrap(), - ); - self.window_mut() - .next_frame - .stacking_context_id_stack - .push(0); - self.window_mut() - .next_frame - .z_index_stack - .push(StackingContext { z_index, id }); + let new_stacking_order_id = self.window_mut().next_frame.next_stacking_order_id; + let new_next_stacking_order_id = new_stacking_order_id + 1; + + self.window_mut().next_frame.next_stacking_order_id = 0; + self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id; + self.window_mut().next_frame.z_index_stack.push(z_index); let result = f(self); - self.window_mut().next_frame.stacking_context_id_stack.pop(); + self.window_mut().next_frame.next_stacking_order_id = new_next_stacking_order_id; self.window_mut().next_frame.z_index_stack.pop(); result }