From 0490c609fb4b524aa57ef8f87daa328980e8bd6c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 2 Sep 2021 11:42:23 +0200 Subject: [PATCH] Introduce a `visible_bounds` parameter to `Element::paint` We're not using this yet but this will be useful to avoid rendering unnecessary portions of text. --- gpui/examples/text.rs | 1 + gpui/src/elements.rs | 19 +++++++++++++------ gpui/src/elements/align.rs | 13 +++++++++---- gpui/src/elements/canvas.rs | 11 +++++------ gpui/src/elements/constrained_box.rs | 3 ++- gpui/src/elements/container.rs | 3 ++- gpui/src/elements/empty.rs | 1 + gpui/src/elements/event_handler.rs | 3 ++- gpui/src/elements/flex.rs | 6 ++++-- gpui/src/elements/label.rs | 1 + gpui/src/elements/line_box.rs | 12 ++++++++---- gpui/src/elements/list.rs | 12 +++++++++--- gpui/src/elements/mouse_event_handler.rs | 3 ++- gpui/src/elements/overlay.rs | 10 ++++++++-- gpui/src/elements/stack.rs | 3 ++- gpui/src/elements/svg.rs | 8 +++++++- gpui/src/elements/text.rs | 1 + gpui/src/elements/uniform_list.rs | 3 ++- gpui/src/presenter.rs | 20 +++++++++++++------- zed/src/editor/element.rs | 1 + zed/src/workspace/pane.rs | 2 +- 21 files changed, 94 insertions(+), 42 deletions(-) diff --git a/gpui/examples/text.rs b/gpui/examples/text.rs index 123481b9910fa113219c6a744b85d3f964b321c2..ecc8ce09561b345110d4cd4ebd977db2e940fd63 100644 --- a/gpui/examples/text.rs +++ b/gpui/examples/text.rs @@ -49,6 +49,7 @@ impl gpui::Element for TextElement { fn paint( &mut self, bounds: RectF, + _: RectF, _: &mut Self::LayoutState, cx: &mut gpui::PaintContext, ) -> Self::PaintState { diff --git a/gpui/src/elements.rs b/gpui/src/elements.rs index 25c13b0abbeaf2d08aa5e610e54396e0419e69c4..abfcadc0421f239f6282621d87b08d3dbd192314 100644 --- a/gpui/src/elements.rs +++ b/gpui/src/elements.rs @@ -50,7 +50,7 @@ use std::{ trait AnyElement { fn layout(&mut self, constraint: SizeConstraint, cx: &mut LayoutContext) -> Vector2F; - fn paint(&mut self, origin: Vector2F, cx: &mut PaintContext); + fn paint(&mut self, origin: Vector2F, visible_bounds: RectF, cx: &mut PaintContext); fn dispatch_event(&mut self, event: &Event, cx: &mut EventContext) -> bool; fn debug(&self, cx: &DebugContext) -> serde_json::Value; @@ -71,6 +71,7 @@ pub trait Element { fn paint( &mut self, bounds: RectF, + visible_bounds: RectF, layout: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState; @@ -168,7 +169,7 @@ impl AnyElement for Lifecycle { result } - fn paint(&mut self, origin: Vector2F, cx: &mut PaintContext) { + fn paint(&mut self, origin: Vector2F, visible_bounds: RectF, cx: &mut PaintContext) { *self = match mem::take(self) { Lifecycle::PostLayout { mut element, @@ -177,7 +178,10 @@ impl AnyElement for Lifecycle { mut layout, } => { let bounds = RectF::new(origin, size); - let paint = element.paint(bounds, &mut layout, cx); + let visible_bounds = visible_bounds + .intersection(bounds) + .unwrap_or_else(|| RectF::new(bounds.origin(), Vector2F::default())); + let paint = element.paint(bounds, visible_bounds, &mut layout, cx); Lifecycle::PostPaint { element, constraint, @@ -194,7 +198,10 @@ impl AnyElement for Lifecycle { .. } => { let bounds = RectF::new(origin, bounds.size()); - let paint = element.paint(bounds, &mut layout, cx); + let visible_bounds = visible_bounds + .intersection(bounds) + .unwrap_or_else(|| RectF::new(bounds.origin(), Vector2F::default())); + let paint = element.paint(bounds, visible_bounds, &mut layout, cx); Lifecycle::PostPaint { element, constraint, @@ -305,8 +312,8 @@ impl ElementRc { self.element.borrow_mut().layout(constraint, cx) } - pub fn paint(&mut self, origin: Vector2F, cx: &mut PaintContext) { - self.element.borrow_mut().paint(origin, cx); + pub fn paint(&mut self, origin: Vector2F, visible_bounds: RectF, cx: &mut PaintContext) { + self.element.borrow_mut().paint(origin, visible_bounds, cx); } pub fn dispatch_event(&mut self, event: &Event, cx: &mut EventContext) -> bool { diff --git a/gpui/src/elements/align.rs b/gpui/src/elements/align.rs index 8963e063b6b7bbb3efc9d7a24f18d25be3a407a2..652a014ddad275faa7e509be73f6bfe98099e096 100644 --- a/gpui/src/elements/align.rs +++ b/gpui/src/elements/align.rs @@ -1,9 +1,10 @@ use crate::{ + geometry::{rect::RectF, vector::Vector2F}, json, DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext, SizeConstraint, }; use json::ToJson; -use pathfinder_geometry::vector::Vector2F; + use serde_json::json; pub struct Align { @@ -53,7 +54,8 @@ impl Element for Align { fn paint( &mut self, - bounds: pathfinder_geometry::rect::RectF, + bounds: RectF, + visible_bounds: RectF, _: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { @@ -63,8 +65,11 @@ impl Element for Align { let child_center = self.child.size() / 2.; let child_target = child_center + child_center * self.alignment; - self.child - .paint(bounds.origin() - (child_target - my_target), cx); + self.child.paint( + bounds.origin() - (child_target - my_target), + visible_bounds, + cx, + ); } fn dispatch_event( diff --git a/gpui/src/elements/canvas.rs b/gpui/src/elements/canvas.rs index 2e9d5d9e883dfacd533423970b88d338809b51d3..d6220fd45f481a97e427ea1092512be3a1f0481d 100644 --- a/gpui/src/elements/canvas.rs +++ b/gpui/src/elements/canvas.rs @@ -9,13 +9,11 @@ use pathfinder_geometry::{ vector::{vec2f, Vector2F}, }; -pub struct Canvas(F) -where - F: FnMut(RectF, &mut PaintContext); +pub struct Canvas(F); impl Canvas where - F: FnMut(RectF, &mut PaintContext), + F: FnMut(RectF, RectF, &mut PaintContext), { pub fn new(f: F) -> Self { Self(f) @@ -24,7 +22,7 @@ where impl Element for Canvas where - F: FnMut(RectF, &mut PaintContext), + F: FnMut(RectF, RectF, &mut PaintContext), { type LayoutState = (); type PaintState = (); @@ -50,10 +48,11 @@ where fn paint( &mut self, bounds: RectF, + visible_bounds: RectF, _: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { - self.0(bounds, cx) + self.0(bounds, visible_bounds, cx) } fn dispatch_event( diff --git a/gpui/src/elements/constrained_box.rs b/gpui/src/elements/constrained_box.rs index f7949274020748e2ed5f537ff5136cce03eceb1c..c712d71a9b7bac276568202108d0b2236ebcb60c 100644 --- a/gpui/src/elements/constrained_box.rs +++ b/gpui/src/elements/constrained_box.rs @@ -70,10 +70,11 @@ impl Element for ConstrainedBox { fn paint( &mut self, bounds: RectF, + visible_bounds: RectF, _: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { - self.child.paint(bounds.origin(), cx); + self.child.paint(bounds.origin(), visible_bounds, cx); } fn dispatch_event( diff --git a/gpui/src/elements/container.rs b/gpui/src/elements/container.rs index 2bab55e832162df52a4232c53daf3e0fb22948ad..464776b5c3c606deec8d12ca94c1d6f2fec31c8d 100644 --- a/gpui/src/elements/container.rs +++ b/gpui/src/elements/container.rs @@ -169,6 +169,7 @@ impl Element for Container { fn paint( &mut self, bounds: RectF, + visible_bounds: RectF, _: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { @@ -198,7 +199,7 @@ impl Element for Container { self.style.border.left_width(), self.style.border.top_width(), ); - self.child.paint(child_origin, cx); + self.child.paint(child_origin, visible_bounds, cx); } fn dispatch_event( diff --git a/gpui/src/elements/empty.rs b/gpui/src/elements/empty.rs index 3c706cc379133cd88c78f2faaf5c2e4190e78431..d6041bd9587f0c5694f374e7a152285876f85b5a 100644 --- a/gpui/src/elements/empty.rs +++ b/gpui/src/elements/empty.rs @@ -42,6 +42,7 @@ impl Element for Empty { fn paint( &mut self, _: RectF, + _: RectF, _: &mut Self::LayoutState, _: &mut PaintContext, ) -> Self::PaintState { diff --git a/gpui/src/elements/event_handler.rs b/gpui/src/elements/event_handler.rs index 686bfd7acce704aaad3b08098adbc1e8b7d26f91..f880b0bb6cf85f976204547041f5964c51110d56 100644 --- a/gpui/src/elements/event_handler.rs +++ b/gpui/src/elements/event_handler.rs @@ -44,10 +44,11 @@ impl Element for EventHandler { fn paint( &mut self, bounds: RectF, + visible_bounds: RectF, _: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { - self.child.paint(bounds.origin(), cx); + self.child.paint(bounds.origin(), visible_bounds, cx); } fn dispatch_event( diff --git a/gpui/src/elements/flex.rs b/gpui/src/elements/flex.rs index d595a466397fdff691d58bf6aca7ae3433ae45a1..58e603fc6fd19a2db73123a6fdab4e9fb661a8cb 100644 --- a/gpui/src/elements/flex.rs +++ b/gpui/src/elements/flex.rs @@ -134,12 +134,13 @@ impl Element for Flex { fn paint( &mut self, bounds: RectF, + visible_bounds: RectF, _: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { let mut child_origin = bounds.origin(); for child in &mut self.children { - child.paint(child_origin, cx); + child.paint(child_origin, visible_bounds, cx); match self.axis { Axis::Horizontal => child_origin += vec2f(child.size().x(), 0.0), Axis::Vertical => child_origin += vec2f(0.0, child.size().y()), @@ -212,10 +213,11 @@ impl Element for Expanded { fn paint( &mut self, bounds: RectF, + visible_bounds: RectF, _: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { - self.child.paint(bounds.origin(), cx) + self.child.paint(bounds.origin(), visible_bounds, cx) } fn dispatch_event( diff --git a/gpui/src/elements/label.rs b/gpui/src/elements/label.rs index 1ad5d83671cdf04e91af9dc0f3efef95301701d1..8fb411e7ef5c1c9c943d24453ea03a5cf110cb49 100644 --- a/gpui/src/elements/label.rs +++ b/gpui/src/elements/label.rs @@ -128,6 +128,7 @@ impl Element for Label { fn paint( &mut self, bounds: RectF, + visible_bounds: RectF, line: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { diff --git a/gpui/src/elements/line_box.rs b/gpui/src/elements/line_box.rs index cf8f6ca605cf45272ab21b12a9f3f6810722a2bc..33fd2510c8869fce725cf4ab7482e5468b142c9a 100644 --- a/gpui/src/elements/line_box.rs +++ b/gpui/src/elements/line_box.rs @@ -48,18 +48,22 @@ impl Element for LineBox { fn paint( &mut self, - bounds: pathfinder_geometry::rect::RectF, + bounds: RectF, + visible_bounds: RectF, padding_top: &mut f32, cx: &mut PaintContext, ) -> Self::PaintState { - self.child - .paint(bounds.origin() + vec2f(0., *padding_top), cx); + self.child.paint( + bounds.origin() + vec2f(0., *padding_top), + visible_bounds, + cx, + ); } fn dispatch_event( &mut self, event: &Event, - _: pathfinder_geometry::rect::RectF, + _: RectF, _: &mut Self::LayoutState, _: &mut Self::PaintState, cx: &mut EventContext, diff --git a/gpui/src/elements/list.rs b/gpui/src/elements/list.rs index b3b61bb30cedac887855b0c095203a8118ca7fd7..1a86e2935cd774837d2dbf03f12acd089c4e487b 100644 --- a/gpui/src/elements/list.rs +++ b/gpui/src/elements/list.rs @@ -230,12 +230,18 @@ impl Element for List { (size, scroll_top) } - fn paint(&mut self, bounds: RectF, scroll_top: &mut ListOffset, cx: &mut PaintContext) { + fn paint( + &mut self, + bounds: RectF, + visible_bounds: RectF, + scroll_top: &mut ListOffset, + cx: &mut PaintContext, + ) { cx.scene.push_layer(Some(bounds)); let state = &mut *self.state.0.borrow_mut(); for (mut element, origin) in state.visible_elements(bounds, scroll_top) { - element.paint(origin, cx); + element.paint(origin, visible_bounds, cx); } cx.scene.pop_layer(); @@ -832,7 +838,7 @@ mod tests { (self.size, ()) } - fn paint(&mut self, _: RectF, _: &mut (), _: &mut PaintContext) { + fn paint(&mut self, _: RectF, _: RectF, _: &mut (), _: &mut PaintContext) { todo!() } diff --git a/gpui/src/elements/mouse_event_handler.rs b/gpui/src/elements/mouse_event_handler.rs index 6f5f3fbc4a47a6f573654c8877944f9514bb289e..1d0907517910e863c30f3acab4f214a89587ae77 100644 --- a/gpui/src/elements/mouse_event_handler.rs +++ b/gpui/src/elements/mouse_event_handler.rs @@ -81,10 +81,11 @@ impl Element for MouseEventHandler { fn paint( &mut self, bounds: RectF, + visible_bounds: RectF, _: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { - self.child.paint(bounds.origin(), cx); + self.child.paint(bounds.origin(), visible_bounds, cx); } fn dispatch_event( diff --git a/gpui/src/elements/overlay.rs b/gpui/src/elements/overlay.rs index a4c44a00130ef94f1041fc255bfdce24e54958fb..e83b95ba91ba4b654ab86a27f8f2f56d38d99624 100644 --- a/gpui/src/elements/overlay.rs +++ b/gpui/src/elements/overlay.rs @@ -27,10 +27,16 @@ impl Element for Overlay { (Vector2F::zero(), size) } - fn paint(&mut self, bounds: RectF, size: &mut Self::LayoutState, cx: &mut PaintContext) { + fn paint( + &mut self, + bounds: RectF, + visible_bounds: RectF, + size: &mut Self::LayoutState, + cx: &mut PaintContext, + ) { let bounds = RectF::new(bounds.origin(), *size); cx.scene.push_stacking_context(None); - self.child.paint(bounds.origin(), cx); + self.child.paint(bounds.origin(), visible_bounds, cx); cx.scene.pop_stacking_context(); } diff --git a/gpui/src/elements/stack.rs b/gpui/src/elements/stack.rs index 5c4f91e0ab5c7ded935f7adcbdf7a29ab5bda52b..dd36b9c4b5aebcbebd8c98253084861202d02378 100644 --- a/gpui/src/elements/stack.rs +++ b/gpui/src/elements/stack.rs @@ -36,12 +36,13 @@ impl Element for Stack { fn paint( &mut self, bounds: RectF, + visible_bounds: RectF, _: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { for child in &mut self.children { cx.scene.push_layer(None); - child.paint(bounds.origin(), cx); + child.paint(bounds.origin(), visible_bounds, cx); cx.scene.pop_layer(); } } diff --git a/gpui/src/elements/svg.rs b/gpui/src/elements/svg.rs index 2cf8f07b6038b9bfc2ee3b202590cba33f7481ac..8adb285b99a73c1e2ab661976d4f2d58d4d635db 100644 --- a/gpui/src/elements/svg.rs +++ b/gpui/src/elements/svg.rs @@ -65,7 +65,13 @@ impl Element for Svg { } } - fn paint(&mut self, bounds: RectF, svg: &mut Self::LayoutState, cx: &mut PaintContext) { + fn paint( + &mut self, + bounds: RectF, + _visible_bounds: RectF, + svg: &mut Self::LayoutState, + cx: &mut PaintContext, + ) { if let Some(svg) = svg.clone() { cx.scene.push_icon(scene::Icon { bounds, diff --git a/gpui/src/elements/text.rs b/gpui/src/elements/text.rs index 6978542071aaf89501fb7899c50db42953581c50..6284fc970473b3981e9b8bcb6b11dfcd3212ad46 100644 --- a/gpui/src/elements/text.rs +++ b/gpui/src/elements/text.rs @@ -76,6 +76,7 @@ impl Element for Text { fn paint( &mut self, bounds: RectF, + visible_bounds: RectF, layout: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { diff --git a/gpui/src/elements/uniform_list.rs b/gpui/src/elements/uniform_list.rs index 567ea036cfa55dea94c31d29702caffa0c8f2ea5..04435bb36eb28e2b06d7d52880e193ade25a3b5a 100644 --- a/gpui/src/elements/uniform_list.rs +++ b/gpui/src/elements/uniform_list.rs @@ -165,6 +165,7 @@ where fn paint( &mut self, bounds: RectF, + visible_bounds: RectF, layout: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { @@ -174,7 +175,7 @@ where bounds.origin() - vec2f(0.0, self.state.scroll_top() % layout.item_height); for item in &mut layout.items { - item.paint(item_origin, cx); + item.paint(item_origin, visible_bounds, cx); item_origin += vec2f(0.0, layout.item_height); } diff --git a/gpui/src/presenter.rs b/gpui/src/presenter.rs index c0b26bbcc4449474fbbfe7d77ba72b9a5c31657f..b2fa59b848aa2bb3ca53c9e5565104a6186bb1dc 100644 --- a/gpui/src/presenter.rs +++ b/gpui/src/presenter.rs @@ -2,6 +2,7 @@ use crate::{ app::{AppContext, MutableAppContext, WindowInvalidation}, elements::Element, font_cache::FontCache, + geometry::rect::RectF, json::{self, ToJson}, platform::Event, text_layout::TextLayoutCache, @@ -111,7 +112,11 @@ impl Presenter { rendered_views: &mut self.rendered_views, app: cx.as_ref(), }; - paint_cx.paint(root_view_id, Vector2F::zero()); + paint_cx.paint( + root_view_id, + Vector2F::zero(), + RectF::new(Vector2F::zero(), window_size), + ); self.text_layout_cache.finish_frame(); if let Some(event) = self.last_mouse_moved_event.clone() { @@ -273,9 +278,9 @@ pub struct PaintContext<'a> { } impl<'a> PaintContext<'a> { - fn paint(&mut self, view_id: usize, origin: Vector2F) { + fn paint(&mut self, view_id: usize, origin: Vector2F, visible_bounds: RectF) { if let Some(mut tree) = self.rendered_views.remove(&view_id) { - tree.paint(origin, self); + tree.paint(origin, visible_bounds, self); self.rendered_views.insert(view_id, tree); } } @@ -455,17 +460,18 @@ impl Element for ChildView { fn paint( &mut self, - bounds: pathfinder_geometry::rect::RectF, + bounds: RectF, + visible_bounds: RectF, _: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { - cx.paint(self.view_id, bounds.origin()); + cx.paint(self.view_id, bounds.origin(), visible_bounds); } fn dispatch_event( &mut self, event: &Event, - _: pathfinder_geometry::rect::RectF, + _: RectF, _: &mut Self::LayoutState, _: &mut Self::PaintState, cx: &mut EventContext, @@ -475,7 +481,7 @@ impl Element for ChildView { fn debug( &self, - bounds: pathfinder_geometry::rect::RectF, + bounds: RectF, _: &Self::LayoutState, _: &Self::PaintState, cx: &DebugContext, diff --git a/zed/src/editor/element.rs b/zed/src/editor/element.rs index 422a37e342a64630c866ca46d53eb1c432c00c37..8ba29481d0dfb8e1e9112d8b94b94ea2d4819220 100644 --- a/zed/src/editor/element.rs +++ b/zed/src/editor/element.rs @@ -559,6 +559,7 @@ impl Element for EditorElement { fn paint( &mut self, bounds: RectF, + _: RectF, layout: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { diff --git a/zed/src/workspace/pane.rs b/zed/src/workspace/pane.rs index 0315337e6bb455ae2af50b16f6a04fc6dafca44a..25afac91b0518bcf2a7cb1e837fea3931a995d05 100644 --- a/zed/src/workspace/pane.rs +++ b/zed/src/workspace/pane.rs @@ -336,7 +336,7 @@ impl Pane { } else { let diameter = 8.; ConstrainedBox::new( - Canvas::new(move |bounds, cx| { + Canvas::new(move |bounds, _, cx| { if let Some(current_color) = current_color { let square = RectF::new(bounds.origin(), vec2f(diameter, diameter)); cx.scene.push_quad(Quad {