1use api::{
6 ColorU, MixBlendMode, FilterPrimitiveInput, FilterPrimitiveKind,
7 ColorSpace, PropertyBinding, PropertyBindingId, CompositeOperator,
8 RasterSpace, FilterOpGraphPictureBufferId,
9};
10use api::units::Au;
11use crate::scene_building::IsVisible;
12use crate::filterdata::SFilterData;
13use crate::intern::ItemUid;
14use crate::intern::{Internable, InternDebug, Handle as InternHandle};
15use crate::internal_types::{LayoutPrimitiveInfo, FilterGraphPictureReference,
16 FilterGraphOp, FilterGraphNode, SVGFE_CONVOLVE_VALUES_LIMIT, Filter};
17use crate::picture::PictureCompositeMode;
18use crate::prim_store::{
19 PrimitiveInstanceKind, PrimitiveStore, VectorKey,
20 InternablePrimitive,
21};
22
23#[cfg_attr(feature = "capture", derive(Serialize))]
24#[cfg_attr(feature = "replay", derive(Deserialize))]
25#[derive(Debug, Clone, MallocSizeOf, PartialEq, Hash, Eq)]
26pub enum CompositeOperatorKey {
27 Over,
28 In,
29 Out,
30 Atop,
31 Xor,
32 Lighter,
33 Arithmetic([Au; 4]),
34}
35
36impl From<CompositeOperator> for CompositeOperatorKey {
37 fn from(operator: CompositeOperator) -> Self {
38 match operator {
39 CompositeOperator::Over => CompositeOperatorKey::Over,
40 CompositeOperator::In => CompositeOperatorKey::In,
41 CompositeOperator::Out => CompositeOperatorKey::Out,
42 CompositeOperator::Atop => CompositeOperatorKey::Atop,
43 CompositeOperator::Xor => CompositeOperatorKey::Xor,
44 CompositeOperator::Lighter => CompositeOperatorKey::Lighter,
45 CompositeOperator::Arithmetic(k_vals) => {
46 let k_vals = [
47 Au::from_f32_px(k_vals[0]),
48 Au::from_f32_px(k_vals[1]),
49 Au::from_f32_px(k_vals[2]),
50 Au::from_f32_px(k_vals[3]),
51 ];
52 CompositeOperatorKey::Arithmetic(k_vals)
53 }
54 }
55 }
56}
57
58#[cfg_attr(feature = "capture", derive(Serialize))]
59#[cfg_attr(feature = "replay", derive(Deserialize))]
60#[derive(Debug, Clone, MallocSizeOf, PartialEq, Hash, Eq)]
61pub enum FilterPrimitiveKey {
62 Identity(ColorSpace, FilterPrimitiveInput),
63 Flood(ColorSpace, ColorU),
64 Blend(ColorSpace, MixBlendMode, FilterPrimitiveInput, FilterPrimitiveInput),
65 Blur(ColorSpace, Au, Au, FilterPrimitiveInput),
66 Opacity(ColorSpace, Au, FilterPrimitiveInput),
67 ColorMatrix(ColorSpace, [Au; 20], FilterPrimitiveInput),
68 DropShadow(ColorSpace, (VectorKey, Au, ColorU), FilterPrimitiveInput),
69 ComponentTransfer(ColorSpace, FilterPrimitiveInput, Vec<SFilterData>),
70 Offset(ColorSpace, FilterPrimitiveInput, VectorKey),
71 Composite(ColorSpace, FilterPrimitiveInput, FilterPrimitiveInput, CompositeOperatorKey),
72}
73
74#[cfg_attr(feature = "capture", derive(Serialize))]
75#[cfg_attr(feature = "replay", derive(Deserialize))]
76#[derive(Debug, Clone, Copy, Default, MallocSizeOf, PartialEq, Hash, Eq)]
77pub enum FilterGraphPictureBufferIdKey {
78 #[default]
79 None,
81 BufferId(i16),
83}
84
85#[cfg_attr(feature = "capture", derive(Serialize))]
86#[cfg_attr(feature = "replay", derive(Deserialize))]
87#[derive(Debug, Clone, Copy, Default, MallocSizeOf, PartialEq, Hash, Eq)]
88pub struct FilterGraphPictureReferenceKey {
89 pub buffer_id: FilterGraphPictureBufferIdKey,
93 pub subregion: [Au; 4],
95 pub offset: [Au; 2],
97}
98
99impl From<FilterGraphPictureReference> for FilterGraphPictureReferenceKey {
100 fn from(pic: FilterGraphPictureReference) -> Self {
101 FilterGraphPictureReferenceKey{
102 buffer_id: match pic.buffer_id {
103 FilterOpGraphPictureBufferId::None => FilterGraphPictureBufferIdKey::None,
104 FilterOpGraphPictureBufferId::BufferId(id) => FilterGraphPictureBufferIdKey::BufferId(id),
105 },
106 subregion: [
107 Au::from_f32_px(pic.subregion.min.x),
108 Au::from_f32_px(pic.subregion.min.y),
109 Au::from_f32_px(pic.subregion.max.x),
110 Au::from_f32_px(pic.subregion.max.y),
111 ],
112 offset: [
113 Au::from_f32_px(pic.offset.x),
114 Au::from_f32_px(pic.offset.y),
115 ],
116 }
117 }
118}
119
120#[cfg_attr(feature = "capture", derive(Serialize))]
121#[cfg_attr(feature = "replay", derive(Deserialize))]
122#[derive(Debug, Clone, MallocSizeOf, PartialEq, Hash, Eq)]
123pub enum FilterGraphOpKey {
124 SVGFEBlendDarken,
130 SVGFEBlendLighten,
136 SVGFEBlendMultiply,
142 SVGFEBlendNormal,
148 SVGFEBlendScreen,
154 SVGFEBlendOverlay,
160 SVGFEBlendColorDodge,
166 SVGFEBlendColorBurn,
172 SVGFEBlendHardLight,
178 SVGFEBlendSoftLight,
184 SVGFEBlendDifference,
190 SVGFEBlendExclusion,
196 SVGFEBlendHue,
202 SVGFEBlendSaturation,
208 SVGFEBlendColor,
214 SVGFEBlendLuminosity,
220 SVGFEColorMatrix{values: [Au; 20]},
227 SVGFEComponentTransferInterned{handle: ItemUid, creates_pixels: bool},
234 SVGFECompositeArithmetic{k1: Au, k2: Au, k3: Au, k4: Au},
241 SVGFECompositeATop,
248 SVGFECompositeIn,
255 SVGFECompositeLighter,
262 SVGFECompositeOut,
269 SVGFECompositeOver,
276 SVGFECompositeXOR,
283 SVGFEConvolveMatrixEdgeModeDuplicate{order_x: i32, order_y: i32,
292 kernel: [Au; SVGFE_CONVOLVE_VALUES_LIMIT], divisor: Au, bias: Au,
293 target_x: i32, target_y: i32, kernel_unit_length_x: Au,
294 kernel_unit_length_y: Au, preserve_alpha: i32},
295 SVGFEConvolveMatrixEdgeModeNone{order_x: i32, order_y: i32,
304 kernel: [Au; SVGFE_CONVOLVE_VALUES_LIMIT], divisor: Au, bias: Au,
305 target_x: i32, target_y: i32, kernel_unit_length_x: Au,
306 kernel_unit_length_y: Au, preserve_alpha: i32},
307 SVGFEConvolveMatrixEdgeModeWrap{order_x: i32, order_y: i32,
316 kernel: [Au; SVGFE_CONVOLVE_VALUES_LIMIT], divisor: Au, bias: Au,
317 target_x: i32, target_y: i32, kernel_unit_length_x: Au,
318 kernel_unit_length_y: Au, preserve_alpha: i32},
319 SVGFEDiffuseLightingDistant{surface_scale: Au, diffuse_constant: Au,
328 kernel_unit_length_x: Au, kernel_unit_length_y: Au, azimuth: Au,
329 elevation: Au},
330 SVGFEDiffuseLightingPoint{surface_scale: Au, diffuse_constant: Au,
339 kernel_unit_length_x: Au, kernel_unit_length_y: Au, x: Au, y: Au,
340 z: Au},
341 SVGFEDiffuseLightingSpot{surface_scale: Au, diffuse_constant: Au,
352 kernel_unit_length_x: Au, kernel_unit_length_y: Au, x: Au, y: Au, z: Au,
353 points_at_x: Au, points_at_y: Au, points_at_z: Au, cone_exponent: Au,
354 limiting_cone_angle: Au},
355 SVGFEDisplacementMap{scale: Au, x_channel_selector: u32,
362 y_channel_selector: u32},
363 SVGFEDropShadow{color: ColorU, dx: Au, dy: Au, std_deviation_x: Au,
371 std_deviation_y: Au},
372 SVGFEFlood{color: ColorU},
378 SVGFEGaussianBlur{std_deviation_x: Au, std_deviation_y: Au},
384 SVGFEIdentity,
387 SVGFEImage{sampling_filter: u32, matrix: [Au; 6]},
394 SVGFEMorphologyDilate{radius_x: Au, radius_y: Au},
401 SVGFEMorphologyErode{radius_x: Au, radius_y: Au},
408 SVGFEOpacity{value: Au},
414 SVGFEOpacityBinding{valuebindingid: PropertyBindingId, value: Au},
420 SVGFESourceGraphic,
426 SVGFESourceAlpha,
432 SVGFESpecularLightingDistant{surface_scale: Au, specular_constant: Au,
441 specular_exponent: Au, kernel_unit_length_x: Au,
442 kernel_unit_length_y: Au, azimuth: Au, elevation: Au},
443 SVGFESpecularLightingPoint{surface_scale: Au, specular_constant: Au,
452 specular_exponent: Au, kernel_unit_length_x: Au,
453 kernel_unit_length_y: Au, x: Au, y: Au, z: Au},
454 SVGFESpecularLightingSpot{surface_scale: Au, specular_constant: Au,
465 specular_exponent: Au, kernel_unit_length_x: Au,
466 kernel_unit_length_y: Au, x: Au, y: Au, z: Au, points_at_x: Au,
467 points_at_y: Au, points_at_z: Au, cone_exponent: Au,
468 limiting_cone_angle: Au},
469 SVGFETile,
476 SVGFEToAlpha,
479 SVGFETurbulenceWithFractalNoiseWithNoStitching{base_frequency_x: Au,
487 base_frequency_y: Au, num_octaves: u32, seed: u32},
488 SVGFETurbulenceWithFractalNoiseWithStitching{base_frequency_x: Au,
496 base_frequency_y: Au, num_octaves: u32, seed: u32},
497 SVGFETurbulenceWithTurbulenceNoiseWithNoStitching{base_frequency_x: Au,
504 base_frequency_y: Au, num_octaves: u32, seed: u32},
505 SVGFETurbulenceWithTurbulenceNoiseWithStitching{base_frequency_x: Au,
512 base_frequency_y: Au, num_octaves: u32, seed: u32},
513}
514
515impl From<FilterGraphOp> for FilterGraphOpKey {
516 fn from(op: FilterGraphOp) -> Self {
517 match op {
518 FilterGraphOp::SVGFEBlendDarken => FilterGraphOpKey::SVGFEBlendDarken,
519 FilterGraphOp::SVGFEBlendLighten => FilterGraphOpKey::SVGFEBlendLighten,
520 FilterGraphOp::SVGFEBlendMultiply => FilterGraphOpKey::SVGFEBlendMultiply,
521 FilterGraphOp::SVGFEBlendNormal => FilterGraphOpKey::SVGFEBlendNormal,
522 FilterGraphOp::SVGFEBlendScreen => FilterGraphOpKey::SVGFEBlendScreen,
523 FilterGraphOp::SVGFEBlendOverlay => FilterGraphOpKey::SVGFEBlendOverlay,
524 FilterGraphOp::SVGFEBlendColorDodge => FilterGraphOpKey::SVGFEBlendColorDodge,
525 FilterGraphOp::SVGFEBlendColorBurn => FilterGraphOpKey::SVGFEBlendColorBurn,
526 FilterGraphOp::SVGFEBlendHardLight => FilterGraphOpKey::SVGFEBlendHardLight,
527 FilterGraphOp::SVGFEBlendSoftLight => FilterGraphOpKey::SVGFEBlendSoftLight,
528 FilterGraphOp::SVGFEBlendDifference => FilterGraphOpKey::SVGFEBlendDifference,
529 FilterGraphOp::SVGFEBlendExclusion => FilterGraphOpKey::SVGFEBlendExclusion,
530 FilterGraphOp::SVGFEBlendHue => FilterGraphOpKey::SVGFEBlendHue,
531 FilterGraphOp::SVGFEBlendSaturation => FilterGraphOpKey::SVGFEBlendSaturation,
532 FilterGraphOp::SVGFEBlendColor => FilterGraphOpKey::SVGFEBlendColor,
533 FilterGraphOp::SVGFEBlendLuminosity => FilterGraphOpKey::SVGFEBlendLuminosity,
534 FilterGraphOp::SVGFEColorMatrix { values: color_matrix } => {
535 let mut quantized_values: [Au; 20] = [Au(0); 20];
536 for (value, result) in color_matrix.iter().zip(quantized_values.iter_mut()) {
537 *result = Au::from_f32_px(*value);
538 }
539 FilterGraphOpKey::SVGFEColorMatrix{values: quantized_values}
540 }
541 FilterGraphOp::SVGFEComponentTransfer => unreachable!(),
542 FilterGraphOp::SVGFEComponentTransferInterned { handle, creates_pixels } => FilterGraphOpKey::SVGFEComponentTransferInterned{
543 handle: handle.uid(),
544 creates_pixels,
545 },
546 FilterGraphOp::SVGFECompositeArithmetic { k1, k2, k3, k4 } => {
547 FilterGraphOpKey::SVGFECompositeArithmetic{
548 k1: Au::from_f32_px(k1),
549 k2: Au::from_f32_px(k2),
550 k3: Au::from_f32_px(k3),
551 k4: Au::from_f32_px(k4),
552 }
553 }
554 FilterGraphOp::SVGFECompositeATop => FilterGraphOpKey::SVGFECompositeATop,
555 FilterGraphOp::SVGFECompositeIn => FilterGraphOpKey::SVGFECompositeIn,
556 FilterGraphOp::SVGFECompositeLighter => FilterGraphOpKey::SVGFECompositeLighter,
557 FilterGraphOp::SVGFECompositeOut => FilterGraphOpKey::SVGFECompositeOut,
558 FilterGraphOp::SVGFECompositeOver => FilterGraphOpKey::SVGFECompositeOver,
559 FilterGraphOp::SVGFECompositeXOR => FilterGraphOpKey::SVGFECompositeXOR,
560 FilterGraphOp::SVGFEConvolveMatrixEdgeModeDuplicate { order_x, order_y, kernel, divisor, bias, target_x, target_y, kernel_unit_length_x, kernel_unit_length_y, preserve_alpha } => {
561 let mut values: [Au; SVGFE_CONVOLVE_VALUES_LIMIT] = [Au(0); SVGFE_CONVOLVE_VALUES_LIMIT];
562 for (value, result) in kernel.iter().zip(values.iter_mut()) {
563 *result = Au::from_f32_px(*value)
564 }
565 FilterGraphOpKey::SVGFEConvolveMatrixEdgeModeDuplicate{
566 order_x,
567 order_y,
568 kernel: values,
569 divisor: Au::from_f32_px(divisor),
570 bias: Au::from_f32_px(bias),
571 target_x,
572 target_y,
573 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
574 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
575 preserve_alpha,
576 }
577 }
578 FilterGraphOp::SVGFEConvolveMatrixEdgeModeNone { order_x, order_y, kernel, divisor, bias, target_x, target_y, kernel_unit_length_x, kernel_unit_length_y, preserve_alpha } => {
579 let mut values: [Au; SVGFE_CONVOLVE_VALUES_LIMIT] = [Au(0); SVGFE_CONVOLVE_VALUES_LIMIT];
580 for (value, result) in kernel.iter().zip(values.iter_mut()) {
581 *result = Au::from_f32_px(*value)
582 }
583 FilterGraphOpKey::SVGFEConvolveMatrixEdgeModeNone{
584 order_x,
585 order_y,
586 kernel: values,
587 divisor: Au::from_f32_px(divisor),
588 bias: Au::from_f32_px(bias),
589 target_x,
590 target_y,
591 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
592 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
593 preserve_alpha,
594 }
595 }
596 FilterGraphOp::SVGFEConvolveMatrixEdgeModeWrap { order_x, order_y, kernel, divisor, bias, target_x, target_y, kernel_unit_length_x, kernel_unit_length_y, preserve_alpha } => {
597 let mut values: [Au; SVGFE_CONVOLVE_VALUES_LIMIT] = [Au(0); SVGFE_CONVOLVE_VALUES_LIMIT];
598 for (value, result) in kernel.iter().zip(values.iter_mut()) {
599 *result = Au::from_f32_px(*value)
600 }
601 FilterGraphOpKey::SVGFEConvolveMatrixEdgeModeWrap{
602 order_x,
603 order_y,
604 kernel: values,
605 divisor: Au::from_f32_px(divisor),
606 bias: Au::from_f32_px(bias),
607 target_x,
608 target_y,
609 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
610 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
611 preserve_alpha,
612 }
613 }
614 FilterGraphOp::SVGFEDiffuseLightingDistant { surface_scale, diffuse_constant, kernel_unit_length_x, kernel_unit_length_y, azimuth, elevation } => {
615 FilterGraphOpKey::SVGFEDiffuseLightingDistant{
616 surface_scale: Au::from_f32_px(surface_scale),
617 diffuse_constant: Au::from_f32_px(diffuse_constant),
618 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
619 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
620 azimuth: Au::from_f32_px(azimuth),
621 elevation: Au::from_f32_px(elevation),
622 }
623 }
624 FilterGraphOp::SVGFEDiffuseLightingPoint { surface_scale, diffuse_constant, kernel_unit_length_x, kernel_unit_length_y, x, y, z } => {
625 FilterGraphOpKey::SVGFEDiffuseLightingPoint{
626 surface_scale: Au::from_f32_px(surface_scale),
627 diffuse_constant: Au::from_f32_px(diffuse_constant),
628 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
629 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
630 x: Au::from_f32_px(x),
631 y: Au::from_f32_px(y),
632 z: Au::from_f32_px(z),
633 }
634 }
635 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 } => {
636 FilterGraphOpKey::SVGFEDiffuseLightingSpot{
637 surface_scale: Au::from_f32_px(surface_scale),
638 diffuse_constant: Au::from_f32_px(diffuse_constant),
639 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
640 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
641 x: Au::from_f32_px(x),
642 y: Au::from_f32_px(y),
643 z: Au::from_f32_px(z),
644 points_at_x: Au::from_f32_px(points_at_x),
645 points_at_y: Au::from_f32_px(points_at_y),
646 points_at_z: Au::from_f32_px(points_at_z),
647 cone_exponent: Au::from_f32_px(cone_exponent),
648 limiting_cone_angle: Au::from_f32_px(limiting_cone_angle),
649 }
650 }
651 FilterGraphOp::SVGFEDisplacementMap { scale, x_channel_selector, y_channel_selector } => {
652 FilterGraphOpKey::SVGFEDisplacementMap{
653 scale: Au::from_f32_px(scale),
654 x_channel_selector,
655 y_channel_selector,
656 }
657 }
658 FilterGraphOp::SVGFEDropShadow { color, dx, dy, std_deviation_x, std_deviation_y } => {
659 FilterGraphOpKey::SVGFEDropShadow{
660 color: color.into(),
661 dx: Au::from_f32_px(dx),
662 dy: Au::from_f32_px(dy),
663 std_deviation_x: Au::from_f32_px(std_deviation_x),
664 std_deviation_y: Au::from_f32_px(std_deviation_y),
665 }
666 }
667 FilterGraphOp::SVGFEFlood { color } => FilterGraphOpKey::SVGFEFlood{color: color.into()},
668 FilterGraphOp::SVGFEGaussianBlur { std_deviation_x, std_deviation_y } => {
669 FilterGraphOpKey::SVGFEGaussianBlur{
670 std_deviation_x: Au::from_f32_px(std_deviation_x),
671 std_deviation_y: Au::from_f32_px(std_deviation_y),
672 }
673 }
674 FilterGraphOp::SVGFEIdentity => FilterGraphOpKey::SVGFEIdentity,
675 FilterGraphOp::SVGFEImage { sampling_filter, matrix } => {
676 let mut values: [Au; 6] = [Au(0); 6];
677 for (value, result) in matrix.iter().zip(values.iter_mut()) {
678 *result = Au::from_f32_px(*value)
679 }
680 FilterGraphOpKey::SVGFEImage{
681 sampling_filter,
682 matrix: values,
683 }
684 }
685 FilterGraphOp::SVGFEMorphologyDilate { radius_x, radius_y } => {
686 FilterGraphOpKey::SVGFEMorphologyDilate{
687 radius_x: Au::from_f32_px(radius_x),
688 radius_y: Au::from_f32_px(radius_y),
689 }
690 }
691 FilterGraphOp::SVGFEMorphologyErode { radius_x, radius_y } => {
692 FilterGraphOpKey::SVGFEMorphologyErode{
693 radius_x: Au::from_f32_px(radius_x),
694 radius_y: Au::from_f32_px(radius_y),
695 }
696 }
697 FilterGraphOp::SVGFEOpacity{valuebinding: binding, value: _} => {
698 match binding {
699 PropertyBinding::Value(value) => {
700 FilterGraphOpKey::SVGFEOpacity{value: Au::from_f32_px(value)}
701 }
702 PropertyBinding::Binding(key, default) => {
703 FilterGraphOpKey::SVGFEOpacityBinding{valuebindingid: key.id, value: Au::from_f32_px(default)}
704 }
705 }
706 }
707 FilterGraphOp::SVGFESourceAlpha => FilterGraphOpKey::SVGFESourceAlpha,
708 FilterGraphOp::SVGFESourceGraphic => FilterGraphOpKey::SVGFESourceGraphic,
709 FilterGraphOp::SVGFESpecularLightingDistant { surface_scale, specular_constant, specular_exponent, kernel_unit_length_x, kernel_unit_length_y, azimuth, elevation } => {
710 FilterGraphOpKey::SVGFESpecularLightingDistant{
711 surface_scale: Au::from_f32_px(surface_scale),
712 specular_constant: Au::from_f32_px(specular_constant),
713 specular_exponent: Au::from_f32_px(specular_exponent),
714 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
715 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
716 azimuth: Au::from_f32_px(azimuth),
717 elevation: Au::from_f32_px(elevation),
718 }
719 }
720 FilterGraphOp::SVGFESpecularLightingPoint { surface_scale, specular_constant, specular_exponent, kernel_unit_length_x, kernel_unit_length_y, x, y, z } => {
721 FilterGraphOpKey::SVGFESpecularLightingPoint{
722 surface_scale: Au::from_f32_px(surface_scale),
723 specular_constant: Au::from_f32_px(specular_constant),
724 specular_exponent: Au::from_f32_px(specular_exponent),
725 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
726 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
727 x: Au::from_f32_px(x),
728 y: Au::from_f32_px(y),
729 z: Au::from_f32_px(z),
730 }
731 }
732 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 } => {
733 FilterGraphOpKey::SVGFESpecularLightingSpot{
734 surface_scale: Au::from_f32_px(surface_scale),
735 specular_constant: Au::from_f32_px(specular_constant),
736 specular_exponent: Au::from_f32_px(specular_exponent),
737 kernel_unit_length_x: Au::from_f32_px(kernel_unit_length_x),
738 kernel_unit_length_y: Au::from_f32_px(kernel_unit_length_y),
739 x: Au::from_f32_px(x),
740 y: Au::from_f32_px(y),
741 z: Au::from_f32_px(z),
742 points_at_x: Au::from_f32_px(points_at_x),
743 points_at_y: Au::from_f32_px(points_at_y),
744 points_at_z: Au::from_f32_px(points_at_z),
745 cone_exponent: Au::from_f32_px(cone_exponent),
746 limiting_cone_angle: Au::from_f32_px(limiting_cone_angle),
747 }
748 }
749 FilterGraphOp::SVGFETile => FilterGraphOpKey::SVGFETile,
750 FilterGraphOp::SVGFEToAlpha => FilterGraphOpKey::SVGFEToAlpha,
751 FilterGraphOp::SVGFETurbulenceWithFractalNoiseWithNoStitching { base_frequency_x, base_frequency_y, num_octaves, seed } => {
752 FilterGraphOpKey::SVGFETurbulenceWithFractalNoiseWithNoStitching {
753 base_frequency_x: Au::from_f32_px(base_frequency_x),
754 base_frequency_y: Au::from_f32_px(base_frequency_y),
755 num_octaves,
756 seed,
757 }
758 }
759 FilterGraphOp::SVGFETurbulenceWithFractalNoiseWithStitching { base_frequency_x, base_frequency_y, num_octaves, seed } => {
760 FilterGraphOpKey::SVGFETurbulenceWithFractalNoiseWithStitching {
761 base_frequency_x: Au::from_f32_px(base_frequency_x),
762 base_frequency_y: Au::from_f32_px(base_frequency_y),
763 num_octaves,
764 seed,
765 }
766 }
767 FilterGraphOp::SVGFETurbulenceWithTurbulenceNoiseWithNoStitching { base_frequency_x, base_frequency_y, num_octaves, seed } => {
768 FilterGraphOpKey::SVGFETurbulenceWithTurbulenceNoiseWithNoStitching {
769 base_frequency_x: Au::from_f32_px(base_frequency_x),
770 base_frequency_y: Au::from_f32_px(base_frequency_y),
771 num_octaves,
772 seed,
773 }
774 }
775 FilterGraphOp::SVGFETurbulenceWithTurbulenceNoiseWithStitching { base_frequency_x, base_frequency_y, num_octaves, seed } => {
776 FilterGraphOpKey::SVGFETurbulenceWithTurbulenceNoiseWithStitching {
777 base_frequency_x: Au::from_f32_px(base_frequency_x),
778 base_frequency_y: Au::from_f32_px(base_frequency_y),
779 num_octaves,
780 seed,
781 }
782 }
783 }
784 }
785}
786
787#[cfg_attr(feature = "capture", derive(Serialize))]
788#[cfg_attr(feature = "replay", derive(Deserialize))]
789#[derive(Debug, Clone, MallocSizeOf, PartialEq, Hash, Eq)]
790pub struct FilterGraphNodeKey {
791 pub kept_by_optimizer: bool,
794 pub linear: bool,
798 pub inputs: Vec<FilterGraphPictureReferenceKey>,
801 pub subregion: [Au; 4],
804}
805
806impl From<FilterGraphNode> for FilterGraphNodeKey {
807 fn from(node: FilterGraphNode) -> Self {
808 FilterGraphNodeKey{
809 kept_by_optimizer: node.kept_by_optimizer,
810 linear: node.linear,
811 inputs: node.inputs.into_iter().map(|node| {node.into()}).collect(),
812 subregion: [
813 Au::from_f32_px(node.subregion.min.x),
814 Au::from_f32_px(node.subregion.min.y),
815 Au::from_f32_px(node.subregion.max.x),
816 Au::from_f32_px(node.subregion.max.y),
817 ],
818 }
819 }
820}
821
822#[cfg_attr(feature = "capture", derive(Serialize))]
825#[cfg_attr(feature = "replay", derive(Deserialize))]
826#[derive(Debug, Clone, MallocSizeOf, PartialEq, Hash, Eq)]
827pub enum PictureCompositeKey {
828 Identity,
830
831 Blur(Au, Au, bool),
833 Brightness(Au),
834 Contrast(Au),
835 Grayscale(Au),
836 HueRotate(Au),
837 Invert(Au),
838 Opacity(Au),
839 OpacityBinding(PropertyBindingId, Au),
840 Saturate(Au),
841 Sepia(Au),
842 DropShadows(Vec<(VectorKey, Au, ColorU)>),
843 ColorMatrix([Au; 20]),
844 SrgbToLinear,
845 LinearToSrgb,
846 ComponentTransfer(ItemUid),
847 Flood(ColorU),
848 SvgFilter(Vec<FilterPrimitiveKey>),
849 SVGFEGraph(Vec<(FilterGraphNodeKey, FilterGraphOpKey)>),
850
851 Multiply,
853 Screen,
854 Overlay,
855 Darken,
856 Lighten,
857 ColorDodge,
858 ColorBurn,
859 HardLight,
860 SoftLight,
861 Difference,
862 Exclusion,
863 Hue,
864 Saturation,
865 Color,
866 Luminosity,
867 PlusLighter,
868}
869
870impl From<Option<PictureCompositeMode>> for PictureCompositeKey {
871 fn from(mode: Option<PictureCompositeMode>) -> Self {
872 match mode {
873 Some(PictureCompositeMode::MixBlend(mode)) => {
874 match mode {
875 MixBlendMode::Normal => PictureCompositeKey::Identity,
876 MixBlendMode::Multiply => PictureCompositeKey::Multiply,
877 MixBlendMode::Screen => PictureCompositeKey::Screen,
878 MixBlendMode::Overlay => PictureCompositeKey::Overlay,
879 MixBlendMode::Darken => PictureCompositeKey::Darken,
880 MixBlendMode::Lighten => PictureCompositeKey::Lighten,
881 MixBlendMode::ColorDodge => PictureCompositeKey::ColorDodge,
882 MixBlendMode::ColorBurn => PictureCompositeKey::ColorBurn,
883 MixBlendMode::HardLight => PictureCompositeKey::HardLight,
884 MixBlendMode::SoftLight => PictureCompositeKey::SoftLight,
885 MixBlendMode::Difference => PictureCompositeKey::Difference,
886 MixBlendMode::Exclusion => PictureCompositeKey::Exclusion,
887 MixBlendMode::Hue => PictureCompositeKey::Hue,
888 MixBlendMode::Saturation => PictureCompositeKey::Saturation,
889 MixBlendMode::Color => PictureCompositeKey::Color,
890 MixBlendMode::Luminosity => PictureCompositeKey::Luminosity,
891 MixBlendMode::PlusLighter => PictureCompositeKey::PlusLighter,
892 }
893 }
894 Some(PictureCompositeMode::Filter(op)) => {
895 match op {
896 Filter::Blur { width, height, should_inflate } =>
897 PictureCompositeKey::Blur(Au::from_f32_px(width), Au::from_f32_px(height), should_inflate),
898 Filter::Brightness(value) => PictureCompositeKey::Brightness(Au::from_f32_px(value)),
899 Filter::Contrast(value) => PictureCompositeKey::Contrast(Au::from_f32_px(value)),
900 Filter::Grayscale(value) => PictureCompositeKey::Grayscale(Au::from_f32_px(value)),
901 Filter::HueRotate(value) => PictureCompositeKey::HueRotate(Au::from_f32_px(value)),
902 Filter::Invert(value) => PictureCompositeKey::Invert(Au::from_f32_px(value)),
903 Filter::Saturate(value) => PictureCompositeKey::Saturate(Au::from_f32_px(value)),
904 Filter::Sepia(value) => PictureCompositeKey::Sepia(Au::from_f32_px(value)),
905 Filter::SrgbToLinear => PictureCompositeKey::SrgbToLinear,
906 Filter::LinearToSrgb => PictureCompositeKey::LinearToSrgb,
907 Filter::Identity => PictureCompositeKey::Identity,
908 Filter::DropShadows(ref shadows) => {
909 PictureCompositeKey::DropShadows(
910 shadows.iter().map(|shadow| {
911 (shadow.offset.into(), Au::from_f32_px(shadow.blur_radius), shadow.color.into())
912 }).collect()
913 )
914 }
915 Filter::Opacity(binding, _) => {
916 match binding {
917 PropertyBinding::Value(value) => {
918 PictureCompositeKey::Opacity(Au::from_f32_px(value))
919 }
920 PropertyBinding::Binding(key, default) => {
921 PictureCompositeKey::OpacityBinding(key.id, Au::from_f32_px(default))
922 }
923 }
924 }
925 Filter::ColorMatrix(values) => {
926 let mut quantized_values: [Au; 20] = [Au(0); 20];
927 for (value, result) in values.iter().zip(quantized_values.iter_mut()) {
928 *result = Au::from_f32_px(*value);
929 }
930 PictureCompositeKey::ColorMatrix(quantized_values)
931 }
932 Filter::ComponentTransfer => unreachable!(),
933 Filter::Flood(color) => PictureCompositeKey::Flood(color.into()),
934 Filter::SVGGraphNode(_node, _op) => unreachable!(),
935 }
936 }
937 Some(PictureCompositeMode::ComponentTransferFilter(handle)) => {
938 PictureCompositeKey::ComponentTransfer(handle.uid())
939 }
940 Some(PictureCompositeMode::SvgFilter(filter_primitives, filter_data)) => {
941 PictureCompositeKey::SvgFilter(filter_primitives.into_iter().map(|primitive| {
942 match primitive.kind {
943 FilterPrimitiveKind::Identity(identity) => FilterPrimitiveKey::Identity(primitive.color_space, identity.input),
944 FilterPrimitiveKind::Blend(blend) => FilterPrimitiveKey::Blend(primitive.color_space, blend.mode, blend.input1, blend.input2),
945 FilterPrimitiveKind::Flood(flood) => FilterPrimitiveKey::Flood(primitive.color_space, flood.color.into()),
946 FilterPrimitiveKind::Blur(blur) =>
947 FilterPrimitiveKey::Blur(primitive.color_space, Au::from_f32_px(blur.width), Au::from_f32_px(blur.height), blur.input),
948 FilterPrimitiveKind::Opacity(opacity) =>
949 FilterPrimitiveKey::Opacity(primitive.color_space, Au::from_f32_px(opacity.opacity), opacity.input),
950 FilterPrimitiveKind::ColorMatrix(color_matrix) => {
951 let mut quantized_values: [Au; 20] = [Au(0); 20];
952 for (value, result) in color_matrix.matrix.iter().zip(quantized_values.iter_mut()) {
953 *result = Au::from_f32_px(*value);
954 }
955 FilterPrimitiveKey::ColorMatrix(primitive.color_space, quantized_values, color_matrix.input)
956 }
957 FilterPrimitiveKind::DropShadow(drop_shadow) => {
958 FilterPrimitiveKey::DropShadow(
959 primitive.color_space,
960 (
961 drop_shadow.shadow.offset.into(),
962 Au::from_f32_px(drop_shadow.shadow.blur_radius),
963 drop_shadow.shadow.color.into(),
964 ),
965 drop_shadow.input,
966 )
967 }
968 FilterPrimitiveKind::ComponentTransfer(component_transfer) =>
969 FilterPrimitiveKey::ComponentTransfer(primitive.color_space, component_transfer.input, filter_data.clone()),
970 FilterPrimitiveKind::Offset(info) =>
971 FilterPrimitiveKey::Offset(primitive.color_space, info.input, info.offset.into()),
972 FilterPrimitiveKind::Composite(info) =>
973 FilterPrimitiveKey::Composite(primitive.color_space, info.input1, info.input2, info.operator.into()),
974 }
975 }).collect())
976 }
977 Some(PictureCompositeMode::SVGFEGraph(filter_nodes)) => {
978 PictureCompositeKey::SVGFEGraph(
979 filter_nodes.into_iter().map(|(node, op)| {
980 (node.into(), op.into())
981 }).collect())
982 }
983 Some(PictureCompositeMode::Blit(_)) |
984 Some(PictureCompositeMode::TileCache { .. }) |
985 Some(PictureCompositeMode::IntermediateSurface) |
986 None => {
987 PictureCompositeKey::Identity
988 }
989 }
990 }
991}
992
993#[cfg_attr(feature = "capture", derive(Serialize))]
994#[cfg_attr(feature = "replay", derive(Deserialize))]
995#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash)]
996pub struct Picture {
997 pub composite_mode_key: PictureCompositeKey,
998 pub raster_space: RasterSpace,
999}
1000
1001#[cfg_attr(feature = "capture", derive(Serialize))]
1002#[cfg_attr(feature = "replay", derive(Deserialize))]
1003#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash)]
1004pub struct PictureKey {
1005 pub composite_mode_key: PictureCompositeKey,
1006 pub raster_space: RasterSpace,
1007}
1008
1009impl PictureKey {
1010 pub fn new(
1011 pic: Picture,
1012 ) -> Self {
1013 PictureKey {
1014 composite_mode_key: pic.composite_mode_key,
1015 raster_space: pic.raster_space,
1016 }
1017 }
1018}
1019
1020impl InternDebug for PictureKey {}
1021
1022#[cfg_attr(feature = "capture", derive(Serialize))]
1023#[cfg_attr(feature = "replay", derive(Deserialize))]
1024#[derive(MallocSizeOf)]
1025pub struct PictureData;
1026
1027#[cfg_attr(feature = "capture", derive(Serialize))]
1028#[cfg_attr(feature = "replay", derive(Deserialize))]
1029#[derive(MallocSizeOf)]
1030pub struct PictureTemplate;
1031
1032impl From<PictureKey> for PictureTemplate {
1033 fn from(_: PictureKey) -> Self {
1034 PictureTemplate
1035 }
1036}
1037
1038pub type PictureDataHandle = InternHandle<Picture>;
1039
1040impl Internable for Picture {
1041 type Key = PictureKey;
1042 type StoreData = PictureTemplate;
1043 type InternData = ();
1044 const PROFILE_COUNTER: usize = crate::profiler::INTERNED_PICTURES;
1045}
1046
1047impl InternablePrimitive for Picture {
1048 fn into_key(
1049 self,
1050 _: &LayoutPrimitiveInfo,
1051 ) -> PictureKey {
1052 PictureKey::new(self)
1053 }
1054
1055 fn make_instance_kind(
1056 _key: PictureKey,
1057 _: PictureDataHandle,
1058 _: &mut PrimitiveStore,
1059 ) -> PrimitiveInstanceKind {
1060 unreachable!();
1063 }
1064}
1065
1066impl IsVisible for Picture {
1067 fn is_visible(&self) -> bool {
1068 true
1069 }
1070}
1071
1072#[test]
1073#[cfg(target_pointer_width = "64")]
1074fn test_struct_sizes() {
1075 use std::mem;
1076 assert_eq!(mem::size_of::<Picture>(), 96, "Picture size changed");
1083 assert_eq!(mem::size_of::<PictureTemplate>(), 0, "PictureTemplate size changed");
1084 assert_eq!(mem::size_of::<PictureKey>(), 96, "PictureKey size changed");
1085}