diff options
author | Martin Robinson <mrobinson@igalia.com> | 2017-04-19 14:45:47 +0200 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2017-04-20 08:51:38 +0200 |
commit | d150cc9f95c45f80a96678a3ed1c8e076f005382 (patch) | |
tree | d3f7dded41ee67b2cc86948207bcc7c74dc3f4cf | |
parent | 7919e591a46274c0d7f3a7c7c99d2643d55d60f1 (diff) | |
download | servo-d150cc9f95c45f80a96678a3ed1c8e076f005382.tar.gz servo-d150cc9f95c45f80a96678a3ed1c8e076f005382.zip |
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.
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>), |