diff --git a/crates/gpui/src/app/entity_map.rs b/crates/gpui/src/app/entity_map.rs index 17f6e47ddf..482a003fe7 100644 --- a/crates/gpui/src/app/entity_map.rs +++ b/crates/gpui/src/app/entity_map.rs @@ -2,7 +2,7 @@ use crate::{seal::Sealed, AppContext, Context, Entity, ModelContext}; use anyhow::{anyhow, Result}; use derive_more::{Deref, DerefMut}; use parking_lot::{RwLock, RwLockUpgradableReadGuard}; -use slotmap::{SecondaryMap, SlotMap}; +use slotmap::{KeyData, SecondaryMap, SlotMap}; use std::{ any::{type_name, Any, TypeId}, fmt::{self, Display}, @@ -21,6 +21,12 @@ use collections::HashMap; slotmap::new_key_type! { pub struct EntityId; } +impl From for EntityId { + fn from(value: u64) -> Self { + Self(KeyData::from_ffi(value)) + } +} + impl EntityId { pub fn as_u64(self) -> u64 { self.0.as_ffi() diff --git a/crates/gpui/src/key_dispatch.rs b/crates/gpui/src/key_dispatch.rs index c6abc101ea..168b1da9fe 100644 --- a/crates/gpui/src/key_dispatch.rs +++ b/crates/gpui/src/key_dispatch.rs @@ -144,6 +144,8 @@ impl DispatchTree { if source_node.parent != Some(*source_ancestor) { source_stack.pop(); self.pop_node(); + } else { + break; } } @@ -159,6 +161,7 @@ impl DispatchTree { } while !source_stack.is_empty() { + source_stack.pop(); self.pop_node(); } diff --git a/crates/gpui/src/scene.rs b/crates/gpui/src/scene.rs index 42183100b7..9c63f80325 100644 --- a/crates/gpui/src/scene.rs +++ b/crates/gpui/src/scene.rs @@ -1,9 +1,9 @@ use crate::{ - point, AtlasTextureId, AtlasTile, Bounds, ContentMask, Corners, Edges, Hsla, Pixels, Point, - ScaledPixels, StackingOrder, + point, AtlasTextureId, AtlasTile, Bounds, ContentMask, Corners, Edges, EntityId, Hsla, Pixels, + Point, ScaledPixels, StackingOrder, }; -use collections::BTreeMap; -use std::{fmt::Debug, iter::Peekable, mem, slice}; +use collections::{BTreeMap, FxHashSet}; +use std::{fmt::Debug, iter::Peekable, slice}; // Exported to metal pub(crate) type PointF = Point; @@ -14,7 +14,7 @@ pub type LayerId = u32; pub type DrawOrder = u32; #[derive(Default)] -pub(crate) struct SceneBuilder { +pub struct Scene { layers_by_order: BTreeMap, orders_by_layer: BTreeMap, shadows: Vec, @@ -26,57 +26,46 @@ pub(crate) struct SceneBuilder { surfaces: Vec, } -impl SceneBuilder { - pub fn build(&mut self) -> Scene { - let mut orders = vec![0; self.layers_by_order.len()]; - for (ix, layer_id) in self.layers_by_order.values().enumerate() { - orders[*layer_id as usize] = ix as u32; - } +impl Scene { + pub fn clear(&mut self) { self.layers_by_order.clear(); + self.orders_by_layer.clear(); + self.shadows.clear(); + self.quads.clear(); + self.paths.clear(); + self.underlines.clear(); + self.monochrome_sprites.clear(); + self.polychrome_sprites.clear(); + self.surfaces.clear(); + } - for shadow in &mut self.shadows { - shadow.order = orders[shadow.layer_id as usize]; - } - self.shadows.sort_by_key(|shadow| shadow.order); + pub fn paths(&self) -> &[Path] { + &self.paths + } - for quad in &mut self.quads { - quad.order = orders[quad.layer_id as usize]; - } - self.quads.sort_by_key(|quad| quad.order); - - for path in &mut self.paths { - path.order = orders[path.layer_id as usize]; - } - self.paths.sort_by_key(|path| path.order); - - for underline in &mut self.underlines { - underline.order = orders[underline.layer_id as usize]; - } - self.underlines.sort_by_key(|underline| underline.order); - - for monochrome_sprite in &mut self.monochrome_sprites { - monochrome_sprite.order = orders[monochrome_sprite.layer_id as usize]; - } - self.monochrome_sprites.sort_by_key(|sprite| sprite.order); - - for polychrome_sprite in &mut self.polychrome_sprites { - polychrome_sprite.order = orders[polychrome_sprite.layer_id as usize]; - } - self.polychrome_sprites.sort_by_key(|sprite| sprite.order); - - for surface in &mut self.surfaces { - surface.order = orders[surface.layer_id as usize]; - } - self.surfaces.sort_by_key(|surface| surface.order); - - Scene { - shadows: mem::take(&mut self.shadows), - quads: mem::take(&mut self.quads), - paths: mem::take(&mut self.paths), - underlines: mem::take(&mut self.underlines), - monochrome_sprites: mem::take(&mut self.monochrome_sprites), - polychrome_sprites: mem::take(&mut self.polychrome_sprites), - surfaces: mem::take(&mut self.surfaces), + pub(crate) fn batches(&self) -> impl Iterator { + BatchIterator { + shadows: &self.shadows, + shadows_start: 0, + shadows_iter: self.shadows.iter().peekable(), + quads: &self.quads, + quads_start: 0, + quads_iter: self.quads.iter().peekable(), + paths: &self.paths, + paths_start: 0, + paths_iter: self.paths.iter().peekable(), + underlines: &self.underlines, + underlines_start: 0, + underlines_iter: self.underlines.iter().peekable(), + monochrome_sprites: &self.monochrome_sprites, + monochrome_sprites_start: 0, + monochrome_sprites_iter: self.monochrome_sprites.iter().peekable(), + polychrome_sprites: &self.polychrome_sprites, + polychrome_sprites_start: 0, + polychrome_sprites_iter: self.polychrome_sprites.iter().peekable(), + surfaces: &self.surfaces, + surfaces_start: 0, + surfaces_iter: self.surfaces.iter().peekable(), } } @@ -135,47 +124,98 @@ impl SceneBuilder { next_id } } -} -pub struct Scene { - pub shadows: Vec, - pub quads: Vec, - pub paths: Vec>, - pub underlines: Vec, - pub monochrome_sprites: Vec, - pub polychrome_sprites: Vec, - pub surfaces: Vec, -} + pub fn insert_views_from_scene(&mut self, views: &FxHashSet, prev_scene: &mut Self) { + for shadow in prev_scene.shadows.drain(..) { + if views.contains(&EntityId::from(shadow.view_id as u64)) { + let order = &prev_scene.orders_by_layer[&shadow.layer_id]; + self.insert(&order, shadow); + } + } -impl Scene { - pub fn paths(&self) -> &[Path] { - &self.paths + for quad in prev_scene.quads.drain(..) { + if views.contains(&EntityId::from(quad.view_id as u64)) { + let order = &prev_scene.orders_by_layer[&quad.layer_id]; + self.insert(&order, quad); + } + } + + for path in prev_scene.paths.drain(..) { + if views.contains(&EntityId::from(path.view_id as u64)) { + let order = &prev_scene.orders_by_layer[&path.layer_id]; + self.insert(&order, path); + } + } + + for underline in prev_scene.underlines.drain(..) { + if views.contains(&EntityId::from(underline.view_id as u64)) { + let order = &prev_scene.orders_by_layer[&underline.layer_id]; + self.insert(&order, underline); + } + } + + for sprite in prev_scene.monochrome_sprites.drain(..) { + if views.contains(&EntityId::from(sprite.view_id as u64)) { + let order = &prev_scene.orders_by_layer[&sprite.layer_id]; + self.insert(&order, sprite); + } + } + + for sprite in prev_scene.polychrome_sprites.drain(..) { + if views.contains(&EntityId::from(sprite.view_id as u64)) { + let order = &prev_scene.orders_by_layer[&sprite.layer_id]; + self.insert(&order, sprite); + } + } + + for surface in prev_scene.surfaces.drain(..) { + if views.contains(&EntityId::from(surface.view_id as u64)) { + let order = &prev_scene.orders_by_layer[&surface.layer_id]; + self.insert(&order, surface); + } + } } - pub(crate) fn batches(&self) -> impl Iterator { - BatchIterator { - shadows: &self.shadows, - shadows_start: 0, - shadows_iter: self.shadows.iter().peekable(), - quads: &self.quads, - quads_start: 0, - quads_iter: self.quads.iter().peekable(), - paths: &self.paths, - paths_start: 0, - paths_iter: self.paths.iter().peekable(), - underlines: &self.underlines, - underlines_start: 0, - underlines_iter: self.underlines.iter().peekable(), - monochrome_sprites: &self.monochrome_sprites, - monochrome_sprites_start: 0, - monochrome_sprites_iter: self.monochrome_sprites.iter().peekable(), - polychrome_sprites: &self.polychrome_sprites, - polychrome_sprites_start: 0, - polychrome_sprites_iter: self.polychrome_sprites.iter().peekable(), - surfaces: &self.surfaces, - surfaces_start: 0, - surfaces_iter: self.surfaces.iter().peekable(), + pub fn finish(&mut self) { + let mut orders = vec![0; self.layers_by_order.len()]; + for (ix, layer_id) in self.layers_by_order.values().enumerate() { + orders[*layer_id as usize] = ix as u32; } + + for shadow in &mut self.shadows { + shadow.order = orders[shadow.layer_id as usize]; + } + self.shadows.sort_by_key(|shadow| shadow.order); + + for quad in &mut self.quads { + quad.order = orders[quad.layer_id as usize]; + } + self.quads.sort_by_key(|quad| quad.order); + + for path in &mut self.paths { + path.order = orders[path.layer_id as usize]; + } + self.paths.sort_by_key(|path| path.order); + + for underline in &mut self.underlines { + underline.order = orders[underline.layer_id as usize]; + } + self.underlines.sort_by_key(|underline| underline.order); + + for monochrome_sprite in &mut self.monochrome_sprites { + monochrome_sprite.order = orders[monochrome_sprite.layer_id as usize]; + } + self.monochrome_sprites.sort_by_key(|sprite| sprite.order); + + for polychrome_sprite in &mut self.polychrome_sprites { + polychrome_sprite.order = orders[polychrome_sprite.layer_id as usize]; + } + self.polychrome_sprites.sort_by_key(|sprite| sprite.order); + + for surface in &mut self.surfaces { + surface.order = orders[surface.layer_id as usize]; + } + self.surfaces.sort_by_key(|surface| surface.order); } } diff --git a/crates/gpui/src/view.rs b/crates/gpui/src/view.rs index 24bc00ce39..d049c47258 100644 --- a/crates/gpui/src/view.rs +++ b/crates/gpui/src/view.rs @@ -231,7 +231,7 @@ impl AnyView { cx.with_absolute_element_offset(origin, |cx| { let (layout_id, mut rendered_element) = (self.request_layout)(self, cx); cx.compute_layout(layout_id, available_space); - rendered_element.paint(cx); + cx.with_view_id(self.entity_id(), |cx| rendered_element.paint(cx)); }) } } diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 8f9a82672d..45dc197e18 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -7,9 +7,9 @@ use crate::{ Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams, - RenderSvgParams, ScaledPixels, Scene, SceneBuilder, Shadow, SharedString, Size, Style, - SubscriberSet, Subscription, Surface, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, - VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS, + RenderSvgParams, ScaledPixels, Scene, Shadow, SharedString, Size, Style, SubscriberSet, + Subscription, Surface, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext, + WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS, }; use anyhow::{anyhow, Context as _, Result}; use collections::{FxHashMap, FxHashSet}; @@ -289,7 +289,7 @@ pub(crate) struct Frame { pub(crate) element_states: FxHashMap, mouse_listeners: FxHashMap>, pub(crate) dispatch_tree: DispatchTree, - pub(crate) scene_builder: SceneBuilder, + pub(crate) scene: Scene, pub(crate) depth_map: Vec<(StackingOrder, Bounds)>, pub(crate) z_index_stack: StackingOrder, pub(crate) next_stacking_order_id: u32, @@ -305,7 +305,7 @@ impl Frame { element_states: FxHashMap::default(), mouse_listeners: FxHashMap::default(), dispatch_tree, - scene_builder: SceneBuilder::default(), + scene: Scene::default(), z_index_stack: StackingOrder::default(), next_stacking_order_id: 0, depth_map: Default::default(), @@ -322,6 +322,7 @@ impl Frame { self.depth_map.clear(); self.next_stacking_order_id = 0; self.reused_views.clear(); + self.scene.clear(); } fn focus_path(&self) -> SmallVec<[FocusId; 8]> { @@ -1028,7 +1029,7 @@ impl<'a> WindowContext<'a> { let mut shadow_bounds = bounds; shadow_bounds.origin += shadow.offset; shadow_bounds.dilate(shadow.spread_radius); - window.next_frame.scene_builder.insert( + window.next_frame.scene.insert( &window.next_frame.z_index_stack, Shadow { view_id: view_id.as_u64() as u32, @@ -1053,7 +1054,7 @@ impl<'a> WindowContext<'a> { let view_id = self.active_view_id(); let window = &mut *self.window; - window.next_frame.scene_builder.insert( + window.next_frame.scene.insert( &window.next_frame.z_index_stack, Quad { view_id: view_id.as_u64() as u32, @@ -1081,7 +1082,7 @@ impl<'a> WindowContext<'a> { let window = &mut *self.window; window .next_frame - .scene_builder + .scene .insert(&window.next_frame.z_index_stack, path.scale(scale_factor)); } @@ -1106,7 +1107,7 @@ impl<'a> WindowContext<'a> { let view_id = self.active_view_id(); let window = &mut *self.window; - window.next_frame.scene_builder.insert( + window.next_frame.scene.insert( &window.next_frame.z_index_stack, Underline { view_id: view_id.as_u64() as u32, @@ -1162,7 +1163,7 @@ impl<'a> WindowContext<'a> { let content_mask = self.content_mask().scale(scale_factor); let view_id = self.active_view_id(); let window = &mut *self.window; - window.next_frame.scene_builder.insert( + window.next_frame.scene.insert( &window.next_frame.z_index_stack, MonochromeSprite { view_id: view_id.as_u64() as u32, @@ -1216,7 +1217,7 @@ impl<'a> WindowContext<'a> { let view_id = self.active_view_id(); let window = &mut *self.window; - window.next_frame.scene_builder.insert( + window.next_frame.scene.insert( &window.next_frame.z_index_stack, PolychromeSprite { view_id: view_id.as_u64() as u32, @@ -1261,7 +1262,7 @@ impl<'a> WindowContext<'a> { let view_id = self.active_view_id(); let window = &mut *self.window; - window.next_frame.scene_builder.insert( + window.next_frame.scene.insert( &window.next_frame.z_index_stack, MonochromeSprite { view_id: view_id.as_u64() as u32, @@ -1300,7 +1301,7 @@ impl<'a> WindowContext<'a> { let view_id = self.active_view_id(); let window = &mut *self.window; - window.next_frame.scene_builder.insert( + window.next_frame.scene.insert( &window.next_frame.z_index_stack, PolychromeSprite { view_id: view_id.as_u64() as u32, @@ -1323,7 +1324,7 @@ impl<'a> WindowContext<'a> { let content_mask = self.content_mask().scale(scale_factor); let view_id = self.active_view_id(); let window = &mut *self.window; - window.next_frame.scene_builder.insert( + window.next_frame.scene.insert( &window.next_frame.z_index_stack, Surface { view_id: view_id.as_u64() as u32, @@ -1337,6 +1338,7 @@ impl<'a> WindowContext<'a> { } pub(crate) fn reuse_geometry(&mut self) { + println!("reusing geometry"); let view_id = self.active_view_id(); let window = &mut self.window; let grafted_view_ids = window @@ -1407,6 +1409,11 @@ impl<'a> WindowContext<'a> { }); } self.window.dirty_views.clear(); + self.window.next_frame.scene.insert_views_from_scene( + &self.window.next_frame.reused_views, + &mut self.window.rendered_frame.scene, + ); + self.window.next_frame.scene.finish(); self.window .next_frame @@ -1454,8 +1461,6 @@ impl<'a> WindowContext<'a> { .retain(&(), |listener| listener(&event, self)); } - let scene = self.window.rendered_frame.scene_builder.build(); - // Set the cursor only if we're the active window. let cursor_style = self .window @@ -1469,7 +1474,9 @@ impl<'a> WindowContext<'a> { self.window.drawing = false; ELEMENT_ARENA.with_borrow_mut(|element_arena| element_arena.clear()); - self.window.platform_window.draw(&scene); + self.window + .platform_window + .draw(&self.window.rendered_frame.scene); } /// Dispatch a mouse or keyboard event on the window.