aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/display_list_builder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout/display_list_builder.rs')
-rw-r--r--components/layout/display_list_builder.rs61
1 files changed, 48 insertions, 13 deletions
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index f29a1f377ae..af08a690ca0 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -181,6 +181,9 @@ pub struct StackingContextCollectionState {
/// The current stacking real context id, which doesn't include pseudo-stacking contexts.
pub current_real_stacking_context_id: StackingContextId,
+ /// The next stacking context id that we will assign to a stacking context.
+ pub next_stacking_context_id: StackingContextId,
+
/// The current clip and scroll info, used to keep track of state when
/// recursively building and processing the display list.
pub current_clip_and_scroll_info: ClipAndScrollInfo,
@@ -212,6 +215,7 @@ impl StackingContextCollectionState {
clip_scroll_node_parents: FnvHashMap::default(),
current_stacking_context_id: StackingContextId::root(),
current_real_stacking_context_id: StackingContextId::root(),
+ next_stacking_context_id: StackingContextId::root().next(),
current_clip_and_scroll_info: root_clip_info,
containing_block_clip_and_scroll_info: root_clip_info,
clip_stack: Vec::new(),
@@ -220,6 +224,11 @@ impl StackingContextCollectionState {
}
}
+ fn generate_stacking_context_id(&mut self) -> StackingContextId {
+ let next_stacking_context_id = self.next_stacking_context_id.next();
+ mem::replace(&mut self.next_stacking_context_id, next_stacking_context_id)
+ }
+
fn add_stacking_context(&mut self,
parent_id: StackingContextId,
stacking_context: StackingContext) {
@@ -611,10 +620,6 @@ pub trait FragmentDisplayListBuilding {
parent_clip_and_scroll_info: ClipAndScrollInfo)
-> 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;
@@ -2169,10 +2174,6 @@ impl FragmentDisplayListBuilding for Fragment {
}
}
- fn stacking_context_id(&self) -> StackingContextId {
- StackingContextId::new(self.unique_id(IdType::StackingContext))
- }
-
fn create_stacking_context(&self,
id: StackingContextId,
base_flow: &BaseFlow,
@@ -2394,9 +2395,11 @@ impl FragmentDisplayListBuilding for Fragment {
bitflags! {
pub flags StackingContextCollectionFlags: u8 {
/// This flow never establishes a containing block.
- const NEVER_CREATES_CONTAINING_BLOCK = 0x01,
+ const NEVER_CREATES_CONTAINING_BLOCK = 0b001,
/// This flow never creates a ClipScrollNode.
- const NEVER_CREATES_CLIP_SCROLL_NODE = 0x02,
+ const NEVER_CREATES_CLIP_SCROLL_NODE = 0b010,
+ /// This flow never creates a stacking context.
+ const NEVER_CREATES_STACKING_CONTEXT = 0b100,
}
}
@@ -2435,6 +2438,11 @@ pub trait BlockFlowDisplayListBuilding {
fn build_display_list_for_block(&mut self,
state: &mut DisplayListBuildState,
border_painting_mode: BorderPaintingMode);
+
+ fn block_stacking_context_type(
+ &self,
+ flags: StackingContextCollectionFlags,
+ ) -> BlockStackingContextType;
}
/// This structure manages ensuring that modification to StackingContextCollectionState is
@@ -2572,11 +2580,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
flags: StackingContextCollectionFlags) {
let mut preserved_state = SavedStackingContextCollectionState::new(state);
- let block_stacking_context_type = self.block_stacking_context_type();
+ let block_stacking_context_type = self.block_stacking_context_type(flags);
self.base.stacking_context_id = match block_stacking_context_type {
BlockStackingContextType::NonstackingContext => state.current_stacking_context_id,
BlockStackingContextType::PseudoStackingContext |
- BlockStackingContextType::StackingContext => self.fragment.stacking_context_id(),
+ BlockStackingContextType::StackingContext => state.generate_stacking_context_id(),
};
state.current_stacking_context_id = self.base.stacking_context_id;
@@ -2963,6 +2971,33 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
state.processing_scrolling_overflow_element = false;
}
+ #[inline]
+ fn block_stacking_context_type(
+ &self,
+ flags: StackingContextCollectionFlags,
+ ) -> BlockStackingContextType {
+ if flags.contains(NEVER_CREATES_STACKING_CONTEXT) {
+ return BlockStackingContextType::NonstackingContext;
+ }
+
+ if self.fragment.establishes_stacking_context() {
+ return BlockStackingContextType::StackingContext
+ }
+
+ if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
+ return BlockStackingContextType::PseudoStackingContext
+ }
+
+ if self.fragment.style.get_box().position != position::T::static_ {
+ return BlockStackingContextType::PseudoStackingContext
+ }
+
+ if self.base.flags.is_float() {
+ return BlockStackingContextType::PseudoStackingContext
+ }
+
+ BlockStackingContextType::NonstackingContext
+ }
}
pub trait InlineFlowDisplayListBuilding {
@@ -2988,7 +3023,7 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
if !fragment.collect_stacking_contexts_for_blocklike_fragment(state) {
if fragment.establishes_stacking_context() {
- fragment.stacking_context_id = fragment.stacking_context_id();
+ fragment.stacking_context_id = state.generate_stacking_context_id();
let current_stacking_context_id = state.current_stacking_context_id;
let stacking_context =