diff --git a/crates/common/src/compositor.rs b/crates/common/src/compositor.rs index a63545e4b..f04a9b66f 100644 --- a/crates/common/src/compositor.rs +++ b/crates/common/src/compositor.rs @@ -8,18 +8,13 @@ use std::sync::{ MutexGuard, }; -use freya_engine::prelude::Canvas; use freya_native_core::NodeId; use itertools::sorted; use rustc_hash::{ FxHashMap, FxHashSet, }; -use torin::prelude::{ - Area, - AreaModel, - Size2D, -}; +use torin::prelude::Area; use crate::Layers; @@ -55,11 +50,10 @@ impl Compositor { pub fn run( &self, dirty_nodes: &CompositorDirtyNodes, - canvas: &Canvas, get_affected: impl Fn(NodeId, bool) -> Vec, get_area: impl Fn(NodeId) -> Option, layers: &Layers, - ) -> (Layers, Area) { + ) -> (Layers, Option) { let mut dirty_nodes = dirty_nodes.get(); let (mut invalidated_nodes, mut dirty_nodes) = { ( @@ -87,26 +81,29 @@ impl Compositor { } let rendering_layers = Layers::default(); - let dirty_area = Area::from_size(Size2D::new(999., 999.)); + let mut dirty_area: Option = None; let full_render = self.full_render.load(Ordering::Relaxed); - let run_check = |layer: i16, nodes: &[NodeId]| { + let mut run_check = |layer: i16, nodes: &[NodeId]| { for node_id in nodes { let Some(area) = get_area(*node_id) else { continue; }; let is_invalidated = full_render || invalidated_nodes.contains(node_id); - let is_area_invalidated = is_invalidated - || invalidated_nodes.iter().any(|invalid_node| { - let Some(invalid_node_area) = get_area(*invalid_node) else { - return false; - }; - invalid_node_area.area_intersects(&area) - }); - - if is_area_invalidated { + let is_area_invalidated = dirty_area + .map(|dirty_area| dirty_area.intersects(&area)) + .unwrap_or_default(); + + if is_invalidated || is_area_invalidated { rendering_layers.insert_node_in_layer(*node_id, layer); + if is_invalidated { + if let Some(dirty_area) = &mut dirty_area { + *dirty_area = dirty_area.union(&area); + } else { + dirty_area = Some(area) + } + } } } }; @@ -122,6 +119,7 @@ impl Compositor { } self.full_render.store(false, Ordering::Relaxed); + (rendering_layers, dirty_area) } diff --git a/crates/common/src/layers.rs b/crates/common/src/layers.rs index c0ba2600f..bbef978dc 100644 --- a/crates/common/src/layers.rs +++ b/crates/common/src/layers.rs @@ -22,18 +22,14 @@ impl Layers { layer.push(node_id); } - pub fn remove_node_from_layer(&self, node_id: NodeId, layer_n: i16) -> bool { + pub fn remove_node_from_layer(&self, node_id: NodeId, layer_n: i16) { let mut layers = self.layers.lock().unwrap(); let layer = layers.get_mut(&layer_n).unwrap(); layer.retain(|id| *id != node_id); - let layer_is_empty = layer.is_empty(); - - if layer_is_empty { + if layer.is_empty() { layers.remove(&layer_n); } - - layer_is_empty } pub fn layers(&self) -> MutexGuard>> { diff --git a/crates/core/src/dom/doms.rs b/crates/core/src/dom/doms.rs index 65c9191d3..200e685e9 100644 --- a/crates/core/src/dom/doms.rs +++ b/crates/core/src/dom/doms.rs @@ -6,7 +6,6 @@ use std::sync::{ use dioxus_core::VirtualDom; use freya_common::{ - Compositor, CompositorDirtyNodes, Layers, ParagraphElements, @@ -167,12 +166,7 @@ impl FreyaDOM { } /// Create the initial DOM from the given Mutations - pub fn init_dom( - &mut self, - vdom: &mut VirtualDom, - scale_factor: f32, - compositor: &mut Compositor, - ) { + pub fn init_dom(&mut self, vdom: &mut VirtualDom, scale_factor: f32) { // Build the RealDOM vdom.rebuild(&mut MutationsWriter { native_writer: self @@ -183,7 +177,6 @@ impl FreyaDOM { paragraphs: &self.paragraphs, scale_factor, compositor_dirty_nodes: &self.compositor_dirty_nodes, - compositor, }); let mut ctx = SendAnyMap::new(); @@ -196,12 +189,7 @@ impl FreyaDOM { } /// Process the given mutations from the [`VirtualDOM`](dioxus_core::VirtualDom). - pub fn render_mutations( - &mut self, - vdom: &mut VirtualDom, - scale_factor: f32, - compositor: &mut Compositor, - ) -> (bool, bool) { + pub fn render_mutations(&mut self, vdom: &mut VirtualDom, scale_factor: f32) -> (bool, bool) { // Update the RealDOM vdom.render_immediate(&mut MutationsWriter { native_writer: self @@ -212,7 +200,6 @@ impl FreyaDOM { paragraphs: &self.paragraphs, scale_factor, compositor_dirty_nodes: &self.compositor_dirty_nodes, - compositor, }); // Update the Nodes states diff --git a/crates/core/src/dom/mutations_writer.rs b/crates/core/src/dom/mutations_writer.rs index 333fd751a..3eda7e9aa 100644 --- a/crates/core/src/dom/mutations_writer.rs +++ b/crates/core/src/dom/mutations_writer.rs @@ -3,7 +3,6 @@ use dioxus_core::{ WriteMutations, }; use freya_common::{ - Compositor, CompositorDirtyNodes, Layers, ParagraphElements, @@ -32,7 +31,6 @@ pub struct MutationsWriter<'a> { pub paragraphs: &'a ParagraphElements, pub scale_factor: f32, pub compositor_dirty_nodes: &'a CompositorDirtyNodes, - pub compositor: &'a mut Compositor, } impl<'a> MutationsWriter<'a> { @@ -74,8 +72,7 @@ impl<'a> MutationsWriter<'a> { } // Remove from layers - let layer_was_removed = self - .layers + self.layers .remove_node_from_layer(node_id, layer_state.layer); // Remove from paragraph elements @@ -83,10 +80,6 @@ impl<'a> MutationsWriter<'a> { self.paragraphs .remove_paragraph(node_id, &cursor_ref.text_id); } - - if layer_was_removed { - //self.compositor.remove_layer(layer_state.layer); - } } } } diff --git a/crates/core/src/render.rs b/crates/core/src/render.rs index 3e15928b5..a92936606 100644 --- a/crates/core/src/render.rs +++ b/crates/core/src/render.rs @@ -3,7 +3,6 @@ use freya_engine::prelude::{ Canvas, ClipOp, Color, - IPoint, Rect, SamplingOptions, Surface, @@ -36,7 +35,6 @@ pub fn process_render( let (dirty_layers, dirty_area) = compositor.run( compositor_dirty_nodes, - dirty_canvas, |node, try_traverse_children| { let node = rdom.get(node); if let Some(node) = node { @@ -65,28 +63,27 @@ pub fn process_render( layers, ); - let layers = layers.layers(); let dirty_layers = dirty_layers.layers(); dirty_canvas.save(); - - dirty_canvas.clip_rect( - Rect::new( - dirty_area.min_x(), - dirty_area.min_y(), - dirty_area.max_x(), - dirty_area.max_y(), - ), - Some(ClipOp::Intersect), - false, - ); - dirty_canvas.clear(Color::TRANSPARENT); + if let Some(dirty_area) = dirty_area { + dirty_canvas.clip_rect( + Rect::new( + dirty_area.min_x(), + dirty_area.min_y(), + dirty_area.max_x(), + dirty_area.max_y(), + ), + Some(ClipOp::Intersect), + false, + ); + dirty_canvas.clear(Color::WHITE); + } let mut painted = Vec::new(); // Render the dirty nodes - for layer in sorted(dirty_layers.keys().copied().collect::>()) { - let nodes = layers.get(&layer).unwrap(); + for (_, nodes) in sorted(dirty_layers.iter()) { 'elements: for node_id in nodes { let node = rdom.get(*node_id).unwrap(); let node_viewports = node.get::().unwrap(); @@ -108,9 +105,6 @@ pub fn process_render( } } - println!("{painted:?}"); - dirty_canvas.restore(); - canvas.clear(Color::TRANSPARENT); dirty_surface.draw(canvas, (0, 0), SamplingOptions::default(), None); } diff --git a/crates/renderer/src/app.rs b/crates/renderer/src/app.rs index 2012351f7..df6f5e9fd 100644 --- a/crates/renderer/src/app.rs +++ b/crates/renderer/src/app.rs @@ -151,9 +151,7 @@ impl Application { self.provide_vdom_contexts(app_state); - self.sdom - .get_mut() - .init_dom(&mut self.vdom, scale_factor, &mut self.compositor); + self.sdom.get_mut().init_dom(&mut self.vdom, scale_factor); self.plugins.send(PluginEvent::FinishedUpdatingDOM); } @@ -161,11 +159,10 @@ impl Application { pub fn render_mutations(&mut self, scale_factor: f32) -> (bool, bool) { self.plugins.send(PluginEvent::StartedUpdatingDOM); - let (repaint, relayout) = self.sdom.get_mut().render_mutations( - &mut self.vdom, - scale_factor, - &mut self.compositor, - ); + let (repaint, relayout) = self + .sdom + .get_mut() + .render_mutations(&mut self.vdom, scale_factor); self.plugins.send(PluginEvent::FinishedUpdatingDOM); diff --git a/crates/renderer/src/renderer.rs b/crates/renderer/src/renderer.rs index 3b72f8470..39d43be62 100644 --- a/crates/renderer/src/renderer.rs +++ b/crates/renderer/src/renderer.rs @@ -416,10 +416,12 @@ impl<'a, State: Clone> ApplicationHandler for DesktopRenderer<'a, *surface = create_surface(window, *fb_info, gr_context, *num_samples, *stencil_size); - *dirty_surface = surface.new_surface_with_dimensions(( - size.width.try_into().expect("Could not convert width"), - size.height.try_into().expect("Could not convert height"), - )).unwrap(); + *dirty_surface = surface + .new_surface_with_dimensions(( + size.width.try_into().expect("Could not convert width"), + size.height.try_into().expect("Could not convert height"), + )) + .unwrap(); gl_surface.resize( gl_context, diff --git a/crates/testing/src/test_handler.rs b/crates/testing/src/test_handler.rs index 6090d4e28..9c0ac7804 100644 --- a/crates/testing/src/test_handler.rs +++ b/crates/testing/src/test_handler.rs @@ -73,11 +73,7 @@ impl TestingHandler { self.provide_vdom_contexts(); let sdom = self.utils.sdom(); let mut fdom = sdom.get(); - fdom.init_dom( - &mut self.vdom, - SCALE_FACTOR as f32, - &mut Compositor::default(), - ); + fdom.init_dom(&mut self.vdom, SCALE_FACTOR as f32); } /// Get a mutable reference to the current [`TestingConfig`]. @@ -189,11 +185,11 @@ impl TestingHandler { .await .ok(); - let (must_repaint, must_relayout) = self.utils.sdom().get_mut().render_mutations( - &mut self.vdom, - SCALE_FACTOR as f32, - &mut Compositor::default(), - ); + let (must_repaint, must_relayout) = self + .utils + .sdom() + .get_mut() + .render_mutations(&mut self.vdom, SCALE_FACTOR as f32); self.wait_for_work(self.config.size()); diff --git a/crates/torin/src/geometry.rs b/crates/torin/src/geometry.rs index 01570e19a..5767f9f95 100644 --- a/crates/torin/src/geometry.rs +++ b/crates/torin/src/geometry.rs @@ -48,8 +48,6 @@ pub trait AreaModel { ); fn adjust_size(&mut self, node: &Node); - - fn area_intersects(&self, other: &Self) -> bool; } impl AreaModel for Area { @@ -179,13 +177,6 @@ impl AreaModel for Area { self.size.height *= p.get() / 100.; } } - - fn area_intersects(&self, other: &Self) -> bool { - (self.min_x() <= other.max_x() && (self.max_x() <= other.min_x())) - || (self.max_x() <= other.min_x() && (self.min_x() <= other.max_x())) - || (self.min_y() <= other.max_y() && (self.max_y() <= other.min_y())) - || (self.max_y() <= other.min_y() && (self.min_y() <= other.max_y())) - } } pub fn get_align_axis(