diff --git a/frontend/resources/wasm-playground/js/lib.js b/frontend/resources/wasm-playground/js/lib.js
index 23656a280..5be649e7b 100644
--- a/frontend/resources/wasm-playground/js/lib.js
+++ b/frontend/resources/wasm-playground/js/lib.js
@@ -108,6 +108,11 @@ export function useShape(id) {
Module._use_shape(...buffer);
}
+export function set_parent(id) {
+ const buffer = getU32(id);
+ Module._set_parent(...buffer);
+}
+
export function setupInteraction(canvas) {
canvas.addEventListener("wheel", (e) => {
e.preventDefault();
diff --git a/frontend/resources/wasm-playground/masks.html b/frontend/resources/wasm-playground/masks.html
new file mode 100644
index 000000000..6c89d7e8b
--- /dev/null
+++ b/frontend/resources/wasm-playground/masks.html
@@ -0,0 +1,86 @@
+
+
+
+
+ WASM + WebGL2 Canvas
+
+
+
+
+
+
+
diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs
index 1fbc29473..a15639372 100644
--- a/render-wasm/src/render.rs
+++ b/render-wasm/src/render.rs
@@ -1,7 +1,7 @@
use skia_safe::{self as skia, image, Matrix, RRect, Rect};
use crate::uuid::Uuid;
-use std::collections::{HashMap, HashSet, VecDeque};
+use std::collections::{HashMap, HashSet};
use crate::performance;
use crate::view::Viewbox;
@@ -90,7 +90,7 @@ pub(crate) struct RenderState {
// Indicates whether the rendering process has pending frames.
pub render_in_progress: bool,
// Stack of nodes pending to be rendered.
- pub pending_nodes: VecDeque,
+ pub pending_nodes: Vec,
pub current_tile: Option,
pub sampling_options: skia::SamplingOptions,
pub render_area: Rect,
@@ -146,7 +146,7 @@ impl RenderState {
background_color: skia::Color::TRANSPARENT,
render_request_id: None,
render_in_progress: false,
- pending_nodes: VecDeque::new(),
+ pending_nodes: vec![],
current_tile: None,
sampling_options,
render_area: Rect::new_empty(),
@@ -552,7 +552,7 @@ impl RenderState {
}
performance::end_measure!("tile_cache");
- self.pending_nodes = VecDeque::new();
+ self.pending_nodes = vec![];
// reorder by distance to the center.
self.pending_tiles.sort_by(|a, b| b.2.cmp(&a.2));
self.current_tile = None;
@@ -720,7 +720,7 @@ impl RenderState {
performance::begin_measure!("render_shape_tree::uncached");
let mut i = 0;
let mut is_empty = true;
- while let Some(node_render_state) = self.pending_nodes.pop_front() {
+ while let Some(node_render_state) = self.pending_nodes.pop() {
let NodeRenderState {
id: node_id,
visited_children,
@@ -751,7 +751,7 @@ impl RenderState {
// the blend mode 'destination-in') the content
// of the group and the mask.
if group.masked {
- self.pending_nodes.push_back(NodeRenderState {
+ self.pending_nodes.push(NodeRenderState {
id: node_id,
visited_children: true,
clip_bounds: None,
@@ -759,7 +759,7 @@ impl RenderState {
mask: false,
});
if let Some(&mask_id) = element.mask_id() {
- self.pending_nodes.push_back(NodeRenderState {
+ self.pending_nodes.push(NodeRenderState {
id: mask_id,
visited_children: false,
clip_bounds: None,
@@ -801,7 +801,7 @@ impl RenderState {
}
// Set the node as visited_children before processing children
- self.pending_nodes.push_back(NodeRenderState {
+ self.pending_nodes.push(NodeRenderState {
id: node_id,
visited_children: true,
clip_bounds: None,
@@ -825,8 +825,8 @@ impl RenderState {
});
}
- for child_id in children_ids.iter().rev() {
- self.pending_nodes.push_front(NodeRenderState {
+ for child_id in children_ids.iter() {
+ self.pending_nodes.push(NodeRenderState {
id: *child_id,
visited_children: false,
clip_bounds: children_clip_bounds,
diff --git a/render-wasm/src/shapes.rs b/render-wasm/src/shapes.rs
index b35724a15..036a76944 100644
--- a/render-wasm/src/shapes.rs
+++ b/render-wasm/src/shapes.rs
@@ -635,12 +635,17 @@ impl Shape {
IndexSet::::new()
} else if let Type::Group(group) = self.shape_type {
if group.masked {
- self.children.iter().skip(1).cloned().collect()
+ self.children
+ .iter()
+ .rev()
+ .take(self.children.len() - 1)
+ .cloned()
+ .collect()
} else {
- self.children.clone().into_iter().collect()
+ self.children.clone().into_iter().rev().collect()
}
} else {
- self.children.clone().into_iter().collect()
+ self.children.clone().into_iter().rev().collect()
}
}