Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend segment building to handle clip in/out, multiple clip regions. #2242

Merged
merged 4 commits into from Dec 20, 2017
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Prev

Address review comments

  • Loading branch information
gw3583 committed Dec 20, 2017
commit 9423cf204adadfd8babc91b4e1171984cc1a0396
@@ -433,28 +433,20 @@ impl FrameBuilder {
);
let p3 = info.rect.bottom_right();

let segment = |x0, y0, x1, y1, mask| BrushSegment::new(
LayerPoint::new(x0, y0),
LayerSize::new(x1-x0, y1-y0),
false,
mask
);

// Add a solid rectangle for each visible edge/corner combination.
if top_edge == BorderEdgeKind::Solid {
let descriptor = BrushSegmentDescriptor {
segments: vec![
BrushSegment::new(
LayerPoint::new(p0.x, p0.y),
LayerSize::new(p1.x - p0.x, p1.y - p0.y),
false,
EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::LEFT,
),
BrushSegment::new(
LayerPoint::new(p2.x, p0.y),
LayerSize::new(p3.x - p2.x, p1.y - p0.y),
false,
EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::RIGHT,
),
BrushSegment::new(
LayerPoint::new(p1.x, p0.y),
LayerSize::new(p2.x - p1.x, p1.y - p0.y),
false,
EdgeAaSegmentMask::TOP,
),
segment(p0.x, p0.y, p1.x, p1.y, EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::LEFT),
segment(p2.x, p0.y, p3.x, p1.y, EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::RIGHT),
segment(p1.x, p0.y, p2.x, p1.y, EdgeAaSegmentMask::TOP),
],
clip_mask_kind: BrushClipMaskKind::Unknown,
};
@@ -463,19 +455,14 @@ impl FrameBuilder {
clip_and_scroll,
&info,
border.top.color,
Some(Box::new(descriptor)),
Some(descriptor),
);
}

if left_edge == BorderEdgeKind::Solid {
let descriptor = BrushSegmentDescriptor {
segments: vec![
BrushSegment::new(
LayerPoint::new(p0.x, p1.y),
LayerSize::new(p1.x - p0.x, p2.y - p1.y),
false,
EdgeAaSegmentMask::LEFT,
),
segment(p0.x, p1.y, p1.x, p2.y, EdgeAaSegmentMask::LEFT),
],
clip_mask_kind: BrushClipMaskKind::Unknown,
};
@@ -484,19 +471,14 @@ impl FrameBuilder {
clip_and_scroll,
&info,
border.left.color,
Some(Box::new(descriptor)),
Some(descriptor),
);
}

if right_edge == BorderEdgeKind::Solid {
let descriptor = BrushSegmentDescriptor {
segments: vec![
BrushSegment::new(
LayerPoint::new(p2.x, p1.y),
LayerSize::new(p3.x - p2.x, p2.y - p1.y),
false,
EdgeAaSegmentMask::RIGHT,
),
segment(p2.x, p1.y, p3.x, p2.y, EdgeAaSegmentMask::RIGHT),
],
clip_mask_kind: BrushClipMaskKind::Unknown,
};
@@ -505,31 +487,16 @@ impl FrameBuilder {
clip_and_scroll,
&info,
border.right.color,
Some(Box::new(descriptor)),
Some(descriptor),
);
}

