aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/webrender_helpers.rs
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2016-10-31 20:24:27 +0100
committerMartin Robinson <mrobinson@igalia.com>2016-11-05 18:36:45 +0100
commitef82d772c19f797228d7ed2a9d8804f17588117c (patch)
tree920e575a8b2f638f05655171861f0730c8f385fe /components/layout/webrender_helpers.rs
parentf7875dad1a43792ff3869f292990d03d30ebd9eb (diff)
downloadservo-ef82d772c19f797228d7ed2a9d8804f17588117c.tar.gz
servo-ef82d772c19f797228d7ed2a9d8804f17588117c.zip
Don't promote all scrollable regions to stacking contexts
Instead annotate all flows with their owning ScrollRoots. When processing the display list items into a flattened display list, we add PushScrollRoot and PopScrollRoot to signal when scrolling regions start and end. It is possible for content from different scrolling regions to intersect and when they do, the stack of scrolling regions is duplicated. When these duplicated scrolling regions stacks reach WebRender, it will scroll them in tandem. The PushScrollRoot and PopScrollRoot items are currently represented as StackingContexts in WebRender, but eventually these will be replaced with special WebRender display items. Fixes #13529. Fixed #13298.
Diffstat (limited to 'components/layout/webrender_helpers.rs')
-rw-r--r--components/layout/webrender_helpers.rs61
1 files changed, 42 insertions, 19 deletions
diff --git a/components/layout/webrender_helpers.rs b/components/layout/webrender_helpers.rs
index cf239f79258..07979940314 100644
--- a/components/layout/webrender_helpers.rs
+++ b/components/layout/webrender_helpers.rs
@@ -8,7 +8,7 @@
// completely converting layout to directly generate WebRender display lists, for example.
use app_units::Au;
-use euclid::{Point2D, Rect, Size2D};
+use euclid::{Matrix4D, Point2D, Rect, Size2D, TypedRect};
use gfx::display_list::{BorderRadii, BoxShadowClipMode, ClippingRegion};
use gfx::display_list::{DisplayItem, DisplayList, DisplayListTraversal};
use gfx::display_list::{StackingContext, StackingContextType};
@@ -24,7 +24,8 @@ trait WebRenderStackingContextConverter {
api: &mut webrender_traits::RenderApi,
pipeline_id: webrender_traits::PipelineId,
epoch: webrender_traits::Epoch,
- frame_builder: &mut WebRenderFrameBuilder)
+ frame_builder: &mut WebRenderFrameBuilder,
+ scroll_layer_id: Option<webrender_traits::ScrollLayerId>)
-> webrender_traits::StackingContextId;
fn convert_children_to_webrender<'a>(&self,
@@ -235,17 +236,39 @@ impl WebRenderStackingContextConverter for StackingContext {
&DisplayItem::PushStackingContext(ref stacking_context_item) => {
let stacking_context = &stacking_context_item.stacking_context;
debug_assert!(stacking_context.context_type == StackingContextType::Real);
-
- let stacking_context_id =
+ builder.push_stacking_context(
stacking_context.convert_to_webrender(traversal,
api,
pipeline_id,
epoch,
- frame_builder);
- builder.push_stacking_context(stacking_context_id);
-
+ frame_builder,
+ None));
}
- &DisplayItem::PopStackingContext(_) => return,
+ &DisplayItem::PushScrollRoot(ref item) => {
+ let stacking_context = StackingContext::new(
+ StackingContextId::new(0),
+ StackingContextType::Real,
+ &item.scroll_root.clip,
+ &TypedRect::new(Point2D::zero(), item.scroll_root.size),
+ 0,
+ filter::T::new(Vec::new()),
+ mix_blend_mode::T::normal,
+ Matrix4D::identity(),
+ Matrix4D::identity(),
+ true,
+ ScrollPolicy::Scrollable,
+ ScrollRootId::root());
+ let scroll_layer_id =
+ Some(frame_builder.next_scroll_layer_id(item.scroll_root.id));
+ builder.push_stacking_context(
+ stacking_context.convert_to_webrender(traversal,
+ api,
+ pipeline_id,
+ epoch,
+ frame_builder,
+ scroll_layer_id));
+ }
+ &DisplayItem::PopStackingContext(_) | &DisplayItem::PopScrollRoot(_) => return,
_ => item.convert_to_webrender(builder, frame_builder),
}
}
@@ -256,21 +279,14 @@ impl WebRenderStackingContextConverter for StackingContext {
api: &mut webrender_traits::RenderApi,
pipeline_id: webrender_traits::PipelineId,
epoch: webrender_traits::Epoch,
- frame_builder: &mut WebRenderFrameBuilder)
+ frame_builder: &mut WebRenderFrameBuilder,
+ scroll_layer_id: Option<webrender_traits::ScrollLayerId>)
-> webrender_traits::StackingContextId {
let webrender_scroll_policy = match self.scroll_policy {
ScrollPolicy::Scrollable => webrender_traits::ScrollPolicy::Scrollable,
ScrollPolicy::FixedPosition => webrender_traits::ScrollPolicy::Fixed,
};
- let scroll_layer_id = if let Some(scroll_root_id) = self.overflow_scroll_id {
- Some(frame_builder.next_scroll_layer_id(scroll_root_id))
- } else if self.id == StackingContextId::root() {
- Some(frame_builder.next_scroll_layer_id(ScrollRootId::root()))
- } else {
- None
- };
-
let mut sc =
webrender_traits::StackingContext::new(scroll_layer_id,
webrender_scroll_policy,
@@ -310,11 +326,14 @@ impl WebRenderDisplayListConverter for DisplayList {
match item {
Some(&DisplayItem::PushStackingContext(ref stacking_context_item)) => {
let stacking_context = &stacking_context_item.stacking_context;
+ let scroll_layer_id =
+ Some(frame_builder.next_scroll_layer_id(ScrollRootId::root()));
stacking_context.convert_to_webrender(&mut traversal,
api,
pipeline_id,
epoch,
- frame_builder)
+ frame_builder,
+ scroll_layer_id)
}
_ => unreachable!("DisplayList did not start with StackingContext."),
@@ -453,7 +472,11 @@ impl WebRenderDisplayItemConverter for DisplayItem {
item.base.clip.to_clip_region(frame_builder),
pipeline_id);
}
- DisplayItem::PushStackingContext(_) | DisplayItem::PopStackingContext(_) => {}
+ DisplayItem::PushStackingContext(_) |
+ DisplayItem::PopStackingContext(_) |
+ DisplayItem::PushScrollRoot(_) |
+ DisplayItem::PopScrollRoot(_) =>
+ unreachable!("Tried to convert a scroll root or stacking context structure item."),
}
}
}