mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
gfx: Eagerly transform clips into ClippingRegion::max()
if possible.
This helps WebRender look for useless clips and optimize them out.
This commit is contained in:
parent
238a8786de
commit
3103b03262
2 changed files with 51 additions and 36 deletions
|
@ -984,12 +984,19 @@ pub struct BaseDisplayItem {
|
||||||
|
|
||||||
impl BaseDisplayItem {
|
impl BaseDisplayItem {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(bounds: Rect<Au>, metadata: DisplayItemMetadata, clip: ClippingRegion)
|
pub fn new(bounds: &Rect<Au>, metadata: DisplayItemMetadata, clip: &ClippingRegion)
|
||||||
-> BaseDisplayItem {
|
-> BaseDisplayItem {
|
||||||
|
// Detect useless clipping regions here and optimize them to `ClippingRegion::max()`.
|
||||||
|
// The painting backend may want to optimize out clipping regions and this makes it easier
|
||||||
|
// for it to do so.
|
||||||
BaseDisplayItem {
|
BaseDisplayItem {
|
||||||
bounds: bounds,
|
bounds: *bounds,
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
clip: clip,
|
clip: if clip.does_not_clip_rect(bounds) {
|
||||||
|
ClippingRegion::max()
|
||||||
|
} else {
|
||||||
|
(*clip).clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1083,6 +1090,14 @@ impl ClippingRegion {
|
||||||
self.complex.iter().all(|complex| complex.rect.intersects(rect))
|
self.complex.iter().all(|complex| complex.rect.intersects(rect))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if this clipping region completely surrounds the given rect.
|
||||||
|
#[inline]
|
||||||
|
pub fn does_not_clip_rect(&self, rect: &Rect<Au>) -> bool {
|
||||||
|
self.main.contains(&rect.origin) && self.main.contains(&rect.bottom_right()) &&
|
||||||
|
self.complex.iter().all(|complex| {
|
||||||
|
complex.rect.contains(&rect.origin) && complex.rect.contains(&rect.bottom_right())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a bounding rect that surrounds this entire clipping region.
|
/// Returns a bounding rect that surrounds this entire clipping region.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -318,11 +318,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
display_list.push(DisplayItem::SolidColorClass(box SolidColorDisplayItem {
|
display_list.push(DisplayItem::SolidColorClass(box SolidColorDisplayItem {
|
||||||
base: BaseDisplayItem::new(bounds,
|
base: BaseDisplayItem::new(&bounds,
|
||||||
DisplayItemMetadata::new(self.node,
|
DisplayItemMetadata::new(self.node,
|
||||||
style,
|
style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
clip.clone()),
|
&clip),
|
||||||
color: background_color.to_gfx_color(),
|
color: background_color.to_gfx_color(),
|
||||||
}), level);
|
}), level);
|
||||||
|
|
||||||
|
@ -505,11 +505,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
// Create the image display item.
|
// Create the image display item.
|
||||||
display_list.push(DisplayItem::ImageClass(box ImageDisplayItem {
|
display_list.push(DisplayItem::ImageClass(box ImageDisplayItem {
|
||||||
base: BaseDisplayItem::new(bounds,
|
base: BaseDisplayItem::new(&bounds,
|
||||||
DisplayItemMetadata::new(self.node,
|
DisplayItemMetadata::new(self.node,
|
||||||
style,
|
style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
clip),
|
&clip),
|
||||||
image: image.clone(),
|
image: image.clone(),
|
||||||
stretch_size: Size2D::new(image_size.width, image_size.height),
|
stretch_size: Size2D::new(image_size.width, image_size.height),
|
||||||
image_rendering: style.get_effects().image_rendering.clone(),
|
image_rendering: style.get_effects().image_rendering.clone(),
|
||||||
|
@ -623,11 +623,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
absolute_bounds.origin.y + absolute_bounds.size.height / 2);
|
absolute_bounds.origin.y + absolute_bounds.size.height / 2);
|
||||||
|
|
||||||
let gradient_display_item = DisplayItem::GradientClass(box GradientDisplayItem {
|
let gradient_display_item = DisplayItem::GradientClass(box GradientDisplayItem {
|
||||||
base: BaseDisplayItem::new(*absolute_bounds,
|
base: BaseDisplayItem::new(absolute_bounds,
|
||||||
DisplayItemMetadata::new(self.node,
|
DisplayItemMetadata::new(self.node,
|
||||||
style,
|
style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
clip),
|
&clip),
|
||||||
start_point: center - delta,
|
start_point: center - delta,
|
||||||
end_point: center + delta,
|
end_point: center + delta,
|
||||||
stops: stops,
|
stops: stops,
|
||||||
|
@ -653,11 +653,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
// TODO(pcwalton): Multiple border radii; elliptical border radii.
|
// TODO(pcwalton): Multiple border radii; elliptical border radii.
|
||||||
list.push(DisplayItem::BoxShadowClass(box BoxShadowDisplayItem {
|
list.push(DisplayItem::BoxShadowClass(box BoxShadowDisplayItem {
|
||||||
base: BaseDisplayItem::new(bounds,
|
base: BaseDisplayItem::new(&bounds,
|
||||||
DisplayItemMetadata::new(self.node,
|
DisplayItemMetadata::new(self.node,
|
||||||
style,
|
style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
(*clip).clone()),
|
clip),
|
||||||
box_bounds: *absolute_bounds,
|
box_bounds: *absolute_bounds,
|
||||||
color: style.resolve_color(box_shadow.color).to_gfx_color(),
|
color: style.resolve_color(box_shadow.color).to_gfx_color(),
|
||||||
offset: Point2D::new(box_shadow.offset_x, box_shadow.offset_y),
|
offset: Point2D::new(box_shadow.offset_x, box_shadow.offset_y),
|
||||||
|
@ -724,11 +724,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
// Append the border to the display list.
|
// Append the border to the display list.
|
||||||
display_list.push(DisplayItem::BorderClass(box BorderDisplayItem {
|
display_list.push(DisplayItem::BorderClass(box BorderDisplayItem {
|
||||||
base: BaseDisplayItem::new(bounds,
|
base: BaseDisplayItem::new(&bounds,
|
||||||
DisplayItemMetadata::new(self.node,
|
DisplayItemMetadata::new(self.node,
|
||||||
style,
|
style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
(*clip).clone()),
|
clip),
|
||||||
border_widths: border.to_physical(style.writing_mode),
|
border_widths: border.to_physical(style.writing_mode),
|
||||||
color: SideOffsets2D::new(colors.top.to_gfx_color(),
|
color: SideOffsets2D::new(colors.top.to_gfx_color(),
|
||||||
colors.right.to_gfx_color(),
|
colors.right.to_gfx_color(),
|
||||||
|
@ -766,11 +766,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
// Append the outline to the display list.
|
// Append the outline to the display list.
|
||||||
let color = style.resolve_color(style.get_outline().outline_color).to_gfx_color();
|
let color = style.resolve_color(style.get_outline().outline_color).to_gfx_color();
|
||||||
display_list.outlines.push_back(DisplayItem::BorderClass(box BorderDisplayItem {
|
display_list.outlines.push_back(DisplayItem::BorderClass(box BorderDisplayItem {
|
||||||
base: BaseDisplayItem::new(bounds,
|
base: BaseDisplayItem::new(&bounds,
|
||||||
DisplayItemMetadata::new(self.node,
|
DisplayItemMetadata::new(self.node,
|
||||||
style,
|
style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
(*clip).clone()),
|
clip),
|
||||||
border_widths: SideOffsets2D::new_all_same(width),
|
border_widths: SideOffsets2D::new_all_same(width),
|
||||||
color: SideOffsets2D::new_all_same(color),
|
color: SideOffsets2D::new_all_same(color),
|
||||||
style: SideOffsets2D::new_all_same(outline_style),
|
style: SideOffsets2D::new_all_same(outline_style),
|
||||||
|
@ -790,11 +790,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
// Compute the text fragment bounds and draw a border surrounding them.
|
// Compute the text fragment bounds and draw a border surrounding them.
|
||||||
display_list.content.push_back(DisplayItem::BorderClass(box BorderDisplayItem {
|
display_list.content.push_back(DisplayItem::BorderClass(box BorderDisplayItem {
|
||||||
base: BaseDisplayItem::new(*stacking_relative_border_box,
|
base: BaseDisplayItem::new(stacking_relative_border_box,
|
||||||
DisplayItemMetadata::new(self.node,
|
DisplayItemMetadata::new(self.node,
|
||||||
style,
|
style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
(*clip).clone()),
|
clip),
|
||||||
border_widths: SideOffsets2D::new_all_same(Au::from_px(1)),
|
border_widths: SideOffsets2D::new_all_same(Au::from_px(1)),
|
||||||
color: SideOffsets2D::new_all_same(color::rgb(0, 0, 200)),
|
color: SideOffsets2D::new_all_same(color::rgb(0, 0, 200)),
|
||||||
style: SideOffsets2D::new_all_same(border_style::T::solid),
|
style: SideOffsets2D::new_all_same(border_style::T::solid),
|
||||||
|
@ -810,11 +810,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let baseline = baseline.to_physical(self.style.writing_mode, container_size);
|
let baseline = baseline.to_physical(self.style.writing_mode, container_size);
|
||||||
|
|
||||||
let line_display_item = box LineDisplayItem {
|
let line_display_item = box LineDisplayItem {
|
||||||
base: BaseDisplayItem::new(baseline,
|
base: BaseDisplayItem::new(&baseline,
|
||||||
DisplayItemMetadata::new(self.node,
|
DisplayItemMetadata::new(self.node,
|
||||||
style,
|
style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
(*clip).clone()),
|
clip),
|
||||||
color: color::rgb(0, 200, 0),
|
color: color::rgb(0, 200, 0),
|
||||||
style: border_style::T::dashed,
|
style: border_style::T::dashed,
|
||||||
};
|
};
|
||||||
|
@ -827,11 +827,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
clip: &ClippingRegion) {
|
clip: &ClippingRegion) {
|
||||||
// This prints a debug border around the border of this fragment.
|
// This prints a debug border around the border of this fragment.
|
||||||
display_list.content.push_back(DisplayItem::BorderClass(box BorderDisplayItem {
|
display_list.content.push_back(DisplayItem::BorderClass(box BorderDisplayItem {
|
||||||
base: BaseDisplayItem::new(*stacking_relative_border_box,
|
base: BaseDisplayItem::new(stacking_relative_border_box,
|
||||||
DisplayItemMetadata::new(self.node,
|
DisplayItemMetadata::new(self.node,
|
||||||
&*self.style,
|
&*self.style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
(*clip).clone()),
|
clip),
|
||||||
border_widths: SideOffsets2D::new_all_same(Au::from_px(1)),
|
border_widths: SideOffsets2D::new_all_same(Au::from_px(1)),
|
||||||
color: SideOffsets2D::new_all_same(color::rgb(0, 0, 200)),
|
color: SideOffsets2D::new_all_same(color::rgb(0, 0, 200)),
|
||||||
style: SideOffsets2D::new_all_same(border_style::T::solid),
|
style: SideOffsets2D::new_all_same(border_style::T::solid),
|
||||||
|
@ -896,9 +896,9 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
};
|
};
|
||||||
|
|
||||||
display_list.push(DisplayItem::SolidColorClass(box SolidColorDisplayItem {
|
display_list.push(DisplayItem::SolidColorClass(box SolidColorDisplayItem {
|
||||||
base: BaseDisplayItem::new(insertion_point_bounds,
|
base: BaseDisplayItem::new(&insertion_point_bounds,
|
||||||
DisplayItemMetadata::new(self.node, &*self.style, cursor),
|
DisplayItemMetadata::new(self.node, &*self.style, cursor),
|
||||||
clip.clone()),
|
&clip),
|
||||||
color: self.style().get_color().color.to_gfx_color(),
|
color: self.style().get_color().color.to_gfx_color(),
|
||||||
}), level);
|
}), level);
|
||||||
}
|
}
|
||||||
|
@ -1100,11 +1100,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let layer_id = self.layer_id();
|
let layer_id = self.layer_id();
|
||||||
display_list.content.push_back(DisplayItem::LayeredItemClass(box LayeredItem {
|
display_list.content.push_back(DisplayItem::LayeredItemClass(box LayeredItem {
|
||||||
item: DisplayItem::NoopClass(
|
item: DisplayItem::NoopClass(
|
||||||
box BaseDisplayItem::new(stacking_relative_content_box,
|
box BaseDisplayItem::new(&stacking_relative_content_box,
|
||||||
DisplayItemMetadata::new(self.node,
|
DisplayItemMetadata::new(self.node,
|
||||||
&*self.style,
|
&*self.style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
(*clip).clone())),
|
clip)),
|
||||||
layer_id: layer_id
|
layer_id: layer_id
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -1117,11 +1117,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
// Place the image into the display list.
|
// Place the image into the display list.
|
||||||
if let Some(ref image) = image_fragment.image {
|
if let Some(ref image) = image_fragment.image {
|
||||||
display_list.content.push_back(DisplayItem::ImageClass(box ImageDisplayItem {
|
display_list.content.push_back(DisplayItem::ImageClass(box ImageDisplayItem {
|
||||||
base: BaseDisplayItem::new(stacking_relative_content_box,
|
base: BaseDisplayItem::new(&stacking_relative_content_box,
|
||||||
DisplayItemMetadata::new(self.node,
|
DisplayItemMetadata::new(self.node,
|
||||||
&*self.style,
|
&*self.style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
(*clip).clone()),
|
clip),
|
||||||
image: image.clone(),
|
image: image.clone(),
|
||||||
stretch_size: stacking_relative_content_box.size,
|
stretch_size: stacking_relative_content_box.size,
|
||||||
image_rendering: self.style.get_effects().image_rendering.clone(),
|
image_rendering: self.style.get_effects().image_rendering.clone(),
|
||||||
|
@ -1153,11 +1153,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
None => IpcSharedMemory::from_byte(0xFFu8, width * height * 4),
|
None => IpcSharedMemory::from_byte(0xFFu8, width * height * 4),
|
||||||
};
|
};
|
||||||
let display_item = DisplayItem::ImageClass(box ImageDisplayItem {
|
let display_item = DisplayItem::ImageClass(box ImageDisplayItem {
|
||||||
base: BaseDisplayItem::new(stacking_relative_content_box,
|
base: BaseDisplayItem::new(&stacking_relative_content_box,
|
||||||
DisplayItemMetadata::new(self.node,
|
DisplayItemMetadata::new(self.node,
|
||||||
&*self.style,
|
&*self.style,
|
||||||
Cursor::DefaultCursor),
|
Cursor::DefaultCursor),
|
||||||
(*clip).clone()),
|
clip),
|
||||||
image: Arc::new(Image {
|
image: Arc::new(Image {
|
||||||
width: width as u32,
|
width: width as u32,
|
||||||
height: height as u32,
|
height: height as u32,
|
||||||
|
@ -1411,9 +1411,9 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
// Create the text display item.
|
// Create the text display item.
|
||||||
display_list.content.push_back(DisplayItem::TextClass(box TextDisplayItem {
|
display_list.content.push_back(DisplayItem::TextClass(box TextDisplayItem {
|
||||||
base: BaseDisplayItem::new(stacking_relative_content_box,
|
base: BaseDisplayItem::new(&stacking_relative_content_box,
|
||||||
DisplayItemMetadata::new(self.node, self.style(), cursor),
|
DisplayItemMetadata::new(self.node, self.style(), cursor),
|
||||||
(*clip).clone()),
|
clip),
|
||||||
text_run: text_fragment.run.clone(),
|
text_run: text_fragment.run.clone(),
|
||||||
range: text_fragment.range,
|
range: text_fragment.range,
|
||||||
text_color: text_color.to_gfx_color(),
|
text_color: text_color.to_gfx_color(),
|
||||||
|
@ -1488,9 +1488,9 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
container_size);
|
container_size);
|
||||||
let metadata = DisplayItemMetadata::new(self.node, &*self.style, Cursor::DefaultCursor);
|
let metadata = DisplayItemMetadata::new(self.node, &*self.style, Cursor::DefaultCursor);
|
||||||
display_list.content.push_back(DisplayItem::BoxShadowClass(box BoxShadowDisplayItem {
|
display_list.content.push_back(DisplayItem::BoxShadowClass(box BoxShadowDisplayItem {
|
||||||
base: BaseDisplayItem::new(shadow_bounds(&stacking_relative_box, blur_radius, Au(0)),
|
base: BaseDisplayItem::new(&shadow_bounds(&stacking_relative_box, blur_radius, Au(0)),
|
||||||
metadata,
|
metadata,
|
||||||
(*clip).clone()),
|
clip),
|
||||||
box_bounds: stacking_relative_box,
|
box_bounds: stacking_relative_box,
|
||||||
color: color.to_gfx_color(),
|
color: color.to_gfx_color(),
|
||||||
offset: Point2D::zero(),
|
offset: Point2D::zero(),
|
||||||
|
@ -1907,13 +1907,13 @@ impl BaseFlowDisplayListBuilding for BaseFlow {
|
||||||
let mut color = THREAD_TINT_COLORS[thread_id as usize % THREAD_TINT_COLORS.len()];
|
let mut color = THREAD_TINT_COLORS[thread_id as usize % THREAD_TINT_COLORS.len()];
|
||||||
color.a = 1.0;
|
color.a = 1.0;
|
||||||
display_list.push(DisplayItem::BorderClass(box BorderDisplayItem {
|
display_list.push(DisplayItem::BorderClass(box BorderDisplayItem {
|
||||||
base: BaseDisplayItem::new(stacking_context_relative_bounds.inflate(Au::from_px(2),
|
base: BaseDisplayItem::new(&stacking_context_relative_bounds.inflate(Au::from_px(2),
|
||||||
Au::from_px(2)),
|
Au::from_px(2)),
|
||||||
DisplayItemMetadata {
|
DisplayItemMetadata {
|
||||||
node: node,
|
node: node,
|
||||||
pointing: None,
|
pointing: None,
|
||||||
},
|
},
|
||||||
self.clip.clone()),
|
&self.clip),
|
||||||
border_widths: SideOffsets2D::new_all_same(Au::from_px(2)),
|
border_widths: SideOffsets2D::new_all_same(Au::from_px(2)),
|
||||||
color: SideOffsets2D::new_all_same(color),
|
color: SideOffsets2D::new_all_same(color),
|
||||||
style: SideOffsets2D::new_all_same(border_style::T::solid),
|
style: SideOffsets2D::new_all_same(border_style::T::solid),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue