mirror of
https://github.com/penpot/penpot.git
synced 2025-07-13 12:27:18 +02:00
♻️ Refactor surface iteration
This commit is contained in:
parent
8922e7454f
commit
fcd3e5c34c
6 changed files with 95 additions and 113 deletions
|
@ -778,13 +778,7 @@
|
||||||
(defn set-objects
|
(defn set-objects
|
||||||
[objects]
|
[objects]
|
||||||
(perf/begin-measure "set-objects")
|
(perf/begin-measure "set-objects")
|
||||||
#_(do
|
(let [shapes (into [] (vals objects))
|
||||||
(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))
|
|
||||||
total-shapes (count shapes)
|
total-shapes (count shapes)
|
||||||
pending
|
pending
|
||||||
(loop [index 0 pending []]
|
(loop [index 0 pending []]
|
||||||
|
@ -792,8 +786,7 @@
|
||||||
(let [shape (nth shapes index)
|
(let [shape (nth shapes index)
|
||||||
pending' (set-object objects shape)]
|
pending' (set-object objects shape)]
|
||||||
(recur (inc index) (into pending pending')))
|
(recur (inc index) (into pending pending')))
|
||||||
pending))
|
pending))]
|
||||||
_ (js/console.log (clj->js (get-memory-measure)))]
|
|
||||||
(perf/end-measure "set-objects")
|
(perf/end-measure "set-objects")
|
||||||
(clear-drawing-cache)
|
(clear-drawing-cache)
|
||||||
(request-render "set-objects")
|
(request-render "set-objects")
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
export function setObject(object) {
|
|
||||||
console.log(object.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setObjects(objects, fn) {
|
|
||||||
objects.forEach((object) => fn(objects, object))
|
|
||||||
}
|
|
|
@ -7,7 +7,7 @@ license-file = "../LICENSE"
|
||||||
description = "Wasm-based canvas renderer for Penpot"
|
description = "Wasm-based canvas renderer for Penpot"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["profile"]
|
default = []
|
||||||
profile = ["profile-macros", "profile-raf"]
|
profile = ["profile-macros", "profile-raf"]
|
||||||
profile-macros = []
|
profile-macros = []
|
||||||
profile-raf = []
|
profile-raf = []
|
||||||
|
|
|
@ -279,18 +279,14 @@ impl RenderState {
|
||||||
Some(&skia::Paint::default()),
|
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(
|
self.surfaces.apply_mut(surface_ids, |s| {
|
||||||
&[
|
s.canvas().clear(skia::Color::TRANSPARENT);
|
||||||
SurfaceId::DropShadows,
|
});
|
||||||
SurfaceId::InnerShadows,
|
|
||||||
SurfaceId::Fills,
|
|
||||||
SurfaceId::Strokes,
|
|
||||||
],
|
|
||||||
|s| {
|
|
||||||
s.canvas().clear(skia::Color::TRANSPARENT);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_shape(
|
pub fn render_shape(
|
||||||
|
@ -306,12 +302,10 @@ impl RenderState {
|
||||||
shape
|
shape
|
||||||
};
|
};
|
||||||
|
|
||||||
let surface_ids = &[
|
let surface_ids = SurfaceId::Strokes as u32
|
||||||
SurfaceId::Fills,
|
| SurfaceId::Fills as u32
|
||||||
SurfaceId::Strokes,
|
| SurfaceId::DropShadows as u32
|
||||||
SurfaceId::DropShadows,
|
| SurfaceId::InnerShadows as u32;
|
||||||
SurfaceId::InnerShadows,
|
|
||||||
];
|
|
||||||
self.surfaces.apply_mut(surface_ids, |s| {
|
self.surfaces.apply_mut(surface_ids, |s| {
|
||||||
s.canvas().save();
|
s.canvas().save();
|
||||||
});
|
});
|
||||||
|
@ -391,17 +385,13 @@ impl RenderState {
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Text(text_content) => {
|
Type::Text(text_content) => {
|
||||||
self.surfaces.apply_mut(
|
let surface_ids = SurfaceId::Strokes as u32
|
||||||
&[
|
| SurfaceId::Fills as u32
|
||||||
SurfaceId::Fills,
|
| SurfaceId::DropShadows as u32
|
||||||
SurfaceId::Strokes,
|
| SurfaceId::InnerShadows as u32;
|
||||||
SurfaceId::DropShadows,
|
self.surfaces.apply_mut(surface_ids, |s| {
|
||||||
SurfaceId::InnerShadows,
|
s.canvas().concat(&matrix);
|
||||||
],
|
});
|
||||||
|s| {
|
|
||||||
s.canvas().concat(&matrix);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let text_content = text_content.new_bounds(shape.selrect());
|
let text_content = text_content.new_bounds(shape.selrect());
|
||||||
let paragraphs = text_content.get_skia_paragraphs(self.fonts.font_collection());
|
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);
|
shadows::render_text_inner_shadows(self, &shape, ¶graphs, antialias);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.surfaces.apply_mut(
|
let surface_ids = SurfaceId::Strokes as u32
|
||||||
&[
|
| SurfaceId::Fills as u32
|
||||||
SurfaceId::Fills,
|
| SurfaceId::DropShadows as u32
|
||||||
SurfaceId::Strokes,
|
| SurfaceId::InnerShadows as u32;
|
||||||
SurfaceId::DropShadows,
|
self.surfaces.apply_mut(surface_ids, |s| {
|
||||||
SurfaceId::InnerShadows,
|
s.canvas().concat(&matrix);
|
||||||
],
|
});
|
||||||
|s| {
|
|
||||||
s.canvas().concat(&matrix);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
for fill in shape.fills().rev() {
|
for fill in shape.fills().rev() {
|
||||||
fills::render(self, &shape, fill, antialias);
|
fills::render(self, &shape, fill, antialias);
|
||||||
|
@ -465,17 +451,13 @@ impl RenderState {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.apply_drawing_to_render_canvas(Some(&shape));
|
self.apply_drawing_to_render_canvas(Some(&shape));
|
||||||
self.surfaces.apply_mut(
|
let surface_ids = SurfaceId::Strokes as u32
|
||||||
&[
|
| SurfaceId::Fills as u32
|
||||||
SurfaceId::Fills,
|
| SurfaceId::DropShadows as u32
|
||||||
SurfaceId::Strokes,
|
| SurfaceId::InnerShadows as u32;
|
||||||
SurfaceId::DropShadows,
|
self.surfaces.apply_mut(surface_ids, |s| {
|
||||||
SurfaceId::InnerShadows,
|
s.canvas().restore();
|
||||||
],
|
});
|
||||||
|s| {
|
|
||||||
s.canvas().restore();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_render_context(&mut self, tile: tiles::Tile) {
|
pub fn update_render_context(&mut self, tile: tiles::Tile) {
|
||||||
|
@ -543,17 +525,13 @@ impl RenderState {
|
||||||
performance::begin_measure!("start_render_loop");
|
performance::begin_measure!("start_render_loop");
|
||||||
|
|
||||||
self.reset_canvas();
|
self.reset_canvas();
|
||||||
self.surfaces.apply_mut(
|
let surface_ids = SurfaceId::Strokes as u32
|
||||||
&[
|
| SurfaceId::Fills as u32
|
||||||
SurfaceId::Fills,
|
| SurfaceId::DropShadows as u32
|
||||||
SurfaceId::Strokes,
|
| SurfaceId::InnerShadows as u32;
|
||||||
SurfaceId::DropShadows,
|
self.surfaces.apply_mut(surface_ids, |s| {
|
||||||
SurfaceId::InnerShadows,
|
s.canvas().scale((scale, scale));
|
||||||
],
|
});
|
||||||
|s| {
|
|
||||||
s.canvas().scale((scale, scale));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let viewbox_cache_size = get_cache_size(self.viewbox, scale);
|
let viewbox_cache_size = get_cache_size(self.viewbox, scale);
|
||||||
let cached_viewbox_cache_size = get_cache_size(self.cached_viewbox, scale);
|
let cached_viewbox_cache_size = get_cache_size(self.cached_viewbox, scale);
|
||||||
|
@ -573,7 +551,8 @@ impl RenderState {
|
||||||
|
|
||||||
self.pending_nodes.clear();
|
self.pending_nodes.clear();
|
||||||
if self.pending_nodes.capacity() < tree.len() {
|
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.
|
// reorder by distance to the center.
|
||||||
self.current_tile = None;
|
self.current_tile = None;
|
||||||
|
@ -887,7 +866,7 @@ impl RenderState {
|
||||||
if !is_empty {
|
if !is_empty {
|
||||||
self.apply_render_to_final_canvas(tile_rect);
|
self.apply_render_to_final_canvas(tile_rect);
|
||||||
} else {
|
} else {
|
||||||
self.surfaces.apply_mut(&[SurfaceId::Target], |s| {
|
self.surfaces.apply_mut(SurfaceId::Target as u32, |s| {
|
||||||
let mut paint = skia::Paint::default();
|
let mut paint = skia::Paint::default();
|
||||||
paint.set_color(self.background_color);
|
paint.set_color(self.background_color);
|
||||||
s.canvas().draw_rect(tile_rect, &paint);
|
s.canvas().draw_rect(tile_rect, &paint);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
use crate::performance;
|
||||||
use crate::shapes::Shape;
|
use crate::shapes::Shape;
|
||||||
|
|
||||||
use skia_safe::{self as skia, IRect, Paint, RRect};
|
use skia_safe::{self as skia, IRect, Paint, RRect};
|
||||||
|
|
||||||
use super::{gpu_state::GpuState, tiles::Tile, tiles::TileViewbox, tiles::TILE_SIZE};
|
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.
|
// If it's too big it could affect performance.
|
||||||
const TILE_SIZE_MULTIPLIER: i32 = 2;
|
const TILE_SIZE_MULTIPLIER: i32 = 2;
|
||||||
|
|
||||||
|
#[repr(u32)]
|
||||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||||
pub enum SurfaceId {
|
pub enum SurfaceId {
|
||||||
Target,
|
Target = 0b0000_0001,
|
||||||
Cache,
|
Cache = 0b0000_0010,
|
||||||
Current,
|
Current = 0b0000_0100,
|
||||||
Fills,
|
Fills = 0b0000_1000,
|
||||||
Strokes,
|
Strokes = 0b0001_0000,
|
||||||
DropShadows,
|
DropShadows = 0b0010_0000,
|
||||||
InnerShadows,
|
InnerShadows = 0b0100_0000,
|
||||||
Debug,
|
Debug = 0b1000_0000,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Surfaces {
|
pub struct Surfaces {
|
||||||
|
@ -137,11 +140,33 @@ impl Surfaces {
|
||||||
.draw(self.canvas(to), (0.0, 0.0), sampling_options, paint);
|
.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)) {
|
pub fn apply_mut(&mut self, ids: u32, mut f: impl FnMut(&mut skia::Surface)) {
|
||||||
for id in ids {
|
performance::begin_measure!("apply_mut::flags");
|
||||||
let surface = self.get_mut(*id);
|
if ids & SurfaceId::Target as u32 != 0 {
|
||||||
f(surface);
|
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) {
|
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,
|
-render_area.top() + self.margins.height as f32 / scale,
|
||||||
);
|
);
|
||||||
self.apply_mut(
|
self.apply_mut(
|
||||||
&[
|
SurfaceId::Fills as u32
|
||||||
SurfaceId::Fills,
|
| SurfaceId::Strokes as u32
|
||||||
SurfaceId::Strokes,
|
| SurfaceId::DropShadows as u32
|
||||||
SurfaceId::DropShadows,
|
| SurfaceId::InnerShadows as u32,
|
||||||
SurfaceId::InnerShadows,
|
|
||||||
],
|
|
||||||
|s| {
|
|s| {
|
||||||
s.canvas().restore();
|
s.canvas().restore();
|
||||||
s.canvas().save();
|
s.canvas().save();
|
||||||
|
@ -164,6 +187,7 @@ impl Surfaces {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn get_mut(&mut self, id: SurfaceId) -> &mut skia::Surface {
|
fn get_mut(&mut self, id: SurfaceId) -> &mut skia::Surface {
|
||||||
match id {
|
match id {
|
||||||
SurfaceId::Target => &mut self.target,
|
SurfaceId::Target => &mut self.target,
|
||||||
|
@ -224,13 +248,11 @@ impl Surfaces {
|
||||||
self.canvas(SurfaceId::Strokes).restore_to_count(1);
|
self.canvas(SurfaceId::Strokes).restore_to_count(1);
|
||||||
self.canvas(SurfaceId::Current).restore_to_count(1);
|
self.canvas(SurfaceId::Current).restore_to_count(1);
|
||||||
self.apply_mut(
|
self.apply_mut(
|
||||||
&[
|
SurfaceId::Fills as u32
|
||||||
SurfaceId::Fills,
|
| SurfaceId::Strokes as u32
|
||||||
SurfaceId::Strokes,
|
| SurfaceId::Current as u32
|
||||||
SurfaceId::Current,
|
| SurfaceId::DropShadows as u32
|
||||||
SurfaceId::DropShadows,
|
| SurfaceId::InnerShadows as u32,
|
||||||
SurfaceId::InnerShadows,
|
|
||||||
],
|
|
||||||
|s| {
|
|s| {
|
||||||
s.canvas().clear(color).reset_matrix();
|
s.canvas().clear(color).reset_matrix();
|
||||||
},
|
},
|
||||||
|
|
|
@ -52,9 +52,7 @@ impl ShapesPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.shapes.extend(
|
self.shapes.extend(
|
||||||
iter::repeat_with(
|
iter::repeat_with(|| Box::new(Shape::new(Uuid::nil()))).take(additional as usize),
|
||||||
|| Box::new(Shape::new(Uuid::nil()))
|
|
||||||
).take(additional as usize)
|
|
||||||
);
|
);
|
||||||
performance::end_measure!("shapes_pool_initialize");
|
performance::end_measure!("shapes_pool_initialize");
|
||||||
}
|
}
|
||||||
|
@ -62,11 +60,8 @@ impl ShapesPool {
|
||||||
pub fn add_shape(&mut self, id: Uuid) -> &mut Shape {
|
pub fn add_shape(&mut self, id: Uuid) -> &mut Shape {
|
||||||
if self.counter >= self.shapes.len() {
|
if self.counter >= self.shapes.len() {
|
||||||
let additional = (self.shapes.len() as f32 * SHAPES_POOL_ALLOC_MULTIPLIER) as usize;
|
let additional = (self.shapes.len() as f32 * SHAPES_POOL_ALLOC_MULTIPLIER) as usize;
|
||||||
self.shapes.extend(
|
self.shapes
|
||||||
iter::repeat_with(
|
.extend(iter::repeat_with(|| Box::new(Shape::new(Uuid::nil()))).take(additional));
|
||||||
|| Box::new(Shape::new(Uuid::nil()))
|
|
||||||
).take(additional)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
let new_shape = &mut self.shapes[self.counter];
|
let new_shape = &mut self.shapes[self.counter];
|
||||||
new_shape.id = id;
|
new_shape.id = id;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue