mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-09 03:57:39 +00:00
WIP
This commit is contained in:
parent
84c36066bc
commit
c9193b586b
2 changed files with 60 additions and 26 deletions
|
@ -95,7 +95,7 @@ impl<V: Render> Element for View<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(&mut self, _: Bounds<Pixels>, element: &mut Self::State, cx: &mut WindowContext) {
|
fn paint(&mut self, _: Bounds<Pixels>, element: &mut Self::State, cx: &mut WindowContext) {
|
||||||
element.take().unwrap().paint(cx);
|
cx.with_view_id(self.entity_id(), |cx| element.take().unwrap().paint(cx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,33 +272,36 @@ impl Element for AnyView {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext) {
|
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext) {
|
||||||
if !self.cache {
|
cx.with_view_id(self.entity_id(), |cx| {
|
||||||
state.element.take().unwrap().paint(cx);
|
if !self.cache {
|
||||||
return;
|
state.element.take().unwrap().paint(cx);
|
||||||
}
|
return;
|
||||||
|
|
||||||
if let Some(cache_key) = state.cache_key.as_mut() {
|
|
||||||
if cache_key.bounds == bounds
|
|
||||||
&& cache_key.content_mask == cx.content_mask()
|
|
||||||
&& cache_key.stacking_order == *cx.stacking_order()
|
|
||||||
&& cache_key.text_style == cx.text_style()
|
|
||||||
{
|
|
||||||
println!("could reuse geometry for view {}", self.entity_id());
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let mut element = state
|
if let Some(cache_key) = state.cache_key.as_mut() {
|
||||||
.element
|
if cache_key.bounds == bounds
|
||||||
.take()
|
&& cache_key.content_mask == cx.content_mask()
|
||||||
.unwrap_or_else(|| (self.request_layout)(self, cx).1);
|
&& cache_key.stacking_order == *cx.stacking_order()
|
||||||
element.draw(bounds.origin, bounds.size.into(), cx);
|
&& cache_key.text_style == cx.text_style()
|
||||||
|
&& !cx.window.dirty_views.contains(&self.entity_id())
|
||||||
|
{
|
||||||
|
println!("could reuse geometry for view {}", self.entity_id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state.cache_key = Some(ViewCacheKey {
|
let mut element = state
|
||||||
bounds,
|
.element
|
||||||
stacking_order: cx.stacking_order().clone(),
|
.take()
|
||||||
content_mask: cx.content_mask(),
|
.unwrap_or_else(|| (self.request_layout)(self, cx).1);
|
||||||
text_style: cx.text_style(),
|
element.draw(bounds.origin, bounds.size.into(), cx);
|
||||||
});
|
|
||||||
|
state.cache_key = Some(ViewCacheKey {
|
||||||
|
bounds,
|
||||||
|
stacking_order: cx.stacking_order().clone(),
|
||||||
|
content_mask: cx.content_mask(),
|
||||||
|
text_style: cx.text_style(),
|
||||||
|
});
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
|
VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Context as _, Result};
|
use anyhow::{anyhow, Context as _, Result};
|
||||||
use collections::FxHashMap;
|
use collections::{FxHashMap, FxHashSet};
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use futures::{
|
use futures::{
|
||||||
channel::{mpsc, oneshot},
|
channel::{mpsc, oneshot},
|
||||||
|
@ -256,6 +256,7 @@ pub struct Window {
|
||||||
pub(crate) element_id_stack: GlobalElementId,
|
pub(crate) element_id_stack: GlobalElementId,
|
||||||
pub(crate) rendered_frame: Frame,
|
pub(crate) rendered_frame: Frame,
|
||||||
pub(crate) next_frame: Frame,
|
pub(crate) next_frame: Frame,
|
||||||
|
pub(crate) dirty_views: FxHashSet<EntityId>,
|
||||||
frame_arena: Arena,
|
frame_arena: Arena,
|
||||||
pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
|
pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
|
||||||
focus_listeners: SubscriberSet<(), AnyWindowFocusListener>,
|
focus_listeners: SubscriberSet<(), AnyWindowFocusListener>,
|
||||||
|
@ -295,6 +296,8 @@ pub(crate) struct Frame {
|
||||||
pub(crate) next_stacking_order_id: u32,
|
pub(crate) next_stacking_order_id: u32,
|
||||||
content_mask_stack: Vec<ContentMask<Pixels>>,
|
content_mask_stack: Vec<ContentMask<Pixels>>,
|
||||||
element_offset_stack: Vec<Point<Pixels>>,
|
element_offset_stack: Vec<Point<Pixels>>,
|
||||||
|
pub(crate) view_parents: FxHashMap<EntityId, EntityId>,
|
||||||
|
pub(crate) view_stack: Vec<EntityId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Frame {
|
impl Frame {
|
||||||
|
@ -310,6 +313,8 @@ impl Frame {
|
||||||
depth_map: Default::default(),
|
depth_map: Default::default(),
|
||||||
content_mask_stack: Vec::new(),
|
content_mask_stack: Vec::new(),
|
||||||
element_offset_stack: Vec::new(),
|
element_offset_stack: Vec::new(),
|
||||||
|
view_parents: FxHashMap::default(),
|
||||||
|
view_stack: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,6 +324,8 @@ impl Frame {
|
||||||
self.dispatch_tree.clear();
|
self.dispatch_tree.clear();
|
||||||
self.depth_map.clear();
|
self.depth_map.clear();
|
||||||
self.next_stacking_order_id = 0;
|
self.next_stacking_order_id = 0;
|
||||||
|
self.view_parents.clear();
|
||||||
|
debug_assert!(self.view_stack.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn focus_path(&self) -> SmallVec<[FocusId; 8]> {
|
fn focus_path(&self) -> SmallVec<[FocusId; 8]> {
|
||||||
|
@ -404,6 +411,7 @@ impl Window {
|
||||||
element_id_stack: GlobalElementId::default(),
|
element_id_stack: GlobalElementId::default(),
|
||||||
rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
|
rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
|
||||||
next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
|
next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
|
||||||
|
dirty_views: FxHashSet::default(),
|
||||||
frame_arena: Arena::new(1024 * 1024),
|
frame_arena: Arena::new(1024 * 1024),
|
||||||
focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
|
focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
|
||||||
focus_listeners: SubscriberSet::new(),
|
focus_listeners: SubscriberSet::new(),
|
||||||
|
@ -1423,6 +1431,7 @@ impl<'a> WindowContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.window.drawing = false;
|
self.window.drawing = false;
|
||||||
|
self.window.dirty_views.clear();
|
||||||
ELEMENT_ARENA.with_borrow_mut(|element_arena| element_arena.clear());
|
ELEMENT_ARENA.with_borrow_mut(|element_arena| element_arena.clear());
|
||||||
|
|
||||||
scene
|
scene
|
||||||
|
@ -2119,6 +2128,13 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn with_view_id<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
|
||||||
|
self.window_mut().next_frame.view_stack.push(view_id);
|
||||||
|
let result = f(self);
|
||||||
|
self.window_mut().next_frame.view_stack.pop();
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
/// Update the global element offset relative to the current offset. This is used to implement
|
/// Update the global element offset relative to the current offset. This is used to implement
|
||||||
/// scrolling.
|
/// scrolling.
|
||||||
fn with_element_offset<R>(
|
fn with_element_offset<R>(
|
||||||
|
@ -2476,6 +2492,21 @@ impl<'a, V: 'static> ViewContext<'a, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn notify(&mut self) {
|
pub fn notify(&mut self) {
|
||||||
|
let mut dirty_view_id = Some(self.view.entity_id());
|
||||||
|
while let Some(view_id) = dirty_view_id {
|
||||||
|
if self.window_cx.window.dirty_views.insert(view_id) {
|
||||||
|
dirty_view_id = self
|
||||||
|
.window_cx
|
||||||
|
.window
|
||||||
|
.rendered_frame
|
||||||
|
.view_parents
|
||||||
|
.get(&view_id)
|
||||||
|
.copied();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !self.window.drawing {
|
if !self.window.drawing {
|
||||||
self.window_cx.notify();
|
self.window_cx.notify();
|
||||||
self.window_cx.app.push_effect(Effect::Notify {
|
self.window_cx.app.push_effect(Effect::Notify {
|
||||||
|
|
Loading…
Reference in a new issue