Eliminate ScrollRootId

Just use WebRender's ClipId directly. This will allow us to create and
use ReferenceFrames in the future, if we need to do that. It will also
make it easier to have Servo responsible for creating the root
scrolling area, which will allow removing some old hacks in the future.
This commit is contained in:
Martin Robinson 2017-04-19 14:45:47 +02:00
parent 7919e591a4
commit d150cc9f95
24 changed files with 226 additions and 281 deletions

View file

@ -9,6 +9,7 @@ use gfx::display_list::{WebRenderImageInfo, OpaqueNode};
use gfx::font_cache_thread::FontCacheThread;
use gfx::font_context::FontContext;
use heapsize::HeapSizeOf;
use msg::constellation_msg::PipelineId;
use net_traits::image_cache::{CanRequestImages, ImageCache, ImageState};
use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
use opaque_node::OpaqueNodeMethods;
@ -76,6 +77,9 @@ pub fn heap_size_of_persistent_local_context() -> usize {
/// Layout information shared among all workers. This must be thread-safe.
pub struct LayoutContext<'a> {
/// The pipeline id of this LayoutContext.
pub id: PipelineId,
/// Bits shared by the layout and style system.
pub style_context: SharedStyleContext<'a>,

View file

@ -29,7 +29,7 @@ use gfx::display_list::{GradientDisplayItem, IframeDisplayItem, ImageDisplayItem
use gfx::display_list::{LineDisplayItem, OpaqueNode};
use gfx::display_list::{SolidColorDisplayItem, ScrollRoot, StackingContext, StackingContextType};
use gfx::display_list::{TextDisplayItem, TextOrientation, WebGLDisplayItem, WebRenderImageInfo};
use gfx_traits::{ScrollRootId, StackingContextId};
use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
use ipc_channel::ipc;
use list_item::ListItemFlow;
@ -38,6 +38,7 @@ use msg::constellation_msg::PipelineId;
use net_traits::image::base::PixelFormat;
use net_traits::image_cache::UsePlaceholder;
use range::Range;
use script_layout_interface::wrapper_traits::PseudoElementType;
use servo_config::opts;
use servo_geometry::max_rect;
use servo_url::ServoUrl;
@ -63,7 +64,7 @@ use style::values::specified::{HorizontalDirection, VerticalDirection};
use style_traits::CSSPixel;
use style_traits::cursor::Cursor;
use table_cell::CollapsedBordersForCell;
use webrender_traits::{ColorF, GradientStop, RepeatMode, ScrollPolicy};
use webrender_traits::{ColorF, ClipId, GradientStop, RepeatMode, ScrollPolicy};
trait ResolvePercentage {
fn resolve(&self, length: u32) -> u32;
@ -152,7 +153,7 @@ pub struct DisplayListBuildState<'a> {
pub root_stacking_context: StackingContext,
pub items: HashMap<StackingContextId, Vec<DisplayItem>>,
stacking_context_info: HashMap<StackingContextId, StackingContextInfo>,
pub scroll_root_parents: HashMap<ScrollRootId, ScrollRootId>,
pub scroll_root_parents: HashMap<ClipId, ClipId>,
pub processing_scroll_root_element: bool,
/// The current stacking context id, used to keep track of state when building.
@ -161,12 +162,12 @@ pub struct DisplayListBuildState<'a> {
/// The current scroll root id, used to keep track of state when
/// recursively building and processing the display list.
pub current_scroll_root_id: ScrollRootId,
pub current_scroll_root_id: ClipId,
/// The scroll root id of the first ancestor which defines a containing block.
/// This is necessary because absolutely positioned items should be clipped
/// by their containing block's scroll root.
pub containing_block_scroll_root_id: ScrollRootId,
pub containing_block_scroll_root_id: ClipId,
/// Vector containing iframe sizes, used to inform the constellation about
/// new iframe sizes
@ -185,14 +186,14 @@ impl<'a> DisplayListBuildState<'a> {
pub fn new(layout_context: &'a LayoutContext) -> DisplayListBuildState<'a> {
DisplayListBuildState {
layout_context: layout_context,
root_stacking_context: StackingContext::root(),
root_stacking_context: StackingContext::root(layout_context.id),
items: HashMap::new(),
stacking_context_info: HashMap::new(),
scroll_root_parents: HashMap::new(),
processing_scroll_root_element: false,
current_stacking_context_id: StackingContextId::root(),
current_scroll_root_id: ScrollRootId::root(),
containing_block_scroll_root_id: ScrollRootId::root(),
current_scroll_root_id: layout_context.id.root_scroll_node(),
containing_block_scroll_root_id: layout_context.id.root_scroll_node(),
iframe_sizes: Vec::new(),
clip_stack: Vec::new(),
containing_block_clip_stack: Vec::new(),
@ -213,7 +214,7 @@ impl<'a> DisplayListBuildState<'a> {
info.children.push(stacking_context);
}
fn has_scroll_root(&mut self, id: ScrollRootId) -> bool {
fn has_scroll_root(&mut self, id: ClipId) -> bool {
self.scroll_root_parents.contains_key(&id)
}
@ -225,9 +226,9 @@ impl<'a> DisplayListBuildState<'a> {
info.scroll_roots.push(scroll_root);
}
fn parent_scroll_root_id(&self, scroll_root_id: ScrollRootId) -> ScrollRootId {
if scroll_root_id == ScrollRootId::root() {
return ScrollRootId::root()
fn parent_scroll_root_id(&self, scroll_root_id: ClipId) -> ClipId {
if scroll_root_id.is_root_scroll_node() {
return scroll_root_id;
}
debug_assert!(self.scroll_root_parents.contains_key(&scroll_root_id));
@ -262,7 +263,8 @@ impl<'a> DisplayListBuildState<'a> {
pub fn to_display_list(mut self) -> DisplayList {
let mut list = Vec::new();
let root_context = mem::replace(&mut self.root_stacking_context, StackingContext::root());
let root_context = mem::replace(&mut self.root_stacking_context,
StackingContext::root(self.layout_context.id));
self.to_display_list_for_stacking_context(&mut list, root_context);
@ -283,13 +285,14 @@ impl<'a> DisplayListBuildState<'a> {
info.children.sort();
let pipeline_id = self.layout_context.id;
if stacking_context.context_type != StackingContextType::Real {
list.extend(info.scroll_roots.into_iter().map(|root| root.to_push()));
list.extend(info.scroll_roots.into_iter().map(|root| root.to_push(pipeline_id)));
self.to_display_list_for_items(list, child_items, info.children);
} else {
let (push_item, pop_item) = stacking_context.to_display_list_items();
let (push_item, pop_item) = stacking_context.to_display_list_items(pipeline_id);
list.push(push_item);
list.extend(info.scroll_roots.into_iter().map(|root| root.to_push()));
list.extend(info.scroll_roots.into_iter().map(|root| root.to_push(pipeline_id)));
self.to_display_list_for_items(list, child_items, info.children);
list.push(pop_item);
}
@ -348,6 +351,12 @@ impl<'a> DisplayListBuildState<'a> {
/// The logical width of an insertion point: at the moment, a one-pixel-wide line.
const INSERTION_POINT_LOGICAL_WIDTH: Au = Au(1 * AU_PER_PX);
pub enum IdType {
StackingContext,
OverflowClip,
CSSClip,
}
pub trait FragmentDisplayListBuilding {
/// Adds the display items necessary to paint the background of this fragment to the display
/// list if necessary.
@ -495,12 +504,16 @@ pub trait FragmentDisplayListBuilding {
base_flow: &BaseFlow,
scroll_policy: ScrollPolicy,
mode: StackingContextCreationMode,
parent_scroll_id: ScrollRootId)
parent_scroll_id: ClipId)
-> StackingContext;
/// The id of stacking context this fragment would create.
fn stacking_context_id(&self) -> StackingContextId;
fn unique_id(&self, id_type: IdType) -> u64;
fn fragment_type(&self) -> FragmentType;
}
fn handle_overlapping_radii(size: &Size2D<Au>, radii: &BorderRadii<Au>) -> BorderRadii<Au> {
@ -1653,7 +1666,7 @@ impl FragmentDisplayListBuilding for Fragment {
}
fn stacking_context_id(&self) -> StackingContextId {
StackingContextId::new_of_type(self.node.id() as usize, self.fragment_type())
StackingContextId::new(self.unique_id(IdType::StackingContext))
}
fn create_stacking_context(&self,
@ -1661,7 +1674,7 @@ impl FragmentDisplayListBuilding for Fragment {
base_flow: &BaseFlow,
scroll_policy: ScrollPolicy,
mode: StackingContextCreationMode,
parent_scroll_id: ScrollRootId)
parent_scroll_id: ClipId)
-> StackingContext {
let border_box =
self.stacking_relative_border_box(&base_flow.stacking_relative_position,
@ -1839,6 +1852,24 @@ impl FragmentDisplayListBuilding for Fragment {
}));
}
fn unique_id(&self, id_type: IdType) -> u64 {
let fragment_type = self.fragment_type();
let id = match id_type {
IdType::StackingContext | IdType::OverflowClip => self.node.id() as usize,
IdType::CSSClip => self as *const _ as usize,
};
combine_id_with_fragment_type(id, fragment_type) as u64
}
fn fragment_type(&self) -> FragmentType {
match self.pseudo {
PseudoElementType::Normal => FragmentType::FragmentBody,
PseudoElementType::Before(_) => FragmentType::BeforePseudoContent,
PseudoElementType::After(_) => FragmentType::AfterPseudoContent,
PseudoElementType::DetailsSummary(_) => FragmentType::FragmentBody,
PseudoElementType::DetailsContent(_) => FragmentType::FragmentBody,
}
}
}
pub trait BlockFlowDisplayListBuilding {
@ -1851,7 +1882,7 @@ pub trait BlockFlowDisplayListBuilding {
state: &mut DisplayListBuildState,
preserved_state: &mut PreservedDisplayListState,
stacking_context_type: BlockStackingContextType)
-> ScrollRootId;
-> ClipId;
fn setup_scroll_root_for_overflow(&mut self,
state: &mut DisplayListBuildState,
preserved_state: &mut PreservedDisplayListState,
@ -1862,11 +1893,11 @@ pub trait BlockFlowDisplayListBuilding {
stacking_relative_border_box: &Rect<Au>);
fn create_pseudo_stacking_context_for_block(&mut self,
parent_stacking_context_id: StackingContextId,
parent_scroll_root_id: ScrollRootId,
parent_scroll_root_id: ClipId,
state: &mut DisplayListBuildState);
fn create_real_stacking_context_for_block(&mut self,
parent_stacking_context_id: StackingContextId,
parent_scroll_root_id: ScrollRootId,
parent_scroll_root_id: ClipId,
state: &mut DisplayListBuildState);
fn build_display_list_for_block(&mut self,
state: &mut DisplayListBuildState,
@ -1880,8 +1911,8 @@ pub trait BlockFlowDisplayListBuilding {
/// TODO(mrobinson): It would be nice to use RAII here to avoid having to call restore.
pub struct PreservedDisplayListState {
stacking_context_id: StackingContextId,
scroll_root_id: ScrollRootId,
containing_block_scroll_root_id: ScrollRootId,
scroll_root_id: ClipId,
containing_block_scroll_root_id: ClipId,
clips_pushed: usize,
containing_block_clips_pushed: usize,
}
@ -2041,7 +2072,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
state: &mut DisplayListBuildState,
preserved_state: &mut PreservedDisplayListState,
stacking_context_type: BlockStackingContextType)
-> ScrollRootId {
-> ClipId {
// If this block is absolutely positioned, we should be clipped and positioned by
// the scroll root of our nearest ancestor that establishes a containing block.
let containing_scroll_root_id = match self.positioning() {
@ -2056,7 +2087,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
}
_ => state.current_scroll_root_id,
};
self.base.scroll_root_id = containing_scroll_root_id;
self.base.scroll_root_id = Some(containing_scroll_root_id);
let coordinate_system = if self.fragment.establishes_stacking_context() {
CoordinateSystem::Own
@ -2108,11 +2139,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
return;
}
let new_scroll_root_id = ScrollRootId::new_of_type(self.fragment.node.id() as usize,
self.fragment.fragment_type());
// If we already have a scroll root for this flow, just return. This can happen
// when fragments map to more than one flow, such as in the case of table
// wrappers. We just accept the first scroll root in that case.
let new_scroll_root_id = ClipId::new(self.fragment.unique_id(IdType::OverflowClip),
state.layout_context.id.to_webrender());
if state.has_scroll_root(new_scroll_root_id) {
return;
}
@ -2148,17 +2179,18 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
clip.intersect_with_rounded_rect(&clip_rect, &radii)
}
let parent_id = self.scroll_root_id(state.layout_context.id);
state.add_scroll_root(
ScrollRoot {
id: new_scroll_root_id,
parent_id: self.base.scroll_root_id,
parent_id: parent_id,
clip: clip,
content_rect: Rect::new(content_box.origin, content_size),
},
self.base.stacking_context_id
);
self.base.scroll_root_id = new_scroll_root_id;
self.base.scroll_root_id = Some(new_scroll_root_id);
state.current_scroll_root_id = new_scroll_root_id;
}
@ -2186,9 +2218,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
// use the fragment address to do the same for CSS clipping.
// TODO(mrobinson): This should be more resilient while maintaining the space
// efficiency of ScrollRootId.
let fragment_id = &mut self.fragment as *mut _;
let new_scroll_root_id = ScrollRootId::new_of_type(fragment_id as usize,
self.fragment.fragment_type());
let new_scroll_root_id = ClipId::new(self.fragment.unique_id(IdType::CSSClip),
state.layout_context.id.to_webrender());
// If we already have a scroll root for this flow, just return. This can happen
// when fragments map to more than one flow, such as in the case of table
@ -2200,24 +2231,24 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
let content_rect = Rect::new(clip_origin, clip_size);
preserved_state.push_clip(state, &content_rect, self.positioning());
let parent_id = self.scroll_root_id(state.layout_context.id);
state.add_scroll_root(
ScrollRoot {
id: new_scroll_root_id,
parent_id: self.base.scroll_root_id,
parent_id: parent_id,
clip: ClippingRegion::from_rect(&Rect::new(Point2D::zero(), clip_size)),
content_rect: content_rect,
},
self.base.stacking_context_id
);
self.base.scroll_root_id = new_scroll_root_id;
self.base.scroll_root_id = Some(new_scroll_root_id);
state.current_scroll_root_id = new_scroll_root_id;
}
fn create_pseudo_stacking_context_for_block(&mut self,
parent_stacking_context_id: StackingContextId,
parent_scroll_root_id: ScrollRootId,
parent_scroll_root_id: ClipId,
state: &mut DisplayListBuildState) {
let creation_mode = if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
self.fragment.style.get_box().position != position::T::static_ {
@ -2251,7 +2282,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
fn create_real_stacking_context_for_block(&mut self,
parent_stacking_context_id: StackingContextId,
parent_scroll_root_id: ScrollRootId,
parent_scroll_root_id: ClipId,
state: &mut DisplayListBuildState) {
let scroll_policy = if self.is_fixed() {
ScrollPolicy::Fixed
@ -2319,7 +2350,7 @@ pub trait InlineFlowDisplayListBuilding {
impl InlineFlowDisplayListBuilding for InlineFlow {
fn collect_stacking_contexts_for_inline(&mut self, state: &mut DisplayListBuildState) {
self.base.stacking_context_id = state.current_stacking_context_id;
self.base.scroll_root_id = state.current_scroll_root_id;
self.base.scroll_root_id = Some(state.current_scroll_root_id);
self.base.clip = state.clip_stack.last().cloned().unwrap_or_else(max_rect);
for mut fragment in self.fragments.fragments.iter_mut() {
@ -2342,9 +2373,8 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
block_flow.collect_stacking_contexts(state);
}
_ if fragment.establishes_stacking_context() => {
fragment.stacking_context_id =
StackingContextId::new_of_type(fragment.fragment_id(),
fragment.fragment_type());
fragment.stacking_context_id = fragment.stacking_context_id();
let current_stacking_context_id = state.current_stacking_context_id;
let current_scroll_root_id = state.current_scroll_root_id;
state.add_stacking_context(current_stacking_context_id,
@ -2565,4 +2595,3 @@ pub enum StackingContextCreationMode {
PseudoPositioned,
PseudoFloat,
}

View file

@ -35,10 +35,11 @@ use floats::{Floats, SpeculatedFloatPlacement};
use flow_list::{FlowList, MutFlowListIterator};
use flow_ref::{FlowRef, WeakFlowRef};
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
use gfx_traits::{ScrollRootId, StackingContextId};
use gfx_traits::StackingContextId;
use gfx_traits::print_tree::PrintTree;
use inline::InlineFlow;
use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
use msg::constellation_msg::PipelineId;
use multicol::MulticolFlow;
use parallel::FlowParallelInfo;
use serde::ser::{Serialize, SerializeStruct, Serializer};
@ -62,6 +63,7 @@ use table_colgroup::TableColGroupFlow;
use table_row::TableRowFlow;
use table_rowgroup::TableRowGroupFlow;
use table_wrapper::TableWrapperFlow;
use webrender_traits::ClipId;
/// Virtual methods that make up a float context.
///
@ -429,8 +431,14 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
/// children of this flow.
fn print_extra_flow_children(&self, _: &mut PrintTree) { }
fn scroll_root_id(&self) -> ScrollRootId {
base(self).scroll_root_id
fn scroll_root_id(&self, pipeline_id: PipelineId) -> ClipId {
match base(self).scroll_root_id {
Some(id) => id,
None => {
warn!("Tried to access scroll root id on Flow before assignment");
pipeline_id.root_scroll_node()
}
}
}
}
@ -961,7 +969,7 @@ pub struct BaseFlow {
/// list construction.
pub stacking_context_id: StackingContextId,
pub scroll_root_id: ScrollRootId,
pub scroll_root_id: Option<ClipId>,
}
impl fmt::Debug for BaseFlow {
@ -1104,8 +1112,8 @@ impl BaseFlow {
flags: flags,
writing_mode: writing_mode,
thread_id: 0,
stacking_context_id: StackingContextId::new(0),
scroll_root_id: ScrollRootId::root(),
stacking_context_id: StackingContextId::root(),
scroll_root_id: None,
}
}

View file

@ -17,7 +17,7 @@ use gfx;
use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
use gfx::text::glyph::ByteIndex;
use gfx::text::text_run::{TextRun, TextRunSlice};
use gfx_traits::{FragmentType, StackingContextId};
use gfx_traits::StackingContextId;
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFragmentContext, InlineFragmentNodeInfo};
use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT, LineMetrics};
use ipc_channel::ipc::IpcSender;
@ -665,7 +665,7 @@ impl Fragment {
pseudo: node.get_pseudo_element_type().strip(),
flags: FragmentFlags::empty(),
debug_id: DebugId::new(),
stacking_context_id: StackingContextId::new(0),
stacking_context_id: StackingContextId::root(),
}
}
@ -694,7 +694,7 @@ impl Fragment {
pseudo: pseudo,
flags: FragmentFlags::empty(),
debug_id: DebugId::new(),
stacking_context_id: StackingContextId::new(0),
stacking_context_id: StackingContextId::root(),
}
}
@ -719,7 +719,7 @@ impl Fragment {
pseudo: self.pseudo,
flags: FragmentFlags::empty(),
debug_id: DebugId::new(),
stacking_context_id: StackingContextId::new(0),
stacking_context_id: StackingContextId::root(),
}
}
@ -747,7 +747,7 @@ impl Fragment {
pseudo: self.pseudo.clone(),
flags: FragmentFlags::empty(),
debug_id: self.debug_id.clone(),
stacking_context_id: StackingContextId::new(0),
stacking_context_id: StackingContextId::root(),
}
}
@ -2798,21 +2798,6 @@ impl Fragment {
}
}
pub fn fragment_id(&self) -> usize {
return self as *const Fragment as usize;
}
pub fn fragment_type(&self) -> FragmentType {
match self.pseudo {
PseudoElementType::Normal => FragmentType::FragmentBody,
PseudoElementType::Before(_) => FragmentType::BeforePseudoContent,
PseudoElementType::After(_) => FragmentType::AfterPseudoContent,
PseudoElementType::DetailsSummary(_) => FragmentType::FragmentBody,
PseudoElementType::DetailsContent(_) => FragmentType::FragmentBody,
}
}
/// Returns true if any of the inline styles associated with this fragment have
/// `vertical-align` set to `top` or `bottom`.
pub fn is_vertically_aligned_to_top_or_bottom(&self) -> bool {

View file

@ -13,9 +13,9 @@ use euclid::size::Size2D;
use flow::{self, Flow};
use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
use gfx::display_list::{DisplayItemMetadata, DisplayList, OpaqueNode, ScrollOffsetMap};
use gfx_traits::ScrollRootId;
use inline::LAST_FRAGMENT_OF_ELEMENT;
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId;
use opaque_node::OpaqueNodeMethods;
use script_layout_interface::PendingImage;
use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse};
@ -41,6 +41,7 @@ use style::selector_parser::PseudoElement;
use style::stylist::Stylist;
use style_traits::ToCss;
use style_traits::cursor::Cursor;
use webrender_traits::ClipId;
use wrapper::{LayoutNodeHelpers, LayoutNodeLayoutData};
/// Mutable data belonging to the LayoutThread.
@ -69,7 +70,7 @@ pub struct LayoutThreadData {
pub hit_test_response: (Option<DisplayItemMetadata>, bool),
/// A queued response for the scroll root id for a given node.
pub scroll_root_id_response: Option<ScrollRootId>,
pub scroll_root_id_response: Option<ClipId>,
/// A pair of overflow property in x and y
pub overflow_response: NodeOverflowResponse,
@ -650,9 +651,11 @@ pub fn process_node_geometry_request<N: LayoutNode>(requested_node: N, layout_ro
iterator.client_rect
}
pub fn process_node_scroll_root_id_request<N: LayoutNode>(requested_node: N) -> ScrollRootId {
pub fn process_node_scroll_root_id_request<N: LayoutNode>(id: PipelineId,
requested_node: N)
-> ClipId {
let layout_node = requested_node.to_threadsafe();
layout_node.scroll_root_id()
layout_node.generate_scroll_root_id(id)
}
pub fn process_node_scroll_area_request< N: LayoutNode>(requested_node: N, layout_root: &mut Flow)

View file

@ -242,7 +242,7 @@ impl<'a> BuildDisplayList<'a> {
self.state.current_stacking_context_id = flow::base(flow).stacking_context_id;
let parent_scroll_root_id = self.state.current_scroll_root_id;
self.state.current_scroll_root_id = flow::base(flow).scroll_root_id;
self.state.current_scroll_root_id = flow.scroll_root_id(self.state.layout_context.id);
if self.should_process() {
flow.build_display_list(&mut self.state);

View file

@ -11,7 +11,6 @@ use app_units::Au;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use gfx::display_list::{BorderDetails, BorderRadii, BoxShadowClipMode, ClippingRegion};
use gfx::display_list::{DisplayItem, DisplayList, DisplayListTraversal, StackingContextType};
use gfx_traits::ScrollRootId;
use msg::constellation_msg::PipelineId;
use style::computed_values::{image_rendering, mix_blend_mode};
use style::computed_values::filter::{self, Filter};
@ -25,7 +24,7 @@ pub trait WebRenderDisplayListConverter {
trait WebRenderDisplayItemConverter {
fn convert_to_webrender(&self,
builder: &mut DisplayListBuilder,
current_scroll_root_id: &mut ScrollRootId);
current_scroll_root_id: &mut ClipId);
}
trait ToBorderStyle {
@ -217,8 +216,8 @@ impl WebRenderDisplayListConverter for DisplayList {
let webrender_pipeline_id = pipeline_id.to_webrender();
let mut builder = DisplayListBuilder::new(webrender_pipeline_id);
let mut current_scroll_root_id = ScrollRootId::root();
builder.push_clip_id(current_scroll_root_id.convert_to_webrender(webrender_pipeline_id));
let mut current_scroll_root_id = ClipId::root_scroll_node(webrender_pipeline_id);
builder.push_clip_id(current_scroll_root_id);
for item in traversal {
item.convert_to_webrender(&mut builder, &mut current_scroll_root_id);
@ -230,12 +229,11 @@ impl WebRenderDisplayListConverter for DisplayList {
impl WebRenderDisplayItemConverter for DisplayItem {
fn convert_to_webrender(&self,
builder: &mut DisplayListBuilder,
current_scroll_root_id: &mut ScrollRootId) {
current_scroll_root_id: &mut ClipId) {
let scroll_root_id = self.base().scroll_root_id;
if scroll_root_id != *current_scroll_root_id {
let pipeline_id = builder.pipeline_id;
builder.pop_clip_id();
builder.push_clip_id(scroll_root_id.convert_to_webrender(pipeline_id));
builder.push_clip_id(scroll_root_id);
*current_scroll_root_id = scroll_root_id;
}
@ -425,10 +423,9 @@ impl WebRenderDisplayItemConverter for DisplayItem {
}
DisplayItem::PopStackingContext(_) => builder.pop_stacking_context(),
DisplayItem::PushScrollRoot(ref item) => {
let pipeline_id = builder.pipeline_id;
builder.push_clip_id(item.scroll_root.parent_id.convert_to_webrender(pipeline_id));
builder.push_clip_id(item.scroll_root.parent_id);
let our_id = item.scroll_root.id.convert_to_webrender(pipeline_id);
let our_id = item.scroll_root.id;
let clip = item.scroll_root.clip.to_clip_region(builder);
let content_rect = item.scroll_root.content_rect.to_rectf();
let webrender_id = builder.define_clip(content_rect, clip, Some(our_id));
@ -440,16 +437,3 @@ impl WebRenderDisplayItemConverter for DisplayItem {
}
}
}
trait WebRenderScrollRootIdConverter {
fn convert_to_webrender(&self, pipeline_id: webrender_traits::PipelineId) -> ClipId;
}
impl WebRenderScrollRootIdConverter for ScrollRootId {
fn convert_to_webrender(&self, pipeline_id: webrender_traits::PipelineId) -> ClipId {
if *self == ScrollRootId::root() {
ClipId::root_scroll_node(pipeline_id)
} else {
ClipId::new(self.0 as u64, pipeline_id)
}
}
}