Bug 1632705 - Part 3 - Add API for rounded rect clips. r=Bert

This adds the last remaining explicit API for defining clips of
a specific type, and ports wrench and examples to use them.

Differential Revision: https://phabricator.services.mozilla.com/D72284
This commit is contained in:
Glenn Watson 2020-04-26 23:30:48 +00:00
Родитель b954ae4e56
Коммит 43db714391
8 изменённых файлов: 128 добавлений и 24 удалений

Просмотреть файл

@ -143,10 +143,9 @@ impl Rectangle {
api::BorderRadius::uniform(20.),
api::ClipMode::Clip
);
let clip_id = builder.define_clip(
let clip_id = builder.define_clip_rounded_rect(
&api::SpaceAndClipInfo::root_scroll(pipeline_id),
rect,
vec![region],
region,
);
builder.push_rect(

Просмотреть файл

@ -84,7 +84,10 @@ impl App {
radii: BorderRadius::uniform(30.0),
mode: ClipMode::Clip,
};
let clip_id = builder.define_clip(&space_and_clip, clip_bounds, vec![complex_clip]);
let clip_id = builder.define_clip_rounded_rect(
&space_and_clip,
complex_clip,
);
// Fill it with a white rect
builder.push_rect(

Просмотреть файл

@ -221,13 +221,12 @@ impl Example for App {
&root_space_and_clip,
mask,
);
let clip_id = builder.define_clip(
let clip_id = builder.define_clip_rounded_rect(
&SpaceAndClipInfo {
spatial_id: root_space_and_clip.spatial_id,
clip_id: mask_clip_id,
},
content_bounds,
vec![complex],
complex,
);
builder.push_rect(

Просмотреть файл

@ -1397,6 +1397,17 @@ impl<'a> SceneBuilder<'a> {
&image_mask,
);
}
DisplayItem::RoundedRectClip(ref info) => {
let parent_space = self.get_space(&info.parent_space_and_clip.spatial_id);
let current_offset = self.current_offset(parent_space);
self.add_rounded_rect_clip_node(
info.id,
&info.parent_space_and_clip,
&info.clip,
current_offset,
);
}
DisplayItem::RectClip(ref info) => {
let parent_space = self.get_space(&info.parent_space_and_clip.spatial_id);
let current_offset = self.current_offset(parent_space);
@ -2427,6 +2438,65 @@ impl<'a> SceneBuilder<'a> {
clip_chain_index
}
pub fn add_rounded_rect_clip_node(
&mut self,
new_node_id: ClipId,
space_and_clip: &SpaceAndClipInfo,
clip: &ComplexClipRegion,
current_offset: LayoutVector2D,
) -> ClipChainId {
// Add a new ClipNode - this is a ClipId that identifies a list of clip items,
// and the positioning node associated with those clip sources.
// Map from parent ClipId to existing clip-chain.
let parent_clip_chain_index = self.id_to_index_mapper.get_clip_chain_id(space_and_clip.clip_id);
// Map the ClipId for the positioning node to a spatial node index.
let spatial_node_index = self.id_to_index_mapper.get_spatial_node_index(space_and_clip.spatial_id);
let snap_to_device = &mut self.sc_stack.last_mut().unwrap().snap_to_device;
snap_to_device.set_target_spatial_node(
spatial_node_index,
&self.spatial_tree,
);
let snapped_region_rect = snap_to_device.snap_rect(&clip.rect.translate(current_offset));
let item = ClipItemKey {
kind: ClipItemKeyKind::rounded_rect(
snapped_region_rect,
clip.radii,
clip.mode,
),
spatial_node_index,
};
let handle = self
.interners
.clip
.intern(&item, || {
ClipInternData {
clip_node_kind: ClipNodeKind::Complex,
spatial_node_index,
}
});
let clip_chain_index = self
.clip_store
.add_clip_chain_node(
handle,
parent_clip_chain_index,
);
// Map the supplied ClipId -> clip chain id.
self.id_to_index_mapper.add_clip_chain(
new_node_id,
clip_chain_index,
1,
);
clip_chain_index
}
pub fn add_clip_node<I>(
&mut self,
new_node_id: ClipId,

Просмотреть файл

@ -137,6 +137,7 @@ pub enum DisplayItem {
// Clips
RectClip(RectClipDisplayItem),
RoundedRectClip(RoundedRectClipDisplayItem),
ImageMaskClip(ImageMaskClipDisplayItem),
Clip(ClipDisplayItem),
ClipChain(ClipChainItem),
@ -187,6 +188,7 @@ pub enum DebugDisplayItem {
BackdropFilter(BackdropFilterDisplayItem),
ImageMaskClip(ImageMaskClipDisplayItem),
RoundedRectClip(RoundedRectClipDisplayItem),
RectClip(RectClipDisplayItem),
Clip(ClipDisplayItem, Vec<ComplexClipRegion>),
ClipChain(ClipChainItem, Vec<ClipId>),
@ -221,6 +223,13 @@ pub struct RectClipDisplayItem {
pub clip_rect: LayoutRect,
}
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
pub struct RoundedRectClipDisplayItem {
pub id: ClipId,
pub parent_space_and_clip: SpaceAndClipInfo,
pub clip: ComplexClipRegion,
}
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
pub struct ClipDisplayItem {
pub id: ClipId,
@ -1483,6 +1492,7 @@ impl DisplayItem {
DisplayItem::ClearRectangle(..) => "clear_rectangle",
DisplayItem::HitTest(..) => "hit_test",
DisplayItem::RectClip(..) => "rect_clip",
DisplayItem::RoundedRectClip(..) => "rounded_rect_clip",
DisplayItem::ImageMaskClip(..) => "image_mask_clip",
DisplayItem::Clip(..) => "clip",
DisplayItem::ClipChain(..) => "clip_chain",

Просмотреть файл

@ -470,6 +470,7 @@ impl BuiltDisplayList {
item.iter.cur_stops.iter().collect()
),
Real::RectClip(v) => Debug::RectClip(v),
Real::RoundedRectClip(v) => Debug::RoundedRectClip(v),
Real::ImageMaskClip(v) => Debug::ImageMaskClip(v),
Real::StickyFrame(v) => Debug::StickyFrame(v),
Real::Rectangle(v) => Debug::Rectangle(v),
@ -891,6 +892,7 @@ impl<'de> Deserialize<'de> for BuiltDisplayList {
Real::SetGradientStops
},
Debug::RectClip(v) => Real::RectClip(v),
Debug::RoundedRectClip(v) => Real::RoundedRectClip(v),
Debug::ImageMaskClip(v) => Real::ImageMaskClip(v),
Debug::Rectangle(v) => Real::Rectangle(v),
Debug::ClearRectangle(v) => Real::ClearRectangle(v),
@ -1768,6 +1770,22 @@ impl DisplayListBuilder {
id
}
pub fn define_clip_rounded_rect(
&mut self,
parent_space_and_clip: &di::SpaceAndClipInfo,
clip: di::ComplexClipRegion,
) -> di::ClipId {
let id = self.generate_clip_index();
let item = di::DisplayItem::RoundedRectClip(di::RoundedRectClipDisplayItem {
id,
parent_space_and_clip: *parent_space_and_clip,
clip,
});
self.push_item(&item);
id
}
pub fn define_clip<I>(
&mut self,
parent_space_and_clip: &di::SpaceAndClipInfo,

Просмотреть файл

@ -1353,10 +1353,9 @@ impl<'a> RawtestHarness<'a> {
// Add a rectangle that is clipped by a rounded rect clip item.
let rect = LayoutRect::new(LayoutPoint::new(100., 100.), LayoutSize::new(100., 100.));
let temp_clip_id = builder.define_clip(
let temp_clip_id = builder.define_clip_rounded_rect(
&space_and_clip,
rect,
vec![make_rounded_complex_clip(&rect, 20.)],
make_rounded_complex_clip(&rect, 20.),
);
builder.push_rect(
&CommonItemProperties {
@ -1372,10 +1371,9 @@ impl<'a> RawtestHarness<'a> {
// Add a rectangle that is clipped by a ClipChain containing a rounded rect.
let rect = LayoutRect::new(LayoutPoint::new(200., 100.), LayoutSize::new(100., 100.));
let clip_id = builder.define_clip(
let clip_id = builder.define_clip_rounded_rect(
&space_and_clip,
rect,
vec![make_rounded_complex_clip(&rect, 20.)],
make_rounded_complex_clip(&rect, 20.),
);
let clip_chain_id = builder.define_clip_chain(None, vec![clip_id]);
builder.push_rect(

Просмотреть файл

@ -1705,10 +1705,9 @@ impl YamlFrameReader {
match item_type {
"clip" | "clip-chain" | "scroll-frame" => {},
_ => {
let id = dl.define_clip(
let id = dl.define_clip_rounded_rect(
&self.top_space_and_clip(),
clip_rect,
vec![complex_clip],
complex_clip,
);
self.clip_id_stack.push(id);
pushed_clip = true;
@ -1958,11 +1957,17 @@ impl YamlFrameReader {
}
fn handle_clip(&mut self, dl: &mut DisplayListBuilder, wrench: &mut Wrench, yaml: &Yaml) {
let clip_rect = yaml["bounds"].as_rect().expect("clip must have a bounds");
let numeric_id = yaml["id"].as_i64();
let complex_clips = self.to_complex_clip_regions(&yaml["complex"]);
let mut space_and_clip = self.top_space_and_clip();
if let Some(clip_rect) = yaml["bounds"].as_rect() {
space_and_clip.clip_id = dl.define_clip_rect(
&space_and_clip,
clip_rect,
);
}
if let Some(image_mask) = self.to_image_mask(&yaml["image-mask"], wrench) {
space_and_clip.clip_id = dl.define_clip_image_mask(
&space_and_clip,
@ -1970,18 +1975,20 @@ impl YamlFrameReader {
);
}
let real_id = dl.define_clip(
&space_and_clip,
clip_rect,
complex_clips,
);
for complex_clip in complex_clips {
space_and_clip.clip_id = dl.define_clip_rounded_rect(
&space_and_clip,
complex_clip,
);
}
if let Some(numeric_id) = numeric_id {
self.add_clip_id_mapping(numeric_id as u64, real_id);
self.add_clip_id_mapping(numeric_id as u64, space_and_clip.clip_id);
self.add_spatial_id_mapping(numeric_id as u64, space_and_clip.spatial_id);
}
if !yaml["items"].is_badvalue() {
self.clip_id_stack.push(real_id);
self.clip_id_stack.push(space_and_clip.clip_id);
self.add_display_list_items_from_yaml(dl, wrench, &yaml["items"]);
self.clip_id_stack.pop().unwrap();
}