diff options
24 files changed, 224 insertions, 279 deletions
diff --git a/Cargo.lock b/Cargo.lock index e42926a39ca..119302c8d0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2339,6 +2339,7 @@ dependencies = [ "selectors 0.18.0", "servo_url 0.0.1", "style 0.0.1", + "webrender_traits 0.35.0 (git+https://github.com/servo/webrender)", ] [[package]] @@ -2383,6 +2384,7 @@ dependencies = [ "style_traits 0.0.1", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webrender_traits 0.35.0 (git+https://github.com/servo/webrender)", "webvr_traits 0.0.1", ] diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index f76ee24b039..96a44a7dc04 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -12,7 +12,7 @@ use euclid::point::TypedPoint2D; use euclid::rect::TypedRect; use euclid::scale_factor::ScaleFactor; use euclid::size::TypedSize2D; -use gfx_traits::{Epoch, ScrollRootId}; +use gfx_traits::Epoch; use gleam::gl; use image::{DynamicImage, ImageFormat, RgbImage}; use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory}; @@ -39,7 +39,7 @@ use style_traits::viewport::ViewportConstraints; use time::{precise_time_ns, precise_time_s}; use touch::{TouchHandler, TouchAction}; use webrender; -use webrender_traits::{self, LayoutPoint, ScrollEventPhase, ClipId, ScrollLocation}; +use webrender_traits::{self, ClipId, LayoutPoint, ScrollEventPhase, ScrollLocation}; use windowing::{self, MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg}; #[derive(Debug, PartialEq)] @@ -72,19 +72,6 @@ impl ConvertPipelineIdFromWebRender for webrender_traits::PipelineId { } } -trait ConvertScrollRootIdFromWebRender { - fn from_webrender(&self) -> ScrollRootId; -} - -impl ConvertScrollRootIdFromWebRender for u64 { - fn from_webrender(&self) -> ScrollRootId { - // This conversion is lossy on 32 bit platforms, - // but we only actually use the bottom 32 bits - // on Servo anyway. - ScrollRootId(*self as usize) - } -} - /// Holds the state when running reftests that determines when it is /// safe to save the output image. #[derive(Copy, Clone, PartialEq)] @@ -505,9 +492,9 @@ impl<Window: WindowMethods> IOCompositor<Window> { self.title_for_main_frame(); } - (Msg::ScrollFragmentPoint(pipeline_id, scroll_root_id, point, _), + (Msg::ScrollFragmentPoint(scroll_root_id, point, _), ShutdownState::NotShuttingDown) => { - self.scroll_fragment_to_point(pipeline_id, scroll_root_id, point); + self.scroll_fragment_to_point(scroll_root_id, point); } (Msg::MoveTo(point), @@ -793,16 +780,7 @@ impl<Window: WindowMethods> IOCompositor<Window> { self.composition_request = CompositionRequest::DelayedComposite(timestamp); } - fn scroll_fragment_to_point(&mut self, - pipeline_id: PipelineId, - scroll_root_id: ScrollRootId, - point: Point2D<f32>) { - let id = if scroll_root_id.0 == 0 { - ClipId::root_scroll_node(pipeline_id.to_webrender()) - } else { - ClipId::new(scroll_root_id.0 as u64, pipeline_id.to_webrender()) - }; - + fn scroll_fragment_to_point(&mut self, id: ClipId, point: Point2D<f32>) { self.webrender_api.scroll_node_with_id(LayoutPoint::from_untyped(&point), id); } @@ -1395,13 +1373,13 @@ impl<Window: WindowMethods> IOCompositor<Window> { fn send_viewport_rects(&self) { let mut stacking_context_scroll_states_per_pipeline = HashMap::new(); for scroll_layer_state in self.webrender_api.get_scroll_node_state() { - let external_id = match scroll_layer_state.id.external_id() { - Some(id) => id, - None => continue, - }; + if scroll_layer_state.id.external_id().is_none() && + scroll_layer_state.id.is_root_scroll_node() { + continue; + } let stacking_context_scroll_state = StackingContextScrollState { - scroll_root_id: external_id.from_webrender(), + scroll_root_id: scroll_layer_state.id, scroll_offset: scroll_layer_state.scroll_offset.to_untyped(), }; diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs index e475bba0514..67d98d9e5e5 100644 --- a/components/compositing/compositor_thread.rs +++ b/components/compositing/compositor_thread.rs @@ -8,7 +8,6 @@ use SendableFrameTree; use compositor::CompositingReason; use euclid::point::Point2D; use euclid::size::Size2D; -use gfx_traits::ScrollRootId; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::{Key, KeyModifiers, KeyState, PipelineId}; use net_traits::image::base::Image; @@ -73,7 +72,7 @@ pub enum Msg { ShutdownComplete, /// Scroll a page in a window - ScrollFragmentPoint(PipelineId, ScrollRootId, Point2D<f32>, bool), + ScrollFragmentPoint(webrender_traits::ClipId, Point2D<f32>, bool), /// Alerts the compositor that the current page has changed its title. ChangePageTitle(PipelineId, Option<String>), /// Alerts the compositor that the current page has changed its URL. diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 31942533990..b2328c8bd08 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -1036,9 +1036,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> self.handle_alert(pipeline_id, message, sender); } - FromScriptMsg::ScrollFragmentPoint(pipeline_id, scroll_root_id, point, smooth) => { - self.compositor_proxy.send(ToCompositorMsg::ScrollFragmentPoint(pipeline_id, - scroll_root_id, + FromScriptMsg::ScrollFragmentPoint(scroll_root_id, point, smooth) => { + self.compositor_proxy.send(ToCompositorMsg::ScrollFragmentPoint(scroll_root_id, point, smooth)); } diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index 4113193fc67..205b4071589 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -19,7 +19,7 @@ use euclid::{Matrix4D, Point2D, Rect, Size2D}; use euclid::num::{One, Zero}; use euclid::rect::TypedRect; use euclid::side_offsets::SideOffsets2D; -use gfx_traits::{ScrollRootId, StackingContextId}; +use gfx_traits::StackingContextId; use gfx_traits::print_tree::PrintTree; use ipc_channel::ipc::IpcSharedMemory; use msg::constellation_msg::PipelineId; @@ -34,7 +34,7 @@ use style::computed_values::{border_style, filter, image_rendering, mix_blend_mo use style_traits::cursor::Cursor; use text::TextRun; use text::glyph::ByteIndex; -use webrender_traits::{self, ColorF, GradientStop, ScrollPolicy, WebGLContextId}; +use webrender_traits::{self, ClipId, ColorF, GradientStop, ScrollPolicy, WebGLContextId}; pub use style::dom::OpaqueNode; @@ -377,7 +377,7 @@ pub struct StackingContext { pub scroll_policy: ScrollPolicy, /// The id of the parent scrolling area that contains this StackingContext. - pub parent_scroll_id: ScrollRootId, + pub parent_scroll_id: ClipId, } impl StackingContext { @@ -393,7 +393,7 @@ impl StackingContext { transform: Option<Matrix4D<f32>>, perspective: Option<Matrix4D<f32>>, scroll_policy: ScrollPolicy, - parent_scroll_id: ScrollRootId) + parent_scroll_id: ClipId) -> StackingContext { StackingContext { id: id, @@ -411,8 +411,8 @@ impl StackingContext { } #[inline] - pub fn root() -> StackingContext { - StackingContext::new(StackingContextId::new(0), + pub fn root(pipeline_id: PipelineId) -> StackingContext { + StackingContext::new(StackingContextId::root(), StackingContextType::Real, &Rect::zero(), &Rect::zero(), @@ -422,11 +422,11 @@ impl StackingContext { None, None, ScrollPolicy::Scrollable, - ScrollRootId::root()) + pipeline_id.root_scroll_node()) } - pub fn to_display_list_items(self) -> (DisplayItem, DisplayItem) { - let mut base_item = BaseDisplayItem::empty(); + pub fn to_display_list_items(self, pipeline_id: PipelineId) -> (DisplayItem, DisplayItem) { + let mut base_item = BaseDisplayItem::empty(pipeline_id); base_item.stacking_context_id = self.id; base_item.scroll_root_id = self.parent_scroll_id; @@ -495,11 +495,12 @@ impl fmt::Debug for StackingContext { /// Defines a stacking context. #[derive(Clone, Debug, HeapSizeOf, Deserialize, Serialize)] pub struct ScrollRoot { - /// The unique ID of this ScrollRoot. - pub id: ScrollRootId, + /// The WebRender clip id of this scroll root based on the source of this clip + /// and information about the fragment. + pub id: ClipId, /// The unique ID of the parent of this ScrollRoot. - pub parent_id: ScrollRootId, + pub parent_id: ClipId, /// The position of this scroll root's frame in the parent stacking context. pub clip: ClippingRegion, @@ -509,9 +510,9 @@ pub struct ScrollRoot { } impl ScrollRoot { - pub fn to_push(&self) -> DisplayItem { + pub fn to_push(&self, pipeline_id: PipelineId) -> DisplayItem { DisplayItem::PushScrollRoot(box PushScrollRootItem { - base: BaseDisplayItem::empty(), + base: BaseDisplayItem::empty(pipeline_id), scroll_root: self.clone(), }) } @@ -555,7 +556,7 @@ pub struct BaseDisplayItem { pub stacking_context_id: StackingContextId, /// The id of the scroll root this item belongs to. - pub scroll_root_id: ScrollRootId, + pub scroll_root_id: ClipId, } impl BaseDisplayItem { @@ -565,7 +566,7 @@ impl BaseDisplayItem { clip: &ClippingRegion, section: DisplayListSection, stacking_context_id: StackingContextId, - scroll_root_id: ScrollRootId) + scroll_root_id: ClipId) -> BaseDisplayItem { // Detect useless clipping regions here and optimize them to `ClippingRegion::max()`. // The painting backend may want to optimize out clipping regions and this makes it easier @@ -585,7 +586,7 @@ impl BaseDisplayItem { } #[inline(always)] - pub fn empty() -> BaseDisplayItem { + pub fn empty(pipeline_id: PipelineId) -> BaseDisplayItem { BaseDisplayItem { bounds: TypedRect::zero(), metadata: DisplayItemMetadata { @@ -595,7 +596,7 @@ impl BaseDisplayItem { clip: ClippingRegion::max(), section: DisplayListSection::Content, stacking_context_id: StackingContextId::root(), - scroll_root_id: ScrollRootId::root(), + scroll_root_id: pipeline_id.root_scroll_node(), } } } @@ -866,7 +867,6 @@ pub struct ImageDisplayItem { #[derive(Clone, HeapSizeOf, Deserialize, Serialize)] pub struct WebGLDisplayItem { pub base: BaseDisplayItem, - #[ignore_heap_size_of = "Defined in webrender_traits"] pub context_id: WebGLContextId, } @@ -931,11 +931,9 @@ pub struct ImageBorder { pub fill: bool, /// How to repeat or stretch horizontal edges (border-image-repeat). - #[ignore_heap_size_of = "WebRender traits type, and tiny"] pub repeat_horizontal: webrender_traits::RepeatMode, /// How to repeat or stretch vertical edges (border-image-repeat). - #[ignore_heap_size_of = "WebRender traits type, and tiny"] pub repeat_vertical: webrender_traits::RepeatMode, } @@ -1136,7 +1134,7 @@ impl DisplayItem { } } - pub fn scroll_root_id(&self) -> ScrollRootId { + pub fn scroll_root_id(&self) -> ClipId { self.base().scroll_root_id } @@ -1262,7 +1260,6 @@ pub struct WebRenderImageInfo { pub width: u32, pub height: u32, pub format: PixelFormat, - #[ignore_heap_size_of = "WebRender traits type, and tiny"] pub key: Option<webrender_traits::ImageKey>, } @@ -1279,7 +1276,7 @@ impl WebRenderImageInfo { } /// The type of the scroll offset list. This is only populated if WebRender is in use. -pub type ScrollOffsetMap = HashMap<ScrollRootId, Point2D<f32>>; +pub type ScrollOffsetMap = HashMap<ClipId, Point2D<f32>>; pub trait SimpleMatrixDetection { diff --git a/components/gfx_traits/lib.rs b/components/gfx_traits/lib.rs index 0dae3d6fff1..14f168671d7 100644 --- a/components/gfx_traits/lib.rs +++ b/components/gfx_traits/lib.rs @@ -19,18 +19,6 @@ pub mod print_tree; use range::RangeIndex; use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering}; -/// The next ID that will be used for a special stacking context. -/// -/// A special stacking context is a stacking context that is one of (a) the outer stacking context -/// of an element with `overflow: scroll`; (b) generated content; (c) both (a) and (b). -static NEXT_SPECIAL_STACKING_CONTEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT; - -/// If none of the bits outside this mask are set, the stacking context is a special stacking -/// context. -/// -/// Note that we assume that the top 16 bits of the address space are unused on the platform. -const SPECIAL_STACKING_CONTEXT_ID_MASK: usize = 0xffff; - /// A newtype struct for denoting the age of messages; prevents race conditions. #[derive(PartialEq, Eq, Debug, Copy, Clone, PartialOrd, Ord, Deserialize, Serialize)] pub struct Epoch(pub u32); @@ -46,89 +34,29 @@ impl Epoch { pub struct StackingContextId( /// The identifier for this StackingContext, derived from the Flow's memory address /// and fragment type. As a space optimization, these are combined into a single word. - usize + u64 ); impl StackingContextId { - #[inline] - pub fn new(id: usize) -> StackingContextId { - StackingContextId::new_of_type(id, FragmentType::FragmentBody) - } - - /// Returns a new stacking context ID for a special stacking context. - fn next_special_id() -> usize { - // We shift this left by 2 to make room for the fragment type ID. - ((NEXT_SPECIAL_STACKING_CONTEXT_ID.fetch_add(1, Ordering::SeqCst) + 1) << 2) & - SPECIAL_STACKING_CONTEXT_ID_MASK - } - - #[inline] - pub fn new_of_type(id: usize, fragment_type: FragmentType) -> StackingContextId { - debug_assert_eq!(id & (fragment_type as usize), 0); - if fragment_type == FragmentType::FragmentBody { - StackingContextId(id) - } else { - StackingContextId(StackingContextId::next_special_id() | (fragment_type as usize)) - } - } - /// Returns the stacking context ID for the outer document/layout root. #[inline] pub fn root() -> StackingContextId { StackingContextId(0) } -} - -/// A unique ID for every scrolling root. -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, HeapSizeOf, PartialEq, Serialize)] -pub struct ScrollRootId( - /// The identifier for this StackingContext, derived from the Flow's memory address - /// and fragment type. As a space optimization, these are combined into a single word. - pub usize -); - -impl ScrollRootId { - /// Returns a new stacking context ID for a special stacking context. - fn next_special_id() -> usize { - // We shift this left by 2 to make room for the fragment type ID. - ((NEXT_SPECIAL_STACKING_CONTEXT_ID.fetch_add(1, Ordering::SeqCst) + 1) << 2) & - SPECIAL_STACKING_CONTEXT_ID_MASK - } - - #[inline] - pub fn new_of_type(id: usize, fragment_type: FragmentType) -> ScrollRootId { - debug_assert_eq!(id & (fragment_type as usize), 0); - if fragment_type == FragmentType::FragmentBody { - ScrollRootId(id) - } else { - ScrollRootId(ScrollRootId::next_special_id() | (fragment_type as usize)) - } - } - - /// Returns the stacking context ID for the outer document/layout root. - #[inline] - pub fn root() -> ScrollRootId { - ScrollRootId(0) - } - /// Returns true if this is a special stacking context. - /// - /// A special stacking context is a stacking context that is one of (a) the outer stacking - /// context of an element with `overflow: scroll`; (b) generated content; (c) both (a) and (b). + /// Returns a new sacking context id with the given numeric id. #[inline] - pub fn is_special(&self) -> bool { - (self.0 & !SPECIAL_STACKING_CONTEXT_ID_MASK) == 0 - } - - #[inline] - pub fn id(&self) -> usize { - self.0 & !3 + pub fn new(id: u64) -> StackingContextId { + StackingContextId(id) } +} - #[inline] - pub fn fragment_type(&self) -> FragmentType { - FragmentType::from_usize(self.0 & 3) - } +int_range_index! { + #[derive(Deserialize, Serialize)] + #[doc = "An index that refers to a byte offset in a text run. This could \ + point to the middle of a glyph."] + #[derive(HeapSizeOf)] + struct ByteIndex(isize) } /// The type of fragment that a stacking context represents. @@ -146,22 +74,37 @@ pub enum FragmentType { AfterPseudoContent, } -impl FragmentType { - #[inline] - pub fn from_usize(n: usize) -> FragmentType { - debug_assert!(n < 3); - match n { - 0 => FragmentType::FragmentBody, - 1 => FragmentType::BeforePseudoContent, - _ => FragmentType::AfterPseudoContent, - } +/// The next ID that will be used for a special stacking context. +/// +/// A special stacking context is a stacking context that is one of (a) the outer stacking context +/// of an element with `overflow: scroll`; (b) generated content; (c) both (a) and (b). +static NEXT_SPECIAL_STACKING_CONTEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT; + +/// If none of the bits outside this mask are set, the stacking context is a special stacking +/// context. +/// +/// Note that we assume that the top 16 bits of the address space are unused on the platform. +const SPECIAL_STACKING_CONTEXT_ID_MASK: usize = 0xffff; + +/// Returns a new stacking context ID for a special stacking context. +fn next_special_id() -> usize { + // We shift this left by 2 to make room for the fragment type ID. + ((NEXT_SPECIAL_STACKING_CONTEXT_ID.fetch_add(1, Ordering::SeqCst) + 1) << 2) & + SPECIAL_STACKING_CONTEXT_ID_MASK +} + +pub fn combine_id_with_fragment_type(id: usize, fragment_type: FragmentType) -> usize { + debug_assert_eq!(id & (fragment_type as usize), 0); + if fragment_type == FragmentType::FragmentBody { + id + } else { + next_special_id() | (fragment_type as usize) } } -int_range_index! { - #[derive(Deserialize, Serialize)] - #[doc = "An index that refers to a byte offset in a text run. This could \ - point to the middle of a glyph."] - #[derive(HeapSizeOf)] - struct ByteIndex(isize) +pub fn node_id_from_clip_id(id: usize) -> Option<usize> { + if (id & !SPECIAL_STACKING_CONTEXT_ID_MASK) != 0 { + return Some((id & !3) as usize); + } + None } diff --git a/components/layout/context.rs b/components/layout/context.rs index 72be2555720..214061e276f 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -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>, diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index bb69af42b68..fdd7692c1f1 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -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, } - diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 372d76a404c..a56cb7537d5 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -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, } } diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 420fb2c42ae..ee892b75f11 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -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 { diff --git a/components/layout/query.rs b/components/layout/query.rs index b4008d24c60..88aca41ae30 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -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) diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index 88852e4193a..ab4f2c2f1b6 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -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); diff --git a/components/layout/webrender_helpers.rs b/components/layout/webrender_helpers.rs index 0f21523ceb9..9756ea6d1d6 100644 --- a/components/layout/webrender_helpers.rs +++ b/components/layout/webrender_helpers.rs @@ -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) - } - } -} diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 286d49484f6..fe6e6d0dea2 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -49,7 +49,7 @@ use gfx::display_list::{OpaqueNode, WebRenderImageInfo}; use gfx::font; use gfx::font_cache_thread::FontCacheThread; use gfx::font_context; -use gfx_traits::{Epoch, FragmentType, ScrollRootId}; +use gfx_traits::{Epoch, node_id_from_clip_id}; use heapsize::HeapSizeOf; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; @@ -514,6 +514,7 @@ impl LayoutThread { ThreadLocalStyleContextCreationInfo::new(self.new_animations_sender.clone()); LayoutContext { + id: self.id, style_context: SharedStyleContext { stylist: rw_data.stylist.clone(), options: StyleSystemOptions::default(), @@ -1282,7 +1283,8 @@ impl LayoutThread { }, ReflowQueryType::NodeScrollRootIdQuery(node) => { let node = unsafe { ServoLayoutNode::new(&node) }; - rw_data.scroll_root_id_response = Some(process_node_scroll_root_id_request(node)); + rw_data.scroll_root_id_response = Some(process_node_scroll_root_id_request(self.id, + node)); }, ReflowQueryType::ResolvedStyleQuery(node, ref pseudo, ref property) => { let node = unsafe { ServoLayoutNode::new(&node) }; @@ -1339,12 +1341,12 @@ impl LayoutThread { let offset = new_scroll_state.scroll_offset; layout_scroll_states.insert(new_scroll_state.scroll_root_id, offset); - if new_scroll_state.scroll_root_id == ScrollRootId::root() { + if new_scroll_state.scroll_root_id.is_root_scroll_node() { script_scroll_states.push((UntrustedNodeAddress::from_id(0), offset)) - } else if !new_scroll_state.scroll_root_id.is_special() && - new_scroll_state.scroll_root_id.fragment_type() == FragmentType::FragmentBody { - let id = new_scroll_state.scroll_root_id.id(); - script_scroll_states.push((UntrustedNodeAddress::from_id(id), offset)) + } else if let Some(id) = new_scroll_state.scroll_root_id.external_id() { + if let Some(node_id) = node_id_from_clip_id(id as usize) { + script_scroll_states.push((UntrustedNodeAddress::from_id(node_id), offset)) + } } } let _ = self.script_chan diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs index dddfb0c0042..5b5110099f6 100644 --- a/components/msg/constellation_msg.rs +++ b/components/msg/constellation_msg.rs @@ -244,6 +244,10 @@ impl PipelineId { let PipelineIndex(index) = self.index; webrender_traits::PipelineId(namespace_id, index) } + + pub fn root_scroll_node(&self) -> webrender_traits::ClipId { + webrender_traits::ClipId::root_scroll_node(self.to_webrender()) + } } impl fmt::Display for PipelineId { diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 940baaca36f..427282630d5 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -93,7 +93,6 @@ use dom_struct::dom_struct; use encoding::EncodingRef; use encoding::all::UTF_8; use euclid::point::Point2D; -use gfx_traits::ScrollRootId; use html5ever_atoms::{LocalName, QualName}; use hyper::header::{Header, SetCookie}; use hyper_serde::Serde; @@ -143,6 +142,7 @@ use time; use timers::OneshotTimerCallback; use url::Host; use url::percent_encoding::percent_decode; +use webrender_traits::ClipId; /// The number of times we are allowed to see spurious `requestAnimationFrame()` calls before /// falling back to fake ones. @@ -699,9 +699,11 @@ impl Document { if let Some((x, y)) = point { // Step 3 + let global_scope = self.window.upcast::<GlobalScope>(); + let webrender_pipeline_id = global_scope.pipeline_id().to_webrender(); self.window.perform_a_scroll(x, y, - ScrollRootId::root(), + ClipId::root_scroll_node(webrender_pipeline_id), ScrollBehavior::Instant, target.r()); } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 0c8ea1a6594..df7fe995c1f 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -52,7 +52,6 @@ use dom::testrunner::TestRunner; use dom_struct::dom_struct; use euclid::{Point2D, Rect, Size2D}; use fetch; -use gfx_traits::ScrollRootId; use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; use js::jsapi::{HandleObject, HandleValue, JSAutoCompartment, JSContext}; @@ -122,6 +121,7 @@ use timers::{IsInterval, TimerCallback}; use tinyfiledialogs::{self, MessageBoxIcon}; use url::Position; use webdriver_handlers::jsval_to_webdriver; +use webrender_traits::ClipId; use webvr_traits::WebVRMsg; /// Current state of the window object @@ -1077,9 +1077,10 @@ impl Window { //TODO Step 11 //let document = self.Document(); // Step 12 + let global_scope = self.upcast::<GlobalScope>(); self.perform_a_scroll(x.to_f32().unwrap_or(0.0f32), y.to_f32().unwrap_or(0.0f32), - ScrollRootId::root(), + global_scope.pipeline_id().root_scroll_node(), behavior, None); } @@ -1088,7 +1089,7 @@ impl Window { pub fn perform_a_scroll(&self, x: f32, y: f32, - scroll_root_id: ScrollRootId, + scroll_root_id: ClipId, behavior: ScrollBehavior, element: Option<&Element>) { //TODO Step 1 @@ -1108,8 +1109,7 @@ impl Window { self.update_viewport_for_scroll(x, y); let global_scope = self.upcast::<GlobalScope>(); - let message = ConstellationMsg::ScrollFragmentPoint( - global_scope.pipeline_id(), scroll_root_id, point, smooth); + let message = ConstellationMsg::ScrollFragmentPoint(scroll_root_id, point, smooth); global_scope.constellation_chan().send(message).unwrap(); } diff --git a/components/script_layout_interface/Cargo.toml b/components/script_layout_interface/Cargo.toml index 62fd1dc2136..9db6a37eea0 100644 --- a/components/script_layout_interface/Cargo.toml +++ b/components/script_layout_interface/Cargo.toml @@ -30,3 +30,4 @@ script_traits = {path = "../script_traits"} selectors = { path = "../selectors" } servo_url = {path = "../url"} style = {path = "../style"} +webrender_traits = {git = "https://github.com/servo/webrender", features = ["ipc"]} diff --git a/components/script_layout_interface/lib.rs b/components/script_layout_interface/lib.rs index 674b5325e81..98375e6a05a 100644 --- a/components/script_layout_interface/lib.rs +++ b/components/script_layout_interface/lib.rs @@ -32,6 +32,7 @@ extern crate script_traits; extern crate selectors; extern crate servo_url; extern crate style; +extern crate webrender_traits; pub mod message; pub mod reporter; diff --git a/components/script_layout_interface/rpc.rs b/components/script_layout_interface/rpc.rs index b07fa25a8c1..82dd9b9ff08 100644 --- a/components/script_layout_interface/rpc.rs +++ b/components/script_layout_interface/rpc.rs @@ -6,9 +6,9 @@ use PendingImage; use app_units::Au; use euclid::point::Point2D; use euclid::rect::Rect; -use gfx_traits::ScrollRootId; use script_traits::UntrustedNodeAddress; use style::properties::longhands::{margin_top, margin_right, margin_bottom, margin_left, overflow_x}; +use webrender_traits::ClipId; /// Synchronous messages that script can send to layout. /// @@ -56,7 +56,7 @@ pub struct NodeGeometryResponse { pub struct NodeOverflowResponse(pub Option<Point2D<overflow_x::computed_value::T>>); -pub struct NodeScrollRootIdResponse(pub ScrollRootId); +pub struct NodeScrollRootIdResponse(pub ClipId); pub struct HitTestResponse { pub node_address: Option<UntrustedNodeAddress>, diff --git a/components/script_layout_interface/wrapper_traits.rs b/components/script_layout_interface/wrapper_traits.rs index 88a1dbebb33..4abc74bcac0 100644 --- a/components/script_layout_interface/wrapper_traits.rs +++ b/components/script_layout_interface/wrapper_traits.rs @@ -9,7 +9,7 @@ use LayoutNodeType; use OpaqueStyleAndLayoutData; use SVGSVGData; use atomic_refcell::AtomicRefCell; -use gfx_traits::{ByteIndex, FragmentType, ScrollRootId}; +use gfx_traits::{ByteIndex, FragmentType, combine_id_with_fragment_type}; use html5ever_atoms::{Namespace, LocalName}; use msg::constellation_msg::PipelineId; use range::Range; @@ -24,6 +24,7 @@ use style::dom::OpaqueNode; use style::font_metrics::ServoMetricsProvider; use style::properties::{CascadeFlags, ServoComputedValues}; use style::selector_parser::{PseudoElement, PseudoElementCascadeType, SelectorImpl}; +use webrender_traits::ClipId; #[derive(Copy, PartialEq, Clone, Debug)] pub enum PseudoElementType<T> { @@ -288,8 +289,9 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + Debug + GetLayoutData + NodeInfo } } - fn scroll_root_id(&self) -> ScrollRootId { - ScrollRootId::new_of_type(self.opaque().id() as usize, self.fragment_type()) + fn generate_scroll_root_id(&self, pipeline_id: PipelineId) -> ClipId { + let id = combine_id_with_fragment_type(self.opaque().id(), self.fragment_type()); + ClipId::new(id as u64, pipeline_id.to_webrender()) } } diff --git a/components/script_traits/Cargo.toml b/components/script_traits/Cargo.toml index c3332046117..da5fcc78704 100644 --- a/components/script_traits/Cargo.toml +++ b/components/script_traits/Cargo.toml @@ -34,4 +34,5 @@ servo_url = {path = "../url"} style_traits = {path = "../style_traits", features = ["servo"]} time = "0.1.12" url = {version = "1.2", features = ["heap_size"]} +webrender_traits = {git = "https://github.com/servo/webrender", features = ["ipc"]} webvr_traits = {path = "../webvr_traits"} diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index f7248466d39..da5191f73bd 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -33,6 +33,7 @@ extern crate serde_derive; extern crate servo_url; extern crate style_traits; extern crate time; +extern crate webrender_traits; extern crate webvr_traits; mod script_msg; @@ -47,7 +48,6 @@ use euclid::rect::Rect; use euclid::scale_factor::ScaleFactor; use euclid::size::TypedSize2D; use gfx_traits::Epoch; -use gfx_traits::ScrollRootId; use heapsize::HeapSizeOf; use hyper::header::Headers; use hyper::method::Method; @@ -71,6 +71,7 @@ use std::sync::Arc; use std::sync::mpsc::{Receiver, Sender}; use style_traits::{CSSPixel, UnsafeNode}; use webdriver_msg::{LoadStatus, WebDriverScriptCommand}; +use webrender_traits::ClipId; use webvr_traits::{WebVREvent, WebVRMsg}; pub use script_msg::{LayoutMsg, ScriptMsg, EventResult, LogEntry}; @@ -662,7 +663,7 @@ pub enum AnimationTickType { #[derive(Copy, Clone, Debug, Deserialize, Serialize)] pub struct StackingContextScrollState { /// The ID of the scroll root. - pub scroll_root_id: ScrollRootId, + pub scroll_root_id: ClipId, /// The scrolling offset of this stacking context. pub scroll_offset: Point2D<f32>, } diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs index 3e61fa8ae62..47a7b103c8c 100644 --- a/components/script_traits/script_msg.rs +++ b/components/script_traits/script_msg.rs @@ -16,7 +16,6 @@ use canvas_traits::CanvasMsg; use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId}; use euclid::point::Point2D; use euclid::size::{Size2D, TypedSize2D}; -use gfx_traits::ScrollRootId; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::{FrameId, FrameType, PipelineId, TraversalDirection}; use msg::constellation_msg::{Key, KeyModifiers, KeyState}; @@ -28,6 +27,7 @@ use servo_url::ServoUrl; use style_traits::CSSPixel; use style_traits::cursor::Cursor; use style_traits::viewport::ViewportConstraints; +use webrender_traits::ClipId; /// Messages from the layout to the constellation. #[derive(Deserialize, Serialize)] @@ -133,7 +133,7 @@ pub enum ScriptMsg { /// Check if an alert dialog box should be presented Alert(PipelineId, String, IpcSender<bool>), /// Scroll a page in a window - ScrollFragmentPoint(PipelineId, ScrollRootId, Point2D<f32>, bool), + ScrollFragmentPoint(ClipId, Point2D<f32>, bool), /// Set title of current page /// https://html.spec.whatwg.org/multipage/#document.title SetTitle(PipelineId, Option<String>), |