[librsvg: 11/22] NodePattern: cache the resolved Pattern
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 11/22] NodePattern: cache the resolved Pattern
- Date: Wed, 2 Oct 2019 21:44:33 +0000 (UTC)
commit 41e5c9d1d0cbe662c6f9b14a9846a006c4b5f319
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Oct 1 14:24:28 2019 -0500
NodePattern: cache the resolved Pattern
This adds back RsvgWeakNode, since the cached pattern needs a
reference back ot the node that contains the pattern's resolved
children. This would cause a reference cycle if it used a strong
reference.
rsvg_internals/src/node.rs | 2 +-
rsvg_internals/src/pattern.rs | 29 +++++++++++++++++++++++------
2 files changed, 24 insertions(+), 7 deletions(-)
---
diff --git a/rsvg_internals/src/node.rs b/rsvg_internals/src/node.rs
index 4566fec0..fa3f7b26 100644
--- a/rsvg_internals/src/node.rs
+++ b/rsvg_internals/src/node.rs
@@ -20,7 +20,7 @@ use rctree;
/// Tree node with specific data
pub type RsvgNode = rctree::Node<NodeData>;
-//pub type RsvgWeakNode = rctree::WeakNode<NodeData>;
+pub type RsvgWeakNode = rctree::WeakNode<NodeData>;
/// Contents of a tree node
pub struct NodeData {
diff --git a/rsvg_internals/src/pattern.rs b/rsvg_internals/src/pattern.rs
index 6be35fd2..c7297da9 100644
--- a/rsvg_internals/src/pattern.rs
+++ b/rsvg_internals/src/pattern.rs
@@ -1,5 +1,6 @@
use cairo;
use markup5ever::local_name;
+use std::cell::RefCell;
use std::f64;
use crate::allowed_url::Fragment;
@@ -63,6 +64,7 @@ struct UnresolvedPattern {
}
/// Resolved pattern
+#[derive(Clone)]
pub struct Pattern {
units: PatternUnits,
content_units: PatternContentUnits,
@@ -78,13 +80,19 @@ pub struct Pattern {
width: LengthHorizontal,
height: LengthVertical,
- node: Option<RsvgNode>,
+ // Link to the node whose children are the pattern's resolved children.
+ //
+ // We use a weak reference because this struct Pattern may be
+ // memoized within the corresponding NodePattern, and we don't
+ // want to create a reference cycle.
+ node: Option<RsvgWeakNode>,
}
-#[derive(Clone, Default)]
+#[derive(Default)]
pub struct NodePattern {
common: Common,
fallback: Option<Fragment>,
+ resolved: RefCell<Option<Pattern>>,
}
impl NodeTrait for NodePattern {
@@ -131,6 +139,11 @@ impl PaintSource for NodePattern {
node: &RsvgNode,
draw_ctx: &mut DrawingCtx,
) -> Result<Self::Resolved, PaintServerError> {
+ let mut resolved = self.resolved.borrow_mut();
+ if let Some(ref pattern) = *resolved {
+ return Ok(pattern.clone());
+ }
+
let Unresolved { mut pattern, mut fallback } = self.get_unresolved(node);
let mut stack = NodeStack::new();
@@ -163,7 +176,11 @@ impl PaintSource for NodePattern {
}
}
- Ok(pattern.to_resolved())
+ let pattern = pattern.to_resolved();
+
+ *resolved = Some(pattern.clone());
+
+ Ok(pattern)
}
}
@@ -324,8 +341,8 @@ impl ResolvedPaintSource for Pattern {
// Set up transformations to be determined by the contents units
// Draw everything
- let pattern_node = self.node.as_ref().unwrap();
- let pattern_cascaded = CascadedValues::new_from_node(pattern_node);
+ let pattern_node = self.node.as_ref().unwrap().upgrade().unwrap();
+ let pattern_cascaded = CascadedValues::new_from_node(&pattern_node);
let pattern_values = pattern_cascaded.get();
cr_pattern.set_matrix(caffine);
@@ -370,7 +387,7 @@ impl UnresolvedPattern {
width: self.common.width.unwrap(),
height: self.common.height.unwrap(),
- node: self.node.clone(),
+ node: self.node.clone().map(|n| n.downgrade()),
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]