aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock2
-rw-r--r--components/compositing/compositor.rs42
-rw-r--r--components/compositing/compositor_thread.rs3
-rw-r--r--components/constellation/constellation.rs5
-rw-r--r--components/gfx/display_list/mod.rs45
-rw-r--r--components/gfx_traits/lib.rs139
-rw-r--r--components/layout/context.rs4
-rw-r--r--components/layout/display_list_builder.rs115
-rw-r--r--components/layout/flow.rs20
-rw-r--r--components/layout/fragment.rs25
-rw-r--r--components/layout/query.rs11
-rw-r--r--components/layout/traversal.rs2
-rw-r--r--components/layout/webrender_helpers.rs30
-rw-r--r--components/layout_thread/lib.rs16
-rw-r--r--components/msg/constellation_msg.rs4
-rw-r--r--components/script/dom/document.rs6
-rw-r--r--components/script/dom/window.rs10
-rw-r--r--components/script_layout_interface/Cargo.toml1
-rw-r--r--components/script_layout_interface/lib.rs1
-rw-r--r--components/script_layout_interface/rpc.rs4
-rw-r--r--components/script_layout_interface/wrapper_traits.rs8
-rw-r--r--components/script_traits/Cargo.toml1
-rw-r--r--components/script_traits/lib.rs5
-rw-r--r--components/script_traits/script_msg.rs4
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>),