mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 08:45:46 +00:00
Bug 1178765
- Part 1: Add backdrop-filter WebRender display items r=gw
Differential Revision: https://phabricator.services.mozilla.com/D39097 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
ec37be04da
commit
afa1fcbaed
@ -344,7 +344,8 @@ struct MOZ_STACK_CLASS StackingContextParams : public WrStackingContextParams {
|
||||
nullptr,
|
||||
/* is_backface_visible = */ true,
|
||||
/* cache_tiles = */ false,
|
||||
wr::MixBlendMode::Normal} {}
|
||||
wr::MixBlendMode::Normal,
|
||||
/* is_backdrop_root = */ false} {}
|
||||
|
||||
void SetPreserve3D(bool aPreserve) {
|
||||
transform_style =
|
||||
|
@ -2085,6 +2085,9 @@ pub struct WrStackingContextParams {
|
||||
/// True if picture caching should be enabled for this stacking context.
|
||||
pub cache_tiles: bool,
|
||||
pub mix_blend_mode: MixBlendMode,
|
||||
/// True if this stacking context is a backdrop root.
|
||||
/// https://drafts.fxtf.org/filter-effects-2/#BackdropRoot
|
||||
pub is_backdrop_root: bool,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -2206,7 +2209,8 @@ pub extern "C" fn wr_dp_push_stacking_context(
|
||||
&r_filter_datas,
|
||||
&[],
|
||||
glyph_raster_space,
|
||||
params.cache_tiles);
|
||||
params.cache_tiles,
|
||||
params.is_backdrop_root);
|
||||
|
||||
result
|
||||
}
|
||||
|
@ -1311,6 +1311,9 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
parent_space,
|
||||
);
|
||||
}
|
||||
DisplayItem::BackdropFilter(ref info) => {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
// Do nothing; these are dummy items for the display list parser
|
||||
DisplayItem::SetGradientStops |
|
||||
|
@ -105,6 +105,7 @@ pub enum DisplayItem {
|
||||
RadialGradient(RadialGradientDisplayItem),
|
||||
Image(ImageDisplayItem),
|
||||
YuvImage(YuvImageDisplayItem),
|
||||
BackdropFilter(BackdropFilterDisplayItem),
|
||||
|
||||
// Clips
|
||||
Clip(ClipDisplayItem),
|
||||
@ -148,6 +149,7 @@ pub enum DebugDisplayItem {
|
||||
RadialGradient(RadialGradientDisplayItem),
|
||||
Image(ImageDisplayItem),
|
||||
YuvImage(YuvImageDisplayItem),
|
||||
BackdropFilter(BackdropFilterDisplayItem),
|
||||
|
||||
Clip(ClipDisplayItem, Vec<ComplexClipRegion>),
|
||||
ClipChain(ClipChainItem, Vec<ClipId>),
|
||||
@ -611,6 +613,13 @@ pub struct RadialGradientDisplayItem {
|
||||
pub tile_spacing: LayoutSize,
|
||||
}
|
||||
|
||||
/// Renders a filtered region of its backdrop
|
||||
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
|
||||
pub struct BackdropFilterDisplayItem {
|
||||
pub common: CommonItemProperties,
|
||||
}
|
||||
// IMPLICIT: filters: Vec<FilterOp>, filter_datas: Vec<FilterData>, filter_primitives: Vec<FilterPrimitive>
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
|
||||
pub struct ReferenceFrameDisplayListItem {
|
||||
pub origin: LayoutPoint,
|
||||
@ -652,7 +661,10 @@ pub struct StackingContext {
|
||||
pub raster_space: RasterSpace,
|
||||
/// True if picture caching should be used on this stacking context.
|
||||
pub cache_tiles: bool,
|
||||
} // IMPLICIT: filters: Vec<FilterOp>, filter_datas: Vec<FilterData>, filter_primitives: Vec<FilterPrimitive>
|
||||
/// True if this stacking context is a backdrop root.
|
||||
pub is_backdrop_root: bool,
|
||||
}
|
||||
// IMPLICIT: filters: Vec<FilterOp>, filter_datas: Vec<FilterData>, filter_primitives: Vec<FilterPrimitive>
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, PeekPoke)]
|
||||
@ -1364,6 +1376,7 @@ impl DisplayItem {
|
||||
DisplayItem::StickyFrame(..) => "sticky_frame",
|
||||
DisplayItem::Text(..) => "text",
|
||||
DisplayItem::YuvImage(..) => "yuv_image",
|
||||
DisplayItem::BackdropFilter(..) => "backdrop_filter",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -329,6 +329,9 @@ impl<'a> BuiltDisplayListIter<'a> {
|
||||
self.cur_stops = ItemRange::default();
|
||||
self.cur_complex_clip = ItemRange::default();
|
||||
self.cur_clip_chain_items = ItemRange::default();
|
||||
self.cur_filters = ItemRange::default();
|
||||
self.cur_filter_primitives = ItemRange::default();
|
||||
self.cur_filter_data.clear();
|
||||
|
||||
loop {
|
||||
self.next_raw()?;
|
||||
@ -629,6 +632,7 @@ impl Serialize for BuiltDisplayList {
|
||||
Real::PushReferenceFrame(v) => Debug::PushReferenceFrame(v),
|
||||
Real::PushStackingContext(v) => Debug::PushStackingContext(v),
|
||||
Real::PushShadow(v) => Debug::PushShadow(v),
|
||||
Real::BackdropFilter(v) => Debug::BackdropFilter(v),
|
||||
|
||||
Real::PopReferenceFrame => Debug::PopReferenceFrame,
|
||||
Real::PopStackingContext => Debug::PopStackingContext,
|
||||
@ -730,6 +734,7 @@ impl<'de> Deserialize<'de> for BuiltDisplayList {
|
||||
Debug::RadialGradient(v) => Real::RadialGradient(v),
|
||||
Debug::PushStackingContext(v) => Real::PushStackingContext(v),
|
||||
Debug::PushShadow(v) => Real::PushShadow(v),
|
||||
Debug::BackdropFilter(v) => Real::BackdropFilter(v),
|
||||
|
||||
Debug::PopStackingContext => Real::PopStackingContext,
|
||||
Debug::PopReferenceFrame => Real::PopReferenceFrame,
|
||||
@ -1235,28 +1240,9 @@ impl DisplayListBuilder {
|
||||
filter_primitives: &[di::FilterPrimitive],
|
||||
raster_space: di::RasterSpace,
|
||||
cache_tiles: bool,
|
||||
is_backdrop_root: bool,
|
||||
) {
|
||||
if filters.len() > 0 {
|
||||
self.push_item(&di::DisplayItem::SetFilterOps);
|
||||
self.push_iter(filters);
|
||||
}
|
||||
|
||||
for filter_data in filter_datas {
|
||||
let func_types = [
|
||||
filter_data.func_r_type, filter_data.func_g_type,
|
||||
filter_data.func_b_type, filter_data.func_a_type];
|
||||
self.push_item(&di::DisplayItem::SetFilterData);
|
||||
self.push_iter(&func_types);
|
||||
self.push_iter(&filter_data.r_values);
|
||||
self.push_iter(&filter_data.g_values);
|
||||
self.push_iter(&filter_data.b_values);
|
||||
self.push_iter(&filter_data.a_values);
|
||||
}
|
||||
|
||||
if !filter_primitives.is_empty() {
|
||||
self.push_item(&di::DisplayItem::SetFilterPrimitives);
|
||||
self.push_iter(filter_primitives);
|
||||
}
|
||||
self.push_filters(filters, filter_datas, filter_primitives);
|
||||
|
||||
let item = di::DisplayItem::PushStackingContext(di::PushStackingContextDisplayItem {
|
||||
origin,
|
||||
@ -1268,6 +1254,7 @@ impl DisplayListBuilder {
|
||||
clip_id,
|
||||
raster_space,
|
||||
cache_tiles,
|
||||
is_backdrop_root,
|
||||
},
|
||||
});
|
||||
|
||||
@ -1281,7 +1268,14 @@ impl DisplayListBuilder {
|
||||
spatial_id: di::SpatialId,
|
||||
is_backface_visible: bool,
|
||||
) {
|
||||
self.push_simple_stacking_context_with_filters(origin, spatial_id, is_backface_visible, &[], &[], &[]);
|
||||
self.push_simple_stacking_context_with_filters(
|
||||
origin,
|
||||
spatial_id,
|
||||
is_backface_visible,
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
);
|
||||
}
|
||||
|
||||
/// Helper for examples/ code.
|
||||
@ -1306,6 +1300,7 @@ impl DisplayListBuilder {
|
||||
filter_primitives,
|
||||
di::RasterSpace::Screen,
|
||||
/* cache_tiles = */ false,
|
||||
/* is_backdrop_root = */ false,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1321,6 +1316,50 @@ impl DisplayListBuilder {
|
||||
self.push_iter(stops);
|
||||
}
|
||||
|
||||
pub fn push_backdrop_filter(
|
||||
&mut self,
|
||||
common: &di::CommonItemProperties,
|
||||
filters: &[di::FilterOp],
|
||||
filter_datas: &[di::FilterData],
|
||||
filter_primitives: &[di::FilterPrimitive],
|
||||
) {
|
||||
self.push_filters(filters, filter_datas, filter_primitives);
|
||||
|
||||
let item = di::DisplayItem::BackdropFilter(di::BackdropFilterDisplayItem {
|
||||
common: *common,
|
||||
});
|
||||
self.push_item(&item);
|
||||
}
|
||||
|
||||
pub fn push_filters(
|
||||
&mut self,
|
||||
filters: &[di::FilterOp],
|
||||
filter_datas: &[di::FilterData],
|
||||
filter_primitives: &[di::FilterPrimitive],
|
||||
) {
|
||||
if filters.len() > 0 {
|
||||
self.push_item(&di::DisplayItem::SetFilterOps);
|
||||
self.push_iter(filters);
|
||||
}
|
||||
|
||||
for filter_data in filter_datas {
|
||||
let func_types = [
|
||||
filter_data.func_r_type, filter_data.func_g_type,
|
||||
filter_data.func_b_type, filter_data.func_a_type];
|
||||
self.push_item(&di::DisplayItem::SetFilterData);
|
||||
self.push_iter(&func_types);
|
||||
self.push_iter(&filter_data.r_values);
|
||||
self.push_iter(&filter_data.g_values);
|
||||
self.push_iter(&filter_data.b_values);
|
||||
self.push_iter(&filter_data.a_values);
|
||||
}
|
||||
|
||||
if !filter_primitives.is_empty() {
|
||||
self.push_item(&di::DisplayItem::SetFilterPrimitives);
|
||||
self.push_iter(filter_primitives);
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_clip_index(&mut self) -> di::ClipId {
|
||||
self.next_clip_index += 1;
|
||||
di::ClipId::Clip(self.next_clip_index - 1, self.pipeline_id)
|
||||
|
@ -1538,6 +1538,7 @@ impl YamlFrameReader {
|
||||
"reference-frame" => self.handle_reference_frame(dl, wrench, item),
|
||||
"shadow" => self.handle_push_shadow(dl, item, &mut info),
|
||||
"pop-all-shadows" => self.handle_pop_all_shadows(dl),
|
||||
"backdrop-filter" => self.handle_backdrop_filter(dl, item, &mut info),
|
||||
_ => println!("Skipping unknown item type: {:?}", item),
|
||||
}
|
||||
|
||||
@ -1873,6 +1874,7 @@ impl YamlFrameReader {
|
||||
.as_raster_space()
|
||||
.unwrap_or(RasterSpace::Screen);
|
||||
let cache_tiles = yaml["cache"].as_bool().unwrap_or(false);
|
||||
let is_backdrop_root = yaml["backdrop-root"].as_bool().unwrap_or(false);
|
||||
|
||||
if is_root {
|
||||
if let Some(size) = yaml["scroll-offset"].as_point() {
|
||||
@ -1897,6 +1899,7 @@ impl YamlFrameReader {
|
||||
&filter_primitives,
|
||||
raster_space,
|
||||
cache_tiles,
|
||||
is_backdrop_root,
|
||||
);
|
||||
|
||||
if !yaml["items"].is_badvalue() {
|
||||
@ -1910,6 +1913,29 @@ impl YamlFrameReader {
|
||||
dl.pop_reference_frame();
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_backdrop_filter(
|
||||
&mut self,
|
||||
dl: &mut DisplayListBuilder,
|
||||
item: &Yaml,
|
||||
info: &mut CommonItemProperties,
|
||||
) {
|
||||
info.clip_rect = try_intersect!(
|
||||
self.resolve_rect(&item["bounds"]),
|
||||
&info.clip_rect
|
||||
);
|
||||
|
||||
let filters = item["filters"].as_vec_filter_op().unwrap_or(vec![]);
|
||||
let filter_datas = item["filter-datas"].as_vec_filter_data().unwrap_or(vec![]);
|
||||
let filter_primitives = item["filter-primitives"].as_vec_filter_primitive().unwrap_or(vec![]);
|
||||
|
||||
dl.push_backdrop_filter(
|
||||
&info,
|
||||
&filters,
|
||||
&filter_datas,
|
||||
&filter_primitives,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl WrenchThing for YamlFrameReader {
|
||||
|
@ -259,31 +259,12 @@ fn shadow_parameters(shadow: &Shadow) -> String {
|
||||
)
|
||||
}
|
||||
|
||||
fn write_stacking_context(
|
||||
fn write_filters(
|
||||
parent: &mut Table,
|
||||
sc: &StackingContext,
|
||||
properties: &SceneProperties,
|
||||
name: &str,
|
||||
filter_iter: impl IntoIterator<Item = FilterOp>,
|
||||
filter_data_iter: &[TempFilterData],
|
||||
filter_primitive_iter: impl IntoIterator<Item = FilterPrimitive>,
|
||||
properties: &SceneProperties,
|
||||
) {
|
||||
enum_node(parent, "transform-style", sc.transform_style);
|
||||
|
||||
let raster_space = match sc.raster_space {
|
||||
RasterSpace::Local(scale) => {
|
||||
format!("local({})", scale)
|
||||
}
|
||||
RasterSpace::Screen => {
|
||||
"screen".to_owned()
|
||||
}
|
||||
};
|
||||
str_node(parent, "raster-space", &raster_space);
|
||||
|
||||
// mix_blend_mode
|
||||
if sc.mix_blend_mode != MixBlendMode::Normal {
|
||||
enum_node(parent, "mix-blend-mode", sc.mix_blend_mode)
|
||||
}
|
||||
// filters
|
||||
let mut filters = vec![];
|
||||
for filter in filter_iter {
|
||||
match filter {
|
||||
@ -324,9 +305,14 @@ fn write_stacking_context(
|
||||
}
|
||||
}
|
||||
|
||||
yaml_node(parent, "filters", Yaml::Array(filters));
|
||||
yaml_node(parent, name, Yaml::Array(filters));
|
||||
}
|
||||
|
||||
// filter datas
|
||||
fn write_filter_datas(
|
||||
parent: &mut Table,
|
||||
name: &str,
|
||||
filter_data_iter: &[TempFilterData],
|
||||
) {
|
||||
let mut filter_datas = vec![];
|
||||
for filter_data in filter_data_iter {
|
||||
let func_types = filter_data.func_types.iter().map(|func_type| {
|
||||
@ -361,9 +347,14 @@ fn write_stacking_context(
|
||||
filter_datas.push(Yaml::Array(avec));
|
||||
}
|
||||
|
||||
yaml_node(parent, "filter-datas", Yaml::Array(filter_datas));
|
||||
yaml_node(parent, name, Yaml::Array(filter_datas));
|
||||
}
|
||||
|
||||
// filter primitives
|
||||
fn write_filter_primitives(
|
||||
parent: &mut Table,
|
||||
name: &str,
|
||||
filter_primitive_iter: impl IntoIterator<Item = FilterPrimitive>,
|
||||
) {
|
||||
let mut filter_primitives = vec![];
|
||||
for filter_primitive in filter_primitive_iter {
|
||||
let mut table = new_table();
|
||||
@ -413,7 +404,37 @@ fn write_stacking_context(
|
||||
filter_primitives.push(Yaml::Hash(table));
|
||||
}
|
||||
|
||||
yaml_node(parent, "filter-primitives", Yaml::Array(filter_primitives));
|
||||
yaml_node(parent, name, Yaml::Array(filter_primitives));
|
||||
}
|
||||
|
||||
fn write_stacking_context(
|
||||
parent: &mut Table,
|
||||
sc: &StackingContext,
|
||||
properties: &SceneProperties,
|
||||
filter_iter: impl IntoIterator<Item = FilterOp>,
|
||||
filter_data_iter: &[TempFilterData],
|
||||
filter_primitive_iter: impl IntoIterator<Item = FilterPrimitive>,
|
||||
) {
|
||||
enum_node(parent, "transform-style", sc.transform_style);
|
||||
|
||||
let raster_space = match sc.raster_space {
|
||||
RasterSpace::Local(scale) => {
|
||||
format!("local({})", scale)
|
||||
}
|
||||
RasterSpace::Screen => {
|
||||
"screen".to_owned()
|
||||
}
|
||||
};
|
||||
str_node(parent, "raster-space", &raster_space);
|
||||
|
||||
// mix_blend_mode
|
||||
if sc.mix_blend_mode != MixBlendMode::Normal {
|
||||
enum_node(parent, "mix-blend-mode", sc.mix_blend_mode)
|
||||
}
|
||||
|
||||
write_filters(parent, "filters", filter_iter, properties);
|
||||
write_filter_datas(parent, "filter-datas", filter_data_iter);
|
||||
write_filter_primitives(parent, "filter-primitives", filter_primitive_iter);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
@ -1340,6 +1361,14 @@ impl YamlFrameWriter {
|
||||
];
|
||||
yaml_node(&mut v, "previously-applied-offset", Yaml::Array(applied));
|
||||
}
|
||||
DisplayItem::BackdropFilter(item) => {
|
||||
str_node(&mut v, "type", "backdrop-filter");
|
||||
common_node(&mut v, clip_id_mapper, &item.common);
|
||||
|
||||
write_filters(&mut v, "filters", base.filters(), &scene.properties);
|
||||
write_filter_datas(&mut v, "filter-datas", base.filter_datas());
|
||||
write_filter_primitives(&mut v, "filter-primitives", base.filter_primitives());
|
||||
}
|
||||
|
||||
DisplayItem::PopReferenceFrame |
|
||||
DisplayItem::PopStackingContext => return,
|
||||
|
Loading…
Reference in New Issue
Block a user