Bug 1573649 - Implement feOffset SVG filter primitive in WebRender r=nical

Differential Revision: https://phabricator.services.mozilla.com/D41840

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Connor Brewster 2019-08-14 20:14:25 +00:00
parent 41e991dd1f
commit 1a77c310c4
9 changed files with 74 additions and 0 deletions

View File

@ -1964,6 +1964,10 @@ impl PictureCompositeMode {
primitive.input.to_index(cur_index).map(|index| output_rects[index]).unwrap_or(picture_rect),
FilterPrimitiveKind::ComponentTransfer(ref primitive) =>
primitive.input.to_index(cur_index).map(|index| output_rects[index]).unwrap_or(picture_rect),
FilterPrimitiveKind::Offset(ref primitive) => {
let input_rect = primitive.input.to_index(cur_index).map(|index| output_rects[index]).unwrap_or(picture_rect);
input_rect.translate(primitive.offset * Scale::new(1.0))
},
FilterPrimitiveKind::Flood(..) => picture_rect,
};

View File

@ -31,6 +31,7 @@ pub enum FilterPrimitiveKey {
ColorMatrix(ColorSpace, [Au; 20], FilterPrimitiveInput),
DropShadow(ColorSpace, (VectorKey, Au, ColorU), FilterPrimitiveInput),
ComponentTransfer(ColorSpace, FilterPrimitiveInput, Vec<SFilterData>),
Offset(ColorSpace, FilterPrimitiveInput, VectorKey),
}
/// Represents a hashable description of how a picture primitive
@ -175,6 +176,8 @@ impl From<Option<PictureCompositeMode>> for PictureCompositeKey {
}
FilterPrimitiveKind::ComponentTransfer(component_transfer) =>
FilterPrimitiveKey::ComponentTransfer(primitive.color_space, component_transfer.input, filter_data.clone()),
FilterPrimitiveKind::Offset(info) =>
FilterPrimitiveKey::Offset(primitive.color_space, info.input, info.offset.into()),
}
}).collect())
}

View File

@ -1476,6 +1476,26 @@ impl RenderTask {
render_tasks.add(task)
}
}
FilterPrimitiveKind::Offset(ref info) => {
let input_task_id = get_task_input(
&info.input,
filter_primitives,
render_tasks,
cur_index,
&outputs,
original_task_id,
primitive.color_space
);
let offset = info.offset * LayoutToWorldScale::new(1.0) * device_pixel_scale;
let offset_task = RenderTask::new_svg_filter_primitive(
vec![input_task_id],
content_size,
uv_rect_kind,
SvgFilterInfo::Offset(offset),
);
render_tasks.add(offset_task)
}
};
outputs.push(render_task_id);
}

View File

@ -837,6 +837,13 @@ pub struct IdentityPrimitive {
pub input: FilterPrimitiveInput,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
pub struct OffsetPrimitive {
pub input: FilterPrimitiveInput,
pub offset: LayoutVector2D,
}
/// See: https://github.com/eqrion/cbindgen/issues/9
/// cbindgen:derive-eq=false
#[repr(C)]
@ -852,6 +859,7 @@ pub enum FilterPrimitiveKind {
ColorMatrix(ColorMatrixPrimitive),
DropShadow(DropShadowPrimitive),
ComponentTransfer(ComponentTransferPrimitive),
Offset(OffsetPrimitive),
}
impl Default for FilterPrimitiveKind {
@ -872,6 +880,7 @@ impl FilterPrimitiveKind {
FilterPrimitiveKind::Identity(..) |
FilterPrimitiveKind::Blend(..) |
FilterPrimitiveKind::ColorMatrix(..) |
FilterPrimitiveKind::Offset(..) |
// Component transfer's filter data is sanitized separately.
FilterPrimitiveKind::ComponentTransfer(..) => {}
}

View File

@ -58,3 +58,4 @@ platform(linux,mac) == svg-filter-drop-shadow-on-viewport-edge.yaml svg-filter-d
platform(linux,mac) == svg-filter-drop-shadow-perspective.yaml svg-filter-drop-shadow-perspective.png
== backdrop-filter-basic.yaml backdrop-filter-basic-ref.yaml
platform(linux,mac) == backdrop-filter-perspective.yaml backdrop-filter-perspective.png
platform(linux,max) == svg-filter-offset.yaml svg-filter-offset-ref.yaml

View File

@ -0,0 +1,11 @@
# Tests the SVG offset filter primitive
# An offset filter should have the same effect as changing the origin of the rectangle.
---
root:
items:
- type: stacking-context
bounds: 0 0 0 0
items:
- type: rect
bounds: 20 20 100 100
color: red

View File

@ -0,0 +1,15 @@
# Tests the SVG offset filter primitive
# An offset filter should have the same effect as changing the origin of the rectangle.
---
root:
items:
- type: stacking-context
bounds: 0 0 0 0
filter-primitives:
- type: offset
offset: 10 10
in: original
items:
- type: rect
bounds: 10 10 100 100
color: red

View File

@ -399,6 +399,11 @@ fn write_filter_primitives(
yaml_node(&mut table, "type", Yaml::String("component-transfer".into()));
filter_input_node(&mut table, "in", component_transfer_primitive.input);
}
FilterPrimitiveKind::Offset(info) => {
yaml_node(&mut table, "type", Yaml::String("offset".into()));
filter_input_node(&mut table, "in", info.input);
vector_node(&mut table, "offset", &info.offset);
}
}
enum_node(&mut table, "color-space", filter_primitive.color_space);
filter_primitives.push(Yaml::Hash(table));

View File

@ -769,6 +769,12 @@ impl YamlHelper for Yaml {
input: self["in"].as_filter_input().unwrap(),
})
}
"offset" => {
FilterPrimitiveKind::Offset(OffsetPrimitive {
input: self["in"].as_filter_input().unwrap(),
offset: self["offset"].as_vector().unwrap(),
})
}
_ => return None,
};