Use a new id type for tracking scrolling areas

This is a step in disassociating scrolling areas from stacking
contexts. Now scroll areas are defined by unique ids, which means that
in the future stacking context will be able to contain more than one.
This commit is contained in:
Martin Robinson 2016-10-21 08:03:01 +02:00
parent fbec79e920
commit 71d285af80
22 changed files with 242 additions and 92 deletions

View file

@ -11,7 +11,7 @@ use euclid::{Point2D, Size2D};
use euclid::point::TypedPoint2D;
use euclid::scale_factor::ScaleFactor;
use euclid::size::TypedSize2D;
use gfx_traits::{DevicePixel, LayerPixel, StackingContextId};
use gfx_traits::{DevicePixel, LayerPixel, ScrollRootId};
use gfx_traits::{Epoch, FrameTreeId, FragmentType};
use gleam::gl;
use gleam::gl::types::{GLint, GLsizei};
@ -74,13 +74,13 @@ impl ConvertPipelineIdFromWebRender for webrender_traits::PipelineId {
}
}
trait ConvertStackingContextFromWebRender {
fn from_webrender(&self) -> StackingContextId;
trait ConvertScrollRootIdFromWebRender {
fn from_webrender(&self) -> ScrollRootId;
}
impl ConvertStackingContextFromWebRender for webrender_traits::ServoStackingContextId {
fn from_webrender(&self) -> StackingContextId {
StackingContextId::new_of_type(self.1, self.0.from_webrender())
impl ConvertScrollRootIdFromWebRender for webrender_traits::ServoScrollRootId {
fn from_webrender(&self) -> ScrollRootId {
ScrollRootId(self.0)
}
}
@ -1312,7 +1312,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
let mut stacking_context_scroll_states_per_pipeline = HashMap::new();
for scroll_layer_state in self.webrender_api.get_scroll_layer_state() {
let stacking_context_scroll_state = StackingContextScrollState {
stacking_context_id: scroll_layer_state.stacking_context_id.from_webrender(),
scroll_root_id: scroll_layer_state.scroll_root_id.from_webrender(),
scroll_offset: scroll_layer_state.scroll_offset,
};
let pipeline_id = scroll_layer_state.pipeline_id;

View file

@ -20,7 +20,7 @@ use euclid::{Matrix4D, Point2D, Rect, Size2D};
use euclid::num::{One, Zero};
use euclid::rect::TypedRect;
use euclid::side_offsets::SideOffsets2D;
use gfx_traits::{ScrollPolicy, StackingContextId};
use gfx_traits::{ScrollPolicy, ScrollRootId, StackingContextId};
use gfx_traits::print_tree::PrintTree;
use ipc_channel::ipc::IpcSharedMemory;
use msg::constellation_msg::PipelineId;
@ -215,9 +215,11 @@ impl DisplayList {
// the DOM-side code has already translated the point for us (e.g. in
// `Window::hit_test_query()`) by now.
if !is_fixed && stacking_context.id != StackingContextId::root() {
if let Some(scroll_offset) = scroll_offsets.get(&stacking_context.id) {
translated_point.x -= Au::from_f32_px(scroll_offset.x);
translated_point.y -= Au::from_f32_px(scroll_offset.y);
if let Some(scroll_root_id) = stacking_context.overflow_scroll_id {
if let Some(scroll_offset) = scroll_offsets.get(&scroll_root_id) {
translated_point.x -= Au::from_f32_px(scroll_offset.x);
translated_point.y -= Au::from_f32_px(scroll_offset.y);
}
}
}
@ -386,7 +388,7 @@ pub struct StackingContext {
pub children: Vec<StackingContext>,
/// If this StackingContext scrolls its overflow area, this will contain the id.
pub overflow_scroll_id: Option<StackingContextId>,
pub overflow_scroll_id: Option<ScrollRootId>,
}
impl StackingContext {
@ -403,7 +405,7 @@ impl StackingContext {
perspective: Matrix4D<f32>,
establishes_3d_context: bool,
scroll_policy: ScrollPolicy,
scroll_id: Option<StackingContextId>)
scroll_root_id: Option<ScrollRootId>)
-> StackingContext {
StackingContext {
id: id,
@ -418,7 +420,7 @@ impl StackingContext {
establishes_3d_context: establishes_3d_context,
scroll_policy: scroll_policy,
children: Vec::new(),
overflow_scroll_id: scroll_id,
overflow_scroll_id: scroll_root_id,
}
}
@ -1194,7 +1196,7 @@ impl WebRenderImageInfo {
}
/// The type of the scroll offset list. This is only populated if WebRender is in use.
pub type ScrollOffsetMap = HashMap<StackingContextId, Point2D<f32>>;
pub type ScrollOffsetMap = HashMap<ScrollRootId, Point2D<f32>>;
pub trait SimpleMatrixDetection {

View file

@ -162,6 +162,58 @@ impl StackingContextId {
}
}
/// 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).
#[inline]
pub fn is_special(&self) -> bool {
(self.0 & !SPECIAL_STACKING_CONTEXT_ID_MASK) == 0
}
#[inline]
pub fn id(&self) -> usize {
self.0 & !3
}
#[inline]
pub fn fragment_type(&self) -> FragmentType {
FragmentType::from_usize(self.0 & 3)
}
}
/// The type of fragment that a stacking context represents.
///
/// This can only ever grow to maximum 4 entries. That's because we cram the value of this enum

View file

@ -44,6 +44,7 @@ use flow_ref::FlowRef;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
use fragment::SpecificFragmentInfo;
use gfx::display_list::{ClippingRegion, StackingContext};
use gfx_traits::ScrollRootId;
use gfx_traits::print_tree::PrintTree;
use layout_debug;
use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo, MaybeAuto};
@ -2162,8 +2163,10 @@ impl Flow for BlockFlow {
}
}
fn collect_stacking_contexts(&mut self, parent: &mut StackingContext) {
self.collect_stacking_contexts_for_block(parent);
fn collect_stacking_contexts(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.collect_stacking_contexts_for_block(parent, parent_scroll_root_id);
}
fn build_display_list(&mut self, state: &mut DisplayListBuildState) {

View file

@ -28,7 +28,7 @@ use gfx::display_list::{GradientStop, IframeDisplayItem, ImageDisplayItem, WebGL
use gfx::display_list::{LineDisplayItem, OpaqueNode};
use gfx::display_list::{SolidColorDisplayItem, StackingContext, StackingContextType};
use gfx::display_list::{TextDisplayItem, TextOrientation, WebRenderImageInfo};
use gfx_traits::{ScrollPolicy, StackingContextId, color};
use gfx_traits::{ScrollPolicy, ScrollRootId, StackingContextId, color};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
use ipc_channel::ipc;
use list_item::ListItemFlow;
@ -78,6 +78,7 @@ pub struct DisplayListBuildState<'a> {
pub shared_layout_context: &'a SharedLayoutContext,
pub items: Vec<DisplayItem>,
pub stacking_context_id_stack: Vec<StackingContextId>,
pub scroll_root_id_stack: Vec<ScrollRootId>,
}
impl<'a> DisplayListBuildState<'a> {
@ -88,6 +89,7 @@ impl<'a> DisplayListBuildState<'a> {
shared_layout_context: shared_layout_context,
items: Vec::new(),
stacking_context_id_stack: vec!(stacking_context_id),
scroll_root_id_stack: vec!(ScrollRootId::root()),
}
}
@ -95,7 +97,7 @@ impl<'a> DisplayListBuildState<'a> {
self.items.push(display_item);
}
fn stacking_context_id(&self) -> StackingContextId {
pub fn stacking_context_id(&self) -> StackingContextId {
self.stacking_context_id_stack.last().unwrap().clone()
}
@ -108,6 +110,19 @@ impl<'a> DisplayListBuildState<'a> {
assert!(!self.stacking_context_id_stack.is_empty());
}
pub fn scroll_root_id(&mut self) -> ScrollRootId {
self.scroll_root_id_stack.last().unwrap().clone()
}
pub fn push_scroll_root_id(&mut self, id: ScrollRootId) {
self.scroll_root_id_stack.push(id);
}
pub fn pop_scroll_root_id(&mut self) {
self.scroll_root_id_stack.pop();
assert!(!self.scroll_root_id_stack.is_empty());
}
fn create_base_display_item(&self,
bounds: &Rect<Au>,
clip: &ClippingRegion,
@ -299,7 +314,7 @@ pub trait FragmentDisplayListBuilding {
base_flow: &BaseFlow,
scroll_policy: ScrollPolicy,
mode: StackingContextCreationMode,
scroll_id: Option<StackingContextId>)
scroll_root_id: Option<ScrollRootId>)
-> StackingContext;
/// Returns the 4D matrix representing this fragment's transform.
@ -1356,7 +1371,7 @@ impl FragmentDisplayListBuilding for Fragment {
base_flow: &BaseFlow,
scroll_policy: ScrollPolicy,
mode: StackingContextCreationMode,
scroll_id: Option<StackingContextId>)
scroll_root_id: Option<ScrollRootId>)
-> StackingContext {
let scrolls_overflow_area = mode == StackingContextCreationMode::ScrollWrapper;
let border_box =
@ -1431,7 +1446,7 @@ impl FragmentDisplayListBuilding for Fragment {
perspective,
establishes_3d_context,
scroll_policy,
scroll_id)
scroll_root_id)
}
fn adjust_clipping_region_for_children(&self,
@ -1687,7 +1702,9 @@ impl FragmentDisplayListBuilding for Fragment {
}
pub trait BlockFlowDisplayListBuilding {
fn collect_stacking_contexts_for_block(&mut self, parent: &mut StackingContext);
fn collect_stacking_contexts_for_block(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId);
fn build_display_list_for_block(&mut self,
state: &mut DisplayListBuildState,
border_painting_mode: BorderPaintingMode);
@ -1704,17 +1721,29 @@ pub trait BlockFlowDisplayListBuilding {
}
impl BlockFlowDisplayListBuilding for BlockFlow {
fn collect_stacking_contexts_for_block(&mut self, parent: &mut StackingContext) {
fn collect_stacking_contexts_for_block(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
let block_stacking_context_type = self.block_stacking_context_type();
if block_stacking_context_type == BlockStackingContextType::NonstackingContext {
self.base.stacking_context_id = parent.id;
self.base.collect_stacking_contexts_for_children(parent);
self.base.collect_stacking_contexts_for_children(parent, parent_scroll_root_id);
return;
}
let has_scrolling_overflow = self.has_scrolling_overflow();
let stacking_context_id = StackingContextId::new_of_type(self.fragment.node.id() as usize,
self.fragment.fragment_type());
let has_scrolling_overflow = self.has_scrolling_overflow();
let scroll_root_id = if has_scrolling_overflow {
ScrollRootId::new_of_type(self.fragment.node.id() as usize,
self.fragment.fragment_type())
} else {
parent_scroll_root_id
};
self.base.scroll_root_id = scroll_root_id;
self.base.stacking_context_id = stacking_context_id;
if block_stacking_context_type == BlockStackingContextType::PseudoStackingContext {
@ -1731,7 +1760,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
ScrollPolicy::Scrollable,
creation_mode,
None);
self.base.collect_stacking_contexts_for_children(&mut new_context);
self.base.collect_stacking_contexts_for_children(&mut new_context, scroll_root_id);
let new_children: Vec<StackingContext> = new_context.children.drain(..).collect();
let mut non_floating_children = Vec::new();
@ -1755,10 +1784,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
};
let (creation_mode, internal_id) = if has_scrolling_overflow {
(StackingContextCreationMode::ScrollWrapper,
Some(StackingContextId::new_of_type(self.fragment.node.id() as usize,
self.fragment.fragment_type())))
(StackingContextCreationMode::ScrollWrapper, Some(self.base.scroll_root_id))
} else {
(StackingContextCreationMode::Normal, None)
};
@ -1769,7 +1795,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
scroll_policy,
creation_mode,
internal_id);
self.base.collect_stacking_contexts_for_children(&mut stacking_context);
self.base.collect_stacking_contexts_for_children(&mut stacking_context, scroll_root_id);
parent.add_child(stacking_context);
}
@ -1859,7 +1885,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
}
pub trait InlineFlowDisplayListBuilding {
fn collect_stacking_contexts_for_inline(&mut self, parent: &mut StackingContext);
fn collect_stacking_contexts_for_inline(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId);
fn build_display_list_for_inline_fragment_at_index(&mut self,
state: &mut DisplayListBuildState,
index: usize);
@ -1867,18 +1895,21 @@ pub trait InlineFlowDisplayListBuilding {
}
impl InlineFlowDisplayListBuilding for InlineFlow {
fn collect_stacking_contexts_for_inline(&mut self, parent: &mut StackingContext) {
fn collect_stacking_contexts_for_inline(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.base.stacking_context_id = parent.id;
self.base.scroll_root_id = parent_scroll_root_id;
for mut fragment in self.fragments.fragments.iter_mut() {
match fragment.specific {
SpecificFragmentInfo::InlineBlock(ref mut block_flow) => {
let block_flow = flow_ref::deref_mut(&mut block_flow.flow_ref);
block_flow.collect_stacking_contexts(parent);
block_flow.collect_stacking_contexts(parent, parent_scroll_root_id);
}
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => {
let block_flow = flow_ref::deref_mut(&mut block_flow.flow_ref);
block_flow.collect_stacking_contexts(parent);
block_flow.collect_stacking_contexts(parent, parent_scroll_root_id);
}
_ if fragment.establishes_stacking_context() => {
fragment.stacking_context_id =

View file

@ -17,6 +17,7 @@ use flow::{Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
use flow::{INLINE_POSITION_IS_STATIC, IS_ABSOLUTELY_POSITIONED};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::StackingContext;
use gfx_traits::ScrollRootId;
use layout_debug;
use model::{Direction, IntrinsicISizes, MaybeAuto, MinMaxConstraint};
use model::{specified, specified_or_none};
@ -956,8 +957,10 @@ impl Flow for FlexFlow {
self.build_display_list_for_flex(state);
}
fn collect_stacking_contexts(&mut self, parent: &mut StackingContext) {
self.block_flow.collect_stacking_contexts(parent);
fn collect_stacking_contexts(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id);
}
fn repair_style(&mut self, new_style: &Arc<ServoComputedValues>) {

View file

@ -35,7 +35,7 @@ use flow_list::{FlowList, MutFlowListIterator};
use flow_ref::{self, FlowRef, WeakFlowRef};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{ClippingRegion, StackingContext};
use gfx_traits::StackingContextId;
use gfx_traits::{ScrollRootId, StackingContextId};
use gfx_traits::print_tree::PrintTree;
use inline::InlineFlow;
use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
@ -223,7 +223,9 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
None
}
fn collect_stacking_contexts(&mut self, _parent: &mut StackingContext);
fn collect_stacking_contexts(&mut self,
_parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId);
/// If this is a float, places it. The default implementation does nothing.
fn place_float_if_applicable<'a>(&mut self) {}
@ -935,6 +937,8 @@ pub struct BaseFlow {
/// to 0, but it assigned during the collect_stacking_contexts phase of display
/// list construction.
pub stacking_context_id: StackingContextId,
pub scroll_root_id: ScrollRootId,
}
impl fmt::Debug for BaseFlow {
@ -1105,6 +1109,7 @@ impl BaseFlow {
writing_mode: writing_mode,
thread_id: 0,
stacking_context_id: StackingContextId::new(0),
scroll_root_id: ScrollRootId::root(),
}
}
@ -1136,9 +1141,11 @@ impl BaseFlow {
return self as *const BaseFlow as usize;
}
pub fn collect_stacking_contexts_for_children(&mut self, parent: &mut StackingContext) {
pub fn collect_stacking_contexts_for_children(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
for kid in self.children.iter_mut() {
kid.collect_stacking_contexts(parent);
kid.collect_stacking_contexts(parent, parent_scroll_root_id);
}
}

View file

@ -19,6 +19,7 @@ use fragment::SpecificFragmentInfo;
use gfx::display_list::{OpaqueNode, StackingContext};
use gfx::font::FontMetrics;
use gfx::font_context::FontContext;
use gfx_traits::ScrollRootId;
use gfx_traits::print_tree::PrintTree;
use layout_debug;
use model::IntrinsicISizesContribution;
@ -1613,8 +1614,10 @@ impl Flow for InlineFlow {
fn update_late_computed_block_position_if_necessary(&mut self, _: Au) {}
fn collect_stacking_contexts(&mut self, parent: &mut StackingContext) {
self.collect_stacking_contexts_for_inline(parent);
fn collect_stacking_contexts(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.collect_stacking_contexts_for_inline(parent, parent_scroll_root_id);
}
fn build_display_list(&mut self, state: &mut DisplayListBuildState) {

View file

@ -18,6 +18,7 @@ use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, GeneratedC
use fragment::Overflow;
use generated_content;
use gfx::display_list::StackingContext;
use gfx_traits::ScrollRootId;
use inline::InlineFlow;
use script_layout_interface::restyle_damage::RESOLVE_GENERATED_CONTENT;
use std::sync::Arc;
@ -145,8 +146,10 @@ impl Flow for ListItemFlow {
self.build_display_list_for_list_item(state);
}
fn collect_stacking_contexts(&mut self, parent: &mut StackingContext) {
self.block_flow.collect_stacking_contexts(parent);
fn collect_stacking_contexts(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id);
}
fn repair_style(&mut self, new_style: &Arc<ServoComputedValues>) {

View file

@ -17,6 +17,7 @@ use flow::{Flow, FlowClass, OpaqueFlow, mut_base, FragmentationContext};
use flow_ref::{self, FlowRef};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::StackingContext;
use gfx_traits::ScrollRootId;
use gfx_traits::print_tree::PrintTree;
use std::cmp::{min, max};
use std::fmt;
@ -185,8 +186,10 @@ impl Flow for MulticolFlow {
self.block_flow.build_display_list(state);
}
fn collect_stacking_contexts(&mut self, parent: &mut StackingContext) {
self.block_flow.collect_stacking_contexts(parent);
fn collect_stacking_contexts(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id);
}
fn repair_style(&mut self, new_style: &Arc<ServoComputedValues>) {
@ -267,8 +270,10 @@ impl Flow for MulticolColumnFlow {
self.block_flow.build_display_list(state);
}
fn collect_stacking_contexts(&mut self, parent: &mut StackingContext) {
self.block_flow.collect_stacking_contexts(parent);
fn collect_stacking_contexts(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id);
}
fn repair_style(&mut self, new_style: &Arc<ServoComputedValues>) {

View file

@ -15,6 +15,7 @@ use flow::IS_ABSOLUTELY_POSITIONED;
use fragment::FragmentBorderBoxIterator;
use generated_content::ResolveGeneratedContent;
use gfx::display_list::{DisplayItem, StackingContext};
use gfx_traits::ScrollRootId;
use script_layout_interface::restyle_damage::{REFLOW, STORE_OVERFLOW};
use style::context::StyleContext;
use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList};
@ -78,7 +79,7 @@ pub fn build_display_list_for_subtree(flow_root: &mut Flow,
root_stacking_context: &mut StackingContext,
shared_layout_context: &SharedLayoutContext)
-> Vec<DisplayItem> {
flow_root.collect_stacking_contexts(root_stacking_context);
flow_root.collect_stacking_contexts(root_stacking_context, ScrollRootId::root());
let mut build_display_list = BuildDisplayList {
state: DisplayListBuildState::new(shared_layout_context,
flow::base(flow_root).stacking_context_id),

View file

@ -17,6 +17,7 @@ use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUt
use flow_list::MutFlowListIterator;
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::StackingContext;
use gfx_traits::ScrollRootId;
use gfx_traits::print_tree::PrintTree;
use layout_debug;
use model::{IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto};
@ -489,8 +490,10 @@ impl Flow for TableFlow {
self.block_flow.build_display_list_for_block(state, border_painting_mode);
}
fn collect_stacking_contexts(&mut self, parent: &mut StackingContext) {
self.block_flow.collect_stacking_contexts(parent);
fn collect_stacking_contexts(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id);
}
fn repair_style(&mut self, new_style: &Arc<ServoComputedValues>) {

View file

@ -14,6 +14,7 @@ use euclid::Point2D;
use flow::{Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::StackingContext;
use gfx_traits::ScrollRootId;
use gfx_traits::print_tree::PrintTree;
use std::fmt;
use std::sync::Arc;
@ -82,8 +83,10 @@ impl Flow for TableCaptionFlow {
self.block_flow.build_display_list(state);
}
fn collect_stacking_contexts(&mut self, parent: &mut StackingContext) {
self.block_flow.collect_stacking_contexts(parent);
fn collect_stacking_contexts(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id);
}
fn repair_style(&mut self, new_style: &Arc<ServoComputedValues>) {

View file

@ -15,6 +15,7 @@ use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use flow::{self, Flow, FlowClass, IS_ABSOLUTELY_POSITIONED, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::StackingContext;
use gfx_traits::ScrollRootId;
use gfx_traits::print_tree::PrintTree;
use layout_debug;
use model::MaybeAuto;
@ -256,8 +257,10 @@ impl Flow for TableCellFlow {
self.block_flow.build_display_list_for_block(state, border_painting_mode)
}
fn collect_stacking_contexts(&mut self, parent: &mut StackingContext) {
self.block_flow.collect_stacking_contexts(parent);
fn collect_stacking_contexts(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id);
}
fn repair_style(&mut self, new_style: &Arc<ServoComputedValues>) {

View file

@ -13,6 +13,7 @@ use euclid::Point2D;
use flow::{BaseFlow, Flow, FlowClass, ForceNonfloatedFlag, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow, SpecificFragmentInfo};
use gfx::display_list::StackingContext;
use gfx_traits::ScrollRootId;
use layout_debug;
use std::cmp::max;
use std::fmt;
@ -95,7 +96,9 @@ impl Flow for TableColGroupFlow {
// Table columns are invisible.
fn build_display_list(&mut self, _: &mut DisplayListBuildState) { }
fn collect_stacking_contexts(&mut self, _parent: &mut StackingContext) { }
fn collect_stacking_contexts(&mut self,
_parent: &mut StackingContext,
_parent_scroll_root_id: ScrollRootId) {}
fn repair_style(&mut self, _: &Arc<ServoComputedValues>) {}

View file

@ -16,6 +16,7 @@ use flow::{self, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils,
use flow_list::MutFlowListIterator;
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::StackingContext;
use gfx_traits::ScrollRootId;
use gfx_traits::print_tree::PrintTree;
use layout_debug;
use model::MaybeAuto;
@ -458,8 +459,10 @@ impl Flow for TableRowFlow {
self.block_flow.build_display_list_for_block(state, border_painting_mode);
}
fn collect_stacking_contexts(&mut self, parent: &mut StackingContext) {
self.block_flow.collect_stacking_contexts(parent);
fn collect_stacking_contexts(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id);
}
fn repair_style(&mut self, new_style: &Arc<ServoComputedValues>) {

View file

@ -14,6 +14,7 @@ use euclid::Point2D;
use flow::{Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::StackingContext;
use gfx_traits::ScrollRootId;
use gfx_traits::print_tree::PrintTree;
use layout_debug;
use rustc_serialize::{Encodable, Encoder};
@ -211,8 +212,10 @@ impl Flow for TableRowGroupFlow {
self.block_flow.build_display_list(state);
}
fn collect_stacking_contexts(&mut self, parent: &mut StackingContext) {
self.block_flow.collect_stacking_contexts(parent);
fn collect_stacking_contexts(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id);
}
fn repair_style(&mut self, new_style: &Arc<ServoComputedValues>) {

View file

@ -23,6 +23,7 @@ use floats::FloatKind;
use flow::{Flow, FlowClass, ImmutableFlowUtils, INLINE_POSITION_IS_STATIC, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::StackingContext;
use gfx_traits::ScrollRootId;
use gfx_traits::print_tree::PrintTree;
use model::MaybeAuto;
use std::cmp::{max, min};
@ -468,8 +469,10 @@ impl Flow for TableWrapperFlow {
self.block_flow.build_display_list(state);
}
fn collect_stacking_contexts(&mut self, parent: &mut StackingContext) {
self.block_flow.collect_stacking_contexts(parent);
fn collect_stacking_contexts(&mut self,
parent: &mut StackingContext,
parent_scroll_root_id: ScrollRootId) {
self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id);
}
fn repair_style(&mut self, new_style: &Arc<ServoComputedValues>) {

View file

@ -247,10 +247,28 @@ impl<'a> BuildDisplayList<'a> {
#[inline]
pub fn traverse(&mut self, flow: &mut Flow) {
if self.should_process() {
self.state.push_stacking_context_id(flow::base(flow).stacking_context_id);
let new_stacking_context =
flow::base(flow).stacking_context_id != self.state.stacking_context_id();
if new_stacking_context {
self.state.push_stacking_context_id(flow::base(flow).stacking_context_id);
}
let new_scroll_root =
flow::base(flow).scroll_root_id != self.state.scroll_root_id();
if new_scroll_root {
self.state.push_scroll_root_id(flow::base(flow).scroll_root_id);
}
flow.build_display_list(&mut self.state);
flow::mut_base(flow).restyle_damage.remove(REPAINT);
self.state.pop_stacking_context_id();
if new_stacking_context {
self.state.pop_stacking_context_id();
}
if new_scroll_root {
self.state.pop_scroll_root_id();
}
}
for kid in flow::child_iter_mut(flow) {

View file

@ -13,7 +13,7 @@ use euclid::{Point2D, Rect, Size2D};
use gfx::display_list::{BorderRadii, BoxShadowClipMode, ClippingRegion};
use gfx::display_list::{DisplayItem, DisplayList, DisplayListTraversal};
use gfx::display_list::{GradientStop, StackingContext, StackingContextType};
use gfx_traits::{FragmentType, ScrollPolicy, StackingContextId};
use gfx_traits::{FragmentType, ScrollPolicy, StackingContextId, ScrollRootId};
use style::computed_values::{image_rendering, mix_blend_mode};
use style::computed_values::filter::{self, Filter};
use style::values::computed::BorderStyle;
@ -287,18 +287,16 @@ impl WebRenderStackingContextConverter for StackingContext {
ScrollPolicy::FixedPosition => webrender_traits::ScrollPolicy::Fixed,
};
let webrender_stacking_context_id = self.id.convert_to_webrender();
let scroll_layer_id = if self.overflow_scroll_id.is_some() ||
self.id == StackingContextId::root() {
Some(frame_builder.next_scroll_layer_id())
let scroll_layer_id = if let Some(scroll_root_id) = self.overflow_scroll_id {
Some(frame_builder.next_scroll_layer_id(scroll_root_id))
} else if self.id == StackingContextId::root() {
Some(frame_builder.next_scroll_layer_id(ScrollRootId::root()))
} else {
None
};
let mut sc =
webrender_traits::StackingContext::new(webrender_stacking_context_id,
scroll_layer_id,
webrender_traits::StackingContext::new(scroll_layer_id,
webrender_scroll_policy,
self.bounds.to_rectf(),
self.overflow.to_rectf(),
@ -532,21 +530,25 @@ impl WebRenderFrameBuilder {
id
}
pub fn next_scroll_layer_id(&mut self) -> webrender_traits::ScrollLayerId {
pub fn next_scroll_layer_id(&mut self,
scroll_root_id: ScrollRootId)
-> webrender_traits::ScrollLayerId {
let scroll_layer_id = self.next_scroll_layer_id;
self.next_scroll_layer_id += 1;
webrender_traits::ScrollLayerId::new(self.root_pipeline_id, scroll_layer_id)
webrender_traits::ScrollLayerId::new(self.root_pipeline_id,
scroll_layer_id,
scroll_root_id.convert_to_webrender())
}
}
trait WebRenderStackingContextIdConverter {
fn convert_to_webrender(&self) -> webrender_traits::ServoStackingContextId;
trait WebRenderScrollRootIdConverter {
fn convert_to_webrender(&self) -> webrender_traits::ServoScrollRootId;
}
impl WebRenderStackingContextIdConverter for StackingContextId {
fn convert_to_webrender(&self) -> webrender_traits::ServoStackingContextId {
webrender_traits::ServoStackingContextId(self.fragment_type().convert_to_webrender(),
self.id())
impl WebRenderScrollRootIdConverter for ScrollRootId {
fn convert_to_webrender(&self) -> webrender_traits::ServoScrollRootId {
webrender_traits::ServoScrollRootId(self.0)
}
}

View file

@ -56,7 +56,7 @@ use gfx::display_list::{StackingContext, StackingContextType, WebRenderImageInfo
use gfx::font;
use gfx::font_cache_thread::FontCacheThread;
use gfx::font_context;
use gfx_traits::{Epoch, FragmentType, ScrollPolicy, StackingContextId, color};
use gfx_traits::{Epoch, FragmentType, ScrollPolicy, ScrollRootId, StackingContextId, color};
use heapsize::HeapSizeOf;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use ipc_channel::router::ROUTER;
@ -1282,14 +1282,13 @@ impl LayoutThread {
let mut layout_scroll_states = HashMap::new();
for new_scroll_state in &new_scroll_states {
let offset = new_scroll_state.scroll_offset;
layout_scroll_states.insert(new_scroll_state.stacking_context_id, offset);
layout_scroll_states.insert(new_scroll_state.scroll_root_id, offset);
if new_scroll_state.stacking_context_id == StackingContextId::root() {
if new_scroll_state.scroll_root_id == ScrollRootId::root() {
script_scroll_states.push((UntrustedNodeAddress::from_id(0), offset))
} else if !new_scroll_state.stacking_context_id.is_special() &&
new_scroll_state.stacking_context_id.fragment_type() ==
FragmentType::FragmentBody {
let id = new_scroll_state.stacking_context_id.id();
} 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))
}
}

View file

@ -45,7 +45,7 @@ use euclid::scale_factor::ScaleFactor;
use euclid::size::TypedSize2D;
use gfx_traits::DevicePixel;
use gfx_traits::Epoch;
use gfx_traits::StackingContextId;
use gfx_traits::ScrollRootId;
use heapsize::HeapSizeOf;
use hyper::header::Headers;
use hyper::method::Method;
@ -600,8 +600,8 @@ pub enum AnimationTickType {
/// The scroll state of a stacking context.
#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
pub struct StackingContextScrollState {
/// The ID of the stacking context.
pub stacking_context_id: StackingContextId,
/// The ID of the scroll root.
pub scroll_root_id: ScrollRootId,
/// The scrolling offset of this stacking context.
pub scroll_offset: Point2D<f32>,
}