diff options
Diffstat (limited to 'components/layout/display_list')
-rw-r--r-- | components/layout/display_list/builder.rs | 6 | ||||
-rw-r--r-- | components/layout/display_list/items.rs | 12 | ||||
-rw-r--r-- | components/layout/display_list/webrender_helpers.rs | 144 |
3 files changed, 95 insertions, 67 deletions
diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs index 1b53ac90249..e6b16710d22 100644 --- a/components/layout/display_list/builder.rs +++ b/components/layout/display_list/builder.rs @@ -2616,6 +2616,8 @@ impl BlockFlow { clip: ClippingRegion::from_rect(border_box.to_layout()), content_rect: LayoutRect::zero(), node_type: ClipScrollNodeType::StickyFrame(sticky_frame_data), + scroll_node_id: None, + clip_chain_id: None, }); let new_clipping_and_scrolling = ClippingAndScrolling::simple(new_clip_scroll_index); @@ -2683,6 +2685,8 @@ impl BlockFlow { clip: clip, content_rect: Rect::new(content_box.origin, content_size).to_layout(), node_type: ClipScrollNodeType::ScrollFrame(sensitivity, external_id), + scroll_node_id: None, + clip_chain_id: None, }); let new_clipping_and_scrolling = ClippingAndScrolling::simple(new_clip_scroll_index); @@ -2719,6 +2723,8 @@ impl BlockFlow { clip: ClippingRegion::from_rect(clip_rect.to_layout()), content_rect: LayoutRect::zero(), // content_rect isn't important for clips. node_type: ClipScrollNodeType::Clip(ClipType::Rect), + scroll_node_id: None, + clip_chain_id: None, }); let new_indices = ClippingAndScrolling::new(new_index, new_index); diff --git a/components/layout/display_list/items.rs b/components/layout/display_list/items.rs index 4b8a5cf1a5e..b1de022d819 100644 --- a/components/layout/display_list/items.rs +++ b/components/layout/display_list/items.rs @@ -18,6 +18,7 @@ use gfx_traits::print_tree::PrintTree; use gfx_traits::{self, StackingContextId}; use msg::constellation_msg::PipelineId; use net_traits::image::base::Image; +use script_traits::compositor::ScrollTreeNodeId; use servo_geometry::MaxRect; use std::cmp::Ordering; use std::collections::HashMap; @@ -31,6 +32,7 @@ use webrender_api::{ FilterOp, GlyphInstance, GradientStop, ImageKey, MixBlendMode, PrimitiveFlags, ScrollSensitivity, Shadow, SpatialId, StickyOffsetBounds, TransformStyle, }; +use wr::ClipChainId; pub use style::dom::OpaqueNode; @@ -369,6 +371,12 @@ pub struct ClipScrollNode { /// The type of this ClipScrollNode. pub node_type: ClipScrollNodeType, + + /// The WebRender spatial id of this node assigned during WebRender conversion. + pub scroll_node_id: Option<ScrollTreeNodeId>, + + /// The WebRender clip id of this node assigned during WebRender conversion. + pub clip_chain_id: Option<ClipChainId>, } impl ClipScrollNode { @@ -378,6 +386,8 @@ impl ClipScrollNode { clip: ClippingRegion::from_rect(LayoutRect::zero()), content_rect: LayoutRect::zero(), node_type: ClipScrollNodeType::Placeholder, + scroll_node_id: None, + clip_chain_id: None, } } @@ -400,6 +410,8 @@ impl ClipScrollNode { clip: ClippingRegion::from_rect(clip_rect), content_rect: LayoutRect::zero(), // content_rect isn't important for clips. node_type: ClipScrollNodeType::Clip(ClipType::Rounded(complex_region)), + scroll_node_id: None, + clip_chain_id: None, } } } diff --git a/components/layout/display_list/webrender_helpers.rs b/components/layout/display_list/webrender_helpers.rs index d84ce7739b7..9489eb357cd 100644 --- a/components/layout/display_list/webrender_helpers.rs +++ b/components/layout/display_list/webrender_helpers.rs @@ -13,22 +13,24 @@ use msg::constellation_msg::PipelineId; use script_traits::compositor::{CompositorDisplayListInfo, ScrollTreeNodeId, ScrollableNodeInfo}; use webrender_api::units::{LayoutPoint, LayoutSize, LayoutVector2D}; use webrender_api::{ - self, ClipId, CommonItemProperties, DisplayItem as WrDisplayItem, DisplayListBuilder, Epoch, - PrimitiveFlags, PropertyBinding, PushStackingContextDisplayItem, RasterSpace, - ReferenceFrameKind, SpaceAndClipInfo, SpatialId, StackingContext, + self, ClipChainId, ClipId, CommonItemProperties, DisplayItem as WrDisplayItem, + DisplayListBuilder, Epoch, PrimitiveFlags, PropertyBinding, PushStackingContextDisplayItem, + RasterSpace, ReferenceFrameKind, SpaceAndClipInfo, SpatialId, StackingContext, }; -struct ClipScrollState { - clip_ids: Vec<Option<ClipId>>, - scroll_node_ids: Vec<Option<ScrollTreeNodeId>>, +struct ClipScrollState<'a> { + clip_scroll_nodes: &'a mut Vec<ClipScrollNode>, compositor_info: CompositorDisplayListInfo, } -impl ClipScrollState { - fn new(size: usize, compositor_info: CompositorDisplayListInfo) -> Self { +impl<'a> ClipScrollState<'a> { + fn new( + clip_scroll_nodes: &'a mut Vec<ClipScrollNode>, + compositor_info: CompositorDisplayListInfo, + builder: &mut DisplayListBuilder, + ) -> Self { let mut state = ClipScrollState { - clip_ids: vec![None; size], - scroll_node_ids: vec![None; size], + clip_scroll_nodes, compositor_info, }; @@ -37,32 +39,38 @@ impl ClipScrollState { // automatically. We also follow the "old" WebRender API for clip/scroll for now, // hence both arrays are initialized based on FIRST_SPATIAL_NODE_INDEX, while // FIRST_CLIP_NODE_INDEX is not taken into account. - state.scroll_node_ids[0] = Some(state.compositor_info.root_reference_frame_id); - state.scroll_node_ids[1] = Some(state.compositor_info.root_scroll_node_id); + state.clip_scroll_nodes[0].scroll_node_id = + Some(state.compositor_info.root_reference_frame_id); + state.clip_scroll_nodes[1].scroll_node_id = Some(state.compositor_info.root_scroll_node_id); - let root_clip_id = ClipId::root(state.compositor_info.pipeline_id); - state.add_clip_node_mapping(0, root_clip_id); - state.add_clip_node_mapping(1, root_clip_id); + let root_clip_chain = + builder.define_clip_chain(None, [ClipId::root(state.compositor_info.pipeline_id)]); + state.add_clip_node_mapping(0, root_clip_chain); + state.add_clip_node_mapping(1, root_clip_chain); state } - fn webrender_clip_id_for_index(&mut self, index: usize) -> ClipId { - self.clip_ids[index].expect("Tried to use WebRender parent ClipId before it was defined.") + fn webrender_clip_id_for_index(&mut self, index: usize) -> ClipChainId { + self.clip_scroll_nodes[index] + .clip_chain_id + .expect("Tried to access WebRender ClipId before definining it.") } fn webrender_spatial_id_for_index(&mut self, index: usize) -> SpatialId { - self.scroll_node_ids[index] + self.clip_scroll_nodes[index] + .scroll_node_id .expect("Tried to use WebRender parent SpatialId before it was defined.") .spatial_id } - fn add_clip_node_mapping(&mut self, index: usize, webrender_id: ClipId) { - self.clip_ids[index] = Some(webrender_id); + fn add_clip_node_mapping(&mut self, index: usize, webrender_id: ClipChainId) { + self.clip_scroll_nodes[index].clip_chain_id = Some(webrender_id); } fn scroll_node_id_from_index(&self, index: usize) -> ScrollTreeNodeId { - self.scroll_node_ids[index] + self.clip_scroll_nodes[index] + .scroll_node_id .expect("Tried to use WebRender parent SpatialId before it was defined.") } @@ -74,15 +82,17 @@ impl ClipScrollState { scroll_info: Option<ScrollableNodeInfo>, ) { let parent_scroll_node_id = parent_index.map(|index| self.scroll_node_id_from_index(index)); - self.scroll_node_ids[index] = Some(self.compositor_info.scroll_tree.add_scroll_tree_node( - parent_scroll_node_id.as_ref(), - spatial_id, - scroll_info, - )); + self.clip_scroll_nodes[index].scroll_node_id = + Some(self.compositor_info.scroll_tree.add_scroll_tree_node( + parent_scroll_node_id.as_ref(), + spatial_id, + scroll_info, + )); } fn add_spatial_node_mapping_to_parent_index(&mut self, index: usize, parent_index: usize) { - self.scroll_node_ids[index] = self.scroll_node_ids[parent_index]; + self.clip_scroll_nodes[index].scroll_node_id = + self.clip_scroll_nodes[parent_index].scroll_node_id } } @@ -100,27 +110,22 @@ impl DisplayList { epoch: Epoch, ) -> (DisplayListBuilder, CompositorDisplayListInfo, IsContentful) { let webrender_pipeline = pipeline_id.to_webrender(); - let mut state = ClipScrollState::new( - self.clip_scroll_nodes.len(), - CompositorDisplayListInfo::new( - viewport_size, - self.bounds().size, - webrender_pipeline, - epoch, - ), - ); - let mut builder = DisplayListBuilder::with_capacity( webrender_pipeline, self.bounds().size, 1024 * 1024, // 1 MB of space ); + let content_size = self.bounds().size; + let mut state = ClipScrollState::new( + &mut self.clip_scroll_nodes, + CompositorDisplayListInfo::new(viewport_size, content_size, webrender_pipeline, epoch), + &mut builder, + ); + let mut is_contentful = IsContentful(false); for item in &mut self.list { - is_contentful.0 |= item - .convert_to_webrender(&self.clip_scroll_nodes, &mut state, &mut builder) - .0; + is_contentful.0 |= item.convert_to_webrender(&mut state, &mut builder).0; } (builder, state.compositor_info, is_contentful) @@ -130,7 +135,6 @@ impl DisplayList { impl DisplayItem { fn convert_to_webrender( &mut self, - clip_scroll_nodes: &[ClipScrollNode], state: &mut ClipScrollState, builder: &mut DisplayListBuilder, ) -> IsContentful { @@ -165,7 +169,7 @@ impl DisplayItem { CommonItemProperties { clip_rect: base.clip_rect, spatial_id: current_scroll_node_id.spatial_id, - clip_id: current_clip_id, + clip_id: ClipId::ClipChain(current_clip_id), // TODO(gw): Make use of the WR backface visibility functionality. flags: PrimitiveFlags::default(), hit_info: tag, @@ -339,48 +343,54 @@ impl DisplayItem { }, DisplayItem::DefineClipScrollNode(ref mut item) => { let index = item.node_index.to_index(); - let node = &clip_scroll_nodes[index]; + let node = state.clip_scroll_nodes[index].clone(); let item_rect = node.clip.main; let parent_index = node.parent_index.to_index(); let parent_spatial_id = state.webrender_spatial_id_for_index(parent_index); - let parent_clip_id = state.webrender_clip_id_for_index(parent_index); + let parent_clip_chain_id = state.webrender_clip_id_for_index(parent_index); + + let parent_space_and_clip_info = SpaceAndClipInfo { + clip_id: ClipId::root(state.compositor_info.pipeline_id), + spatial_id: parent_spatial_id, + }; match node.node_type { ClipScrollNodeType::Clip(clip_type) => { - let space_and_clip_info = SpaceAndClipInfo { - clip_id: parent_clip_id, - spatial_id: parent_spatial_id, - }; let clip_id = match clip_type { ClipType::Rect => { - builder.define_clip_rect(&space_and_clip_info, item_rect) - }, - ClipType::Rounded(complex) => { - builder.define_clip_rounded_rect(&space_and_clip_info, complex) + builder.define_clip_rect(&parent_space_and_clip_info, item_rect) }, + ClipType::Rounded(complex) => builder + .define_clip_rounded_rect(&parent_space_and_clip_info, complex), }; - state.add_clip_node_mapping(index, clip_id); + let clip_chain_id = + builder.define_clip_chain(Some(parent_clip_chain_id), [clip_id]); + state.add_clip_node_mapping(index, clip_chain_id); state.add_spatial_node_mapping_to_parent_index(index, parent_index); }, ClipScrollNodeType::ScrollFrame(scroll_sensitivity, external_id) => { - let space_clip_info = builder.define_scroll_frame( - &SpaceAndClipInfo { - clip_id: parent_clip_id, - spatial_id: parent_spatial_id, - }, - Some(external_id), - node.content_rect, - item_rect, - scroll_sensitivity, - LayoutVector2D::zero(), - ); + let clip_id = + builder.define_clip_rect(&parent_space_and_clip_info, item_rect); + let clip_chain_id = + builder.define_clip_chain(Some(parent_clip_chain_id), [clip_id]); + state.add_clip_node_mapping(index, clip_chain_id); + + let spatial_id = builder + .define_scroll_frame( + &parent_space_and_clip_info, + Some(external_id), + node.content_rect, + item_rect, + scroll_sensitivity, + LayoutVector2D::zero(), + ) + .spatial_id; - state.add_clip_node_mapping(index, space_clip_info.clip_id); state.register_spatial_node( index, - space_clip_info.spatial_id, + spatial_id, Some(parent_index), Some(ScrollableNodeInfo { external_id, @@ -401,7 +411,7 @@ impl DisplayItem { LayoutVector2D::zero(), ); - state.add_clip_node_mapping(index, parent_clip_id); + state.add_clip_node_mapping(index, parent_clip_chain_id); state.register_spatial_node(index, id, Some(current_scrolling_index), None); }, ClipScrollNodeType::Placeholder => { |