webrender/svg_filter.rs
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use api::{FilterOpGraphPictureReference, FilterOpGraphNode, ColorF, ColorU, PropertyBinding, PropertyBindingId};
6use api::SVGFE_GRAPH_MAX;
7use api::units::*;
8use api::FilterOpGraphPictureBufferId;
9use crate::profiler::add_text_marker;
10use crate::filterdata::FilterDataHandle;
11use crate::intern::ItemUid;
12use core::time::Duration;
13
14
15#[cfg_attr(feature = "capture", derive(Serialize))]
16#[cfg_attr(feature = "replay", derive(Deserialize))]
17#[derive(Debug, Clone, Copy, Default, MallocSizeOf, PartialEq, Hash, Eq)]
18pub enum FilterGraphPictureBufferIdKey {
19 #[default]
20 /// empty slot in feMerge inputs
21 None,
22 /// reference to another (earlier) node in filter graph
23 BufferId(i16),
24}
25
26#[cfg_attr(feature = "capture", derive(Serialize))]
27#[cfg_attr(feature = "replay", derive(Deserialize))]
28#[derive(Debug, Clone, Copy, Default, MallocSizeOf, PartialEq, Hash, Eq)]
29pub struct FilterGraphPictureReferenceKey {
30 /// Id of the picture in question in a namespace unique to this filter DAG,
31 /// some are special values like
32 /// FilterPrimitiveDescription::kPrimitiveIndexSourceGraphic.
33 pub buffer_id: FilterGraphPictureBufferIdKey,
34 /// Place the input image here in Layout space (like node.subregion)
35 pub subregion: [Au; 4],
36 /// Translate the subregion by this amount
37 pub offset: [Au; 2],
38}
39
40impl From<FilterGraphPictureReference> for FilterGraphPictureReferenceKey {
41 fn from(pic: FilterGraphPictureReference) -> Self {
42 FilterGraphPictureReferenceKey{
43 buffer_id: match pic.buffer_id {
44 FilterOpGraphPictureBufferId::None => FilterGraphPictureBufferIdKey::None,
45 FilterOpGraphPictureBufferId::BufferId(id) => FilterGraphPictureBufferIdKey::BufferId(id),
46 },
47 subregion: [
48 Au::from_f32_px(pic.subregion.min.x),
49 Au::from_f32_px(pic.subregion.min.y),
50 Au::from_f32_px(pic.subregion.max.x),
51 Au::from_f32_px(pic.subregion.max.y),
52 ],
53 offset: [
54 Au::from_f32_px(pic.offset.x),
55 Au::from_f32_px(pic.offset.y),
56 ],
57 }
58 }
59}
60
61#[cfg_attr(feature = "capture", derive(Serialize))]
62#[cfg_attr(feature = "replay", derive(Deserialize))]
63#[derive(Debug, Clone, MallocSizeOf, PartialEq, Hash, Eq)]
64pub enum FilterGraphOpKey {
65 /// combine 2 images with SVG_FEBLEND_MODE_DARKEN
66 /// parameters: FilterOpGraphNode
67 /// SVG filter semantics - selectable input(s), selectable between linear
68 /// (default) and sRGB color space for calculations
69 /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
70 SVGFEBlendDarken,
71 /// combine 2 images with SVG_FEBLEND_MODE_LIGHTEN
72 /// parameters: FilterOpGraphNode
73 /// SVG filter semantics - selectable input(s), selectable between linear
74 /// (default) and sRGB color space for calculations
75 /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
76 SVGFEBlendLighten,
77 /// combine 2 images with SVG_FEBLEND_MODE_MULTIPLY
78 /// parameters: FilterOpGraphNode
79 /// SVG filter semantics - selectable input(s), selectable between linear
80 /// (default) and sRGB color space for calculations
81 /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
82 SVGFEBlendMultiply,
83 /// combine 2 images with SVG_FEBLEND_MODE_NORMAL
84 /// parameters: FilterOpGraphNode
85 /// SVG filter semantics - selectable input(s), selectable between linear
86 /// (default) and sRGB color space for calculations
87 /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
88 SVGFEBlendNormal,
89 /// combine 2 images with SVG_FEBLEND_MODE_SCREEN
90 /// parameters: FilterOpGraphNode
91 /// SVG filter semantics - selectable input(s), selectable between linear
92 /// (default) and sRGB color space for calculations
93 /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
94 SVGFEBlendScreen,
95 /// combine 2 images with SVG_FEBLEND_MODE_OVERLAY
96 /// parameters: FilterOpGraphNode
97 /// SVG filter semantics - selectable input(s), selectable between linear
98 /// (default) and sRGB color space for calculations
99 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
100 SVGFEBlendOverlay,
101 /// combine 2 images with SVG_FEBLEND_MODE_COLOR_DODGE
102 /// parameters: FilterOpGraphNode
103 /// SVG filter semantics - selectable input(s), selectable between linear
104 /// (default) and sRGB color space for calculations
105 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
106 SVGFEBlendColorDodge,
107 /// combine 2 images with SVG_FEBLEND_MODE_COLOR_BURN
108 /// parameters: FilterOpGraphNode
109 /// SVG filter semantics - selectable input(s), selectable between linear
110 /// (default) and sRGB color space for calculations
111 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
112 SVGFEBlendColorBurn,
113 /// combine 2 images with SVG_FEBLEND_MODE_HARD_LIGHT
114 /// parameters: FilterOpGraphNode
115 /// SVG filter semantics - selectable input(s), selectable between linear
116 /// (default) and sRGB color space for calculations
117 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
118 SVGFEBlendHardLight,
119 /// combine 2 images with SVG_FEBLEND_MODE_SOFT_LIGHT
120 /// parameters: FilterOpGraphNode
121 /// SVG filter semantics - selectable input(s), selectable between linear
122 /// (default) and sRGB color space for calculations
123 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
124 SVGFEBlendSoftLight,
125 /// combine 2 images with SVG_FEBLEND_MODE_DIFFERENCE
126 /// parameters: FilterOpGraphNode
127 /// SVG filter semantics - selectable input(s), selectable between linear
128 /// (default) and sRGB color space for calculations
129 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
130 SVGFEBlendDifference,
131 /// combine 2 images with SVG_FEBLEND_MODE_EXCLUSION
132 /// parameters: FilterOpGraphNode
133 /// SVG filter semantics - selectable input(s), selectable between linear
134 /// (default) and sRGB color space for calculations
135 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
136 SVGFEBlendExclusion,
137 /// combine 2 images with SVG_FEBLEND_MODE_HUE
138 /// parameters: FilterOpGraphNode
139 /// SVG filter semantics - selectable input(s), selectable between linear
140 /// (default) and sRGB color space for calculations
141 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
142 SVGFEBlendHue,
143 /// combine 2 images with SVG_FEBLEND_MODE_SATURATION
144 /// parameters: FilterOpGraphNode
145 /// SVG filter semantics - selectable input(s), selectable between linear
146 /// (default) and sRGB color space for calculations
147 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
148 SVGFEBlendSaturation,
149 /// combine 2 images with SVG_FEBLEND_MODE_COLOR
150 /// parameters: FilterOpGraphNode
151 /// SVG filter semantics - selectable input(s), selectable between linear
152 /// (default) and sRGB color space for calculations
153 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
154 SVGFEBlendColor,
155 /// combine 2 images with SVG_FEBLEND_MODE_LUMINOSITY
156 /// parameters: FilterOpGraphNode
157 /// SVG filter semantics - selectable input(s), selectable between linear
158 /// (default) and sRGB color space for calculations
159 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
160 SVGFEBlendLuminosity,
161 /// transform colors of image through 5x4 color matrix (transposed for
162 /// efficiency)
163 /// parameters: FilterOpGraphNode, matrix[5][4]
164 /// SVG filter semantics - selectable input(s), selectable between linear
165 /// (default) and sRGB color space for calculations
166 /// Spec: https://www.w3.org/TR/filter-effects-1/#feColorMatrixElement
167 SVGFEColorMatrix{values: [Au; 20]},
168 /// transform colors of image through configurable gradients with component
169 /// swizzle
170 /// parameters: FilterOpGraphNode, FilterData
171 /// SVG filter semantics - selectable input(s), selectable between linear
172 /// (default) and sRGB color space for calculations
173 /// Spec: https://www.w3.org/TR/filter-effects-1/#feComponentTransferElement
174 SVGFEComponentTransferInterned{handle: ItemUid, creates_pixels: bool},
175 /// composite 2 images with chosen composite mode with parameters for that
176 /// mode
177 /// parameters: FilterOpGraphNode, k1, k2, k3, k4
178 /// SVG filter semantics - selectable input(s), selectable between linear
179 /// (default) and sRGB color space for calculations
180 /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
181 SVGFECompositeArithmetic{k1: Au, k2: Au, k3: Au, k4: Au},
182 /// composite 2 images with chosen composite mode with parameters for that
183 /// mode
184 /// parameters: FilterOpGraphNode
185 /// SVG filter semantics - selectable input(s), selectable between linear
186 /// (default) and sRGB color space for calculations
187 /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
188 SVGFECompositeATop,
189 /// composite 2 images with chosen composite mode with parameters for that
190 /// mode
191 /// parameters: FilterOpGraphNode
192 /// SVG filter semantics - selectable input(s), selectable between linear
193 /// (default) and sRGB color space for calculations
194 /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
195 SVGFECompositeIn,
196 /// composite 2 images with chosen composite mode with parameters for that
197 /// mode
198 /// parameters: FilterOpGraphNode
199 /// SVG filter semantics - selectable input(s), selectable between linear
200 /// (default) and sRGB color space for calculations
201 /// Docs: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feComposite
202 SVGFECompositeLighter,
203 /// composite 2 images with chosen composite mode with parameters for that
204 /// mode
205 /// parameters: FilterOpGraphNode
206 /// SVG filter semantics - selectable input(s), selectable between linear
207 /// (default) and sRGB color space for calculations
208 /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
209 SVGFECompositeOut,
210 /// composite 2 images with chosen composite mode with parameters for that
211 /// mode
212 /// parameters: FilterOpGraphNode
213 /// SVG filter semantics - selectable input(s), selectable between linear
214 /// (default) and sRGB color space for calculations
215 /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
216 SVGFECompositeOver,
217 /// composite 2 images with chosen composite mode with parameters for that
218 /// mode
219 /// parameters: FilterOpGraphNode
220 /// SVG filter semantics - selectable input(s), selectable between linear
221 /// (default) and sRGB color space for calculations
222 /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
223 SVGFECompositeXOR,
224 /// transform image through convolution matrix of up to 25 values (spec
225 /// allows more but for performance reasons we do not)
226 /// parameters: FilterOpGraphNode, orderX, orderY, kernelValues[25],
227 /// divisor, bias, targetX, targetY, kernelUnitLengthX, kernelUnitLengthY,
228 /// preserveAlpha
229 /// SVG filter semantics - selectable input(s), selectable between linear
230 /// (default) and sRGB color space for calculations
231 /// Spec: https://www.w3.org/TR/filter-effects-1/#feConvolveMatrixElement
232 SVGFEConvolveMatrixEdgeModeDuplicate{order_x: i32, order_y: i32,
233 kernel: [Au; SVGFE_CONVOLVE_VALUES_LIMIT], divisor: Au, bias: Au,
234 target_x: i32, target_y: i32, kernel_unit_length_x: Au,
235 kernel_unit_length_y: Au, preserve_alpha: i32},
236 /// transform image through convolution matrix of up to 25 values (spec
237 /// allows more but for performance reasons we do not)
238 /// parameters: FilterOpGraphNode, orderX, orderY, kernelValues[25],
239 /// divisor, bias, targetX, targetY, kernelUnitLengthX, kernelUnitLengthY,
240 /// preserveAlpha
241 /// SVG filter semantics - selectable input(s), selectable between linear
242 /// (default) and sRGB color space for calculations
243 /// Spec: https://www.w3.org/TR/filter-effects-1/#feConvolveMatrixElement
244 SVGFEConvolveMatrixEdgeModeNone{order_x: i32, order_y: i32,
245 kernel: [Au; SVGFE_CONVOLVE_VALUES_LIMIT], divisor: Au, bias: Au,
246 target_x: i32, target_y: i32, kernel_unit_length_x: Au,
247 kernel_unit_length_y: Au, preserve_alpha: i32},
248 /// transform image through convolution matrix of up to 25 values (spec
249 /// allows more but for performance reasons we do not)
250 /// parameters: FilterOpGraphNode, orderX, orderY, kernelValues[25],
251 /// divisor, bias, targetX, targetY, kernelUnitLengthX, kernelUnitLengthY,
252 /// preserveAlpha
253 /// SVG filter semantics - selectable input(s), selectable between linear
254 /// (default) and sRGB color space for calculations
255 /// Spec: https://www.w3.org/TR/filter-effects-1/#feConvolveMatrixElement
256 SVGFEConvolveMatrixEdgeModeWrap{order_x: i32, order_y: i32,
257 kernel: [Au; SVGFE_CONVOLVE_VALUES_LIMIT], divisor: Au, bias: Au,
258 target_x: i32, target_y: i32, kernel_unit_length_x: Au,
259 kernel_unit_length_y: Au, preserve_alpha: i32},
260 /// calculate lighting based on heightmap image with provided values for a
261 /// distant light source with specified direction
262 /// parameters: FilterOpGraphNode, surfaceScale, diffuseConstant,
263 /// kernelUnitLengthX, kernelUnitLengthY, azimuth, elevation
264 /// SVG filter semantics - selectable input(s), selectable between linear
265 /// (default) and sRGB color space for calculations
266 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDiffuseLightingElement
267 /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDistantLightElement
268 SVGFEDiffuseLightingDistant{surface_scale: Au, diffuse_constant: Au,
269 kernel_unit_length_x: Au, kernel_unit_length_y: Au, azimuth: Au,
270 elevation: Au},
271 /// calculate lighting based on heightmap image with provided values for a
272 /// point light source at specified location
273 /// parameters: FilterOpGraphNode, surfaceScale, diffuseConstant,
274 /// kernelUnitLengthX, kernelUnitLengthY, x, y, z
275 /// SVG filter semantics - selectable input(s), selectable between linear
276 /// (default) and sRGB color space for calculations
277 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDiffuseLightingElement
278 /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEPointLightElement
279 SVGFEDiffuseLightingPoint{surface_scale: Au, diffuse_constant: Au,
280 kernel_unit_length_x: Au, kernel_unit_length_y: Au, x: Au, y: Au,
281 z: Au},
282 /// calculate lighting based on heightmap image with provided values for a
283 /// spot light source at specified location pointing at specified target
284 /// location with specified hotspot sharpness and cone angle
285 /// parameters: FilterOpGraphNode, surfaceScale, diffuseConstant,
286 /// kernelUnitLengthX, kernelUnitLengthY, x, y, z, pointsAtX, pointsAtY,
287 /// pointsAtZ, specularExponent, limitingConeAngle
288 /// SVG filter semantics - selectable input(s), selectable between linear
289 /// (default) and sRGB color space for calculations
290 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDiffuseLightingElement
291 /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpotLightElement
292 SVGFEDiffuseLightingSpot{surface_scale: Au, diffuse_constant: Au,
293 kernel_unit_length_x: Au, kernel_unit_length_y: Au, x: Au, y: Au, z: Au,
294 points_at_x: Au, points_at_y: Au, points_at_z: Au, cone_exponent: Au,
295 limiting_cone_angle: Au},
296 /// calculate a distorted version of first input image using offset values
297 /// from second input image at specified intensity
298 /// parameters: FilterOpGraphNode, scale, xChannelSelector, yChannelSelector
299 /// SVG filter semantics - selectable input(s), selectable between linear
300 /// (default) and sRGB color space for calculations
301 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDisplacementMapElement
302 SVGFEDisplacementMap{scale: Au, x_channel_selector: u32,
303 y_channel_selector: u32},
304 /// create and merge a dropshadow version of the specified image's alpha
305 /// channel with specified offset and blur radius
306 /// parameters: FilterOpGraphNode, flood_color, flood_opacity, dx, dy,
307 /// stdDeviationX, stdDeviationY
308 /// SVG filter semantics - selectable input(s), selectable between linear
309 /// (default) and sRGB color space for calculations
310 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDropShadowElement
311 SVGFEDropShadow{color: ColorU, dx: Au, dy: Au, std_deviation_x: Au,
312 std_deviation_y: Au},
313 /// synthesize a new image of specified size containing a solid color
314 /// parameters: FilterOpGraphNode, color
315 /// SVG filter semantics - selectable input(s), selectable between linear
316 /// (default) and sRGB color space for calculations
317 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEFloodElement
318 SVGFEFlood{color: ColorU},
319 /// create a blurred version of the input image
320 /// parameters: FilterOpGraphNode, stdDeviationX, stdDeviationY
321 /// SVG filter semantics - selectable input(s), selectable between linear
322 /// (default) and sRGB color space for calculations
323 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEGaussianBlurElement
324 SVGFEGaussianBlur{std_deviation_x: Au, std_deviation_y: Au},
325 /// Filter that does no transformation of the colors, needed for
326 /// debug purposes, and is the default value in impl_default_for_enums.
327 SVGFEIdentity,
328 /// synthesize a new image based on a url (i.e. blob image source)
329 /// parameters: FilterOpGraphNode, sampling_filter (see SamplingFilter in
330 /// Types.h), transform
331 /// SVG filter semantics - selectable input(s), selectable between linear
332 /// (default) and sRGB color space for calculations
333 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEImageElement
334 SVGFEImage{sampling_filter: u32, matrix: [Au; 6]},
335 /// create a new image based on the input image with the contour stretched
336 /// outward (dilate operator)
337 /// parameters: FilterOpGraphNode, radiusX, radiusY
338 /// SVG filter semantics - selectable input(s), selectable between linear
339 /// (default) and sRGB color space for calculations
340 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEMorphologyElement
341 SVGFEMorphologyDilate{radius_x: Au, radius_y: Au},
342 /// create a new image based on the input image with the contour shrunken
343 /// inward (erode operator)
344 /// parameters: FilterOpGraphNode, radiusX, radiusY
345 /// SVG filter semantics - selectable input(s), selectable between linear
346 /// (default) and sRGB color space for calculations
347 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEMorphologyElement
348 SVGFEMorphologyErode{radius_x: Au, radius_y: Au},
349 /// represents CSS opacity property as a graph node like the rest of the
350 /// SVGFE* filters
351 /// parameters: FilterOpGraphNode
352 /// SVG filter semantics - selectable input(s), selectable between linear
353 /// (default) and sRGB color space for calculations
354 SVGFEOpacity{value: Au},
355 /// represents CSS opacity property as a graph node like the rest of the
356 /// SVGFE* filters
357 /// parameters: FilterOpGraphNode
358 /// SVG filter semantics - selectable input(s), selectable between linear
359 /// (default) and sRGB color space for calculations
360 SVGFEOpacityBinding{valuebindingid: PropertyBindingId, value: Au},
361 /// Filter that copies the SourceGraphic image into the specified subregion,
362 /// This is intentionally the only way to get SourceGraphic into the graph,
363 /// as the filter region must be applied before it is used.
364 /// parameters: FilterOpGraphNode
365 /// SVG filter semantics - no inputs, no linear
366 SVGFESourceGraphic,
367 /// Filter that copies the SourceAlpha image into the specified subregion,
368 /// This is intentionally the only way to get SourceAlpha into the graph,
369 /// as the filter region must be applied before it is used.
370 /// parameters: FilterOpGraphNode
371 /// SVG filter semantics - no inputs, no linear
372 SVGFESourceAlpha,
373 /// calculate lighting based on heightmap image with provided values for a
374 /// distant light source with specified direction
375 /// parameters: FilerData, surfaceScale, specularConstant, specularExponent,
376 /// kernelUnitLengthX, kernelUnitLengthY, azimuth, elevation
377 /// SVG filter semantics - selectable input(s), selectable between linear
378 /// (default) and sRGB color space for calculations
379 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpecularLightingElement
380 /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDistantLightElement
381 SVGFESpecularLightingDistant{surface_scale: Au, specular_constant: Au,
382 specular_exponent: Au, kernel_unit_length_x: Au,
383 kernel_unit_length_y: Au, azimuth: Au, elevation: Au},
384 /// calculate lighting based on heightmap image with provided values for a
385 /// point light source at specified location
386 /// parameters: FilterOpGraphNode, surfaceScale, specularConstant,
387 /// specularExponent, kernelUnitLengthX, kernelUnitLengthY, x, y, z
388 /// SVG filter semantics - selectable input(s), selectable between linear
389 /// (default) and sRGB color space for calculations
390 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpecularLightingElement
391 /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEPointLightElement
392 SVGFESpecularLightingPoint{surface_scale: Au, specular_constant: Au,
393 specular_exponent: Au, kernel_unit_length_x: Au,
394 kernel_unit_length_y: Au, x: Au, y: Au, z: Au},
395 /// calculate lighting based on heightmap image with provided values for a
396 /// spot light source at specified location pointing at specified target
397 /// location with specified hotspot sharpness and cone angle
398 /// parameters: FilterOpGraphNode, surfaceScale, specularConstant,
399 /// specularExponent, kernelUnitLengthX, kernelUnitLengthY, x, y, z,
400 /// pointsAtX, pointsAtY, pointsAtZ, specularExponent, limitingConeAngle
401 /// SVG filter semantics - selectable input(s), selectable between linear
402 /// (default) and sRGB color space for calculations
403 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpecularLightingElement
404 /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpotLightElement
405 SVGFESpecularLightingSpot{surface_scale: Au, specular_constant: Au,
406 specular_exponent: Au, kernel_unit_length_x: Au,
407 kernel_unit_length_y: Au, x: Au, y: Au, z: Au, points_at_x: Au,
408 points_at_y: Au, points_at_z: Au, cone_exponent: Au,
409 limiting_cone_angle: Au},
410 /// create a new image based on the input image, repeated throughout the
411 /// output rectangle
412 /// parameters: FilterOpGraphNode
413 /// SVG filter semantics - selectable input(s), selectable between linear
414 /// (default) and sRGB color space for calculations
415 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETileElement
416 SVGFETile,
417 /// convert a color image to an alpha channel - internal use; generated by
418 /// SVGFilterInstance::GetOrCreateSourceAlphaIndex().
419 SVGFEToAlpha,
420 /// synthesize a new image based on Fractal Noise (Perlin) with the chosen
421 /// stitching mode
422 /// parameters: FilterOpGraphNode, baseFrequencyX, baseFrequencyY,
423 /// numOctaves, seed
424 /// SVG filter semantics - selectable input(s), selectable between linear
425 /// (default) and sRGB color space for calculations
426 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETurbulenceElement
427 SVGFETurbulenceWithFractalNoiseWithNoStitching{base_frequency_x: Au,
428 base_frequency_y: Au, num_octaves: u32, seed: u32},
429 /// synthesize a new image based on Fractal Noise (Perlin) with the chosen
430 /// stitching mode
431 /// parameters: FilterOpGraphNode, baseFrequencyX, baseFrequencyY,
432 /// numOctaves, seed
433 /// SVG filter semantics - selectable input(s), selectable between linear
434 /// (default) and sRGB color space for calculations
435 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETurbulenceElement
436 SVGFETurbulenceWithFractalNoiseWithStitching{base_frequency_x: Au,
437 base_frequency_y: Au, num_octaves: u32, seed: u32},
438 /// synthesize a new image based on Turbulence Noise (offset vectors)
439 /// parameters: FilterOpGraphNode, baseFrequencyX, baseFrequencyY,
440 /// numOctaves, seed
441 /// SVG filter semantics - selectable input(s), selectable between linear
442 /// (default) and sRGB color space for calculations
443 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETurbulenceElement
444 SVGFETurbulenceWithTurbulenceNoiseWithNoStitching{base_frequency_x: Au,
445 base_frequency_y: Au, num_octaves: u32, seed: u32},
446 /// synthesize a new image based on Turbulence Noise (offset vectors)
447 /// parameters: FilterOpGraphNode, baseFrequencyX, baseFrequencyY,
448 /// numOctaves, seed
449 /// SVG filter semantics - selectable input(s), selectable between linear
450 /// (default) and sRGB color space for calculations
451 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETurbulenceElement
452 SVGFETurbulenceWithTurbulenceNoiseWithStitching{base_frequency_x: Au,
453 base_frequency_y: Au, num_octaves: u32, seed: u32},
454}
455
456impl From<FilterGraphOp> for FilterGraphOpKey {
457 fn from(op: FilterGraphOp) -> Self {
458 match op {
459 FilterGraphOp::SVGFEBlendDarken => FilterGraphOpKey::SVGFEBlendDarken,
460 FilterGraphOp::SVGFEBlendLighten => FilterGraphOpKey::SVGFEBlendLighten,
461 FilterGraphOp::SVGFEBlendMultiply => FilterGraphOpKey::SVGFEBlendMultiply,
462 FilterGraphOp::SVGFEBlendNormal => FilterGraphOpKey::SVGFEBlendNormal,
463 FilterGraphOp::SVGFEBlendScreen => FilterGraphOpKey::SVGFEBlendScreen,
464 FilterGraphOp::SVGFEBlendOverlay => FilterGraphOpKey::SVGFEBlendOverlay,
465 FilterGraphOp::SVGFEBlendColorDodge => FilterGraphOpKey::SVGFEBlendColorDodge,
466 FilterGraphOp::SVGFEBlendColorBurn => FilterGraphOpKey::SVGFEBlendColorBurn,
467 FilterGraphOp::SVGFEBlendHardLight => FilterGraphOpKey::SVGFEBlendHardLight,
468 FilterGraphOp::SVGFEBlendSoftLight => FilterGraphOpKey::SVGFEBlendSoftLight,
469 FilterGraphOp::SVGFEBlendDifference => FilterGraphOpKey::SVGFEBlendDifference,
470 FilterGraphOp::SVGFEBlendExclusion => FilterGraphOpKey::SVGFEBlendExclusion,
471 FilterGraphOp::SVGFEBlendHue => FilterGraphOpKey::SVGFEBlendHue,
472 FilterGraphOp::SVGFEBlendSaturation => FilterGraphOpKey::SVGFEBlendSaturation,
473 FilterGraphOp::SVGFEBlendColor => FilterGraphOpKey::SVGFEBlendColor,
474 FilterGraphOp::SVGFEBlendLuminosity => FilterGraphOpKey::SVGFEBlendLuminosity,
475 FilterGraphOp::SVGFEColorMatrix { values: color_matrix } => {
476 let mut quantized_values: [Au; 20] = [Au(0); 20];
477 for (value, result) in color_matrix.iter().zip(quantized_values.iter_mut()) {
478 *result = Au::from_f32_px(*value);
479 }
480 FilterGraphOpKey::SVGFEColorMatrix{values: quantized_values}
481 }
482 FilterGraphOp::SVGFEComponentTransfer => unreachable!(),
483 FilterGraphOp::SVGFEComponentTransferInterned { handle, creates_pixels } => FilterGraphOpKey::SVGFEComponentTransferInterned{
484 handle: handle.uid(),
485 creates_pixels,
486 },
487 FilterGraphOp::SVGFECompositeArithmetic { k1, k2, k3, k4 } => {
488 FilterGraphOpKey::SVGFECompositeArithmetic{
489 k1: Au::from_f32_px(k1),
490 k2: Au::from_f32_px(k2),
491 k3: Au::from_f32_px(k3),
492 k4: Au::from_f32_px(k4),
493 }
494 }
495 FilterGraphOp::SVGFECompositeATop => FilterGraphOpKey::SVGFECompositeATop,
496 FilterGraphOp::SVGFECompositeIn => FilterGraphOpKey::SVGFECompositeIn,
497 FilterGraphOp::SVGFECompositeLighter => FilterGraphOpKey::SVGFECompositeLighter,
498 FilterGraphOp::SVGFECompositeOut => FilterGraphOpKey::SVGFECompositeOut,
499 FilterGraphOp::SVGFECompositeOver => FilterGraphOpKey::SVGFECompositeOver,
500 FilterGraphOp::SVGFECompositeXOR => FilterGraphOpKey::SVGFECompositeXOR,
501 FilterGraphOp::SVGFEConvolveMatrixEdgeModeDuplicate { order_x, order_y, kernel, divisor, bias, target_x, target_y, kernel_unit_length_x, kernel_unit_length_y, preserve_alpha } => {
502 let mut values: [Au; SVGFE_CONVOLVE_VALUES_LIMIT] = [Au(0); SVGFE_CONVOLVE_VALUES_LIMIT];
503 for (value, result) in kernel.iter().zip(values.iter_mut()) {
504 *result = Au::from_f32_px(*value)
505 }
506 FilterGraphOpKey::SVGFEConvolveMatrixEdgeModeDuplicate{
507 order_x,
508 order_y,
509 kernel: values,
510 divisor: Au::from_f32_px(divisor),
511 bias: Au::from_f32_px(bias),
512 target_x,
513 target_y,
514 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
515 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
516 preserve_alpha,
517 }
518 }
519 FilterGraphOp::SVGFEConvolveMatrixEdgeModeNone { order_x, order_y, kernel, divisor, bias, target_x, target_y, kernel_unit_length_x, kernel_unit_length_y, preserve_alpha } => {
520 let mut values: [Au; SVGFE_CONVOLVE_VALUES_LIMIT] = [Au(0); SVGFE_CONVOLVE_VALUES_LIMIT];
521 for (value, result) in kernel.iter().zip(values.iter_mut()) {
522 *result = Au::from_f32_px(*value)
523 }
524 FilterGraphOpKey::SVGFEConvolveMatrixEdgeModeNone{
525 order_x,
526 order_y,
527 kernel: values,
528 divisor: Au::from_f32_px(divisor),
529 bias: Au::from_f32_px(bias),
530 target_x,
531 target_y,
532 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
533 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
534 preserve_alpha,
535 }
536 }
537 FilterGraphOp::SVGFEConvolveMatrixEdgeModeWrap { order_x, order_y, kernel, divisor, bias, target_x, target_y, kernel_unit_length_x, kernel_unit_length_y, preserve_alpha } => {
538 let mut values: [Au; SVGFE_CONVOLVE_VALUES_LIMIT] = [Au(0); SVGFE_CONVOLVE_VALUES_LIMIT];
539 for (value, result) in kernel.iter().zip(values.iter_mut()) {
540 *result = Au::from_f32_px(*value)
541 }
542 FilterGraphOpKey::SVGFEConvolveMatrixEdgeModeWrap{
543 order_x,
544 order_y,
545 kernel: values,
546 divisor: Au::from_f32_px(divisor),
547 bias: Au::from_f32_px(bias),
548 target_x,
549 target_y,
550 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
551 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
552 preserve_alpha,
553 }
554 }
555 FilterGraphOp::SVGFEDiffuseLightingDistant { surface_scale, diffuse_constant, kernel_unit_length_x, kernel_unit_length_y, azimuth, elevation } => {
556 FilterGraphOpKey::SVGFEDiffuseLightingDistant{
557 surface_scale: Au::from_f32_px(surface_scale),
558 diffuse_constant: Au::from_f32_px(diffuse_constant),
559 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
560 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
561 azimuth: Au::from_f32_px(azimuth),
562 elevation: Au::from_f32_px(elevation),
563 }
564 }
565 FilterGraphOp::SVGFEDiffuseLightingPoint { surface_scale, diffuse_constant, kernel_unit_length_x, kernel_unit_length_y, x, y, z } => {
566 FilterGraphOpKey::SVGFEDiffuseLightingPoint{
567 surface_scale: Au::from_f32_px(surface_scale),
568 diffuse_constant: Au::from_f32_px(diffuse_constant),
569 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
570 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
571 x: Au::from_f32_px(x),
572 y: Au::from_f32_px(y),
573 z: Au::from_f32_px(z),
574 }
575 }
576 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 } => {
577 FilterGraphOpKey::SVGFEDiffuseLightingSpot{
578 surface_scale: Au::from_f32_px(surface_scale),
579 diffuse_constant: Au::from_f32_px(diffuse_constant),
580 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
581 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
582 x: Au::from_f32_px(x),
583 y: Au::from_f32_px(y),
584 z: Au::from_f32_px(z),
585 points_at_x: Au::from_f32_px(points_at_x),
586 points_at_y: Au::from_f32_px(points_at_y),
587 points_at_z: Au::from_f32_px(points_at_z),
588 cone_exponent: Au::from_f32_px(cone_exponent),
589 limiting_cone_angle: Au::from_f32_px(limiting_cone_angle),
590 }
591 }
592 FilterGraphOp::SVGFEDisplacementMap { scale, x_channel_selector, y_channel_selector } => {
593 FilterGraphOpKey::SVGFEDisplacementMap{
594 scale: Au::from_f32_px(scale),
595 x_channel_selector,
596 y_channel_selector,
597 }
598 }
599 FilterGraphOp::SVGFEDropShadow { color, dx, dy, std_deviation_x, std_deviation_y } => {
600 FilterGraphOpKey::SVGFEDropShadow{
601 color: color.into(),
602 dx: Au::from_f32_px(dx),
603 dy: Au::from_f32_px(dy),
604 std_deviation_x: Au::from_f32_px(std_deviation_x),
605 std_deviation_y: Au::from_f32_px(std_deviation_y),
606 }
607 }
608 FilterGraphOp::SVGFEFlood { color } => FilterGraphOpKey::SVGFEFlood{color: color.into()},
609 FilterGraphOp::SVGFEGaussianBlur { std_deviation_x, std_deviation_y } => {
610 FilterGraphOpKey::SVGFEGaussianBlur{
611 std_deviation_x: Au::from_f32_px(std_deviation_x),
612 std_deviation_y: Au::from_f32_px(std_deviation_y),
613 }
614 }
615 FilterGraphOp::SVGFEIdentity => FilterGraphOpKey::SVGFEIdentity,
616 FilterGraphOp::SVGFEImage { sampling_filter, matrix } => {
617 let mut values: [Au; 6] = [Au(0); 6];
618 for (value, result) in matrix.iter().zip(values.iter_mut()) {
619 *result = Au::from_f32_px(*value)
620 }
621 FilterGraphOpKey::SVGFEImage{
622 sampling_filter,
623 matrix: values,
624 }
625 }
626 FilterGraphOp::SVGFEMorphologyDilate { radius_x, radius_y } => {
627 FilterGraphOpKey::SVGFEMorphologyDilate{
628 radius_x: Au::from_f32_px(radius_x),
629 radius_y: Au::from_f32_px(radius_y),
630 }
631 }
632 FilterGraphOp::SVGFEMorphologyErode { radius_x, radius_y } => {
633 FilterGraphOpKey::SVGFEMorphologyErode{
634 radius_x: Au::from_f32_px(radius_x),
635 radius_y: Au::from_f32_px(radius_y),
636 }
637 }
638 FilterGraphOp::SVGFEOpacity{valuebinding: binding, value: _} => {
639 match binding {
640 PropertyBinding::Value(value) => {
641 FilterGraphOpKey::SVGFEOpacity{value: Au::from_f32_px(value)}
642 }
643 PropertyBinding::Binding(key, default) => {
644 FilterGraphOpKey::SVGFEOpacityBinding{valuebindingid: key.id, value: Au::from_f32_px(default)}
645 }
646 }
647 }
648 FilterGraphOp::SVGFESourceAlpha => FilterGraphOpKey::SVGFESourceAlpha,
649 FilterGraphOp::SVGFESourceGraphic => FilterGraphOpKey::SVGFESourceGraphic,
650 FilterGraphOp::SVGFESpecularLightingDistant { surface_scale, specular_constant, specular_exponent, kernel_unit_length_x, kernel_unit_length_y, azimuth, elevation } => {
651 FilterGraphOpKey::SVGFESpecularLightingDistant{
652 surface_scale: Au::from_f32_px(surface_scale),
653 specular_constant: Au::from_f32_px(specular_constant),
654 specular_exponent: Au::from_f32_px(specular_exponent),
655 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
656 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
657 azimuth: Au::from_f32_px(azimuth),
658 elevation: Au::from_f32_px(elevation),
659 }
660 }
661 FilterGraphOp::SVGFESpecularLightingPoint { surface_scale, specular_constant, specular_exponent, kernel_unit_length_x, kernel_unit_length_y, x, y, z } => {
662 FilterGraphOpKey::SVGFESpecularLightingPoint{
663 surface_scale: Au::from_f32_px(surface_scale),
664 specular_constant: Au::from_f32_px(specular_constant),
665 specular_exponent: Au::from_f32_px(specular_exponent),
666 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
667 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
668 x: Au::from_f32_px(x),
669 y: Au::from_f32_px(y),
670 z: Au::from_f32_px(z),
671 }
672 }
673 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 } => {
674 FilterGraphOpKey::SVGFESpecularLightingSpot{
675 surface_scale: Au::from_f32_px(surface_scale),
676 specular_constant: Au::from_f32_px(specular_constant),
677 specular_exponent: Au::from_f32_px(specular_exponent),
678 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
679 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
680 x: Au::from_f32_px(x),
681 y: Au::from_f32_px(y),
682 z: Au::from_f32_px(z),
683 points_at_x: Au::from_f32_px(points_at_x),
684 points_at_y: Au::from_f32_px(points_at_y),
685 points_at_z: Au::from_f32_px(points_at_z),
686 cone_exponent: Au::from_f32_px(cone_exponent),
687 limiting_cone_angle: Au::from_f32_px(limiting_cone_angle),
688 }
689 }
690 FilterGraphOp::SVGFETile => FilterGraphOpKey::SVGFETile,
691 FilterGraphOp::SVGFEToAlpha => FilterGraphOpKey::SVGFEToAlpha,
692 FilterGraphOp::SVGFETurbulenceWithFractalNoiseWithNoStitching { base_frequency_x, base_frequency_y, num_octaves, seed } => {
693 FilterGraphOpKey::SVGFETurbulenceWithFractalNoiseWithNoStitching {
694 base_frequency_x: Au::from_f32_px(base_frequency_x),
695 base_frequency_y: Au::from_f32_px(base_frequency_y),
696 num_octaves,
697 seed,
698 }
699 }
700 FilterGraphOp::SVGFETurbulenceWithFractalNoiseWithStitching { base_frequency_x, base_frequency_y, num_octaves, seed } => {
701 FilterGraphOpKey::SVGFETurbulenceWithFractalNoiseWithStitching {
702 base_frequency_x: Au::from_f32_px(base_frequency_x),
703 base_frequency_y: Au::from_f32_px(base_frequency_y),
704 num_octaves,
705 seed,
706 }
707 }
708 FilterGraphOp::SVGFETurbulenceWithTurbulenceNoiseWithNoStitching { base_frequency_x, base_frequency_y, num_octaves, seed } => {
709 FilterGraphOpKey::SVGFETurbulenceWithTurbulenceNoiseWithNoStitching {
710 base_frequency_x: Au::from_f32_px(base_frequency_x),
711 base_frequency_y: Au::from_f32_px(base_frequency_y),
712 num_octaves,
713 seed,
714 }
715 }
716 FilterGraphOp::SVGFETurbulenceWithTurbulenceNoiseWithStitching { base_frequency_x, base_frequency_y, num_octaves, seed } => {
717 FilterGraphOpKey::SVGFETurbulenceWithTurbulenceNoiseWithStitching {
718 base_frequency_x: Au::from_f32_px(base_frequency_x),
719 base_frequency_y: Au::from_f32_px(base_frequency_y),
720 num_octaves,
721 seed,
722 }
723 }
724 }
725 }
726}
727
728#[cfg_attr(feature = "capture", derive(Serialize))]
729#[cfg_attr(feature = "replay", derive(Deserialize))]
730#[derive(Debug, Clone, MallocSizeOf, PartialEq, Hash, Eq)]
731pub struct FilterGraphNodeKey {
732 /// Indicates this graph node was marked as unnecessary by the DAG optimizer
733 /// (for example SVGFEOffset can often be folded into downstream nodes)
734 pub kept_by_optimizer: bool,
735 /// True if color_interpolation_filter == LinearRgb; shader will convert
736 /// sRGB texture pixel colors on load and convert back on store, for correct
737 /// interpolation
738 pub linear: bool,
739 /// virtualized picture input binding 1 (i.e. texture source), typically
740 /// this is used, but certain filters do not use it
741 pub inputs: Vec<FilterGraphPictureReferenceKey>,
742 /// rect this node will render into, in filter space, does not account for
743 /// inflate or device_pixel_scale
744 pub subregion: [Au; 4],
745}
746
747impl From<FilterGraphNode> for FilterGraphNodeKey {
748 fn from(node: FilterGraphNode) -> Self {
749 FilterGraphNodeKey{
750 kept_by_optimizer: node.kept_by_optimizer,
751 linear: node.linear,
752 inputs: node.inputs.into_iter().map(|node| {node.into()}).collect(),
753 subregion: [
754 Au::from_f32_px(node.subregion.min.x),
755 Au::from_f32_px(node.subregion.min.y),
756 Au::from_f32_px(node.subregion.max.x),
757 Au::from_f32_px(node.subregion.max.y),
758 ],
759 }
760 }
761}
762
763#[derive(Clone, Copy, Debug)]
764#[cfg_attr(feature = "capture", derive(Serialize))]
765#[cfg_attr(feature = "replay", derive(Deserialize))]
766pub struct FilterGraphPictureReference {
767 /// Id of the picture in question in a namespace unique to this filter DAG,
768 /// some are special values like
769 /// FilterPrimitiveDescription::kPrimitiveIndexSourceGraphic.
770 pub buffer_id: FilterOpGraphPictureBufferId,
771 /// Set by wrap_prim_with_filters to the subregion of the input node, may
772 /// also have been offset for feDropShadow or feOffset
773 pub subregion: LayoutRect,
774 /// During scene build this is the offset to apply to the input subregion
775 /// for feOffset, which can be optimized away by pushing its offset and
776 /// subregion crop to downstream nodes. This is always zero in render tasks
777 /// where it has already been applied to subregion by that point. Not used
778 /// in get_coverage_svgfe because source_padding/target_padding represent
779 /// the offset there.
780 pub offset: LayoutVector2D,
781 /// Equal to the inflate value of the referenced buffer, or 0
782 pub inflate: i16,
783 /// Padding on each side to represent how this input is read relative to the
784 /// node's output subregion, this represents what the operation needs to
785 /// read from ths input, which may be blurred or offset.
786 pub source_padding: LayoutRect,
787 /// Padding on each side to represent how this input affects the node's
788 /// subregion, this can be used to calculate target subregion based on
789 /// SourceGraphic subregion. This is usually equal to source_padding except
790 /// offset in the opposite direction, inflates typically do the same thing
791 /// to both types of padding.
792 pub target_padding: LayoutRect,
793}
794
795impl From<FilterOpGraphPictureReference> for FilterGraphPictureReference {
796 fn from(pic: FilterOpGraphPictureReference) -> Self {
797 FilterGraphPictureReference{
798 buffer_id: pic.buffer_id,
799 // All of these are set by wrap_prim_with_filters
800 subregion: LayoutRect::zero(),
801 offset: LayoutVector2D::zero(),
802 inflate: 0,
803 source_padding: LayoutRect::zero(),
804 target_padding: LayoutRect::zero(),
805 }
806 }
807}
808
809pub const SVGFE_CONVOLVE_DIAMETER_LIMIT: usize = 5;
810pub const SVGFE_CONVOLVE_VALUES_LIMIT: usize = SVGFE_CONVOLVE_DIAMETER_LIMIT *
811 SVGFE_CONVOLVE_DIAMETER_LIMIT;
812
813#[derive(Clone, Debug)]
814#[cfg_attr(feature = "capture", derive(Serialize))]
815#[cfg_attr(feature = "replay", derive(Deserialize))]
816pub enum FilterGraphOp {
817 /// Filter that copies the SourceGraphic image into the specified subregion,
818 /// This is intentionally the only way to get SourceGraphic into the graph,
819 /// as the filter region must be applied before it is used.
820 /// parameters: FilterOpGraphNode
821 /// SVG filter semantics - no inputs, no linear
822 SVGFESourceGraphic,
823 /// Filter that copies the SourceAlpha image into the specified subregion,
824 /// This is intentionally the only way to get SourceAlpha into the graph,
825 /// as the filter region must be applied before it is used.
826 /// parameters: FilterOpGraphNode
827 /// SVG filter semantics - no inputs, no linear
828 SVGFESourceAlpha,
829 /// Filter that does no transformation of the colors, used to implement a
830 /// few things like SVGFEOffset, and this is the default value in
831 /// impl_default_for_enums.
832 /// parameters: FilterGraphNode
833 /// SVG filter semantics - selectable input with offset
834 SVGFEIdentity,
835 /// represents CSS opacity property as a graph node like the rest of the
836 /// SVGFE* filters
837 /// parameters: FilterGraphNode
838 /// SVG filter semantics - selectable input(s), selectable between linear
839 /// (default) and sRGB color space for calculations
840 SVGFEOpacity{valuebinding: api::PropertyBinding<f32>, value: f32},
841 /// convert a color image to an alpha channel - internal use; generated by
842 /// SVGFilterInstance::GetOrCreateSourceAlphaIndex().
843 SVGFEToAlpha,
844 /// combine 2 images with SVG_FEBLEND_MODE_DARKEN
845 /// parameters: FilterGraphNode
846 /// SVG filter semantics - selectable input(s), selectable between linear
847 /// (default) and sRGB color space for calculations
848 /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
849 SVGFEBlendDarken,
850 /// combine 2 images with SVG_FEBLEND_MODE_LIGHTEN
851 /// parameters: FilterGraphNode
852 /// SVG filter semantics - selectable input(s), selectable between linear
853 /// (default) and sRGB color space for calculations
854 /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
855 SVGFEBlendLighten,
856 /// combine 2 images with SVG_FEBLEND_MODE_MULTIPLY
857 /// parameters: FilterGraphNode
858 /// SVG filter semantics - selectable input(s), selectable between linear
859 /// (default) and sRGB color space for calculations
860 /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
861 SVGFEBlendMultiply,
862 /// combine 2 images with SVG_FEBLEND_MODE_NORMAL
863 /// parameters: FilterGraphNode
864 /// SVG filter semantics - selectable input(s), selectable between linear
865 /// (default) and sRGB color space for calculations
866 /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
867 SVGFEBlendNormal,
868 /// combine 2 images with SVG_FEBLEND_MODE_SCREEN
869 /// parameters: FilterGraphNode
870 /// SVG filter semantics - selectable input(s), selectable between linear
871 /// (default) and sRGB color space for calculations
872 /// Spec: https://www.w3.org/TR/filter-effects-1/#feBlendElement
873 SVGFEBlendScreen,
874 /// combine 2 images with SVG_FEBLEND_MODE_OVERLAY
875 /// parameters: FilterOpGraphNode
876 /// SVG filter semantics - selectable input(s), selectable between linear
877 /// (default) and sRGB color space for calculations
878 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
879 SVGFEBlendOverlay,
880 /// combine 2 images with SVG_FEBLEND_MODE_COLOR_DODGE
881 /// parameters: FilterOpGraphNode
882 /// SVG filter semantics - selectable input(s), selectable between linear
883 /// (default) and sRGB color space for calculations
884 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
885 SVGFEBlendColorDodge,
886 /// combine 2 images with SVG_FEBLEND_MODE_COLOR_BURN
887 /// parameters: FilterOpGraphNode
888 /// SVG filter semantics - selectable input(s), selectable between linear
889 /// (default) and sRGB color space for calculations
890 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
891 SVGFEBlendColorBurn,
892 /// combine 2 images with SVG_FEBLEND_MODE_HARD_LIGHT
893 /// parameters: FilterOpGraphNode
894 /// SVG filter semantics - selectable input(s), selectable between linear
895 /// (default) and sRGB color space for calculations
896 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
897 SVGFEBlendHardLight,
898 /// combine 2 images with SVG_FEBLEND_MODE_SOFT_LIGHT
899 /// parameters: FilterOpGraphNode
900 /// SVG filter semantics - selectable input(s), selectable between linear
901 /// (default) and sRGB color space for calculations
902 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
903 SVGFEBlendSoftLight,
904 /// combine 2 images with SVG_FEBLEND_MODE_DIFFERENCE
905 /// parameters: FilterOpGraphNode
906 /// SVG filter semantics - selectable input(s), selectable between linear
907 /// (default) and sRGB color space for calculations
908 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
909 SVGFEBlendDifference,
910 /// combine 2 images with SVG_FEBLEND_MODE_EXCLUSION
911 /// parameters: FilterOpGraphNode
912 /// SVG filter semantics - selectable input(s), selectable between linear
913 /// (default) and sRGB color space for calculations
914 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
915 SVGFEBlendExclusion,
916 /// combine 2 images with SVG_FEBLEND_MODE_HUE
917 /// parameters: FilterOpGraphNode
918 /// SVG filter semantics - selectable input(s), selectable between linear
919 /// (default) and sRGB color space for calculations
920 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
921 SVGFEBlendHue,
922 /// combine 2 images with SVG_FEBLEND_MODE_SATURATION
923 /// parameters: FilterOpGraphNode
924 /// SVG filter semantics - selectable input(s), selectable between linear
925 /// (default) and sRGB color space for calculations
926 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
927 SVGFEBlendSaturation,
928 /// combine 2 images with SVG_FEBLEND_MODE_COLOR
929 /// parameters: FilterOpGraphNode
930 /// SVG filter semantics - selectable input(s), selectable between linear
931 /// (default) and sRGB color space for calculations
932 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
933 SVGFEBlendColor,
934 /// combine 2 images with SVG_FEBLEND_MODE_LUMINOSITY
935 /// parameters: FilterOpGraphNode
936 /// SVG filter semantics - selectable input(s), selectable between linear
937 /// (default) and sRGB color space for calculations
938 /// Source: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
939 SVGFEBlendLuminosity,
940 /// transform colors of image through 5x4 color matrix (transposed for
941 /// efficiency)
942 /// parameters: FilterGraphNode, matrix[5][4]
943 /// SVG filter semantics - selectable input(s), selectable between linear
944 /// (default) and sRGB color space for calculations
945 /// Spec: https://www.w3.org/TR/filter-effects-1/#feColorMatrixElement
946 SVGFEColorMatrix{values: [f32; 20]},
947 /// transform colors of image through configurable gradients with component
948 /// swizzle
949 /// parameters: FilterGraphNode
950 /// SVG filter semantics - selectable input(s), selectable between linear
951 /// (default) and sRGB color space for calculations
952 /// Spec: https://www.w3.org/TR/filter-effects-1/#feComponentTransferElement
953 SVGFEComponentTransfer,
954 /// Processed version of SVGFEComponentTransfer with the FilterData
955 /// replaced by an interned handle, this is made in wrap_prim_with_filters.
956 /// Aside from the interned handle, creates_pixels indicates if the transfer
957 /// parameters will probably fill the entire subregion with non-zero alpha.
958 SVGFEComponentTransferInterned{handle: FilterDataHandle, creates_pixels: bool},
959 /// composite 2 images with chosen composite mode with parameters for that
960 /// mode
961 /// parameters: FilterGraphNode, k1, k2, k3, k4
962 /// SVG filter semantics - selectable input(s), selectable between linear
963 /// (default) and sRGB color space for calculations
964 /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
965 SVGFECompositeArithmetic{k1: f32, k2: f32, k3: f32, k4: f32},
966 /// composite 2 images with chosen composite mode with parameters for that
967 /// mode
968 /// parameters: FilterGraphNode
969 /// SVG filter semantics - selectable input(s), selectable between linear
970 /// (default) and sRGB color space for calculations
971 /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
972 SVGFECompositeATop,
973 /// composite 2 images with chosen composite mode with parameters for that
974 /// mode
975 /// parameters: FilterGraphNode
976 /// SVG filter semantics - selectable input(s), selectable between linear
977 /// (default) and sRGB color space for calculations
978 /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
979 SVGFECompositeIn,
980 /// composite 2 images with chosen composite mode with parameters for that
981 /// mode
982 /// parameters: FilterOpGraphNode
983 /// SVG filter semantics - selectable input(s), selectable between linear
984 /// (default) and sRGB color space for calculations
985 /// Docs: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feComposite
986 SVGFECompositeLighter,
987 /// composite 2 images with chosen composite mode with parameters for that
988 /// mode
989 /// parameters: FilterGraphNode
990 /// SVG filter semantics - selectable input(s), selectable between linear
991 /// (default) and sRGB color space for calculations
992 /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
993 SVGFECompositeOut,
994 /// composite 2 images with chosen composite mode with parameters for that
995 /// mode
996 /// parameters: FilterGraphNode
997 /// SVG filter semantics - selectable input(s), selectable between linear
998 /// (default) and sRGB color space for calculations
999 /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
1000 SVGFECompositeOver,
1001 /// composite 2 images with chosen composite mode with parameters for that
1002 /// mode
1003 /// parameters: FilterGraphNode
1004 /// SVG filter semantics - selectable input(s), selectable between linear
1005 /// (default) and sRGB color space for calculations
1006 /// Spec: https://www.w3.org/TR/filter-effects-1/#feCompositeElement
1007 SVGFECompositeXOR,
1008 /// transform image through convolution matrix of up to 25 values (spec
1009 /// allows more but for performance reasons we do not)
1010 /// parameters: FilterGraphNode, orderX, orderY, kernelValues[25], divisor,
1011 /// bias, targetX, targetY, kernelUnitLengthX, kernelUnitLengthY,
1012 /// preserveAlpha
1013 /// SVG filter semantics - selectable input(s), selectable between linear
1014 /// (default) and sRGB color space for calculations
1015 /// Spec: https://www.w3.org/TR/filter-effects-1/#feConvolveMatrixElement
1016 SVGFEConvolveMatrixEdgeModeDuplicate{order_x: i32, order_y: i32,
1017 kernel: [f32; SVGFE_CONVOLVE_VALUES_LIMIT], divisor: f32, bias: f32,
1018 target_x: i32, target_y: i32, kernel_unit_length_x: f32,
1019 kernel_unit_length_y: f32, preserve_alpha: i32},
1020 /// transform image through convolution matrix of up to 25 values (spec
1021 /// allows more but for performance reasons we do not)
1022 /// parameters: FilterGraphNode, orderX, orderY, kernelValues[25], divisor,
1023 /// bias, targetX, targetY, kernelUnitLengthX, kernelUnitLengthY,
1024 /// preserveAlpha
1025 /// SVG filter semantics - selectable input(s), selectable between linear
1026 /// (default) and sRGB color space for calculations
1027 /// Spec: https://www.w3.org/TR/filter-effects-1/#feConvolveMatrixElement
1028 SVGFEConvolveMatrixEdgeModeNone{order_x: i32, order_y: i32,
1029 kernel: [f32; SVGFE_CONVOLVE_VALUES_LIMIT], divisor: f32, bias: f32,
1030 target_x: i32, target_y: i32, kernel_unit_length_x: f32,
1031 kernel_unit_length_y: f32, preserve_alpha: i32},
1032 /// transform image through convolution matrix of up to 25 values (spec
1033 /// allows more but for performance reasons we do not)
1034 /// parameters: FilterGraphNode, orderX, orderY, kernelValues[25], divisor,
1035 /// bias, targetX, targetY, kernelUnitLengthX, kernelUnitLengthY,
1036 /// preserveAlpha
1037 /// SVG filter semantics - selectable input(s), selectable between linear
1038 /// (default) and sRGB color space for calculations
1039 /// Spec: https://www.w3.org/TR/filter-effects-1/#feConvolveMatrixElement
1040 SVGFEConvolveMatrixEdgeModeWrap{order_x: i32, order_y: i32,
1041 kernel: [f32; SVGFE_CONVOLVE_VALUES_LIMIT], divisor: f32, bias: f32,
1042 target_x: i32, target_y: i32, kernel_unit_length_x: f32,
1043 kernel_unit_length_y: f32, preserve_alpha: i32},
1044 /// calculate lighting based on heightmap image with provided values for a
1045 /// distant light source with specified direction
1046 /// parameters: FilterGraphNode, surfaceScale, diffuseConstant,
1047 /// kernelUnitLengthX, kernelUnitLengthY, azimuth, elevation
1048 /// SVG filter semantics - selectable input(s), selectable between linear
1049 /// (default) and sRGB color space for calculations
1050 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDiffuseLightingElement
1051 /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDistantLightElement
1052 SVGFEDiffuseLightingDistant{surface_scale: f32, diffuse_constant: f32,
1053 kernel_unit_length_x: f32, kernel_unit_length_y: f32, azimuth: f32,
1054 elevation: f32},
1055 /// calculate lighting based on heightmap image with provided values for a
1056 /// point light source at specified location
1057 /// parameters: FilterGraphNode, surfaceScale, diffuseConstant,
1058 /// kernelUnitLengthX, kernelUnitLengthY, x, y, z
1059 /// SVG filter semantics - selectable input(s), selectable between linear
1060 /// (default) and sRGB color space for calculations
1061 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDiffuseLightingElement
1062 /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEPointLightElement
1063 SVGFEDiffuseLightingPoint{surface_scale: f32, diffuse_constant: f32,
1064 kernel_unit_length_x: f32, kernel_unit_length_y: f32, x: f32, y: f32,
1065 z: f32},
1066 /// calculate lighting based on heightmap image with provided values for a
1067 /// spot light source at specified location pointing at specified target
1068 /// location with specified hotspot sharpness and cone angle
1069 /// parameters: FilterGraphNode, surfaceScale, diffuseConstant,
1070 /// kernelUnitLengthX, kernelUnitLengthY, x, y, z, pointsAtX, pointsAtY,
1071 /// pointsAtZ, specularExponent, limitingConeAngle
1072 /// SVG filter semantics - selectable input(s), selectable between linear
1073 /// (default) and sRGB color space for calculations
1074 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDiffuseLightingElement
1075 /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpotLightElement
1076 SVGFEDiffuseLightingSpot{surface_scale: f32, diffuse_constant: f32,
1077 kernel_unit_length_x: f32, kernel_unit_length_y: f32, x: f32, y: f32,
1078 z: f32, points_at_x: f32, points_at_y: f32, points_at_z: f32,
1079 cone_exponent: f32, limiting_cone_angle: f32},
1080 /// calculate a distorted version of first input image using offset values
1081 /// from second input image at specified intensity
1082 /// parameters: FilterGraphNode, scale, xChannelSelector, yChannelSelector
1083 /// SVG filter semantics - selectable input(s), selectable between linear
1084 /// (default) and sRGB color space for calculations
1085 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDisplacementMapElement
1086 SVGFEDisplacementMap{scale: f32, x_channel_selector: u32,
1087 y_channel_selector: u32},
1088 /// create and merge a dropshadow version of the specified image's alpha
1089 /// channel with specified offset and blur radius
1090 /// parameters: FilterGraphNode, flood_color, flood_opacity, dx, dy,
1091 /// stdDeviationX, stdDeviationY
1092 /// SVG filter semantics - selectable input(s), selectable between linear
1093 /// (default) and sRGB color space for calculations
1094 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDropShadowElement
1095 SVGFEDropShadow{color: ColorF, dx: f32, dy: f32, std_deviation_x: f32,
1096 std_deviation_y: f32},
1097 /// synthesize a new image of specified size containing a solid color
1098 /// parameters: FilterGraphNode, color
1099 /// SVG filter semantics - selectable input(s), selectable between linear
1100 /// (default) and sRGB color space for calculations
1101 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEFloodElement
1102 SVGFEFlood{color: ColorF},
1103 /// create a blurred version of the input image
1104 /// parameters: FilterGraphNode, stdDeviationX, stdDeviationY
1105 /// SVG filter semantics - selectable input(s), selectable between linear
1106 /// (default) and sRGB color space for calculations
1107 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEGaussianBlurElement
1108 SVGFEGaussianBlur{std_deviation_x: f32, std_deviation_y: f32},
1109 /// synthesize a new image based on a url (i.e. blob image source)
1110 /// parameters: FilterGraphNode,
1111 /// samplingFilter (see SamplingFilter in Types.h), transform
1112 /// SVG filter semantics - selectable input(s), selectable between linear
1113 /// (default) and sRGB color space for calculations
1114 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEImageElement
1115 SVGFEImage{sampling_filter: u32, matrix: [f32; 6]},
1116 /// create a new image based on the input image with the contour stretched
1117 /// outward (dilate operator)
1118 /// parameters: FilterGraphNode, radiusX, radiusY
1119 /// SVG filter semantics - selectable input(s), selectable between linear
1120 /// (default) and sRGB color space for calculations
1121 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEMorphologyElement
1122 SVGFEMorphologyDilate{radius_x: f32, radius_y: f32},
1123 /// create a new image based on the input image with the contour shrunken
1124 /// inward (erode operator)
1125 /// parameters: FilterGraphNode, radiusX, radiusY
1126 /// SVG filter semantics - selectable input(s), selectable between linear
1127 /// (default) and sRGB color space for calculations
1128 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEMorphologyElement
1129 SVGFEMorphologyErode{radius_x: f32, radius_y: f32},
1130 /// calculate lighting based on heightmap image with provided values for a
1131 /// distant light source with specified direction
1132 /// parameters: FilerData, surfaceScale, specularConstant, specularExponent,
1133 /// kernelUnitLengthX, kernelUnitLengthY, azimuth, elevation
1134 /// SVG filter semantics - selectable input(s), selectable between linear
1135 /// (default) and sRGB color space for calculations
1136 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpecularLightingElement
1137 /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEDistantLightElement
1138 SVGFESpecularLightingDistant{surface_scale: f32, specular_constant: f32,
1139 specular_exponent: f32, kernel_unit_length_x: f32,
1140 kernel_unit_length_y: f32, azimuth: f32, elevation: f32},
1141 /// calculate lighting based on heightmap image with provided values for a
1142 /// point light source at specified location
1143 /// parameters: FilterGraphNode, surfaceScale, specularConstant,
1144 /// specularExponent, kernelUnitLengthX, kernelUnitLengthY, x, y, z
1145 /// SVG filter semantics - selectable input(s), selectable between linear
1146 /// (default) and sRGB color space for calculations
1147 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpecularLightingElement
1148 /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEPointLightElement
1149 SVGFESpecularLightingPoint{surface_scale: f32, specular_constant: f32,
1150 specular_exponent: f32, kernel_unit_length_x: f32,
1151 kernel_unit_length_y: f32, x: f32, y: f32, z: f32},
1152 /// calculate lighting based on heightmap image with provided values for a
1153 /// spot light source at specified location pointing at specified target
1154 /// location with specified hotspot sharpness and cone angle
1155 /// parameters: FilterGraphNode, surfaceScale, specularConstant,
1156 /// specularExponent, kernelUnitLengthX, kernelUnitLengthY, x, y, z,
1157 /// pointsAtX, pointsAtY, pointsAtZ, specularExponent, limitingConeAngle
1158 /// SVG filter semantics - selectable input(s), selectable between linear
1159 /// (default) and sRGB color space for calculations
1160 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpecularLightingElement
1161 /// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFESpotLightElement
1162 SVGFESpecularLightingSpot{surface_scale: f32, specular_constant: f32,
1163 specular_exponent: f32, kernel_unit_length_x: f32,
1164 kernel_unit_length_y: f32, x: f32, y: f32, z: f32, points_at_x: f32,
1165 points_at_y: f32, points_at_z: f32, cone_exponent: f32,
1166 limiting_cone_angle: f32},
1167 /// create a new image based on the input image, repeated throughout the
1168 /// output rectangle
1169 /// parameters: FilterGraphNode
1170 /// SVG filter semantics - selectable input(s), selectable between linear
1171 /// (default) and sRGB color space for calculations
1172 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETileElement
1173 SVGFETile,
1174 /// synthesize a new image based on Fractal Noise (Perlin) with the chosen
1175 /// stitching mode
1176 /// parameters: FilterGraphNode, baseFrequencyX, baseFrequencyY, numOctaves,
1177 /// seed
1178 /// SVG filter semantics - selectable input(s), selectable between linear
1179 /// (default) and sRGB color space for calculations
1180 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETurbulenceElement
1181 SVGFETurbulenceWithFractalNoiseWithNoStitching{base_frequency_x: f32,
1182 base_frequency_y: f32, num_octaves: u32, seed: u32},
1183 /// synthesize a new image based on Fractal Noise (Perlin) with the chosen
1184 /// stitching mode
1185 /// parameters: FilterGraphNode, baseFrequencyX, baseFrequencyY, numOctaves,
1186 /// seed
1187 /// SVG filter semantics - selectable input(s), selectable between linear
1188 /// (default) and sRGB color space for calculations
1189 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETurbulenceElement
1190 SVGFETurbulenceWithFractalNoiseWithStitching{base_frequency_x: f32,
1191 base_frequency_y: f32, num_octaves: u32, seed: u32},
1192 /// synthesize a new image based on Turbulence Noise (offset vectors)
1193 /// parameters: FilterGraphNode, baseFrequencyX, baseFrequencyY, numOctaves,
1194 /// seed
1195 /// SVG filter semantics - selectable input(s), selectable between linear
1196 /// (default) and sRGB color space for calculations
1197 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETurbulenceElement
1198 SVGFETurbulenceWithTurbulenceNoiseWithNoStitching{base_frequency_x: f32,
1199 base_frequency_y: f32, num_octaves: u32, seed: u32},
1200 /// synthesize a new image based on Turbulence Noise (offset vectors)
1201 /// parameters: FilterGraphNode, baseFrequencyX, baseFrequencyY, numOctaves,
1202 /// seed
1203 /// SVG filter semantics - selectable input(s), selectable between linear
1204 /// (default) and sRGB color space for calculations
1205 /// Spec: https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFETurbulenceElement
1206 SVGFETurbulenceWithTurbulenceNoiseWithStitching{base_frequency_x: f32,
1207 base_frequency_y: f32, num_octaves: u32, seed: u32},
1208}
1209
1210impl FilterGraphOp {
1211 pub fn kind(&self) -> &'static str {
1212 match *self {
1213 FilterGraphOp::SVGFEBlendColor => "SVGFEBlendColor",
1214 FilterGraphOp::SVGFEBlendColorBurn => "SVGFEBlendColorBurn",
1215 FilterGraphOp::SVGFEBlendColorDodge => "SVGFEBlendColorDodge",
1216 FilterGraphOp::SVGFEBlendDarken => "SVGFEBlendDarken",
1217 FilterGraphOp::SVGFEBlendDifference => "SVGFEBlendDifference",
1218 FilterGraphOp::SVGFEBlendExclusion => "SVGFEBlendExclusion",
1219 FilterGraphOp::SVGFEBlendHardLight => "SVGFEBlendHardLight",
1220 FilterGraphOp::SVGFEBlendHue => "SVGFEBlendHue",
1221 FilterGraphOp::SVGFEBlendLighten => "SVGFEBlendLighten",
1222 FilterGraphOp::SVGFEBlendLuminosity => "SVGFEBlendLuminosity",
1223 FilterGraphOp::SVGFEBlendMultiply => "SVGFEBlendMultiply",
1224 FilterGraphOp::SVGFEBlendNormal => "SVGFEBlendNormal",
1225 FilterGraphOp::SVGFEBlendOverlay => "SVGFEBlendOverlay",
1226 FilterGraphOp::SVGFEBlendSaturation => "SVGFEBlendSaturation",
1227 FilterGraphOp::SVGFEBlendScreen => "SVGFEBlendScreen",
1228 FilterGraphOp::SVGFEBlendSoftLight => "SVGFEBlendSoftLight",
1229 FilterGraphOp::SVGFEColorMatrix{..} => "SVGFEColorMatrix",
1230 FilterGraphOp::SVGFEComponentTransfer => "SVGFEComponentTransfer",
1231 FilterGraphOp::SVGFEComponentTransferInterned{..} => "SVGFEComponentTransferInterned",
1232 FilterGraphOp::SVGFECompositeArithmetic{..} => "SVGFECompositeArithmetic",
1233 FilterGraphOp::SVGFECompositeATop => "SVGFECompositeATop",
1234 FilterGraphOp::SVGFECompositeIn => "SVGFECompositeIn",
1235 FilterGraphOp::SVGFECompositeLighter => "SVGFECompositeLighter",
1236 FilterGraphOp::SVGFECompositeOut => "SVGFECompositeOut",
1237 FilterGraphOp::SVGFECompositeOver => "SVGFECompositeOver",
1238 FilterGraphOp::SVGFECompositeXOR => "SVGFECompositeXOR",
1239 FilterGraphOp::SVGFEConvolveMatrixEdgeModeDuplicate{..} => "SVGFEConvolveMatrixEdgeModeDuplicate",
1240 FilterGraphOp::SVGFEConvolveMatrixEdgeModeNone{..} => "SVGFEConvolveMatrixEdgeModeNone",
1241 FilterGraphOp::SVGFEConvolveMatrixEdgeModeWrap{..} => "SVGFEConvolveMatrixEdgeModeWrap",
1242 FilterGraphOp::SVGFEDiffuseLightingDistant{..} => "SVGFEDiffuseLightingDistant",
1243 FilterGraphOp::SVGFEDiffuseLightingPoint{..} => "SVGFEDiffuseLightingPoint",
1244 FilterGraphOp::SVGFEDiffuseLightingSpot{..} => "SVGFEDiffuseLightingSpot",
1245 FilterGraphOp::SVGFEDisplacementMap{..} => "SVGFEDisplacementMap",
1246 FilterGraphOp::SVGFEDropShadow{..} => "SVGFEDropShadow",
1247 FilterGraphOp::SVGFEFlood{..} => "SVGFEFlood",
1248 FilterGraphOp::SVGFEGaussianBlur{..} => "SVGFEGaussianBlur",
1249 FilterGraphOp::SVGFEIdentity => "SVGFEIdentity",
1250 FilterGraphOp::SVGFEImage{..} => "SVGFEImage",
1251 FilterGraphOp::SVGFEMorphologyDilate{..} => "SVGFEMorphologyDilate",
1252 FilterGraphOp::SVGFEMorphologyErode{..} => "SVGFEMorphologyErode",
1253 FilterGraphOp::SVGFEOpacity{..} => "SVGFEOpacity",
1254 FilterGraphOp::SVGFESourceAlpha => "SVGFESourceAlpha",
1255 FilterGraphOp::SVGFESourceGraphic => "SVGFESourceGraphic",
1256 FilterGraphOp::SVGFESpecularLightingDistant{..} => "SVGFESpecularLightingDistant",
1257 FilterGraphOp::SVGFESpecularLightingPoint{..} => "SVGFESpecularLightingPoint",
1258 FilterGraphOp::SVGFESpecularLightingSpot{..} => "SVGFESpecularLightingSpot",
1259 FilterGraphOp::SVGFETile => "SVGFETile",
1260 FilterGraphOp::SVGFEToAlpha => "SVGFEToAlpha",
1261 FilterGraphOp::SVGFETurbulenceWithFractalNoiseWithNoStitching{..} => "SVGFETurbulenceWithFractalNoiseWithNoStitching",
1262 FilterGraphOp::SVGFETurbulenceWithFractalNoiseWithStitching{..} => "SVGFETurbulenceWithFractalNoiseWithStitching",
1263 FilterGraphOp::SVGFETurbulenceWithTurbulenceNoiseWithNoStitching{..} => "SVGFETurbulenceWithTurbulenceNoiseWithNoStitching",
1264 FilterGraphOp::SVGFETurbulenceWithTurbulenceNoiseWithStitching{..} => "SVGFETurbulenceWithTurbulenceNoiseWithStitching",
1265 }
1266 }
1267}
1268
1269#[derive(Clone, Debug)]
1270#[cfg_attr(feature = "capture", derive(Serialize))]
1271#[cfg_attr(feature = "replay", derive(Deserialize))]
1272pub struct FilterGraphNode {
1273 /// Indicates this graph node was marked as necessary by the DAG optimizer
1274 pub kept_by_optimizer: bool,
1275 /// true if color_interpolation_filter == LinearRgb; shader will convert
1276 /// sRGB texture pixel colors on load and convert back on store, for correct
1277 /// interpolation
1278 pub linear: bool,
1279 /// padding for output rect if we need a border to get correct clamping, or
1280 /// to account for larger final subregion than source rect (see bug 1869672)
1281 pub inflate: i16,
1282 /// virtualized picture input bindings, these refer to other filter outputs
1283 /// by number within the graph, usually there is one element
1284 pub inputs: Vec<FilterGraphPictureReference>,
1285 /// clipping rect for filter node output
1286 pub subregion: LayoutRect,
1287}
1288
1289impl From<FilterOpGraphNode> for FilterGraphNode {
1290 fn from(node: FilterOpGraphNode) -> Self {
1291 let mut inputs: Vec<FilterGraphPictureReference> = Vec::new();
1292 if node.input.buffer_id != FilterOpGraphPictureBufferId::None {
1293 inputs.push(node.input.into());
1294 }
1295 if node.input2.buffer_id != FilterOpGraphPictureBufferId::None {
1296 inputs.push(node.input2.into());
1297 }
1298 // If the op used by this node is a feMerge, it will add more inputs
1299 // after this invocation.
1300 FilterGraphNode{
1301 linear: node.linear,
1302 inputs,
1303 subregion: node.subregion,
1304 // These are computed later in scene_building
1305 kept_by_optimizer: true,
1306 inflate: 0,
1307 }
1308 }
1309}
1310
1311/// Here we transform source rect to target rect for SVGFEGraph by walking
1312/// the whole graph and propagating subregions based on the provided
1313/// invalidation rect, and we want it to be a tight fit so we don't waste
1314/// time applying multiple filters to pixels that do not contribute to the
1315/// invalidated rect.
1316///
1317/// The interesting parts of the handling of SVG filters are:
1318/// * scene_building.rs : wrap_prim_with_filters
1319/// * picture.rs : get_coverage_target_svgfe (you are here)
1320/// * picture.rs : get_coverage_source_svgfe
1321/// * render_task.rs : new_svg_filter_graph
1322/// * render_target.rs : add_svg_filter_node_instances
1323pub fn get_coverage_target_svgfe(
1324 filters: &[(FilterGraphNode, FilterGraphOp)],
1325 surface_rect: LayoutRect,
1326) -> LayoutRect {
1327
1328 // The value of BUFFER_LIMIT here must be the same as in
1329 // scene_building.rs, or we'll hit asserts here.
1330 const BUFFER_LIMIT: usize = SVGFE_GRAPH_MAX;
1331
1332 // We need to evaluate the subregions based on the proposed
1333 // SourceGraphic rect as it isn't known at scene build time.
1334 let mut subregion_by_buffer_id: [LayoutRect; BUFFER_LIMIT] = [LayoutRect::zero(); BUFFER_LIMIT];
1335 for (id, (node, op)) in filters.iter().enumerate() {
1336 let full_subregion = node.subregion;
1337 let mut used_subregion = LayoutRect::zero();
1338 for input in &node.inputs {
1339 match input.buffer_id {
1340 FilterOpGraphPictureBufferId::BufferId(id) => {
1341 assert!((id as usize) < BUFFER_LIMIT, "BUFFER_LIMIT must be the same in frame building and scene building");
1342 // This id lookup should always succeed.
1343 let input_subregion = subregion_by_buffer_id[id as usize];
1344 // Now add the padding that transforms from
1345 // source to target, this was determined during
1346 // scene build based on the operation.
1347 let input_subregion =
1348 LayoutRect::new(
1349 LayoutPoint::new(
1350 input_subregion.min.x + input.target_padding.min.x,
1351 input_subregion.min.y + input.target_padding.min.y,
1352 ),
1353 LayoutPoint::new(
1354 input_subregion.max.x + input.target_padding.max.x,
1355 input_subregion.max.y + input.target_padding.max.y,
1356 ),
1357 );
1358 used_subregion = used_subregion
1359 .union(&input_subregion);
1360 }
1361 FilterOpGraphPictureBufferId::None => {
1362 panic!("Unsupported BufferId type");
1363 }
1364 }
1365 }
1366 // We can clip the used subregion to the node subregion
1367 used_subregion = used_subregion
1368 .intersection(&full_subregion)
1369 .unwrap_or(LayoutRect::zero());
1370 match op {
1371 FilterGraphOp::SVGFEBlendColor => {}
1372 FilterGraphOp::SVGFEBlendColorBurn => {}
1373 FilterGraphOp::SVGFEBlendColorDodge => {}
1374 FilterGraphOp::SVGFEBlendDarken => {}
1375 FilterGraphOp::SVGFEBlendDifference => {}
1376 FilterGraphOp::SVGFEBlendExclusion => {}
1377 FilterGraphOp::SVGFEBlendHardLight => {}
1378 FilterGraphOp::SVGFEBlendHue => {}
1379 FilterGraphOp::SVGFEBlendLighten => {}
1380 FilterGraphOp::SVGFEBlendLuminosity => {}
1381 FilterGraphOp::SVGFEBlendMultiply => {}
1382 FilterGraphOp::SVGFEBlendNormal => {}
1383 FilterGraphOp::SVGFEBlendOverlay => {}
1384 FilterGraphOp::SVGFEBlendSaturation => {}
1385 FilterGraphOp::SVGFEBlendScreen => {}
1386 FilterGraphOp::SVGFEBlendSoftLight => {}
1387 FilterGraphOp::SVGFEColorMatrix { values } => {
1388 if values[19] > 0.0 {
1389 // Manipulating alpha offset can easily create new
1390 // pixels outside of input subregions
1391 used_subregion = full_subregion;
1392 add_text_marker(
1393 "SVGFEColorMatrix",
1394 "SVGFEColorMatrix with non-zero alpha offset, using full subregion",
1395 Duration::from_millis(1));
1396 }
1397 }
1398 FilterGraphOp::SVGFEComponentTransfer => unreachable!(),
1399 FilterGraphOp::SVGFEComponentTransferInterned{handle: _, creates_pixels} => {
1400 // Check if the value of alpha[0] is modified, if so
1401 // the whole subregion is used because it will be
1402 // creating new pixels outside of input subregions
1403 if *creates_pixels {
1404 used_subregion = full_subregion;
1405 add_text_marker(
1406 "SVGFEComponentTransfer",
1407 "SVGFEComponentTransfer with non-zero minimum alpha, using full subregion",
1408 Duration::from_millis(1));
1409 }
1410 }
1411 FilterGraphOp::SVGFECompositeArithmetic { k1, k2, k3, k4 } => {
1412 // Optimization opportunity - some inputs may be
1413 // smaller subregions due to the way the math works,
1414 // k1 is the intersection of the two inputs, k2 is
1415 // the first input only, k3 is the second input
1416 // only, and k4 changes the whole subregion.
1417 //
1418 // See logic for SVG_FECOMPOSITE_OPERATOR_ARITHMETIC
1419 // in FilterSupport.cpp
1420 //
1421 // We can at least ignore the entire node if
1422 // everything is zero.
1423 if *k1 <= 0.0 &&
1424 *k2 <= 0.0 &&
1425 *k3 <= 0.0 {
1426 used_subregion = LayoutRect::zero();
1427 }
1428 // Check if alpha is added to pixels as it means it
1429 // can fill pixels outside input subregions
1430 if *k4 > 0.0 {
1431 used_subregion = full_subregion;
1432 add_text_marker(
1433 "SVGFECompositeArithmetic",
1434 "SVGFECompositeArithmetic with non-zero offset, using full subregion",
1435 Duration::from_millis(1));
1436 }
1437 }
1438 FilterGraphOp::SVGFECompositeATop => {}
1439 FilterGraphOp::SVGFECompositeIn => {}
1440 FilterGraphOp::SVGFECompositeLighter => {}
1441 FilterGraphOp::SVGFECompositeOut => {}
1442 FilterGraphOp::SVGFECompositeOver => {}
1443 FilterGraphOp::SVGFECompositeXOR => {}
1444 FilterGraphOp::SVGFEConvolveMatrixEdgeModeDuplicate{..} => {}
1445 FilterGraphOp::SVGFEConvolveMatrixEdgeModeNone{..} => {}
1446 FilterGraphOp::SVGFEConvolveMatrixEdgeModeWrap{..} => {}
1447 FilterGraphOp::SVGFEDiffuseLightingDistant{..} => {}
1448 FilterGraphOp::SVGFEDiffuseLightingPoint{..} => {}
1449 FilterGraphOp::SVGFEDiffuseLightingSpot{..} => {}
1450 FilterGraphOp::SVGFEDisplacementMap{..} => {}
1451 FilterGraphOp::SVGFEDropShadow{..} => {}
1452 FilterGraphOp::SVGFEFlood { color } => {
1453 // Subregion needs to be set to the full node
1454 // subregion for fills (unless the fill is a no-op)
1455 if color.a > 0.0 {
1456 used_subregion = full_subregion;
1457 }
1458 }
1459 FilterGraphOp::SVGFEGaussianBlur{..} => {}
1460 FilterGraphOp::SVGFEIdentity => {}
1461 FilterGraphOp::SVGFEImage { sampling_filter: _sampling_filter, matrix: _matrix } => {
1462 // TODO: calculate the actual subregion
1463 used_subregion = full_subregion;
1464 }
1465 FilterGraphOp::SVGFEMorphologyDilate{..} => {}
1466 FilterGraphOp::SVGFEMorphologyErode{..} => {}
1467 FilterGraphOp::SVGFEOpacity { valuebinding: _valuebinding, value } => {
1468 // If fully transparent, we can ignore this node
1469 if *value <= 0.0 {
1470 used_subregion = LayoutRect::zero();
1471 }
1472 }
1473 FilterGraphOp::SVGFESourceAlpha |
1474 FilterGraphOp::SVGFESourceGraphic => {
1475 used_subregion = surface_rect;
1476 }
1477 FilterGraphOp::SVGFESpecularLightingDistant{..} => {}
1478 FilterGraphOp::SVGFESpecularLightingPoint{..} => {}
1479 FilterGraphOp::SVGFESpecularLightingSpot{..} => {}
1480 FilterGraphOp::SVGFETile => {
1481 // feTile fills the entire output with
1482 // source pixels, so it's effectively a flood.
1483 used_subregion = full_subregion;
1484 }
1485 FilterGraphOp::SVGFEToAlpha => {}
1486 FilterGraphOp::SVGFETurbulenceWithFractalNoiseWithNoStitching{..} |
1487 FilterGraphOp::SVGFETurbulenceWithFractalNoiseWithStitching{..} |
1488 FilterGraphOp::SVGFETurbulenceWithTurbulenceNoiseWithNoStitching{..} |
1489 FilterGraphOp::SVGFETurbulenceWithTurbulenceNoiseWithStitching{..} => {
1490 // Turbulence produces pixel values throughout the
1491 // node subregion.
1492 used_subregion = full_subregion;
1493 }
1494 }
1495 // Store the subregion so later nodes can refer back
1496 // to this and propagate rects properly
1497 assert!((id as usize) < BUFFER_LIMIT, "BUFFER_LIMIT must be the same in frame building and scene building");
1498 subregion_by_buffer_id[id] = used_subregion;
1499 }
1500 subregion_by_buffer_id[filters.len() - 1]
1501}
1502
1503/// Here we transform target rect to source rect for SVGFEGraph by walking
1504/// the whole graph and propagating subregions based on the provided
1505/// invalidation rect, and we want it to be a tight fit so we don't waste
1506/// time applying multiple filters to pixels that do not contribute to the
1507/// invalidated rect.
1508///
1509/// The interesting parts of the handling of SVG filters are:
1510/// * scene_building.rs : wrap_prim_with_filters
1511/// * picture.rs : get_coverage_target_svgfe
1512/// * picture.rs : get_coverage_source_svgfe (you are here)
1513/// * render_task.rs : new_svg_filter_graph
1514/// * render_target.rs : add_svg_filter_node_instances
1515pub fn get_coverage_source_svgfe(
1516 filters: &[(FilterGraphNode, FilterGraphOp)],
1517 surface_rect: LayoutRect,
1518) -> LayoutRect {
1519
1520 // The value of BUFFER_LIMIT here must be the same as in
1521 // scene_building.rs, or we'll hit asserts here.
1522 const BUFFER_LIMIT: usize = SVGFE_GRAPH_MAX;
1523
1524 // We're solving the source rect from target rect (e.g. due
1525 // to invalidation of a region, we need to know how much of
1526 // SourceGraphic is needed to draw that region accurately),
1527 // so we need to walk the DAG in reverse and accumulate the source
1528 // subregion for each input onto the referenced node, which can then
1529 // propagate that to its inputs when it is iterated.
1530 let mut source_subregion = LayoutRect::zero();
1531 let mut subregion_by_buffer_id: [LayoutRect; BUFFER_LIMIT] =
1532 [LayoutRect::zero(); BUFFER_LIMIT];
1533 let final_buffer_id = filters.len() - 1;
1534 assert!(final_buffer_id < BUFFER_LIMIT, "BUFFER_LIMIT must be the same in frame building and scene building");
1535 subregion_by_buffer_id[final_buffer_id] = surface_rect;
1536 for (node_buffer_id, (node, op)) in filters.iter().enumerate().rev() {
1537 // This is the subregion this node outputs, we can clip
1538 // the inputs based on source_padding relative to this,
1539 // and accumulate a new subregion for them.
1540 assert!(node_buffer_id < BUFFER_LIMIT, "BUFFER_LIMIT must be the same in frame building and scene building");
1541 let full_subregion = node.subregion;
1542 let mut used_subregion =
1543 subregion_by_buffer_id[node_buffer_id];
1544 // We can clip the propagated subregion to the node subregion before
1545 // we add source_padding for each input and propogate to them
1546 used_subregion = used_subregion
1547 .intersection(&full_subregion)
1548 .unwrap_or(LayoutRect::zero());
1549 if !used_subregion.is_empty() {
1550 for input in &node.inputs {
1551 let input_subregion = LayoutRect::new(
1552 LayoutPoint::new(
1553 used_subregion.min.x + input.source_padding.min.x,
1554 used_subregion.min.y + input.source_padding.min.y,
1555 ),
1556 LayoutPoint::new(
1557 used_subregion.max.x + input.source_padding.max.x,
1558 used_subregion.max.y + input.source_padding.max.y,
1559 ),
1560 );
1561 match input.buffer_id {
1562 FilterOpGraphPictureBufferId::BufferId(id) => {
1563 // Add the used area to the input, later when
1564 // the referneced node is iterated as a node it
1565 // will propagate the used bounds.
1566 subregion_by_buffer_id[id as usize] =
1567 subregion_by_buffer_id[id as usize]
1568 .union(&input_subregion);
1569 }
1570 FilterOpGraphPictureBufferId::None => {}
1571 }
1572 }
1573 }
1574 // If this is the SourceGraphic or SourceAlpha, we now have the
1575 // source subregion we're looking for. If both exist in the
1576 // same graph, we need to combine them, so don't merely replace.
1577 match op {
1578 FilterGraphOp::SVGFESourceAlpha |
1579 FilterGraphOp::SVGFESourceGraphic => {
1580 source_subregion = source_subregion.union(&used_subregion);
1581 }
1582 _ => {}
1583 }
1584 }
1585
1586 // Note that this can be zero if SourceGraphic/SourceAlpha is not used
1587 // in this graph.
1588 source_subregion
1589}