Skip to content

Commit

Permalink
No longer allow clipping items by complex clips
Browse files Browse the repository at this point in the history
This is part of an API simplification which should hopefully lead to
less code complexity in the future.

Fixes #1742.
  • Loading branch information
mrobinson committed Mar 13, 2018
1 parent 1de1c0c commit 1828236
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 157 deletions.
10 changes: 1 addition & 9 deletions direct-composition/src/main_windows.rs
Expand Up @@ -131,15 +131,7 @@ impl Rectangle {
let mut builder = api::DisplayListBuilder::new(pipeline_id, layout_size);

let rect = euclid::TypedRect::new(euclid::TypedPoint2D::zero(), layout_size);
builder.push_rect(
&api::PrimitiveInfo::with_clip(
rect,
api::LocalClip::RoundedRect(rect, api::ComplexClipRegion::new(
rect, api::BorderRadius::uniform(20.), api::ClipMode::Clip,
))
),
self.color,
);
builder.push_rect(&api::PrimitiveInfo::new(rect), self.color);

let mut transaction = api::Transaction::new();
transaction.set_display_list(
Expand Down
5 changes: 1 addition & 4 deletions webrender/examples/alpha_perf.rs
Expand Up @@ -29,10 +29,7 @@ impl Example for App {
_document_id: DocumentId,
) {
let bounds = (0, 0).to(1920, 1080);
let info = LayoutPrimitiveInfo {
local_clip: LocalClip::Rect(bounds),
.. LayoutPrimitiveInfo::new(bounds)
};
let info = LayoutPrimitiveInfo::new(bounds);

builder.push_stacking_context(
&info,
Expand Down
20 changes: 11 additions & 9 deletions webrender/examples/animation.rs
Expand Up @@ -41,20 +41,12 @@ impl Example for App {
) {
// Create a 200x200 stacking context with an animated transform property.
let bounds = (0, 0).to(200, 200);
let complex_clip = ComplexClipRegion {
rect: bounds,
radii: BorderRadius::uniform(50.0),
mode: ClipMode::Clip,
};
let info = LayoutPrimitiveInfo {
local_clip: LocalClip::RoundedRect(bounds, complex_clip),
.. LayoutPrimitiveInfo::new(bounds)
};

let filters = vec![
FilterOp::Opacity(PropertyBinding::Binding(self.opacity_key), self.opacity),
];

let info = LayoutPrimitiveInfo::new(bounds);
builder.push_stacking_context(
&info,
ScrollPolicy::Scrollable,
Expand All @@ -65,9 +57,19 @@ impl Example for App {
filters,
);

let complex_clip = ComplexClipRegion {
rect: bounds,
radii: BorderRadius::uniform(50.0),
mode: ClipMode::Clip,
};
let clip_id = builder.define_clip(bounds, vec![complex_clip], None);
builder.push_clip_id(clip_id);

// Fill it with a white rect
builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0));

builder.pop_clip_id();

builder.pop_stacking_context();
}

Expand Down
42 changes: 9 additions & 33 deletions webrender/src/box_shadow.rs
Expand Up @@ -2,9 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use api::{BorderRadius, BoxShadowClipMode, ClipMode, ColorF, ComplexClipRegion};
use api::{LayerPrimitiveInfo, LayerRect, LayerSize, LayerVector2D, LayoutSize, LocalClip};
use api::{DeviceIntSize};
use api::{BorderRadius, BoxShadowClipMode, ClipMode, ColorF, DeviceIntSize, LayerPrimitiveInfo};
use api::{LayerRect, LayerSize, LayerVector2D, LayoutSize};
use clip::ClipSource;
use display_list_flattener::DisplayListFlattener;
use gpu_cache::GpuCacheHandle;
Expand Down Expand Up @@ -113,9 +112,7 @@ impl<'a> DisplayListFlattener<'a> {
}

let mut clips = Vec::with_capacity(2);
clips.push(ClipSource::Rectangle(*prim_info.local_clip.clip_rect()));

let fast_info = match clip_mode {
let (final_prim_rect, clip_radius) = match clip_mode {
BoxShadowClipMode::Outset => {
if !shadow_rect.is_well_formed_and_nonempty() {
return;
Expand All @@ -128,17 +125,7 @@ impl<'a> DisplayListFlattener<'a> {
ClipMode::ClipOut
));

LayerPrimitiveInfo::with_clip(
shadow_rect,
LocalClip::RoundedRect(
shadow_rect,
ComplexClipRegion::new(
shadow_rect,
shadow_radius,
ClipMode::Clip,
),
),
)
(shadow_rect, shadow_radius)
}
BoxShadowClipMode::Inset => {
if shadow_rect.is_well_formed_and_nonempty() {
Expand All @@ -149,23 +136,15 @@ impl<'a> DisplayListFlattener<'a> {
));
}

LayerPrimitiveInfo::with_clip(
prim_info.rect,
LocalClip::RoundedRect(
prim_info.rect,
ComplexClipRegion::new(
prim_info.rect,
border_radius,
ClipMode::Clip
),
),
)
(prim_info.rect, border_radius)
}
};

clips.push(ClipSource::new_rounded_rect(final_prim_rect, clip_radius, ClipMode::Clip));

self.add_primitive(
clip_and_scroll,
&fast_info,
&LayerPrimitiveInfo::with_clip_rect(final_prim_rect, prim_info.clip_rect),
clips,
PrimitiveContainer::Brush(
BrushPrimitive::new(BrushKind::Solid {
Expand Down Expand Up @@ -222,10 +201,7 @@ impl<'a> DisplayListFlattener<'a> {

// Outset shadows are expanded by the shadow
// region from the original primitive.
LayerPrimitiveInfo::with_clip_rect(
dest_rect,
*prim_info.local_clip.clip_rect()
)
LayerPrimitiveInfo::with_clip_rect(dest_rect, prim_info.clip_rect)
}
BoxShadowClipMode::Inset => {
// If the inner shadow rect contains the prim
Expand Down
31 changes: 5 additions & 26 deletions webrender/src/clip.rs
Expand Up @@ -421,32 +421,11 @@ impl From<LayerRect> for Geometry {
}
}

pub trait Contains {
fn contains(&self, point: &LayoutPoint) -> bool;
}

impl Contains for LocalClip {
fn contains(&self, point: &LayoutPoint) -> bool {
if !self.clip_rect().contains(point) {
return false;
}
match self {
&LocalClip::Rect(..) => true,
&LocalClip::RoundedRect(_, complex_clip) => complex_clip.contains(point),
}
}
}

impl Contains for ComplexClipRegion {
fn contains(&self, point: &LayoutPoint) -> bool {
rounded_rectangle_contains_point(point, &self.rect, &self.radii)
}
}

pub fn rounded_rectangle_contains_point(point: &LayoutPoint,
rect: &LayerRect,
radii: &BorderRadius)
-> bool {
pub fn rounded_rectangle_contains_point(
point: &LayoutPoint,
rect: &LayerRect,
radii: &BorderRadius
) -> bool {
if !rect.contains(point) {
return false;
}
Expand Down
57 changes: 22 additions & 35 deletions webrender/src/display_list_flattener.rs
Expand Up @@ -3,17 +3,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter};
use api::{ClipAndScrollInfo, ClipId, ColorF, ComplexClipRegion, DeviceIntPoint, DeviceIntRect};
use api::{DeviceIntSize, DevicePixelScale, DeviceUintRect};
use api::{DisplayItemRef, Epoch, ExtendMode, ExternalScrollId, FilterOp};
use api::{FontInstanceKey, FontRenderMode, GlyphInstance, GlyphOptions, GradientStop};
use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, LayerPoint};
use api::{LayerPrimitiveInfo, LayerRect, LayerSize, LayerVector2D, LayoutSize, LayoutTransform};
use api::{LayoutVector2D, LineOrientation, LineStyle, LocalClip, PipelineId};
use api::{PropertyBinding, RepeatMode, ScrollFrameDisplayItem, ScrollPolicy, ScrollSensitivity};
use api::{Shadow, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, TexelRect};
use api::{TileOffset, TransformStyle, YuvColorSpace, YuvData};
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter, ClipAndScrollInfo};
use api::{ClipId, ColorF, ComplexClipRegion, DeviceIntPoint, DeviceIntRect, DeviceIntSize};
use api::{DevicePixelScale, DeviceUintRect, DisplayItemRef, Epoch, ExtendMode, ExternalScrollId};
use api::{FilterOp, FontInstanceKey, FontRenderMode, GlyphInstance, GlyphOptions, GradientStop};
use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, LayerPoint, LayerPrimitiveInfo};
use api::{LayerRect, LayerSize, LayerVector2D, LayoutRect, LayoutSize, LayoutTransform};
use api::{LayoutVector2D, LineOrientation, LineStyle, LocalClip, PipelineId, PropertyBinding};
use api::{RepeatMode, ScrollFrameDisplayItem, ScrollPolicy, ScrollSensitivity, Shadow};
use api::{SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, TexelRect, TileOffset};
use api::{TransformStyle, YuvColorSpace, YuvData};
use app_units::Au;
use border::ImageBorderSegment;
use clip::{ClipRegion, ClipSource, ClipSources, ClipStore};
Expand Down Expand Up @@ -442,7 +441,7 @@ impl<'a> DisplayListFlattener<'a> {
) {
let complex_clips = self.get_complex_clips(pipeline_id, item.complex_clip().0);
let clip_region = ClipRegion::create_for_clip_node(
*item.local_clip().clip_rect(),
*item.clip_rect(),
complex_clips,
info.image_mask,
&reference_frame_relative_offset,
Expand All @@ -451,9 +450,7 @@ impl<'a> DisplayListFlattener<'a> {
// This is useful when calculating scroll extents for the
// ClipScrollNode::scroll(..) API as well as for properly setting sticky
// positioning offsets.
let frame_rect = item.local_clip()
.clip_rect()
.translate(&reference_frame_relative_offset);
let frame_rect = item.clip_rect().translate(&reference_frame_relative_offset);
let content_rect = item.rect().translate(&reference_frame_relative_offset);

debug_assert!(info.clip_id != info.scroll_frame_id);
Expand Down Expand Up @@ -584,7 +581,7 @@ impl<'a> DisplayListFlattener<'a> {
info.clip_id,
clip_and_scroll_ids.scroll_node_id,
ClipRegion::create_for_clip_node_with_local_clip(
&item.local_clip(),
&LocalClip::from(*item.clip_rect()),
&reference_frame_relative_offset
),
);
Expand Down Expand Up @@ -804,7 +801,7 @@ impl<'a> DisplayListFlattener<'a> {
SpecificDisplayItem::Clip(ref info) => {
let complex_clips = self.get_complex_clips(pipeline_id, item.complex_clip().0);
let clip_region = ClipRegion::create_for_clip_node(
*item.local_clip().clip_rect(),
*item.clip_rect(),
complex_clips,
info.image_mask,
&reference_frame_relative_offset,
Expand Down Expand Up @@ -867,19 +864,9 @@ impl<'a> DisplayListFlattener<'a> {
pub fn create_primitive(
&mut self,
info: &LayerPrimitiveInfo,
mut clip_sources: Vec<ClipSource>,
clip_sources: Vec<ClipSource>,
container: PrimitiveContainer,
) -> PrimitiveIndex {
if let &LocalClip::RoundedRect(main, region) = &info.local_clip {
clip_sources.push(ClipSource::Rectangle(main));

clip_sources.push(ClipSource::new_rounded_rect(
region.rect,
region.radii,
region.mode,
));
}

let stacking_context = self.sc_stack.last().expect("bug: no stacking context!");

let clip_sources = if clip_sources.is_empty() {
Expand All @@ -890,7 +877,7 @@ impl<'a> DisplayListFlattener<'a> {

let prim_index = self.prim_store.add_primitive(
&info.rect,
&info.local_clip.clip_rect(),
&info.clip_rect,
info.is_backface_visible && stacking_context.is_backface_visible,
clip_sources,
info.tag,
Expand Down Expand Up @@ -1570,8 +1557,7 @@ impl<'a> DisplayListFlattener<'a> {
);
let mut info = info.clone();
info.rect = info.rect.translate(&shadow_offset);
info.local_clip =
LocalClip::from(info.local_clip.clip_rect().translate(&shadow_offset));
info.clip_rect = info.clip_rect.translate(&shadow_offset);
let prim_index = self.create_primitive(
&info,
Vec::new(),
Expand Down Expand Up @@ -2164,8 +2150,7 @@ impl<'a> DisplayListFlattener<'a> {
let rect = info.rect;
let mut info = info.clone();
info.rect = rect.translate(&text_prim.offset);
info.local_clip =
LocalClip::from(info.local_clip.clip_rect().translate(&text_prim.offset));
info.clip_rect = info.clip_rect.translate(&text_prim.offset);
let prim_index = self.create_primitive(
&info,
Vec::new(),
Expand Down Expand Up @@ -2383,7 +2368,9 @@ impl PrimitiveInfoTiler for LayerPrimitiveInfo {

if tile_repeat.width < self.rect.size.width ||
tile_repeat.height < self.rect.size.height {
let local_clip = self.local_clip.clip_by(&self.rect);
let clip_rect = self.clip_rect
.intersection(&self.rect)
.unwrap_or_else(LayoutRect::zero);
let rect_p0 = self.rect.origin;
let rect_p1 = self.rect.bottom_right();

Expand All @@ -2397,7 +2384,7 @@ impl PrimitiveInfoTiler for LayerPrimitiveInfo {
LayerPoint::new(x0, y0),
tile_size,
),
local_clip,
clip_rect,
is_backface_visible: self.is_backface_visible,
tag: self.tag,
});
Expand Down
11 changes: 6 additions & 5 deletions webrender/src/hit_test.rs
Expand Up @@ -3,8 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use api::{BorderRadius, ClipMode, HitTestFlags, HitTestItem, HitTestResult, ItemTag, LayerPoint};
use api::{LayerPrimitiveInfo, LayerRect, LocalClip, PipelineId, WorldPoint};
use clip::{ClipSource, ClipStore, Contains, rounded_rectangle_contains_point};
use api::{LayerPrimitiveInfo, LayerRect, PipelineId, WorldPoint};
use clip::{ClipSource, ClipStore, rounded_rectangle_contains_point};
use clip_scroll_node::{ClipScrollNode, NodeType};
use clip_scroll_tree::{ClipChainIndex, ClipScrollNodeIndex, ClipScrollTree};
use internal_types::FastHashMap;
Expand Down Expand Up @@ -55,15 +55,15 @@ impl HitTestClipChainDescriptor {
#[derive(Clone)]
pub struct HitTestingItem {
rect: LayerRect,
clip: LocalClip,
clip_rect: LayerRect,
tag: ItemTag,
}

impl HitTestingItem {
pub fn new(tag: ItemTag, info: &LayerPrimitiveInfo) -> HitTestingItem {
HitTestingItem {
rect: info.rect,
clip: info.local_clip,
clip_rect: info.clip_rect,
tag: tag,
}
}
Expand Down Expand Up @@ -239,7 +239,8 @@ impl HitTester {

let mut clipped_in = false;
for item in items.iter().rev() {
if !item.rect.contains(&point_in_layer) || !item.clip.contains(&point_in_layer) {
if !item.rect.contains(&point_in_layer) ||
!item.clip_rect.contains(&point_in_layer) {
continue;
}

Expand Down
10 changes: 3 additions & 7 deletions webrender_api/src/display_item.rs
Expand Up @@ -64,7 +64,7 @@ pub type DisplayItem = GenericDisplayItem<SpecificDisplayItem>;
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct PrimitiveInfo<T> {
pub rect: TypedRect<f32, T>,
pub local_clip: LocalClip,
pub clip_rect: TypedRect<f32, T>,
pub is_backface_visible: bool,
pub tag: Option<ItemTag>,
}
Expand All @@ -78,13 +78,9 @@ impl LayerPrimitiveInfo {
rect: TypedRect<f32, LayerPixel>,
clip_rect: TypedRect<f32, LayerPixel>,
) -> Self {
Self::with_clip(rect, LocalClip::from(clip_rect))
}

pub fn with_clip(rect: TypedRect<f32, LayerPixel>, clip: LocalClip) -> Self {
PrimitiveInfo {
rect: rect,
local_clip: clip,
rect,
clip_rect,
is_backface_visible: true,
tag: None,
}
Expand Down

0 comments on commit 1828236

Please sign in to comment.