This commit is contained in:
Aitor Moreno 2026-06-24 17:38:16 +02:00
parent 2ed7e55c31
commit 37add2c6d4
5 changed files with 72 additions and 16 deletions

View File

@ -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;

View File

@ -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<Rect> = 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(&current_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(
&current_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

View File

@ -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;

View File

@ -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<Option<math::Rect>>,
pub svg_transform: Option<Matrix>,
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;
}

View File

@ -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<Uuid>> {
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),