aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/webrender_helpers.rs
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2017-09-30 15:50:47 +0200
committerMartin Robinson <mrobinson@igalia.com>2017-10-17 23:33:13 +0200
commitb5d51dd2636935471447fc741ffbb95c62e37f94 (patch)
treed437a0a5114788c529692628729cdc3169ec4b2e /components/layout/webrender_helpers.rs
parent00e2a1c62a04ae337f9008dcea8e265edd2d3ef4 (diff)
downloadservo-b5d51dd2636935471447fc741ffbb95c62e37f94.tar.gz
servo-b5d51dd2636935471447fc741ffbb95c62e37f94.zip
Switch to using WebRender hit testing
This trades quite a bit of complicated code in Servo for few more messages and a significant performance improvement. In particular, WebRender can search the entire display list at once instead of ping-ponging down the pipeline tree. This allows us to send mouse events to the correct pipeline immediately.
Diffstat (limited to 'components/layout/webrender_helpers.rs')
-rw-r--r--components/layout/webrender_helpers.rs72
1 files changed, 34 insertions, 38 deletions
diff --git a/components/layout/webrender_helpers.rs b/components/layout/webrender_helpers.rs
index fbd5d423ddf..4477294fced 100644
--- a/components/layout/webrender_helpers.rs
+++ b/components/layout/webrender_helpers.rs
@@ -19,23 +19,12 @@ use style::values::generics::effects::Filter as GenericFilter;
use webrender_api::{self, ClipAndScrollInfo, ComplexClipRegion, DisplayListBuilder};
use webrender_api::{ExtendMode, LayoutTransform};
-fn prim_info(local_rect: Rect<Au>,
- local_clip: Option<webrender_api::LocalClip>) -> webrender_api::LayoutPrimitiveInfo {
- match local_clip {
- Some(local_clip) => {
- webrender_api::LayoutPrimitiveInfo::with_clip(local_rect.to_rectf(), local_clip)
- }
- None => {
- webrender_api::LayoutPrimitiveInfo::new(local_rect.to_rectf())
- }
- }
-}
-
pub trait WebRenderDisplayListConverter {
fn convert_to_webrender(&self, pipeline_id: PipelineId) -> DisplayListBuilder;
}
trait WebRenderDisplayItemConverter {
+ fn prim_info(&self) -> webrender_api::LayoutPrimitiveInfo;
fn convert_to_webrender(&self,
builder: &mut DisplayListBuilder,
current_clip_and_scroll_info: &mut ClipAndScrollInfo);
@@ -249,6 +238,20 @@ impl WebRenderDisplayListConverter for DisplayList {
}
impl WebRenderDisplayItemConverter for DisplayItem {
+ fn prim_info(&self) -> webrender_api::LayoutPrimitiveInfo {
+ let tag = match self.base().metadata.pointing {
+ Some(cursor) => Some((self.base().metadata.node.0 as u64, cursor as u8)),
+ None => None,
+ };
+ webrender_api::LayoutPrimitiveInfo {
+ rect: self.base().bounds.to_rectf(),
+ local_clip: self.base().local_clip,
+ // TODO(gw): Make use of the WR backface visibility functionality.
+ is_backface_visible: true,
+ tag: tag,
+ }
+ }
+
fn convert_to_webrender(&self,
builder: &mut DisplayListBuilder,
current_clip_and_scroll_info: &mut ClipAndScrollInfo) {
@@ -261,11 +264,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
match *self {
DisplayItem::SolidColor(ref item) => {
- let color = item.color;
- if color.a > 0.0 {
- builder.push_rect(&prim_info(item.base.bounds, Some(item.base.local_clip)),
- color);
- }
+ builder.push_rect(&self.prim_info(), item.color);
}
DisplayItem::Text(ref item) => {
let mut origin = item.baseline_origin.clone();
@@ -294,7 +293,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
}
if glyphs.len() > 0 {
- builder.push_text(&prim_info(item.base.bounds, Some(item.base.local_clip)),
+ builder.push_text(&self.prim_info(),
&glyphs,
item.text_run.font_key,
item.text_color,
@@ -305,7 +304,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
if let Some(id) = item.webrender_image.key {
if item.stretch_size.width > Au(0) &&
item.stretch_size.height > Au(0) {
- builder.push_image(&prim_info(item.base.bounds, Some(item.base.local_clip)),
+ builder.push_image(&self.prim_info(),
item.stretch_size.to_sizef(),
item.tile_spacing.to_sizef(),
item.image_rendering.to_image_rendering(),
@@ -314,7 +313,6 @@ impl WebRenderDisplayItemConverter for DisplayItem {
}
}
DisplayItem::Border(ref item) => {
- let rect = item.base.bounds;
let widths = item.border_widths.to_border_widths();
let details = match item.details {
@@ -395,7 +393,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
}
};
- builder.push_border(&prim_info(rect, Some(item.base.local_clip)), widths, details);
+ builder.push_border(&self.prim_info(), widths, details);
}
DisplayItem::Gradient(ref item) => {
let rect = item.base.bounds;
@@ -410,7 +408,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
end_point,
item.gradient.stops.clone(),
extend_mode);
- builder.push_gradient(&prim_info(rect, Some(item.base.local_clip)),
+ builder.push_gradient(&self.prim_info(),
gradient,
rect.size.to_sizef(),
webrender_api::LayoutSize::zero());
@@ -428,14 +426,14 @@ impl WebRenderDisplayItemConverter for DisplayItem {
radius,
item.gradient.stops.clone(),
extend_mode);
- builder.push_radial_gradient(&prim_info(rect, Some(item.base.local_clip)),
+ builder.push_radial_gradient(&self.prim_info(),
gradient,
rect.size.to_sizef(),
webrender_api::LayoutSize::zero());
}
DisplayItem::Line(ref item) => {
let box_bounds = item.base.bounds.to_rectf();
- builder.push_line(&prim_info(item.base.bounds, Some(item.base.local_clip)),
+ builder.push_line(&self.prim_info(),
box_bounds.origin.y + box_bounds.size.height,
box_bounds.origin.x,
box_bounds.origin.x + box_bounds.size.width,
@@ -445,9 +443,8 @@ impl WebRenderDisplayItemConverter for DisplayItem {
item.style);
}
DisplayItem::BoxShadow(ref item) => {
- let rect = item.base.bounds;
let box_bounds = item.box_bounds.to_rectf();
- builder.push_box_shadow(&prim_info(rect, Some(item.base.local_clip)),
+ builder.push_box_shadow(&self.prim_info(),
box_bounds,
item.offset.to_vectorf(),
item.color,
@@ -457,8 +454,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
item.clip_mode.to_clip_mode());
}
DisplayItem::PushTextShadow(ref item) => {
- let rect = item.base.bounds;
- builder.push_shadow(&prim_info(rect, Some(item.base.local_clip)),
+ builder.push_shadow(&self.prim_info(),
webrender_api::Shadow {
blur_radius: item.blur_radius.to_f32_px(),
offset: item.offset.to_vectorf(),
@@ -469,9 +465,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
builder.pop_all_shadows();
}
DisplayItem::Iframe(ref item) => {
- let rect = item.base.bounds;
- let pipeline_id = item.iframe.to_webrender();
- builder.push_iframe(&prim_info(rect, Some(item.base.local_clip)), pipeline_id);
+ builder.push_iframe(&self.prim_info(), item.iframe.to_webrender());
}
DisplayItem::PushStackingContext(ref item) => {
let stacking_context = &item.stacking_context;
@@ -484,13 +478,15 @@ impl WebRenderDisplayItemConverter for DisplayItem {
LayoutTransform::from_untyped(&perspective)
});
- builder.push_stacking_context(&prim_info(stacking_context.bounds, None),
- stacking_context.scroll_policy,
- transform,
- stacking_context.transform_style,
- perspective,
- stacking_context.mix_blend_mode,
- stacking_context.filters.to_filter_ops());
+ builder.push_stacking_context(
+ &webrender_api::LayoutPrimitiveInfo::new(stacking_context.bounds.to_rectf()),
+ stacking_context.scroll_policy,
+ transform,
+ stacking_context.transform_style,
+ perspective,
+ stacking_context.mix_blend_mode,
+ stacking_context.filters.to_filter_ops()
+ );
}
DisplayItem::PopStackingContext(_) => builder.pop_stacking_context(),
DisplayItem::DefineClipScrollNode(ref item) => {