From 37efe82c5e5f98978b386df85b3be61ccc83b078 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 18 Dec 2023 19:35:17 +0100 Subject: [PATCH] Use a different frame arena for all elements Co-Authored-By: Nathan Sobo Co-Authored-By: Max Brunsfeld --- crates/gpui2/src/arena.rs | 4 +++ crates/gpui2/src/element.rs | 7 ++-- crates/gpui2/src/window.rs | 70 ++++++++++++++++++++----------------- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/crates/gpui2/src/arena.rs b/crates/gpui2/src/arena.rs index c99f09d29f46e33117698cfc8ffbacaa239c9e9e..24434153fb344b442d7c2652f3da25b4811d48a2 100644 --- a/crates/gpui2/src/arena.rs +++ b/crates/gpui2/src/arena.rs @@ -78,6 +78,10 @@ impl Arena { } } } + + pub fn size(&self) -> usize { + self.offset + } } impl Drop for Arena { diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index 6f739d8e33ac93972401508039a8d9e9db3e5c52..d0ed50a3d54780130a0894b77c35493b0278e344 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -1,6 +1,6 @@ use crate::{ - frame_alloc, ArenaRef, AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, - Point, Size, ViewContext, WindowContext, + ArenaRef, AvailableSpace, BorrowWindow, Bounds, ElementId, LayoutId, Pixels, Point, Size, + ViewContext, WindowContext, ELEMENT_ARENA, }; use derive_more::{Deref, DerefMut}; pub(crate) use smallvec::SmallVec; @@ -413,7 +413,8 @@ impl AnyElement { E: 'static + Element, E::State: Any, { - let element = frame_alloc(|| Some(DrawableElement::new(element))) + let element = ELEMENT_ARENA + .with_borrow_mut(|arena| arena.alloc(|| Some(DrawableElement::new(element)))) .map(|element| element as &mut dyn ElementObject); AnyElement(element) } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index e00c707de34f5a098cc4539aa3a75568969b21d9..0cef1644605a977417efffb43dca42263884d172 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -99,12 +99,7 @@ struct FocusEvent { slotmap::new_key_type! { pub struct FocusId; } thread_local! { - pub static FRAME_ARENA: RefCell> = RefCell::new(None); -} - -#[inline(always)] -pub(crate) fn frame_alloc(f: impl FnOnce() -> T) -> ArenaRef { - FRAME_ARENA.with_borrow_mut(|arena| arena.as_mut().unwrap().alloc(f)) + pub(crate) static ELEMENT_ARENA: RefCell = RefCell::new(Arena::new(4 * 1024 * 1024)); } impl FocusId { @@ -254,7 +249,7 @@ pub struct Window { pub(crate) element_id_stack: GlobalElementId, pub(crate) rendered_frame: Frame, pub(crate) next_frame: Frame, - frame_arena: Option, + frame_arena: Arena, pub(crate) focus_handles: Arc>>, focus_listeners: SubscriberSet<(), AnyWindowFocusListener>, blur_listeners: SubscriberSet<(), AnyObserver>, @@ -398,7 +393,7 @@ impl Window { element_id_stack: GlobalElementId::default(), rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), - frame_arena: Some(Arena::new(16 * 1024 * 1024)), + frame_arena: Arena::new(1 * 1024 * 1024), focus_handles: Arc::new(RwLock::new(SlotMap::with_key())), focus_listeners: SubscriberSet::new(), blur_listeners: SubscriberSet::new(), @@ -836,12 +831,15 @@ impl<'a> WindowContext<'a> { mut handler: impl FnMut(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { let order = self.window.next_frame.z_index_stack.clone(); - let handler = frame_alloc(|| { - move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { - handler(event.downcast_ref().unwrap(), phase, cx) - } - }) - .map(|handler| handler as _); + let handler = self + .window + .frame_arena + .alloc(|| { + move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| { + handler(event.downcast_ref().unwrap(), phase, cx) + } + }) + .map(|handler| handler as _); self.window .next_frame .mouse_listeners @@ -860,14 +858,17 @@ impl<'a> WindowContext<'a> { &mut self, listener: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static, ) { - let listener = frame_alloc(|| { - move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { - if let Some(event) = event.downcast_ref::() { - listener(event, phase, cx) + let listener = self + .window + .frame_arena + .alloc(|| { + move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| { + if let Some(event) = event.downcast_ref::() { + listener(event, phase, cx) + } } - } - }) - .map(|handler| handler as _); + }) + .map(|handler| handler as _); self.window.next_frame.dispatch_tree.on_key_event(listener); } @@ -882,7 +883,11 @@ impl<'a> WindowContext<'a> { action_type: TypeId, listener: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static, ) { - let listener = frame_alloc(|| listener).map(|handler| handler as _); + let listener = self + .window + .frame_arena + .alloc(|| listener) + .map(|handler| handler as _); self.window .next_frame .dispatch_tree @@ -1280,21 +1285,22 @@ impl<'a> WindowContext<'a> { self.window.platform_window.clear_input_handler(); self.window.layout_engine.as_mut().unwrap().clear(); self.window.next_frame.clear(); - let mut frame_arena = self.window.frame_arena.take().unwrap(); - frame_arena.clear(); - FRAME_ARENA.replace(Some(frame_arena)); + self.window.frame_arena.clear(); let root_view = self.window.root_view.take().unwrap(); self.with_z_index(0, |cx| { cx.with_key_dispatch(Some(KeyContext::default()), None, |_, cx| { for (action_type, action_listeners) in &cx.app.global_action_listeners { for action_listener in action_listeners.iter().cloned() { - let listener = frame_alloc(|| { - move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { - action_listener(action, phase, cx) - } - }) - .map(|listener| listener as _); + let listener = cx + .window + .frame_arena + .alloc(|| { + move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| { + action_listener(action, phase, cx) + } + }) + .map(|listener| listener as _); cx.window .next_frame .dispatch_tree @@ -1368,7 +1374,7 @@ impl<'a> WindowContext<'a> { } self.window.drawing = false; - self.window.frame_arena = Some(FRAME_ARENA.take().unwrap()); + ELEMENT_ARENA.with_borrow_mut(|element_arena| element_arena.clear()); scene }