aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/gfx/display_list/mod.rs21
-rw-r--r--components/layout/display_list_builder.rs66
2 files changed, 51 insertions, 36 deletions
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs
index 9763e882585..69b611a0919 100644
--- a/components/gfx/display_list/mod.rs
+++ b/components/gfx/display_list/mod.rs
@@ -984,12 +984,19 @@ pub struct BaseDisplayItem {
impl BaseDisplayItem {
#[inline(always)]
- pub fn new(bounds: Rect<Au>, metadata: DisplayItemMetadata, clip: ClippingRegion)
+ pub fn new(bounds: &Rect<Au>, metadata: DisplayItemMetadata, clip: &ClippingRegion)
-> 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 {
- bounds: bounds,
+ bounds: *bounds,
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))
}
+ /// 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.
#[inline]
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 7cc1d3f6311..26bffec5031 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -318,11 +318,11 @@ impl FragmentDisplayListBuilding for Fragment {
}
display_list.push(DisplayItem::SolidColorClass(box SolidColorDisplayItem {
- base: BaseDisplayItem::new(bounds,
+ base: BaseDisplayItem::new(&bounds,
DisplayItemMetadata::new(self.node,
style,
Cursor::DefaultCursor),
- clip.clone()),
+ &clip),
color: background_color.to_gfx_color(),
}), level);
@@ -505,11 +505,11 @@ impl FragmentDisplayListBuilding for Fragment {
// Create the image display item.
display_list.push(DisplayItem::ImageClass(box ImageDisplayItem {
- base: BaseDisplayItem::new(bounds,
+ base: BaseDisplayItem::new(&bounds,
DisplayItemMetadata::new(self.node,
style,
Cursor::DefaultCursor),
- clip),
+ &clip),
image: image.clone(),
stretch_size: Size2D::new(image_size.width, image_size.height),
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);
let gradient_display_item = DisplayItem::GradientClass(box GradientDisplayItem {
- base: BaseDisplayItem::new(*absolute_bounds,
+ base: BaseDisplayItem::new(absolute_bounds,
DisplayItemMetadata::new(self.node,
style,
Cursor::DefaultCursor),
- clip),
+ &clip),
start_point: center - delta,
end_point: center + delta,
stops: stops,
@@ -653,11 +653,11 @@ impl FragmentDisplayListBuilding for Fragment {
// TODO(pcwalton): Multiple border radii; elliptical border radii.
list.push(DisplayItem::BoxShadowClass(box BoxShadowDisplayItem {
- base: BaseDisplayItem::new(bounds,
+ base: BaseDisplayItem::new(&bounds,
DisplayItemMetadata::new(self.node,
style,
Cursor::DefaultCursor),
- (*clip).clone()),
+ clip),
box_bounds: *absolute_bounds,
color: style.resolve_color(box_shadow.color).to_gfx_color(),
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.
display_list.push(DisplayItem::BorderClass(box BorderDisplayItem {
- base: BaseDisplayItem::new(bounds,
+ base: BaseDisplayItem::new(&bounds,
DisplayItemMetadata::new(self.node,
style,
Cursor::DefaultCursor),
- (*clip).clone()),
+ clip),
border_widths: border.to_physical(style.writing_mode),
color: SideOffsets2D::new(colors.top.to_gfx_color(),
colors.right.to_gfx_color(),
@@ -766,11 +766,11 @@ impl FragmentDisplayListBuilding for Fragment {
// Append the outline to the display list.
let color = style.resolve_color(style.get_outline().outline_color).to_gfx_color();
display_list.outlines.push_back(DisplayItem::BorderClass(box BorderDisplayItem {
- base: BaseDisplayItem::new(bounds,
+ base: BaseDisplayItem::new(&bounds,
DisplayItemMetadata::new(self.node,
style,
Cursor::DefaultCursor),
- (*clip).clone()),
+ clip),
border_widths: SideOffsets2D::new_all_same(width),
color: SideOffsets2D::new_all_same(color),
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.
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,
style,
Cursor::DefaultCursor),
- (*clip).clone()),
+ clip),
border_widths: SideOffsets2D::new_all_same(Au::from_px(1)),
color: SideOffsets2D::new_all_same(color::rgb(0, 0, 200)),
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 line_display_item = box LineDisplayItem {
- base: BaseDisplayItem::new(baseline,
+ base: BaseDisplayItem::new(&baseline,
DisplayItemMetadata::new(self.node,
style,
Cursor::DefaultCursor),
- (*clip).clone()),
+ clip),
color: color::rgb(0, 200, 0),
style: border_style::T::dashed,
};
@@ -827,11 +827,11 @@ impl FragmentDisplayListBuilding for Fragment {
clip: &ClippingRegion) {
// This prints a debug border around the border of this fragment.
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,
&*self.style,
Cursor::DefaultCursor),
- (*clip).clone()),
+ clip),
border_widths: SideOffsets2D::new_all_same(Au::from_px(1)),
color: SideOffsets2D::new_all_same(color::rgb(0, 0, 200)),
style: SideOffsets2D::new_all_same(border_style::T::solid),
@@ -896,9 +896,9 @@ impl FragmentDisplayListBuilding for Fragment {
};
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),
- clip.clone()),
+ &clip),
color: self.style().get_color().color.to_gfx_color(),
}), level);
}
@@ -1100,11 +1100,11 @@ impl FragmentDisplayListBuilding for Fragment {
let layer_id = self.layer_id();
display_list.content.push_back(DisplayItem::LayeredItemClass(box LayeredItem {
item: DisplayItem::NoopClass(
- box BaseDisplayItem::new(stacking_relative_content_box,
+ box BaseDisplayItem::new(&stacking_relative_content_box,
DisplayItemMetadata::new(self.node,
&*self.style,
Cursor::DefaultCursor),
- (*clip).clone())),
+ clip)),
layer_id: layer_id
}));
@@ -1117,11 +1117,11 @@ impl FragmentDisplayListBuilding for Fragment {
// Place the image into the display list.
if let Some(ref image) = image_fragment.image {
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,
&*self.style,
Cursor::DefaultCursor),
- (*clip).clone()),
+ clip),
image: image.clone(),
stretch_size: stacking_relative_content_box.size,
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),
};
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,
&*self.style,
Cursor::DefaultCursor),
- (*clip).clone()),
+ clip),
image: Arc::new(Image {
width: width as u32,
height: height as u32,
@@ -1411,9 +1411,9 @@ impl FragmentDisplayListBuilding for Fragment {
// Create the text display item.
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),
- (*clip).clone()),
+ clip),
text_run: text_fragment.run.clone(),
range: text_fragment.range,
text_color: text_color.to_gfx_color(),
@@ -1488,9 +1488,9 @@ impl FragmentDisplayListBuilding for Fragment {
container_size);
let metadata = DisplayItemMetadata::new(self.node, &*self.style, Cursor::DefaultCursor);
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,
- (*clip).clone()),
+ clip),
box_bounds: stacking_relative_box,
color: color.to_gfx_color(),
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()];
color.a = 1.0;
display_list.push(DisplayItem::BorderClass(box BorderDisplayItem {
- base: BaseDisplayItem::new(stacking_context_relative_bounds.inflate(Au::from_px(2),
- Au::from_px(2)),
+ base: BaseDisplayItem::new(&stacking_context_relative_bounds.inflate(Au::from_px(2),
+ Au::from_px(2)),
DisplayItemMetadata {
node: node,
pointing: None,
},
- self.clip.clone()),
+ &self.clip),
border_widths: SideOffsets2D::new_all_same(Au::from_px(2)),
color: SideOffsets2D::new_all_same(color),
style: SideOffsets2D::new_all_same(border_style::T::solid),