diff --git a/render-wasm/src/math.rs b/render-wasm/src/math.rs index 0b8feeed04..c58d401303 100644 --- a/render-wasm/src/math.rs +++ b/render-wasm/src/math.rs @@ -3,6 +3,7 @@ use skia_safe as skia; pub mod bools; pub type Rect = skia::Rect; +pub type IRect = skia::IRect; pub type Matrix = skia::Matrix; pub type Vector = skia::Vector; pub type Point = skia::Point; diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs index a48cdceb63..c629ad2c69 100644 --- a/render-wasm/src/render.rs +++ b/render-wasm/src/render.rs @@ -557,6 +557,7 @@ impl RenderState { ) -> Result<()> { #[cfg(feature = "stats")] self.stats.count(shape.id); + println!("render_shape"); let surface_ids = fills_surface_id as u32 | strokes_surface_id as u32 @@ -660,7 +661,6 @@ impl RenderState { // ); if can_render_directly { - println!("can_render_directly"); let scale = self.get_scale_fast(); let translation = self .surfaces @@ -821,6 +821,7 @@ impl RenderState { .concat(&matrix); if let Some(svg) = shape.svg.as_ref() { + println!("Never passes"); svg.render(self.surfaces.canvas_and_mark_dirty(fills_surface_id)); } else { let font_manager = skia::FontMgr::from(self.fonts().font_provider().clone()); @@ -1420,7 +1421,7 @@ impl RenderState { // std::ptr::addr_of!(tree), // ); let frame_type = - self.render_shape_tree_tiled( tree, timestamp, allow_stop)?; + self.render_shape_tree_tiled(tree, timestamp, allow_stop)?; // `draw_atlas` needs a snapshot of the tile atlas. Partial frames are not // presented (only flushed), so defer composition to the final frame and @@ -1644,7 +1645,6 @@ impl RenderState { pub fn render_shape_tree_tile( &mut self, - tree: ShapesPoolRef, timestamp: i32, allow_stop: bool, export: bool, @@ -1656,6 +1656,9 @@ impl RenderState { target_surface = SurfaceId::Export; } + let design_state = get_design_state(); + let tree = &design_state.shapes; + while let Some(node_render_state) = self.pending_nodes.pop() { let node_id = node_render_state.id; let visited_children = node_render_state.visited_children; @@ -1673,10 +1676,25 @@ impl RenderState { let scale = self.get_scale_fast(); let mut extrect: Option = None; + let Some(current_tile) = self.tile.current else { + println!("There's no current_tile"); + continue; + }; + + // let element_tile_rect = element.get_tile_rect(&self.viewbox); + // if !element_tile_rect.contains(¤t_tile) { + // continue; + // } + + // println!("element_tile_rect {:?}", element_tile_rect); + // if !self.tile.tiles.has_shape_at(current_tile, node_id) { + // continue; + // } + // If the shape is not in the tile set, then we add them. - if self.tile.tiles.get_tiles_of(node_id).is_none() { - self.add_shape_tiles(element, tree); - } + // if self.tile.tiles.get_tiles_of(node_id).is_none() { + // self.add_shape_tiles(element, tree); + // } if visited_children { if !node_render_state.flattened { @@ -1976,7 +1994,7 @@ impl RenderState { { performance::begin_measure!("render_shape_tree::uncached"); let (is_empty, early_return) = self - .render_shape_tree_tile(tree, timestamp, allow_stop, false)?; + .render_shape_tree_tile(timestamp, allow_stop, false)?; if early_return { self.viewer_render_root = None; @@ -1991,11 +2009,12 @@ impl RenderState { if !is_empty || self.tile.current_had_shapes { let tile_rect = self.get_current_aligned_tile_bounds()?; - let current_tile = *self - .tile - .current - .as_ref() - .ok_or(Error::CriticalError("Current tile not found".to_string()))?; + // NOTE: Unnecessary code + // let current_tile = *self + // .tile + // .current + // .as_ref() + // .ok_or(Error::CriticalError("Current tile not found".to_string()))?; self.surfaces.draw_current_tile_into_tile_atlas( ¤t_tile, @@ -2097,6 +2116,10 @@ impl RenderState { Ok(FrameType::Full) } + pub fn render_shape_tree() { + + } + /* * Given a shape returns the TileRect with the range of tiles that the shape is in. * This is always limited to the interest area to optimize performance and prevent diff --git a/render-wasm/src/render/export.rs b/render-wasm/src/render/export.rs index c4a6ead1d7..d6954e3f37 100644 --- a/render-wasm/src/render/export.rs +++ b/render-wasm/src/render/export.rs @@ -56,7 +56,7 @@ pub fn render_shape_pixels( mask: false, flattened: false, }); - render_state.render_shape_tree_tile(tree, timestamp, false, true)?; + render_state.render_shape_tree_tile( timestamp, false, true)?; } render_state.export_context = None; diff --git a/render-wasm/src/shapes.rs b/render-wasm/src/shapes.rs index 017145b846..26fff74e93 100644 --- a/render-wasm/src/shapes.rs +++ b/render-wasm/src/shapes.rs @@ -2,7 +2,9 @@ use skia_safe::{self as skia}; use indexmap::IndexSet; +use crate::tiles::{self, TileRect}; use crate::uuid::Uuid; +use crate::view::Viewbox; use std::borrow::Cow; use std::cell::{OnceCell, RefCell}; use std::collections::HashSet; @@ -51,7 +53,7 @@ pub use svgraw::*; pub use text::*; pub use transform::*; -use crate::math::{self, Bounds, Matrix, Point}; +use crate::math::{self, Bounds, Matrix, Point, IRect}; use crate::state::ShapesPoolRef; @@ -200,6 +202,7 @@ pub struct Shape { pub extrect_cache: RefCell>, pub svg_transform: Option, pub ignore_constraints: bool, + pub tile_rect: TileRect, deleted: bool, } @@ -303,6 +306,7 @@ impl Shape { extrect_cache: RefCell::new(None), svg_transform: None, ignore_constraints: false, + tile_rect: TileRect::new_empty(), deleted: false, } } @@ -402,6 +406,7 @@ impl Shape { text.update_layout(self.selrect); text.set_xywh(left, top, self.selrect.width(), self.selrect.height()); } + self.tile_rect.set_from_tile_bounds(left, top, right, bottom, tiles::TILE_SIZE); } pub fn set_masked(&mut self, masked: bool) { @@ -442,6 +447,10 @@ impl Shape { transform } + pub fn get_tile_rect(&self, viewbox: &Viewbox) -> TileRect { + TileRect::from_scaled(&self.tile_rect, viewbox.get_scale()) + } + pub fn set_opacity(&mut self, opacity: f32) { self.opacity = opacity; } diff --git a/render-wasm/src/tiles.rs b/render-wasm/src/tiles.rs index 1319e8ab5a..20dda84d83 100644 --- a/render-wasm/src/tiles.rs +++ b/render-wasm/src/tiles.rs @@ -37,10 +37,19 @@ pub struct TileRect(pub i32, pub i32, pub i32, pub i32); #[allow(dead_code)] impl TileRect { - pub fn empty() -> Self { + pub fn new_empty() -> Self { Self(0, 0, 0, 0) } + pub fn from_scaled(other: &TileRect, scale: f32) -> Self { + Self ( + (other.0 as f32 * scale).trunc() as i32, + (other.1 as f32 * scale).trunc() as i32, + (other.2 as f32 * scale).trunc() as i32, + (other.3 as f32 * scale).trunc() as i32, + ) + } + #[inline(always)] pub fn is_degenerate(&self) -> bool { self.left() > self.right() || self.top() > self.bottom() @@ -121,6 +130,13 @@ impl TileRect { && tile.y() <= self.bottom() } + pub fn set_from_tile_bounds(&mut self, l: f32, t: f32, r: f32, b: f32, tile_size: f32) { + self.0 = (l / tile_size) as i32; + self.1 = (t / tile_size) as i32; + self.2 = (r / tile_size) as i32; + self.3 = (b / tile_size) as i32; + } + pub fn iter(self, inclusive: bool) -> TileRectIter { TileRectIter::new(self, inclusive) } @@ -269,6 +285,13 @@ impl TileHashMap { true } + pub fn has_shape_at(&self, tile: Tile, id: Uuid) -> bool { + let Some(shapes) = self.grid.get(&tile) else { + return false; + }; + shapes.contains(&id) + } + pub fn get_shapes_at(&mut self, tile: Tile) -> Option<&HashSet> { self.grid.get(&tile) } @@ -409,7 +432,7 @@ impl PendingTiles { Self { list: Vec::with_capacity(VIEWPORT_DEFAULT_CAPACITY), spiral: TileSpiral::new(), - spiral_rect: TileRect::empty(), + spiral_rect: TileRect::new_empty(), visible_cached: Vec::with_capacity(VIEWPORT_DEFAULT_CAPACITY), visible_uncached: Vec::with_capacity(VIEWPORT_DEFAULT_CAPACITY), interest_cached: Vec::with_capacity(VIEWPORT_DEFAULT_CAPACITY),