if bottom_edge == BorderEdgeKind::Solid {
let descriptor = BrushSegmentDescriptor {
segments: vec![
BrushSegment::new(
LayerPoint::new(p1.x, p2.y),
LayerSize::new(p2.x - p1.x, p3.y - p2.y),
false,
EdgeAaSegmentMask::BOTTOM,
),
BrushSegment::new(
LayerPoint::new(p2.x, p2.y),
LayerSize::new(p3.x - p2.x, p3.y - p2.y),
false,
EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::RIGHT,
),
BrushSegment::new(
LayerPoint::new(p0.x, p2.y),
LayerSize::new(p1.x - p0.x, p3.y - p2.y),
false,
EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::LEFT,
),
segment(p1.x, p2.y, p2.x, p3.y, EdgeAaSegmentMask::BOTTOM),
segment(p2.x, p2.y, p3.x, p3.y, EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::RIGHT),
segment(p0.x, p2.y, p1.x, p3.y, EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::LEFT),
],
clip_mask_kind: BrushClipMaskKind::Unknown,
};
@@ -538,7 +505,7 @@ impl FrameBuilder {
clip_and_scroll,
&info,
border.bottom.color,
Some(Box::new(descriptor)),
Some(descriptor),
);
}
} else {
@@ -759,7 +759,7 @@ impl FrameBuilder {
clip_and_scroll: ClipAndScrollInfo,
info: &LayerPrimitiveInfo,
color: ColorF,
segments: Option<Box<BrushSegmentDescriptor>>,
segments: Option<BrushSegmentDescriptor>,
) {
if color.a == 0.0 {
// Don't add transparent rectangles to the draw list, but do consider them for hit
@@ -275,13 +275,13 @@ pub struct BrushSegmentDescriptor {
#[derive(Debug)]
pub struct BrushPrimitive {
pub kind: BrushKind,
pub segment_desc: Option<Box<BrushSegmentDescriptor>>,
pub segment_desc: Option<BrushSegmentDescriptor>,
}

impl BrushPrimitive {
pub fn new(
kind: BrushKind,
segment_desc: Option<Box<BrushSegmentDescriptor>>,
segment_desc: Option<BrushSegmentDescriptor>,
) -> BrushPrimitive {
BrushPrimitive {
kind,
@@ -1359,67 +1359,62 @@ impl PrimitiveStore {
// If true, we need a clip mask for the entire primitive. This
// is either because we don't handle segmenting this clip source,
// or we have a clip source from a different coordinate system.
let mut has_global_mask = false;
let mut clip_mask_kind = BrushClipMaskKind::Individual;

// Segment the primitive on all the local-space clip sources
// that we can.
for clip_item in clips {
if clip_item.coordinate_system_id == prim_context.scroll_node.coordinate_system_id {
let local_clips = clip_store.get_opt(&clip_item.clip_sources).expect("bug");
if clip_item.coordinate_system_id != prim_context.scroll_node.coordinate_system_id {
clip_mask_kind = BrushClipMaskKind::Global;
continue;
}

for &(ref clip, _) in &local_clips.clips {
let (local_clip_rect, radius, mode) = match *clip {
ClipSource::RoundedRectangle(rect, radii, clip_mode) => {
(rect, Some(radii), clip_mode)
}
ClipSource::Rectangle(rect) => {
(rect, None, ClipMode::Clip)
}
ClipSource::BorderCorner(..) |
ClipSource::Image(..) => {
// TODO(gw): We can easily extend the segment builder
// to support these clip sources in the
// future, but they are rarely used.
has_global_mask = true;
continue;
}
};
let local_clips = clip_store.get_opt(&clip_item.clip_sources).expect("bug");

// If the scroll node transforms are different between the clip
// node and the primitive, we need to get the clip rect in the
// local space of the primitive, in order to generate correct
// local segments.
let local_clip_rect = if clip_item.scroll_node_data_index == prim_context.scroll_node.node_data_index {
local_clip_rect
} else {
let clip_transform_data = &node_data[clip_item.scroll_node_data_index.0 as usize];
let prim_transform = &prim_context.scroll_node.world_content_transform;

let relative_transform = prim_transform
.inverse()
.unwrap_or(WorldToLayerTransform::identity())
.pre_mul(&clip_transform_data.transform);

relative_transform.transform_rect(&local_clip_rect)
};
for &(ref clip, _) in &local_clips.clips {
let (local_clip_rect, radius, mode) = match *clip {
ClipSource::RoundedRectangle(rect, radii, clip_mode) => {
(rect, Some(radii), clip_mode)
}
ClipSource::Rectangle(rect) => {
(rect, None, ClipMode::Clip)
}
ClipSource::BorderCorner(..) |
ClipSource::Image(..) => {
// TODO(gw): We can easily extend the segment builder
// to support these clip sources in the
// future, but they are rarely used.
clip_mask_kind = BrushClipMaskKind::Global;
continue;
}
};

segment_builder.push_rect(
local_clip_rect,
radius,
mode
);
}
} else {
has_global_mask = true;
// If the scroll node transforms are different between the clip
// node and the primitive, we need to get the clip rect in the
// local space of the primitive, in order to generate correct
// local segments.
let local_clip_rect = if clip_item.scroll_node_data_index == prim_context.scroll_node.node_data_index {
local_clip_rect
} else {
let clip_transform_data = &node_data[clip_item.scroll_node_data_index.0 as usize];
let prim_transform = &prim_context.scroll_node.world_content_transform;

let relative_transform = prim_transform
.inverse()
.unwrap_or(WorldToLayerTransform::identity())
.pre_mul(&clip_transform_data.transform);

relative_transform.transform_rect(&local_clip_rect)
};

segment_builder.push_rect(
local_clip_rect,
radius,
mode
);
}
}

let clip_mask_kind = if has_global_mask {
BrushClipMaskKind::Global
} else {
BrushClipMaskKind::Individual
};

match brush.segment_desc {
Some(ref mut segment_desc) => {
segment_desc.clip_mask_kind = clip_mask_kind;
@@ -1442,10 +1437,10 @@ impl PrimitiveStore {
);
});

brush.segment_desc = Some(Box::new(BrushSegmentDescriptor {
brush.segment_desc = Some(BrushSegmentDescriptor {
segments,
clip_mask_kind,
}));
});
}
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.