[librsvg: 1/2] filters: simplify code to render filters
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 1/2] filters: simplify code to render filters
- Date: Mon, 3 Jun 2019 19:54:34 +0000 (UTC)
commit adcb65f8f82b3e6debd2fb675ba9b050f76b61c8
Author: Paolo Borelli <pborelli gnome org>
Date: Sun Jun 2 16:15:03 2019 +0200
filters: simplify code to render filters
Instead of using owning_ref, we define an as_filter method
on the NodeTrait that returns None for other nodes and returns
the Filter trait for filter primitives.
Cargo.lock | 16 ----
rsvg_internals/Cargo.toml | 1 -
rsvg_internals/src/filters/blend.rs | 2 +
rsvg_internals/src/filters/color_matrix.rs | 2 +
rsvg_internals/src/filters/component_transfer.rs | 2 +
rsvg_internals/src/filters/composite.rs | 2 +
rsvg_internals/src/filters/convolve_matrix.rs | 2 +
rsvg_internals/src/filters/displacement_map.rs | 2 +
rsvg_internals/src/filters/flood.rs | 2 +
rsvg_internals/src/filters/gaussian_blur.rs | 2 +
rsvg_internals/src/filters/image.rs | 2 +
rsvg_internals/src/filters/light/lighting.rs | 2 +
rsvg_internals/src/filters/merge.rs | 2 +
rsvg_internals/src/filters/mod.rs | 113 +++++++----------------
rsvg_internals/src/filters/morphology.rs | 2 +
rsvg_internals/src/filters/offset.rs | 2 +
rsvg_internals/src/filters/tile.rs | 2 +
rsvg_internals/src/filters/turbulence.rs | 2 +
rsvg_internals/src/node.rs | 14 ++-
19 files changed, 77 insertions(+), 97 deletions(-)
---
diff --git a/Cargo.lock b/Cargo.lock
index 0a8f5475..f7d00f6e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -630,14 +630,6 @@ name = "numtoa"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "owning_ref"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
[[package]]
name = "pango"
version = "0.6.0"
@@ -982,7 +974,6 @@ dependencies = [
"markup5ever 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"nalgebra 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pango 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pango-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pangocairo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1046,11 +1037,6 @@ name = "smallvec"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-[[package]]
-name = "stable_deref_trait"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
[[package]]
name = "string_cache"
version = "0.7.3"
@@ -1319,7 +1305,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" =
"6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
-"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
"checksum pango 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"4e36b55d7cd522bd183efeb3dfabc547bda1f26eadf8a1241dac09ab3fd3242c"
"checksum pango-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"747ab9cd4d537e6dc5ef0e4308c10dde8b706673b0237fed4e056b8d2c0b23c8"
"checksum pangocairo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"706e885b46a16ba96f46f3c8d880ca6082c2c62693b75f3d167bd3aa4e34b0d4"
@@ -1363,7 +1348,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" =
"5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" =
"0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" =
"c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
-"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" =
"dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" =
"25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
"checksum string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" =
"1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da"
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
diff --git a/rsvg_internals/Cargo.toml b/rsvg_internals/Cargo.toml
index 919bcd0e..737f9adc 100644
--- a/rsvg_internals/Cargo.toml
+++ b/rsvg_internals/Cargo.toml
@@ -41,7 +41,6 @@ locale_config = "*" # recommended explicitly by locale_config's README.md
markup5ever = "0.8.1"
nalgebra = "0.18"
num-traits = "0.2"
-owning_ref = "0.4.0"
pango = "0.6.0"
pango-sys = "0.8.0"
pangocairo = "0.7.0"
diff --git a/rsvg_internals/src/filters/blend.rs b/rsvg_internals/src/filters/blend.rs
index 993f468a..9dd2f7db 100644
--- a/rsvg_internals/src/filters/blend.rs
+++ b/rsvg_internals/src/filters/blend.rs
@@ -44,6 +44,8 @@ impl Default for Blend {
}
impl NodeTrait for Blend {
+ impl_node_as_filter!();
+
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)?;
diff --git a/rsvg_internals/src/filters/color_matrix.rs b/rsvg_internals/src/filters/color_matrix.rs
index c70ecc65..8963fc7a 100644
--- a/rsvg_internals/src/filters/color_matrix.rs
+++ b/rsvg_internals/src/filters/color_matrix.rs
@@ -48,6 +48,8 @@ impl Default for ColorMatrix {
}
impl NodeTrait for ColorMatrix {
+ impl_node_as_filter!();
+
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)?;
diff --git a/rsvg_internals/src/filters/component_transfer.rs
b/rsvg_internals/src/filters/component_transfer.rs
index 21a00780..eb9634ac 100644
--- a/rsvg_internals/src/filters/component_transfer.rs
+++ b/rsvg_internals/src/filters/component_transfer.rs
@@ -202,6 +202,8 @@ impl FuncX {
}
impl NodeTrait for ComponentTransfer {
+ impl_node_as_filter!();
+
#[inline]
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)
diff --git a/rsvg_internals/src/filters/composite.rs b/rsvg_internals/src/filters/composite.rs
index fa247fce..959f3ba8 100644
--- a/rsvg_internals/src/filters/composite.rs
+++ b/rsvg_internals/src/filters/composite.rs
@@ -60,6 +60,8 @@ impl Default for Composite {
}
impl NodeTrait for Composite {
+ impl_node_as_filter!();
+
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)?;
diff --git a/rsvg_internals/src/filters/convolve_matrix.rs b/rsvg_internals/src/filters/convolve_matrix.rs
index 6f2c1c5d..1b56bd0c 100644
--- a/rsvg_internals/src/filters/convolve_matrix.rs
+++ b/rsvg_internals/src/filters/convolve_matrix.rs
@@ -57,6 +57,8 @@ impl Default for ConvolveMatrix {
}
impl NodeTrait for ConvolveMatrix {
+ impl_node_as_filter!();
+
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)?;
diff --git a/rsvg_internals/src/filters/displacement_map.rs b/rsvg_internals/src/filters/displacement_map.rs
index 68374d3a..0faacd1c 100644
--- a/rsvg_internals/src/filters/displacement_map.rs
+++ b/rsvg_internals/src/filters/displacement_map.rs
@@ -46,6 +46,8 @@ impl Default for DisplacementMap {
}
impl NodeTrait for DisplacementMap {
+ impl_node_as_filter!();
+
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)?;
diff --git a/rsvg_internals/src/filters/flood.rs b/rsvg_internals/src/filters/flood.rs
index a501b5cf..5fb457cc 100644
--- a/rsvg_internals/src/filters/flood.rs
+++ b/rsvg_internals/src/filters/flood.rs
@@ -25,6 +25,8 @@ impl Default for Flood {
}
impl NodeTrait for Flood {
+ impl_node_as_filter!();
+
#[inline]
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)
diff --git a/rsvg_internals/src/filters/gaussian_blur.rs b/rsvg_internals/src/filters/gaussian_blur.rs
index 40bf098e..84866763 100644
--- a/rsvg_internals/src/filters/gaussian_blur.rs
+++ b/rsvg_internals/src/filters/gaussian_blur.rs
@@ -42,6 +42,8 @@ impl Default for GaussianBlur {
}
impl NodeTrait for GaussianBlur {
+ impl_node_as_filter!();
+
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)?;
diff --git a/rsvg_internals/src/filters/image.rs b/rsvg_internals/src/filters/image.rs
index bf2f90eb..fd1b9e5f 100644
--- a/rsvg_internals/src/filters/image.rs
+++ b/rsvg_internals/src/filters/image.rs
@@ -175,6 +175,8 @@ impl Image {
}
impl NodeTrait for Image {
+ impl_node_as_filter!();
+
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)?;
diff --git a/rsvg_internals/src/filters/light/lighting.rs b/rsvg_internals/src/filters/light/lighting.rs
index cd2f7b98..345bb16d 100644
--- a/rsvg_internals/src/filters/light/lighting.rs
+++ b/rsvg_internals/src/filters/light/lighting.rs
@@ -96,6 +96,8 @@ impl Lighting {
}
impl NodeTrait for Lighting {
+ impl_node_as_filter!();
+
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)?;
diff --git a/rsvg_internals/src/filters/merge.rs b/rsvg_internals/src/filters/merge.rs
index f42742c8..ab287783 100644
--- a/rsvg_internals/src/filters/merge.rs
+++ b/rsvg_internals/src/filters/merge.rs
@@ -34,6 +34,8 @@ impl Default for Merge {
}
impl NodeTrait for Merge {
+ impl_node_as_filter!();
+
#[inline]
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)
diff --git a/rsvg_internals/src/filters/mod.rs b/rsvg_internals/src/filters/mod.rs
index 971b2faa..b80f4396 100644
--- a/rsvg_internals/src/filters/mod.rs
+++ b/rsvg_internals/src/filters/mod.rs
@@ -3,20 +3,18 @@ use std::ops::Deref;
use std::time::Instant;
use cairo::{self, MatrixTrait};
-use owning_ref::RcRef;
use crate::bbox::BoundingBox;
use crate::coord_units::CoordUnits;
use crate::drawing_ctx::DrawingCtx;
use crate::error::{RenderingError, ValueErrorKind};
use crate::length::{LengthHorizontal, LengthUnit, LengthVertical};
-use crate::node::{CascadedValues, NodeData, NodeResult, NodeTrait, NodeType, RsvgNode};
+use crate::node::{CascadedValues, NodeResult, NodeTrait, NodeType, RsvgNode};
use crate::parsers::{ParseError, ParseValue};
use crate::properties::ComputedValues;
use crate::property_bag::PropertyBag;
use crate::property_defs::ColorInterpolationFilters;
use crate::surface_utils::shared_surface::{SharedImageSurface, SurfaceType};
-use crate::tree_utils::{Node, NodeRef};
mod bounds;
use self::bounds::BoundsBuilder;
@@ -33,24 +31,8 @@ use self::input::Input;
pub mod node;
use self::node::NodeFilter;
-pub mod blend;
-pub mod color_matrix;
-pub mod component_transfer;
-pub mod composite;
-pub mod convolve_matrix;
-pub mod displacement_map;
-pub mod flood;
-pub mod gaussian_blur;
-pub mod image;
-pub mod light;
-pub mod merge;
-pub mod morphology;
-pub mod offset;
-pub mod tile;
-pub mod turbulence;
-
/// A filter primitive interface.
-trait Filter: NodeTrait {
+pub trait Filter: NodeTrait {
/// Renders this filter primitive.
///
/// If this filter primitive can't be rendered for whatever reason (for instance, a required
@@ -70,6 +52,30 @@ trait Filter: NodeTrait {
fn is_affected_by_color_interpolation_filters(&self) -> bool;
}
+macro_rules! impl_node_as_filter {
+ () => (
+ fn as_filter(&self) -> Option<&Filter> {
+ Some(self)
+ }
+ )
+}
+
+pub mod blend;
+pub mod color_matrix;
+pub mod component_transfer;
+pub mod composite;
+pub mod convolve_matrix;
+pub mod displacement_map;
+pub mod flood;
+pub mod gaussian_blur;
+pub mod image;
+pub mod light;
+pub mod merge;
+pub mod morphology;
+pub mod offset;
+pub mod tile;
+pub mod turbulence;
+
/// The base filter primitive node containing common properties.
struct Primitive {
x: Cell<Option<LengthHorizontal>>,
@@ -289,6 +295,8 @@ pub fn render(
!in_error
})
+ // Keep only filter primitives (those that implement the Filter trait)
+ .filter(|c| c.borrow().get_node_trait().as_filter().is_some())
// Check if the node wants linear RGB.
.map(|c| {
let linear_rgb = {
@@ -299,68 +307,17 @@ pub fn render(
};
(c, linear_rgb)
- })
- // Keep only filter primitives (those that implement the Filter trait)
- .filter_map(|(c, linear_rgb)| {
- let rr = RcRef::new(c.0)
- .try_map(|c: &Node<NodeData>| {
- // Go through the filter primitives and see if the node is one of them.
- #[inline]
- fn as_filter<T: Filter>(x: &T) -> &Filter {
- x
- }
-
- // Unfortunately it's not possible to downcast to a trait object. So, we
- // try downcasting to each filter type individually, and use
- // owning_ref::RcRef to reduce the children to a list of
- // OwningRef<Rc<Node<NodeData>>, dyn Filter> -- which is essentially the
- // NodeRef, and something inside the NodeRef that implements the Filter
- // trait.
- macro_rules! try_downcasting_to_filter {
- ($c:expr; $($t:ty),+$(,)*) => ({
- let mut filter = None;
- $(
- filter = filter.or_else(|| $c.borrow().get_impl::<$t>().map(as_filter));
- )+
- filter
- })
- }
-
- let filter = try_downcasting_to_filter!(c;
- blend::Blend,
- color_matrix::ColorMatrix,
- component_transfer::ComponentTransfer,
- composite::Composite,
- convolve_matrix::ConvolveMatrix,
- displacement_map::DisplacementMap,
- flood::Flood,
- gaussian_blur::GaussianBlur,
- image::Image,
- light::lighting::Lighting,
- merge::Merge,
- morphology::Morphology,
- offset::Offset,
- tile::Tile,
- turbulence::Turbulence,
- );
- filter.ok_or(())
- })
- .ok();
-
- rr.map(|rr| (rr, linear_rgb))
});
- for (rr, linear_rgb) in primitives {
- // rr: OwningRef<Rc<Node<NodeData>>, dyn Filter>
-
- let rr_node = NodeRef(rr.as_owner().clone());
+ for (c, linear_rgb) in primitives {
+ let filter = c.borrow().get_node_trait().as_filter().unwrap();
let mut render = |filter_ctx: &mut FilterContext| {
- if let Err(err) = rr
- .render(&rr_node, filter_ctx, draw_ctx)
+ if let Err(err) = filter
+ .render(&c, filter_ctx, draw_ctx)
.and_then(|result| filter_ctx.store_result(result))
{
- rsvg_log!("(filter primitive {} returned an error: {})", rr_node, err);
+ rsvg_log!("(filter primitive {} returned an error: {})", c, err);
// Exit early on Cairo errors. Continue rendering otherwise.
if let FilterError::CairoError(status) = err {
@@ -373,7 +330,7 @@ pub fn render(
let start = Instant::now();
- if rr.is_affected_by_color_interpolation_filters() && linear_rgb {
+ if filter.is_affected_by_color_interpolation_filters() && linear_rgb {
filter_ctx.with_linear_rgb(render)?;
} else {
render(&mut filter_ctx)?;
@@ -382,7 +339,7 @@ pub fn render(
let elapsed = start.elapsed();
rsvg_log!(
"(rendered filter primitive {} in\n {} seconds)",
- rr_node,
+ c,
elapsed.as_secs() as f64 + f64::from(elapsed.subsec_nanos()) / 1e9
);
}
diff --git a/rsvg_internals/src/filters/morphology.rs b/rsvg_internals/src/filters/morphology.rs
index 9eabfa87..ed13a0dd 100644
--- a/rsvg_internals/src/filters/morphology.rs
+++ b/rsvg_internals/src/filters/morphology.rs
@@ -48,6 +48,8 @@ impl Default for Morphology {
}
impl NodeTrait for Morphology {
+ impl_node_as_filter!();
+
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)?;
diff --git a/rsvg_internals/src/filters/offset.rs b/rsvg_internals/src/filters/offset.rs
index 94ebb235..681af12f 100644
--- a/rsvg_internals/src/filters/offset.rs
+++ b/rsvg_internals/src/filters/offset.rs
@@ -34,6 +34,8 @@ impl Default for Offset {
}
impl NodeTrait for Offset {
+ impl_node_as_filter!();
+
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)?;
diff --git a/rsvg_internals/src/filters/tile.rs b/rsvg_internals/src/filters/tile.rs
index 4269eebb..a9df1a58 100644
--- a/rsvg_internals/src/filters/tile.rs
+++ b/rsvg_internals/src/filters/tile.rs
@@ -24,6 +24,8 @@ impl Default for Tile {
}
impl NodeTrait for Tile {
+ impl_node_as_filter!();
+
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)
}
diff --git a/rsvg_internals/src/filters/turbulence.rs b/rsvg_internals/src/filters/turbulence.rs
index be9d5421..3e608dc8 100644
--- a/rsvg_internals/src/filters/turbulence.rs
+++ b/rsvg_internals/src/filters/turbulence.rs
@@ -59,6 +59,8 @@ impl Default for Turbulence {
}
impl NodeTrait for Turbulence {
+ impl_node_as_filter!();
+
#[inline]
fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
self.base.set_atts(node, pbag)?;
diff --git a/rsvg_internals/src/node.rs b/rsvg_internals/src/node.rs
index 221621ca..3550e5ef 100644
--- a/rsvg_internals/src/node.rs
+++ b/rsvg_internals/src/node.rs
@@ -8,6 +8,7 @@ use std::fmt;
use crate::cond::{RequiredExtensions, RequiredFeatures, SystemLanguage};
use crate::css::CssRules;
use crate::drawing_ctx::DrawingCtx;
+use crate::filters::Filter;
use crate::error::*;
use crate::parsers::Parse;
use crate::properties::{ComputedValues, SpecifiedValue, SpecifiedValues};
@@ -60,6 +61,10 @@ impl NodeData {
}
}
+ pub fn get_node_trait(&self) -> &NodeTrait {
+ self.node_impl.as_ref()
+ }
+
pub fn get_impl<T: NodeTrait>(&self) -> Option<&T> {
(&self.node_impl).downcast_ref::<T>()
}
@@ -328,6 +333,11 @@ pub trait NodeTrait: Downcast {
// by default nodes don't draw themselves
Ok(())
}
+
+ /// Returns the Filter trait if this node is a filter primitive
+ fn as_filter(&self) -> Option<&Filter> {
+ None
+ }
}
impl_downcast!(NodeTrait);
@@ -474,7 +484,7 @@ impl RsvgNode {
let cr = dc.get_cairo_context();
cr.transform(self.get_transform());
- self.borrow().node_impl.draw(self, cascaded, dc, clipping)
+ self.borrow().get_node_trait().draw(self, cascaded, dc, clipping)
})
} else {
rsvg_log!("(not rendering element {} because it is in error)", self);
@@ -488,7 +498,7 @@ impl RsvgNode {
}
pub fn get_impl<T: NodeTrait>(&self) -> &T {
- if let Some(t) = (&self.borrow().node_impl).downcast_ref::<T>() {
+ if let Some(t) = self.borrow().get_impl::<T>() {
t
} else {
panic!("could not downcast");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]