diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index c11799dce6..dbaac9252e 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -778,13 +778,7 @@ (defn set-objects [objects] (perf/begin-measure "set-objects") - #_(do - (api-js/setObjects objects set-object) - (clear-drawing-cache) - (request-render "set-objects") - (perf/end-measure "set-objects")) - (let [get-memory-measure (perf/memory-measure) - shapes (into [] (vals objects)) + (let [shapes (into [] (vals objects)) total-shapes (count shapes) pending (loop [index 0 pending []] @@ -792,8 +786,7 @@ (let [shape (nth shapes index) pending' (set-object objects shape)] (recur (inc index) (into pending pending'))) - pending)) - _ (js/console.log (clj->js (get-memory-measure)))] + pending))] (perf/end-measure "set-objects") (clear-drawing-cache) (request-render "set-objects") diff --git a/frontend/src/app/render_wasm/api.js b/frontend/src/app/render_wasm/api.js deleted file mode 100644 index 0667a34fda..0000000000 --- a/frontend/src/app/render_wasm/api.js +++ /dev/null @@ -1,7 +0,0 @@ -export function setObject(object) { - console.log(object.id) -} - -export function setObjects(objects, fn) { - objects.forEach((object) => fn(objects, object)) -} diff --git a/render-wasm/Cargo.toml b/render-wasm/Cargo.toml index 9d786c471a..55f41c1e2d 100644 --- a/render-wasm/Cargo.toml +++ b/render-wasm/Cargo.toml @@ -7,7 +7,7 @@ license-file = "../LICENSE" description = "Wasm-based canvas renderer for Penpot" [features] -default = ["profile"] +default = [] profile = ["profile-macros", "profile-raf"] profile-macros = [] profile-raf = [] diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs index 6eb76d5f43..67fab0e98c 100644 --- a/render-wasm/src/render.rs +++ b/render-wasm/src/render.rs @@ -279,18 +279,14 @@ impl RenderState { Some(&skia::Paint::default()), ); } + let surface_ids = SurfaceId::Strokes as u32 + | SurfaceId::Fills as u32 + | SurfaceId::DropShadows as u32 + | SurfaceId::InnerShadows as u32; - self.surfaces.apply_mut( - &[ - SurfaceId::DropShadows, - SurfaceId::InnerShadows, - SurfaceId::Fills, - SurfaceId::Strokes, - ], - |s| { - s.canvas().clear(skia::Color::TRANSPARENT); - }, - ); + self.surfaces.apply_mut(surface_ids, |s| { + s.canvas().clear(skia::Color::TRANSPARENT); + }); } pub fn render_shape( @@ -306,12 +302,10 @@ impl RenderState { shape }; - let surface_ids = &[ - SurfaceId::Fills, - SurfaceId::Strokes, - SurfaceId::DropShadows, - SurfaceId::InnerShadows, - ]; + let surface_ids = SurfaceId::Strokes as u32 + | SurfaceId::Fills as u32 + | SurfaceId::DropShadows as u32 + | SurfaceId::InnerShadows as u32; self.surfaces.apply_mut(surface_ids, |s| { s.canvas().save(); }); @@ -391,17 +385,13 @@ impl RenderState { } Type::Text(text_content) => { - self.surfaces.apply_mut( - &[ - SurfaceId::Fills, - SurfaceId::Strokes, - SurfaceId::DropShadows, - SurfaceId::InnerShadows, - ], - |s| { - s.canvas().concat(&matrix); - }, - ); + let surface_ids = SurfaceId::Strokes as u32 + | SurfaceId::Fills as u32 + | SurfaceId::DropShadows as u32 + | SurfaceId::InnerShadows as u32; + self.surfaces.apply_mut(surface_ids, |s| { + s.canvas().concat(&matrix); + }); let text_content = text_content.new_bounds(shape.selrect()); let paragraphs = text_content.get_skia_paragraphs(self.fonts.font_collection()); @@ -437,17 +427,13 @@ impl RenderState { shadows::render_text_inner_shadows(self, &shape, ¶graphs, antialias); } _ => { - self.surfaces.apply_mut( - &[ - SurfaceId::Fills, - SurfaceId::Strokes, - SurfaceId::DropShadows, - SurfaceId::InnerShadows, - ], - |s| { - s.canvas().concat(&matrix); - }, - ); + let surface_ids = SurfaceId::Strokes as u32 + | SurfaceId::Fills as u32 + | SurfaceId::DropShadows as u32 + | SurfaceId::InnerShadows as u32; + self.surfaces.apply_mut(surface_ids, |s| { + s.canvas().concat(&matrix); + }); for fill in shape.fills().rev() { fills::render(self, &shape, fill, antialias); @@ -465,17 +451,13 @@ impl RenderState { }; self.apply_drawing_to_render_canvas(Some(&shape)); - self.surfaces.apply_mut( - &[ - SurfaceId::Fills, - SurfaceId::Strokes, - SurfaceId::DropShadows, - SurfaceId::InnerShadows, - ], - |s| { - s.canvas().restore(); - }, - ); + let surface_ids = SurfaceId::Strokes as u32 + | SurfaceId::Fills as u32 + | SurfaceId::DropShadows as u32 + | SurfaceId::InnerShadows as u32; + self.surfaces.apply_mut(surface_ids, |s| { + s.canvas().restore(); + }); } pub fn update_render_context(&mut self, tile: tiles::Tile) { @@ -543,17 +525,13 @@ impl RenderState { performance::begin_measure!("start_render_loop"); self.reset_canvas(); - self.surfaces.apply_mut( - &[ - SurfaceId::Fills, - SurfaceId::Strokes, - SurfaceId::DropShadows, - SurfaceId::InnerShadows, - ], - |s| { - s.canvas().scale((scale, scale)); - }, - ); + let surface_ids = SurfaceId::Strokes as u32 + | SurfaceId::Fills as u32 + | SurfaceId::DropShadows as u32 + | SurfaceId::InnerShadows as u32; + self.surfaces.apply_mut(surface_ids, |s| { + s.canvas().scale((scale, scale)); + }); let viewbox_cache_size = get_cache_size(self.viewbox, scale); let cached_viewbox_cache_size = get_cache_size(self.cached_viewbox, scale); @@ -573,7 +551,8 @@ impl RenderState { self.pending_nodes.clear(); if self.pending_nodes.capacity() < tree.len() { - self.pending_nodes.reserve(tree.len() - self.pending_nodes.capacity()); + self.pending_nodes + .reserve(tree.len() - self.pending_nodes.capacity()); } // reorder by distance to the center. self.current_tile = None; @@ -887,7 +866,7 @@ impl RenderState { if !is_empty { self.apply_render_to_final_canvas(tile_rect); } else { - self.surfaces.apply_mut(&[SurfaceId::Target], |s| { + self.surfaces.apply_mut(SurfaceId::Target as u32, |s| { let mut paint = skia::Paint::default(); paint.set_color(self.background_color); s.canvas().draw_rect(tile_rect, &paint); diff --git a/render-wasm/src/render/surfaces.rs b/render-wasm/src/render/surfaces.rs index d1c1b513f9..ef479d9d9b 100644 --- a/render-wasm/src/render/surfaces.rs +++ b/render-wasm/src/render/surfaces.rs @@ -1,4 +1,6 @@ +use crate::performance; use crate::shapes::Shape; + use skia_safe::{self as skia, IRect, Paint, RRect}; use super::{gpu_state::GpuState, tiles::Tile, tiles::TileViewbox, tiles::TILE_SIZE}; @@ -12,16 +14,17 @@ const TEXTURES_BATCH_DELETE: usize = 32; // If it's too big it could affect performance. const TILE_SIZE_MULTIPLIER: i32 = 2; +#[repr(u32)] #[derive(Debug, PartialEq, Clone, Copy)] pub enum SurfaceId { - Target, - Cache, - Current, - Fills, - Strokes, - DropShadows, - InnerShadows, - Debug, + Target = 0b0000_0001, + Cache = 0b0000_0010, + Current = 0b0000_0100, + Fills = 0b0000_1000, + Strokes = 0b0001_0000, + DropShadows = 0b0010_0000, + InnerShadows = 0b0100_0000, + Debug = 0b1000_0000, } pub struct Surfaces { @@ -137,11 +140,33 @@ impl Surfaces { .draw(self.canvas(to), (0.0, 0.0), sampling_options, paint); } - pub fn apply_mut(&mut self, ids: &[SurfaceId], mut f: impl FnMut(&mut skia::Surface)) { - for id in ids { - let surface = self.get_mut(*id); - f(surface); + pub fn apply_mut(&mut self, ids: u32, mut f: impl FnMut(&mut skia::Surface)) { + performance::begin_measure!("apply_mut::flags"); + if ids & SurfaceId::Target as u32 != 0 { + f(self.get_mut(SurfaceId::Target)); } + if ids & SurfaceId::Current as u32 != 0 { + f(self.get_mut(SurfaceId::Current)); + } + if ids & SurfaceId::Cache as u32 != 0 { + f(self.get_mut(SurfaceId::Cache)); + } + if ids & SurfaceId::Fills as u32 != 0 { + f(self.get_mut(SurfaceId::Fills)); + } + if ids & SurfaceId::Strokes as u32 != 0 { + f(self.get_mut(SurfaceId::Strokes)); + } + if ids & SurfaceId::InnerShadows as u32 != 0 { + f(self.get_mut(SurfaceId::InnerShadows)); + } + if ids & SurfaceId::DropShadows as u32 != 0 { + f(self.get_mut(SurfaceId::DropShadows)); + } + if ids & SurfaceId::Debug as u32 != 0 { + f(self.get_mut(SurfaceId::Debug)); + } + performance::begin_measure!("apply_mut::flags"); } pub fn update_render_context(&mut self, render_area: skia::Rect, scale: f32) { @@ -150,12 +175,10 @@ impl Surfaces { -render_area.top() + self.margins.height as f32 / scale, ); self.apply_mut( - &[ - SurfaceId::Fills, - SurfaceId::Strokes, - SurfaceId::DropShadows, - SurfaceId::InnerShadows, - ], + SurfaceId::Fills as u32 + | SurfaceId::Strokes as u32 + | SurfaceId::DropShadows as u32 + | SurfaceId::InnerShadows as u32, |s| { s.canvas().restore(); s.canvas().save(); @@ -164,6 +187,7 @@ impl Surfaces { ); } + #[inline] fn get_mut(&mut self, id: SurfaceId) -> &mut skia::Surface { match id { SurfaceId::Target => &mut self.target, @@ -224,13 +248,11 @@ impl Surfaces { self.canvas(SurfaceId::Strokes).restore_to_count(1); self.canvas(SurfaceId::Current).restore_to_count(1); self.apply_mut( - &[ - SurfaceId::Fills, - SurfaceId::Strokes, - SurfaceId::Current, - SurfaceId::DropShadows, - SurfaceId::InnerShadows, - ], + SurfaceId::Fills as u32 + | SurfaceId::Strokes as u32 + | SurfaceId::Current as u32 + | SurfaceId::DropShadows as u32 + | SurfaceId::InnerShadows as u32, |s| { s.canvas().clear(color).reset_matrix(); }, diff --git a/render-wasm/src/state.rs b/render-wasm/src/state.rs index 0e5c9691e9..4607bea8e9 100644 --- a/render-wasm/src/state.rs +++ b/render-wasm/src/state.rs @@ -52,9 +52,7 @@ impl ShapesPool { } self.shapes.extend( - iter::repeat_with( - || Box::new(Shape::new(Uuid::nil())) - ).take(additional as usize) + iter::repeat_with(|| Box::new(Shape::new(Uuid::nil()))).take(additional as usize), ); performance::end_measure!("shapes_pool_initialize"); } @@ -62,11 +60,8 @@ impl ShapesPool { pub fn add_shape(&mut self, id: Uuid) -> &mut Shape { if self.counter >= self.shapes.len() { let additional = (self.shapes.len() as f32 * SHAPES_POOL_ALLOC_MULTIPLIER) as usize; - self.shapes.extend( - iter::repeat_with( - || Box::new(Shape::new(Uuid::nil())) - ).take(additional) - ); + self.shapes + .extend(iter::repeat_with(|| Box::new(Shape::new(Uuid::nil()))).take(additional)); } let new_shape = &mut self.shapes[self.counter]; new_shape.id = id;