From a4639d5ca0d59918040f994f222bfbc1115451fa Mon Sep 17 00:00:00 2001 From: Brad Werth Date: Wed, 14 Apr 2021 17:17:14 +0000 Subject: [PATCH] Bug 1675375 Part 1: Define WebRender structures for polygons. r=gw This patch defines a SetPoints DisplayItem for providing polygon mask points associated with a ImageMaskClipDisplayItem. It also defines a WR enum for the polygon fill rule. The method to provide these values to WR is mere scaffolding until later patches in this series. Differential Revision: https://phabricator.services.mozilla.com/D105396 --- gfx/wr/webrender/src/scene_building.rs | 11 +++++++++-- gfx/wr/webrender_api/src/display_item.rs | 33 +++++++++++++++++++++++++++++++- gfx/wr/webrender_api/src/display_list.rs | 28 ++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/gfx/wr/webrender/src/scene_building.rs b/gfx/wr/webrender/src/scene_building.rs index bc24a28513df..e462d46a628f 100644 --- a/gfx/wr/webrender/src/scene_building.rs +++ b/gfx/wr/webrender/src/scene_building.rs @@ -44,7 +44,7 @@ use api::{LineOrientation, LineStyle, NinePatchBorderSource, PipelineId, MixBlen use api::{PropertyBinding, ReferenceFrameKind, ScrollFrameDisplayItem, ScrollSensitivity}; use api::{Shadow, SpaceAndClipInfo, SpatialId, StickyFrameDisplayItem, ImageMask, ItemTag}; use api::{ClipMode, PrimitiveKeyKind, TransformStyle, YuvColorSpace, ColorRange, YuvData, TempFilterData}; -use api::{ReferenceTransformBinding, Rotation}; +use api::{ReferenceTransformBinding, Rotation, FillRule}; use api::units::*; use crate::image_tiling::simplify_repeated_primitive; use crate::clip::{ClipChainId, ClipRegion, ClipItemKey, ClipStore, ClipItemKeyKind}; @@ -1387,6 +1387,8 @@ impl<'a> SceneBuilder<'a> { info.id, &info.parent_space_and_clip, &image_mask, + info.fill_rule, + item.points(), ); } DisplayItem::RoundedRectClip(ref info) => { @@ -1489,7 +1491,8 @@ impl<'a> SceneBuilder<'a> { DisplayItem::SetGradientStops | DisplayItem::SetFilterOps | DisplayItem::SetFilterData | - DisplayItem::SetFilterPrimitives => {} + DisplayItem::SetFilterPrimitives | + DisplayItem::SetPoints => {} // Special items that are handled in the parent method DisplayItem::PushStackingContext(..) | @@ -2326,7 +2329,11 @@ impl<'a> SceneBuilder<'a> { new_node_id: ClipId, space_and_clip: &SpaceAndClipInfo, image_mask: &ImageMask, + _fill_rule: FillRule, + _points_range: ItemRange, ) { + // TODO(bradwerth): incorporate fill_rule and points_range into + // the ClipItemKey. let spatial_node_index = self.id_to_index_mapper.get_spatial_node_index(space_and_clip.spatial_id); let snapped_mask_rect = self.snap_rect( diff --git a/gfx/wr/webrender_api/src/display_item.rs b/gfx/wr/webrender_api/src/display_item.rs index b4a3ec03a1a0..43a392a59f1e 100644 --- a/gfx/wr/webrender_api/src/display_item.rs +++ b/gfx/wr/webrender_api/src/display_item.rs @@ -155,6 +155,7 @@ pub enum DisplayItem { SetFilterOps, SetFilterData, SetFilterPrimitives, + SetPoints, // These marker items terminate a scope introduced by a previous item. PopReferenceFrame, @@ -203,6 +204,7 @@ pub enum DebugDisplayItem { SetFilterOps(Vec), SetFilterData(FilterData), SetFilterPrimitives(Vec), + SetPoints(Vec), PopReferenceFrame, PopStackingContext, @@ -214,7 +216,8 @@ pub struct ImageMaskClipDisplayItem { pub id: ClipId, pub parent_space_and_clip: SpaceAndClipInfo, pub image_mask: ImageMask, -} + pub fill_rule: FillRule, +} // IMPLICIT points: Vec #[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)] pub struct RectClipDisplayItem { @@ -1488,6 +1491,32 @@ impl ComplexClipRegion { } } +#[repr(u8)] +#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize, Eq, Hash, PeekPoke)] +pub enum FillRule { + Nonzero = 0x1, // Behaves as the SVG fill-rule definition for nonzero. + Evenodd = 0x2, // Behaves as the SVG fill-rule definition for evenodd. +} + +impl From for FillRule { + fn from(fill_rule: u8) -> Self { + match fill_rule { + 0x1 => FillRule::Nonzero, + 0x2 => FillRule::Evenodd, + _ => panic!("Unexpected FillRule value."), + } + } +} + +impl From for u8 { + fn from(fill_rule: FillRule) -> Self { + match fill_rule { + FillRule::Nonzero => 0x1, + FillRule::Evenodd => 0x2, + } + } +} + #[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize, PeekPoke)] pub struct ClipChainId(pub u64, pub PipelineId); @@ -1615,6 +1644,7 @@ impl DisplayItem { DisplayItem::SetFilterOps => "set_filter_ops", DisplayItem::SetFilterData => "set_filter_data", DisplayItem::SetFilterPrimitives => "set_filter_primitives", + DisplayItem::SetPoints => "set_points", DisplayItem::RadialGradient(..) => "radial_gradient", DisplayItem::Rectangle(..) => "rectangle", DisplayItem::ScrollFrame(..) => "scroll_frame", @@ -1656,6 +1686,7 @@ impl_default_for_enums! { FilterOp => Identity, ComponentTransferFuncType => Identity, ClipMode => Clip, + FillRule => Nonzero, ClipId => ClipId::invalid(), ReferenceFrameKind => Transform { is_2d_scale_translation: false, diff --git a/gfx/wr/webrender_api/src/display_list.rs b/gfx/wr/webrender_api/src/display_list.rs index cac5e2004eac..094f3f9d4b78 100644 --- a/gfx/wr/webrender_api/src/display_list.rs +++ b/gfx/wr/webrender_api/src/display_list.rs @@ -227,6 +227,7 @@ pub struct BuiltDisplayListIter<'a> { cur_filter_primitives: ItemRange<'a, di::FilterPrimitive>, cur_clip_chain_items: ItemRange<'a, di::ClipId>, cur_complex_clip: ItemRange<'a, di::ComplexClipRegion>, + cur_points: ItemRange<'a, LayoutPoint>, peeking: Peek, /// Should just be initialized but never populated in release builds debug_stats: DebugStats, @@ -324,6 +325,10 @@ impl<'a, 'b> DisplayItemRef<'a, 'b> { self.iter.cur_complex_clip } + pub fn points(&self) -> ItemRange { + self.iter.cur_points + } + pub fn glyphs(&self) -> ItemRange { self.iter.glyphs() } @@ -479,6 +484,9 @@ impl BuiltDisplayList { Real::SetGradientStops => Debug::SetGradientStops( item.iter.cur_stops.iter().collect() ), + Real::SetPoints => Debug::SetPoints( + item.iter.cur_points.iter().collect() + ), Real::RectClip(v) => Debug::RectClip(v), Real::RoundedRectClip(v) => Debug::RoundedRectClip(v), Real::ImageMaskClip(v) => Debug::ImageMaskClip(v), @@ -548,6 +556,7 @@ impl<'a> BuiltDisplayListIter<'a> { cur_filter_primitives: ItemRange::default(), cur_clip_chain_items: ItemRange::default(), cur_complex_clip: ItemRange::default(), + cur_points: ItemRange::default(), peeking: Peek::NotPeeking, debug_stats: DebugStats { last_addr: data.as_ptr() as usize, @@ -616,6 +625,7 @@ impl<'a> BuiltDisplayListIter<'a> { self.cur_stops = ItemRange::default(); self.cur_complex_clip = ItemRange::default(); self.cur_clip_chain_items = ItemRange::default(); + self.cur_points = ItemRange::default(); self.cur_filters = ItemRange::default(); self.cur_filter_primitives = ItemRange::default(); self.cur_filter_data.clear(); @@ -626,7 +636,8 @@ impl<'a> BuiltDisplayListIter<'a> { SetGradientStops | SetFilterOps | SetFilterData | - SetFilterPrimitives => { + SetFilterPrimitives | + SetPoints => { // These are marker items for populating other display items, don't yield them. continue; } @@ -688,6 +699,10 @@ impl<'a> BuiltDisplayListIter<'a> { self.cur_filter_primitives = skip_slice::(&mut self.data); self.debug_stats.log_slice("set_filter_primitives.primitives", &self.cur_filter_primitives); } + SetPoints => { + self.cur_points = skip_slice::(&mut self.data); + self.debug_stats.log_slice("set_points.points", &self.cur_points); + } ClipChain(_) => { self.cur_clip_chain_items = skip_slice::(&mut self.data); self.debug_stats.log_slice("clip_chain.clip_ids", &self.cur_clip_chain_items); @@ -901,6 +916,10 @@ impl<'de> Deserialize<'de> for BuiltDisplayList { DisplayListBuilder::push_iter_impl(&mut temp, stops); Real::SetGradientStops }, + Debug::SetPoints(points) => { + DisplayListBuilder::push_iter_impl(&mut temp, points); + Real::SetPoints + }, Debug::RectClip(v) => Real::RectClip(v), Debug::RoundedRectClip(v) => Real::RoundedRectClip(v), Debug::ImageMaskClip(v) => Real::ImageMaskClip(v), @@ -1782,13 +1801,20 @@ impl DisplayListBuilder { parent_space_and_clip: &di::SpaceAndClipInfo, image_mask: di::ImageMask, ) -> di::ClipId { + // TODO(bradwerth): get points and fill_rule as parameters. + let points = Vec::::new(); + let fill_rule = di::FillRule::Nonzero; + let id = self.generate_clip_index(); let item = di::DisplayItem::ImageMaskClip(di::ImageMaskClipDisplayItem { id, parent_space_and_clip: *parent_space_and_clip, image_mask, + fill_rule, }); + self.push_item(&di::DisplayItem::SetPoints); + self.push_iter(points); self.push_item(&item); id } -- 2.11.4.GIT