summaryrefslogtreecommitdiffstats
path: root/gfx/wr/webrender/src/prim_store/picture.rs
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/wr/webrender/src/prim_store/picture.rs')
-rw-r--r--gfx/wr/webrender/src/prim_store/picture.rs768
1 files changed, 765 insertions, 3 deletions
diff --git a/gfx/wr/webrender/src/prim_store/picture.rs b/gfx/wr/webrender/src/prim_store/picture.rs
index c3ec88783a..f8857a4f11 100644
--- a/gfx/wr/webrender/src/prim_store/picture.rs
+++ b/gfx/wr/webrender/src/prim_store/picture.rs
@@ -3,15 +3,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{
- ColorU, MixBlendMode, FilterPrimitiveInput, FilterPrimitiveKind, ColorSpace,
- PropertyBinding, PropertyBindingId, CompositeOperator, RasterSpace,
+ ColorU, MixBlendMode, FilterPrimitiveInput, FilterPrimitiveKind,
+ ColorSpace, PropertyBinding, PropertyBindingId, CompositeOperator,
+ RasterSpace, FilterOpGraphPictureBufferId,
};
use api::units::{Au, LayoutVector2D};
use crate::scene_building::IsVisible;
use crate::filterdata::SFilterData;
use crate::intern::ItemUid;
use crate::intern::{Internable, InternDebug, Handle as InternHandle};
-use crate::internal_types::{LayoutPrimitiveInfo, Filter};
+use crate::internal_types::{LayoutPrimitiveInfo, FilterGraphPictureReference,
+ FilterGraphOp, FilterGraphNode, SVGFE_CONVOLVE_VALUES_LIMIT, Filter};
use crate::picture::PictureCompositeMode;
use crate::prim_store::{
PrimitiveInstanceKind, PrimitiveStore, VectorKey,
@@ -69,6 +71,758 @@ pub enum FilterPrimitiveKey {
Composite(ColorSpace, FilterPrimitiveInput, FilterPrimitiveInput, CompositeOperatorKey),
}
+#[cfg_attr(feature = "capture", derive(Serialize))]
+#[cfg_attr(feature = "replay", derive(Deserialize))]
+#[derive(Debug, Clone, Copy, Default, MallocSizeOf, PartialEq, Hash, Eq)]
+pub enum FilterGraphPictureBufferIdKey {
+ #[default]
+ /// empty slot in feMerge inputs
+ None,
+ /// reference to another (earlier) node in filter graph
+ BufferId(i16),
+}
+
+#[cfg_attr(feature = "capture", derive(Serialize))]
+#[cfg_attr(feature = "replay", derive(Deserialize))]
+#[derive(Debug, Clone, Copy, Default, MallocSizeOf, PartialEq, Hash, Eq)]
+pub struct FilterGraphPictureReferenceKey {
+ /// Id of the picture in question in a namespace unique to this filter DAG,
+ /// some are special values like
+ /// FilterPrimitiveDescription::kPrimitiveIndexSourceGraphic.
+ pub buffer_id: FilterGraphPictureBufferIdKey,
+ /// Place the input image here in Layout space (like node.subregion)
+ pub subregion: [Au; 4],
+ /// Translate the subregion by this amount
+ pub offset: [Au; 2],
+}
+
+impl From<FilterGraphPictureReference> for FilterGraphPictureReferenceKey {
+ fn from(pic: FilterGraphPictureReference) -> Self {
+ FilterGraphPictureReferenceKey{
+ buffer_id: match pic.buffer_id {
+ FilterOpGraphPictureBufferId::None => FilterGraphPictureBufferIdKey::None,
+ FilterOpGraphPictureBufferId::BufferId(id) => FilterGraphPictureBufferIdKey::BufferId(id),
+ },
+ subregion: [
+ Au::from_f32_px(pic.subregion.min.x),
+ Au::from_f32_px(pic.subregion.min.y),
+ Au::from_f32_px(pic.subregion.max.x),
+ Au::from_f32_px(pic.subregion.max.y),
+ ],
+ offset: [
+ Au::from_f32_px(pic.offset.x),
+ Au::from_f32_px(pic.offset.y),
+ ],
+ }
+ }
+}
+
+#[cfg_attr(feature = "capture", derive(Serialize))]
+#[cfg_attr(feature = "replay", derive(Deserialize))]
+#[derive(Debug, Clone, MallocSizeOf, PartialEq, Hash, Eq)]
+pub enum FilterGraphOpKey {
+ /// combine 2 images with SVG_FEBLEND_MODE_DARKEN
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
+ SVGFEBlendDarken,
+ /// combine 2 images with SVG_FEBLEND_MODE_LIGHTEN
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
+ SVGFEBlendLighten,
+ /// combine 2 images with SVG_FEBLEND_MODE_MULTIPLY
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
+ SVGFEBlendMultiply,
+ /// combine 2 images with SVG_FEBLEND_MODE_NORMAL
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
+ SVGFEBlendNormal,
+ /// combine 2 images with SVG_FEBLEND_MODE_SCREEN
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
+ SVGFEBlendScreen,
+ /// combine 2 images with SVG_FEBLEND_MODE_OVERLAY
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
+ SVGFEBlendOverlay,
+ /// combine 2 images with SVG_FEBLEND_MODE_COLOR_DODGE
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
+ SVGFEBlendColorDodge,
+ /// combine 2 images with SVG_FEBLEND_MODE_COLOR_BURN
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
+ SVGFEBlendColorBurn,
+ /// combine 2 images with SVG_FEBLEND_MODE_HARD_LIGHT
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
+ SVGFEBlendHardLight,
+ /// combine 2 images with SVG_FEBLEND_MODE_SOFT_LIGHT
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
+ SVGFEBlendSoftLight,
+ /// combine 2 images with SVG_FEBLEND_MODE_DIFFERENCE
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
+ SVGFEBlendDifference,
+ /// combine 2 images with SVG_FEBLEND_MODE_EXCLUSION
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
+ SVGFEBlendExclusion,
+ /// combine 2 images with SVG_FEBLEND_MODE_HUE
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
+ SVGFEBlendHue,
+ /// combine 2 images with SVG_FEBLEND_MODE_SATURATION
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
+ SVGFEBlendSaturation,
+ /// combine 2 images with SVG_FEBLEND_MODE_COLOR
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
+ SVGFEBlendColor,
+ /// combine 2 images with SVG_FEBLEND_MODE_LUMINOSITY
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
+ SVGFEBlendLuminosity,
+ /// transform colors of image through 5x4 color matrix (transposed for
+ /// efficiency)
+ /// parameters: FilterOpGraphNode, matrix[5][4]
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feColorMatrixElement
+ SVGFEColorMatrix{values: [Au; 20]},
+ /// transform colors of image through configurable gradients with component
+ /// swizzle
+ /// parameters: FilterOpGraphNode, FilterData
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feComponentTransferElement
+ SVGFEComponentTransferInterned{handle: ItemUid, creates_pixels: bool},
+ /// composite 2 images with chosen composite mode with parameters for that
+ /// mode
+ /// parameters: FilterOpGraphNode, k1, k2, k3, k4
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
+ SVGFECompositeArithmetic{k1: Au, k2: Au, k3: Au, k4: Au},
+ /// composite 2 images with chosen composite mode with parameters for that
+ /// mode
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
+ SVGFECompositeATop,
+ /// composite 2 images with chosen composite mode with parameters for that
+ /// mode
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
+ SVGFECompositeIn,
+ /// composite 2 images with chosen composite mode with parameters for that
+ /// mode
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Docs: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feComposite
+ SVGFECompositeLighter,
+ /// composite 2 images with chosen composite mode with parameters for that
+ /// mode
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
+ SVGFECompositeOut,
+ /// composite 2 images with chosen composite mode with parameters for that
+ /// mode
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
+ SVGFECompositeOver,
+ /// composite 2 images with chosen composite mode with parameters for that
+ /// mode
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
+ SVGFECompositeXOR,
+ /// transform image through convolution matrix of up to 25 values (spec
+ /// allows more but for performance reasons we do not)
+ /// parameters: FilterOpGraphNode, orderX, orderY, kernelValues[25],
+ /// divisor, bias, targetX, targetY, kernelUnitLengthX, kernelUnitLengthY,
+ /// preserveAlpha
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feConvolveMatrixElement
+ SVGFEConvolveMatrixEdgeModeDuplicate{order_x: i32, order_y: i32,
+ kernel: [Au; SVGFE_CONVOLVE_VALUES_LIMIT], divisor: Au, bias: Au,
+ target_x: i32, target_y: i32, kernel_unit_length_x: Au,
+ kernel_unit_length_y: Au, preserve_alpha: i32},
+ /// transform image through convolution matrix of up to 25 values (spec
+ /// allows more but for performance reasons we do not)
+ /// parameters: FilterOpGraphNode, orderX, orderY, kernelValues[25],
+ /// divisor, bias, targetX, targetY, kernelUnitLengthX, kernelUnitLengthY,
+ /// preserveAlpha
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feConvolveMatrixElement
+ SVGFEConvolveMatrixEdgeModeNone{order_x: i32, order_y: i32,
+ kernel: [Au; SVGFE_CONVOLVE_VALUES_LIMIT], divisor: Au, bias: Au,
+ target_x: i32, target_y: i32, kernel_unit_length_x: Au,
+ kernel_unit_length_y: Au, preserve_alpha: i32},
+ /// transform image through convolution matrix of up to 25 values (spec
+ /// allows more but for performance reasons we do not)
+ /// parameters: FilterOpGraphNode, orderX, orderY, kernelValues[25],
+ /// divisor, bias, targetX, targetY, kernelUnitLengthX, kernelUnitLengthY,
+ /// preserveAlpha
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#feConvolveMatrixElement
+ SVGFEConvolveMatrixEdgeModeWrap{order_x: i32, order_y: i32,
+ kernel: [Au; SVGFE_CONVOLVE_VALUES_LIMIT], divisor: Au, bias: Au,
+ target_x: i32, target_y: i32, kernel_unit_length_x: Au,
+ kernel_unit_length_y: Au, preserve_alpha: i32},
+ /// calculate lighting based on heightmap image with provided values for a
+ /// distant light source with specified direction
+ /// parameters: FilterOpGraphNode, surfaceScale, diffuseConstant,
+ /// kernelUnitLengthX, kernelUnitLengthY, azimuth, elevation
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDiffuseLightingElement
+ /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDistantLightElement
+ SVGFEDiffuseLightingDistant{surface_scale: Au, diffuse_constant: Au,
+ kernel_unit_length_x: Au, kernel_unit_length_y: Au, azimuth: Au,
+ elevation: Au},
+ /// calculate lighting based on heightmap image with provided values for a
+ /// point light source at specified location
+ /// parameters: FilterOpGraphNode, surfaceScale, diffuseConstant,
+ /// kernelUnitLengthX, kernelUnitLengthY, x, y, z
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDiffuseLightingElement
+ /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEPointLightElement
+ SVGFEDiffuseLightingPoint{surface_scale: Au, diffuse_constant: Au,
+ kernel_unit_length_x: Au, kernel_unit_length_y: Au, x: Au, y: Au,
+ z: Au},
+ /// calculate lighting based on heightmap image with provided values for a
+ /// spot light source at specified location pointing at specified target
+ /// location with specified hotspot sharpness and cone angle
+ /// parameters: FilterOpGraphNode, surfaceScale, diffuseConstant,
+ /// kernelUnitLengthX, kernelUnitLengthY, x, y, z, pointsAtX, pointsAtY,
+ /// pointsAtZ, specularExponent, limitingConeAngle
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDiffuseLightingElement
+ /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpotLightElement
+ SVGFEDiffuseLightingSpot{surface_scale: Au, diffuse_constant: Au,
+ kernel_unit_length_x: Au, kernel_unit_length_y: Au, x: Au, y: Au, z: Au,
+ points_at_x: Au, points_at_y: Au, points_at_z: Au, cone_exponent: Au,
+ limiting_cone_angle: Au},
+ /// calculate a distorted version of first input image using offset values
+ /// from second input image at specified intensity
+ /// parameters: FilterOpGraphNode, scale, xChannelSelector, yChannelSelector
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDisplacementMapElement
+ SVGFEDisplacementMap{scale: Au, x_channel_selector: u32,
+ y_channel_selector: u32},
+ /// create and merge a dropshadow version of the specified image's alpha
+ /// channel with specified offset and blur radius
+ /// parameters: FilterOpGraphNode, flood_color, flood_opacity, dx, dy,
+ /// stdDeviationX, stdDeviationY
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDropShadowElement
+ SVGFEDropShadow{color: ColorU, dx: Au, dy: Au, std_deviation_x: Au,
+ std_deviation_y: Au},
+ /// synthesize a new image of specified size containing a solid color
+ /// parameters: FilterOpGraphNode, color
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEFloodElement
+ SVGFEFlood{color: ColorU},
+ /// create a blurred version of the input image
+ /// parameters: FilterOpGraphNode, stdDeviationX, stdDeviationY
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEGaussianBlurElement
+ SVGFEGaussianBlur{std_deviation_x: Au, std_deviation_y: Au},
+ /// Filter that does no transformation of the colors, needed for
+ /// debug purposes, and is the default value in impl_default_for_enums.
+ SVGFEIdentity,
+ /// synthesize a new image based on a url (i.e. blob image source)
+ /// parameters: FilterOpGraphNode, sampling_filter (see SamplingFilter in
+ /// Types.h), transform
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEImageElement
+ SVGFEImage{sampling_filter: u32, matrix: [Au; 6]},
+ /// create a new image based on the input image with the contour stretched
+ /// outward (dilate operator)
+ /// parameters: FilterOpGraphNode, radiusX, radiusY
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEMorphologyElement
+ SVGFEMorphologyDilate{radius_x: Au, radius_y: Au},
+ /// create a new image based on the input image with the contour shrunken
+ /// inward (erode operator)
+ /// parameters: FilterOpGraphNode, radiusX, radiusY
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEMorphologyElement
+ SVGFEMorphologyErode{radius_x: Au, radius_y: Au},
+ /// represents CSS opacity property as a graph node like the rest of the
+ /// SVGFE* filters
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ SVGFEOpacity{value: Au},
+ /// represents CSS opacity property as a graph node like the rest of the
+ /// SVGFE* filters
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ SVGFEOpacityBinding{valuebindingid: PropertyBindingId, value: Au},
+ /// Filter that copies the SourceGraphic image into the specified subregion,
+ /// This is intentionally the only way to get SourceGraphic into the graph,
+ /// as the filter region must be applied before it is used.
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - no inputs, no linear
+ SVGFESourceGraphic,
+ /// Filter that copies the SourceAlpha image into the specified subregion,
+ /// This is intentionally the only way to get SourceAlpha into the graph,
+ /// as the filter region must be applied before it is used.
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - no inputs, no linear
+ SVGFESourceAlpha,
+ /// calculate lighting based on heightmap image with provided values for a
+ /// distant light source with specified direction
+ /// parameters: FilerData, surfaceScale, specularConstant, specularExponent,
+ /// kernelUnitLengthX, kernelUnitLengthY, azimuth, elevation
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpecularLightingElement
+ /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDistantLightElement
+ SVGFESpecularLightingDistant{surface_scale: Au, specular_constant: Au,
+ specular_exponent: Au, kernel_unit_length_x: Au,
+ kernel_unit_length_y: Au, azimuth: Au, elevation: Au},
+ /// calculate lighting based on heightmap image with provided values for a
+ /// point light source at specified location
+ /// parameters: FilterOpGraphNode, surfaceScale, specularConstant,
+ /// specularExponent, kernelUnitLengthX, kernelUnitLengthY, x, y, z
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpecularLightingElement
+ /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEPointLightElement
+ SVGFESpecularLightingPoint{surface_scale: Au, specular_constant: Au,
+ specular_exponent: Au, kernel_unit_length_x: Au,
+ kernel_unit_length_y: Au, x: Au, y: Au, z: Au},
+ /// calculate lighting based on heightmap image with provided values for a
+ /// spot light source at specified location pointing at specified target
+ /// location with specified hotspot sharpness and cone angle
+ /// parameters: FilterOpGraphNode, surfaceScale, specularConstant,
+ /// specularExponent, kernelUnitLengthX, kernelUnitLengthY, x, y, z,
+ /// pointsAtX, pointsAtY, pointsAtZ, specularExponent, limitingConeAngle
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpecularLightingElement
+ /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpotLightElement
+ SVGFESpecularLightingSpot{surface_scale: Au, specular_constant: Au,
+ specular_exponent: Au, kernel_unit_length_x: Au,
+ kernel_unit_length_y: Au, x: Au, y: Au, z: Au, points_at_x: Au,
+ points_at_y: Au, points_at_z: Au, cone_exponent: Au,
+ limiting_cone_angle: Au},
+ /// create a new image based on the input image, repeated throughout the
+ /// output rectangle
+ /// parameters: FilterOpGraphNode
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETileElement
+ SVGFETile,
+ /// convert a color image to an alpha channel - internal use; generated by
+ /// SVGFilterInstance::GetOrCreateSourceAlphaIndex().
+ SVGFEToAlpha,
+ /// synthesize a new image based on Fractal Noise (Perlin) with the chosen
+ /// stitching mode
+ /// parameters: FilterOpGraphNode, baseFrequencyX, baseFrequencyY,
+ /// numOctaves, seed
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETurbulenceElement
+ SVGFETurbulenceWithFractalNoiseWithNoStitching{base_frequency_x: Au,
+ base_frequency_y: Au, num_octaves: u32, seed: u32},
+ /// synthesize a new image based on Fractal Noise (Perlin) with the chosen
+ /// stitching mode
+ /// parameters: FilterOpGraphNode, baseFrequencyX, baseFrequencyY,
+ /// numOctaves, seed
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETurbulenceElement
+ SVGFETurbulenceWithFractalNoiseWithStitching{base_frequency_x: Au,
+ base_frequency_y: Au, num_octaves: u32, seed: u32},
+ /// synthesize a new image based on Turbulence Noise (offset vectors)
+ /// parameters: FilterOpGraphNode, baseFrequencyX, baseFrequencyY,
+ /// numOctaves, seed
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETurbulenceElement
+ SVGFETurbulenceWithTurbulenceNoiseWithNoStitching{base_frequency_x: Au,
+ base_frequency_y: Au, num_octaves: u32, seed: u32},
+ /// synthesize a new image based on Turbulence Noise (offset vectors)
+ /// parameters: FilterOpGraphNode, baseFrequencyX, baseFrequencyY,
+ /// numOctaves, seed
+ /// SVG filter semantics - selectable input(s), selectable between linear
+ /// (default) and sRGB color space for calculations
+ /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETurbulenceElement
+ SVGFETurbulenceWithTurbulenceNoiseWithStitching{base_frequency_x: Au,
+ base_frequency_y: Au, num_octaves: u32, seed: u32},
+}
+
+impl From<FilterGraphOp> for FilterGraphOpKey {
+ fn from(op: FilterGraphOp) -> Self {
+ match op {
+ FilterGraphOp::SVGFEBlendDarken => FilterGraphOpKey::SVGFEBlendDarken,
+ FilterGraphOp::SVGFEBlendLighten => FilterGraphOpKey::SVGFEBlendLighten,
+ FilterGraphOp::SVGFEBlendMultiply => FilterGraphOpKey::SVGFEBlendMultiply,
+ FilterGraphOp::SVGFEBlendNormal => FilterGraphOpKey::SVGFEBlendNormal,
+ FilterGraphOp::SVGFEBlendScreen => FilterGraphOpKey::SVGFEBlendScreen,
+ FilterGraphOp::SVGFEBlendOverlay => FilterGraphOpKey::SVGFEBlendOverlay,
+ FilterGraphOp::SVGFEBlendColorDodge => FilterGraphOpKey::SVGFEBlendColorDodge,
+ FilterGraphOp::SVGFEBlendColorBurn => FilterGraphOpKey::SVGFEBlendColorBurn,
+ FilterGraphOp::SVGFEBlendHardLight => FilterGraphOpKey::SVGFEBlendHardLight,
+ FilterGraphOp::SVGFEBlendSoftLight => FilterGraphOpKey::SVGFEBlendSoftLight,
+ FilterGraphOp::SVGFEBlendDifference => FilterGraphOpKey::SVGFEBlendDifference,
+ FilterGraphOp::SVGFEBlendExclusion => FilterGraphOpKey::SVGFEBlendExclusion,
+ FilterGraphOp::SVGFEBlendHue => FilterGraphOpKey::SVGFEBlendHue,
+ FilterGraphOp::SVGFEBlendSaturation => FilterGraphOpKey::SVGFEBlendSaturation,
+ FilterGraphOp::SVGFEBlendColor => FilterGraphOpKey::SVGFEBlendColor,
+ FilterGraphOp::SVGFEBlendLuminosity => FilterGraphOpKey::SVGFEBlendLuminosity,
+ FilterGraphOp::SVGFEColorMatrix { values: color_matrix } => {
+ let mut quantized_values: [Au; 20] = [Au(0); 20];
+ for (value, result) in color_matrix.iter().zip(quantized_values.iter_mut()) {
+ *result = Au::from_f32_px(*value);
+ }
+ FilterGraphOpKey::SVGFEColorMatrix{values: quantized_values}
+ }
+ FilterGraphOp::SVGFEComponentTransfer => unreachable!(),
+ FilterGraphOp::SVGFEComponentTransferInterned { handle, creates_pixels } => FilterGraphOpKey::SVGFEComponentTransferInterned{
+ handle: handle.uid(),
+ creates_pixels,
+ },
+ FilterGraphOp::SVGFECompositeArithmetic { k1, k2, k3, k4 } => {
+ FilterGraphOpKey::SVGFECompositeArithmetic{
+ k1: Au::from_f32_px(k1),
+ k2: Au::from_f32_px(k2),
+ k3: Au::from_f32_px(k3),
+ k4: Au::from_f32_px(k4),
+ }
+ }
+ FilterGraphOp::SVGFECompositeATop => FilterGraphOpKey::SVGFECompositeATop,
+ FilterGraphOp::SVGFECompositeIn => FilterGraphOpKey::SVGFECompositeIn,
+ FilterGraphOp::SVGFECompositeLighter => FilterGraphOpKey::SVGFECompositeLighter,
+ FilterGraphOp::SVGFECompositeOut => FilterGraphOpKey::SVGFECompositeOut,
+ FilterGraphOp::SVGFECompositeOver => FilterGraphOpKey::SVGFECompositeOver,
+ FilterGraphOp::SVGFECompositeXOR => FilterGraphOpKey::SVGFECompositeXOR,
+ FilterGraphOp::SVGFEConvolveMatrixEdgeModeDuplicate { order_x, order_y, kernel, divisor, bias, target_x, target_y, kernel_unit_length_x, kernel_unit_length_y, preserve_alpha } => {
+ let mut values: [Au; SVGFE_CONVOLVE_VALUES_LIMIT] = [Au(0); SVGFE_CONVOLVE_VALUES_LIMIT];
+ for (value, result) in kernel.iter().zip(values.iter_mut()) {
+ *result = Au::from_f32_px(*value)
+ }
+ FilterGraphOpKey::SVGFEConvolveMatrixEdgeModeDuplicate{
+ order_x,
+ order_y,
+ kernel: values,
+ divisor: Au::from_f32_px(divisor),
+ bias: Au::from_f32_px(bias),
+ target_x,
+ target_y,
+ kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
+ kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
+ preserve_alpha,
+ }
+ }
+ FilterGraphOp::SVGFEConvolveMatrixEdgeModeNone { order_x, order_y, kernel, divisor, bias, target_x, target_y, kernel_unit_length_x, kernel_unit_length_y, preserve_alpha } => {
+ let mut values: [Au; SVGFE_CONVOLVE_VALUES_LIMIT] = [Au(0); SVGFE_CONVOLVE_VALUES_LIMIT];
+ for (value, result) in kernel.iter().zip(values.iter_mut()) {
+ *result = Au::from_f32_px(*value)
+ }
+ FilterGraphOpKey::SVGFEConvolveMatrixEdgeModeNone{
+ order_x,
+ order_y,
+ kernel: values,
+ divisor: Au::from_f32_px(divisor),
+ bias: Au::from_f32_px(bias),
+ target_x,
+ target_y,
+ kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
+ kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
+ preserve_alpha,
+ }
+ }
+ FilterGraphOp::SVGFEConvolveMatrixEdgeModeWrap { order_x, order_y, kernel, divisor, bias, target_x, target_y, kernel_unit_length_x, kernel_unit_length_y, preserve_alpha } => {
+ let mut values: [Au; SVGFE_CONVOLVE_VALUES_LIMIT] = [Au(0); SVGFE_CONVOLVE_VALUES_LIMIT];
+ for (value, result) in kernel.iter().zip(values.iter_mut()) {
+ *result = Au::from_f32_px(*value)
+ }
+ FilterGraphOpKey::SVGFEConvolveMatrixEdgeModeWrap{
+ order_x,
+ order_y,
+ kernel: values,
+ divisor: Au::from_f32_px(divisor),
+ bias: Au::from_f32_px(bias),
+ target_x,
+ target_y,
+ kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
+ kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
+ preserve_alpha,
+ }
+ }
+ FilterGraphOp::SVGFEDiffuseLightingDistant { surface_scale, diffuse_constant, kernel_unit_length_x, kernel_unit_length_y, azimuth, elevation } => {
+ FilterGraphOpKey::SVGFEDiffuseLightingDistant{
+ surface_scale: Au::from_f32_px(surface_scale),
+ diffuse_constant: Au::from_f32_px(diffuse_constant),
+ kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
+ kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
+ azimuth: Au::from_f32_px(azimuth),
+ elevation: Au::from_f32_px(elevation),
+ }
+ }
+ FilterGraphOp::SVGFEDiffuseLightingPoint { surface_scale, diffuse_constant, kernel_unit_length_x, kernel_unit_length_y, x, y, z } => {
+ FilterGraphOpKey::SVGFEDiffuseLightingPoint{
+ surface_scale: Au::from_f32_px(surface_scale),
+ diffuse_constant: Au::from_f32_px(diffuse_constant),
+ kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
+ kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
+ x: Au::from_f32_px(x),
+ y: Au::from_f32_px(y),
+ z: Au::from_f32_px(z),
+ }
+ }
+ FilterGraphOp::SVGFEDiffuseLightingSpot { surface_scale, diffuse_constant, kernel_unit_length_x, kernel_unit_length_y, x, y, z, points_at_x, points_at_y, points_at_z, cone_exponent, limiting_cone_angle } => {
+ FilterGraphOpKey::SVGFEDiffuseLightingSpot{
+ surface_scale: Au::from_f32_px(surface_scale),
+ diffuse_constant: Au::from_f32_px(diffuse_constant),
+ kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
+ kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
+ x: Au::from_f32_px(x),
+ y: Au::from_f32_px(y),
+ z: Au::from_f32_px(z),
+ points_at_x: Au::from_f32_px(points_at_x),
+ points_at_y: Au::from_f32_px(points_at_y),
+ points_at_z: Au::from_f32_px(points_at_z),
+ cone_exponent: Au::from_f32_px(cone_exponent),
+ limiting_cone_angle: Au::from_f32_px(limiting_cone_angle),
+ }
+ }
+ FilterGraphOp::SVGFEDisplacementMap { scale, x_channel_selector, y_channel_selector } => {
+ FilterGraphOpKey::SVGFEDisplacementMap{
+ scale: Au::from_f32_px(scale),
+ x_channel_selector,
+ y_channel_selector,
+ }
+ }
+ FilterGraphOp::SVGFEDropShadow { color, dx, dy, std_deviation_x, std_deviation_y } => {
+ FilterGraphOpKey::SVGFEDropShadow{
+ color: color.into(),
+ dx: Au::from_f32_px(dx),
+ dy: Au::from_f32_px(dy),
+ std_deviation_x: Au::from_f32_px(std_deviation_x),
+ std_deviation_y: Au::from_f32_px(std_deviation_y),
+ }
+ }
+ FilterGraphOp::SVGFEFlood { color } => FilterGraphOpKey::SVGFEFlood{color: color.into()},
+ FilterGraphOp::SVGFEGaussianBlur { std_deviation_x, std_deviation_y } => {
+ FilterGraphOpKey::SVGFEGaussianBlur{
+ std_deviation_x: Au::from_f32_px(std_deviation_x),
+ std_deviation_y: Au::from_f32_px(std_deviation_y),
+ }
+ }
+ FilterGraphOp::SVGFEIdentity => FilterGraphOpKey::SVGFEIdentity,
+ FilterGraphOp::SVGFEImage { sampling_filter, matrix } => {
+ let mut values: [Au; 6] = [Au(0); 6];
+ for (value, result) in matrix.iter().zip(values.iter_mut()) {
+ *result = Au::from_f32_px(*value)
+ }
+ FilterGraphOpKey::SVGFEImage{
+ sampling_filter,
+ matrix: values,
+ }
+ }
+ FilterGraphOp::SVGFEMorphologyDilate { radius_x, radius_y } => {
+ FilterGraphOpKey::SVGFEMorphologyDilate{
+ radius_x: Au::from_f32_px(radius_x),
+ radius_y: Au::from_f32_px(radius_y),
+ }
+ }
+ FilterGraphOp::SVGFEMorphologyErode { radius_x, radius_y } => {
+ FilterGraphOpKey::SVGFEMorphologyErode{
+ radius_x: Au::from_f32_px(radius_x),
+ radius_y: Au::from_f32_px(radius_y),
+ }
+ }
+ FilterGraphOp::SVGFEOpacity{valuebinding: binding, value: _} => {
+ match binding {
+ PropertyBinding::Value(value) => {
+ FilterGraphOpKey::SVGFEOpacity{value: Au::from_f32_px(value)}
+ }
+ PropertyBinding::Binding(key, default) => {
+ FilterGraphOpKey::SVGFEOpacityBinding{valuebindingid: key.id, value: Au::from_f32_px(default)}
+ }
+ }
+ }
+ FilterGraphOp::SVGFESourceAlpha => FilterGraphOpKey::SVGFESourceAlpha,
+ FilterGraphOp::SVGFESourceGraphic => FilterGraphOpKey::SVGFESourceGraphic,
+ FilterGraphOp::SVGFESpecularLightingDistant { surface_scale, specular_constant, specular_exponent, kernel_unit_length_x, kernel_unit_length_y, azimuth, elevation } => {
+ FilterGraphOpKey::SVGFESpecularLightingDistant{
+ surface_scale: Au::from_f32_px(surface_scale),
+ specular_constant: Au::from_f32_px(specular_constant),
+ specular_exponent: Au::from_f32_px(specular_exponent),
+ kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
+ kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
+ azimuth: Au::from_f32_px(azimuth),
+ elevation: Au::from_f32_px(elevation),
+ }
+ }
+ FilterGraphOp::SVGFESpecularLightingPoint { surface_scale, specular_constant, specular_exponent, kernel_unit_length_x, kernel_unit_length_y, x, y, z } => {
+ FilterGraphOpKey::SVGFESpecularLightingPoint{
+ surface_scale: Au::from_f32_px(surface_scale),
+ specular_constant: Au::from_f32_px(specular_constant),
+ specular_exponent: Au::from_f32_px(specular_exponent),
+ kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
+ kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
+ x: Au::from_f32_px(x),
+ y: Au::from_f32_px(y),
+ z: Au::from_f32_px(z),
+ }
+ }
+ FilterGraphOp::SVGFESpecularLightingSpot { surface_scale, specular_constant, specular_exponent, kernel_unit_length_x, kernel_unit_length_y, x, y, z, points_at_x, points_at_y, points_at_z, cone_exponent, limiting_cone_angle } => {
+ FilterGraphOpKey::SVGFESpecularLightingSpot{
+ surface_scale: Au::from_f32_px(surface_scale),
+ specular_constant: Au::from_f32_px(specular_constant),
+ specular_exponent: Au::from_f32_px(specular_exponent),
+ kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
+ kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
+ x: Au::from_f32_px(x),
+ y: Au::from_f32_px(y),
+ z: Au::from_f32_px(z),
+ points_at_x: Au::from_f32_px(points_at_x),
+ points_at_y: Au::from_f32_px(points_at_y),
+ points_at_z: Au::from_f32_px(points_at_z),
+ cone_exponent: Au::from_f32_px(cone_exponent),
+ limiting_cone_angle: Au::from_f32_px(limiting_cone_angle),
+ }
+ }
+ FilterGraphOp::SVGFETile => FilterGraphOpKey::SVGFETile,
+ FilterGraphOp::SVGFEToAlpha => FilterGraphOpKey::SVGFEToAlpha,
+ FilterGraphOp::SVGFETurbulenceWithFractalNoiseWithNoStitching { base_frequency_x, base_frequency_y, num_octaves, seed } => {
+ FilterGraphOpKey::SVGFETurbulenceWithFractalNoiseWithNoStitching {
+ base_frequency_x: Au::from_f32_px(base_frequency_x),
+ base_frequency_y: Au::from_f32_px(base_frequency_y),
+ num_octaves,
+ seed,
+ }
+ }
+ FilterGraphOp::SVGFETurbulenceWithFractalNoiseWithStitching { base_frequency_x, base_frequency_y, num_octaves, seed } => {
+ FilterGraphOpKey::SVGFETurbulenceWithFractalNoiseWithStitching {
+ base_frequency_x: Au::from_f32_px(base_frequency_x),
+ base_frequency_y: Au::from_f32_px(base_frequency_y),
+ num_octaves,
+ seed,
+ }
+ }
+ FilterGraphOp::SVGFETurbulenceWithTurbulenceNoiseWithNoStitching { base_frequency_x, base_frequency_y, num_octaves, seed } => {
+ FilterGraphOpKey::SVGFETurbulenceWithTurbulenceNoiseWithNoStitching {
+ base_frequency_x: Au::from_f32_px(base_frequency_x),
+ base_frequency_y: Au::from_f32_px(base_frequency_y),
+ num_octaves,
+ seed,
+ }
+ }
+ FilterGraphOp::SVGFETurbulenceWithTurbulenceNoiseWithStitching { base_frequency_x, base_frequency_y, num_octaves, seed } => {
+ FilterGraphOpKey::SVGFETurbulenceWithTurbulenceNoiseWithStitching {
+ base_frequency_x: Au::from_f32_px(base_frequency_x),
+ base_frequency_y: Au::from_f32_px(base_frequency_y),
+ num_octaves,
+ seed,
+ }
+ }
+ }
+ }
+}
+
+#[cfg_attr(feature = "capture", derive(Serialize))]
+#[cfg_attr(feature = "replay", derive(Deserialize))]
+#[derive(Debug, Clone, MallocSizeOf, PartialEq, Hash, Eq)]
+pub struct FilterGraphNodeKey {
+ /// Indicates this graph node was marked as unnecessary by the DAG optimizer
+ /// (for example SVGFEOffset can often be folded into downstream nodes)
+ pub kept_by_optimizer: bool,
+ /// True if color_interpolation_filter == LinearRgb; shader will convert
+ /// sRGB texture pixel colors on load and convert back on store, for correct
+ /// interpolation
+ pub linear: bool,
+ /// padding for output rect if we need a border to get correct clamping, or
+ /// to account for larger final subregion than source rect (see bug 1869672)
+ pub inflate: i16,
+ /// virtualized picture input binding 1 (i.e. texture source), typically
+ /// this is used, but certain filters do not use it
+ pub inputs: Vec<FilterGraphPictureReferenceKey>,
+ /// rect this node will render into, in filter space, does not account for
+ /// inflate or device_pixel_scale
+ pub subregion: [Au; 4],
+}
+
+impl From<FilterGraphNode> for FilterGraphNodeKey {
+ fn from(node: FilterGraphNode) -> Self {
+ FilterGraphNodeKey{
+ kept_by_optimizer: node.kept_by_optimizer,
+ linear: node.linear,
+ inflate: node.inflate,
+ inputs: node.inputs.into_iter().map(|node| {node.into()}).collect(),
+ subregion: [
+ Au::from_f32_px(node.subregion.min.x),
+ Au::from_f32_px(node.subregion.min.y),
+ Au::from_f32_px(node.subregion.max.x),
+ Au::from_f32_px(node.subregion.max.y),
+ ],
+ }
+ }
+}
+
/// Represents a hashable description of how a picture primitive
/// will be composited into its parent.
#[cfg_attr(feature = "capture", derive(Serialize))]
@@ -96,6 +850,7 @@ pub enum PictureCompositeKey {
ComponentTransfer(ItemUid),
Flood(ColorU),
SvgFilter(Vec<FilterPrimitiveKey>),
+ SVGFEGraph(Vec<(FilterGraphNodeKey, FilterGraphOpKey)>),
// MixBlendMode
Multiply,
@@ -180,6 +935,7 @@ impl From<Option<PictureCompositeMode>> for PictureCompositeKey {
}
Filter::ComponentTransfer => unreachable!(),
Filter::Flood(color) => PictureCompositeKey::Flood(color.into()),
+ Filter::SVGGraphNode(_node, _op) => unreachable!(),
}
}
Some(PictureCompositeMode::ComponentTransferFilter(handle)) => {
@@ -222,6 +978,12 @@ impl From<Option<PictureCompositeMode>> for PictureCompositeKey {
}
}).collect())
}
+ Some(PictureCompositeMode::SVGFEGraph(filter_nodes)) => {
+ PictureCompositeKey::SVGFEGraph(
+ filter_nodes.into_iter().map(|(node, op)| {
+ (node.into(), op.into())
+ }).collect())
+ }
Some(PictureCompositeMode::Blit(_)) |
Some(PictureCompositeMode::TileCache { .. }) |
Some(PictureCompositeMode::IntermediateSurface) |