mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Auto merge of #18921 - mrobinson:incremental-stacking-context-ids, r=emilio
Fix duplicate stacking context creation for anonymous Flows Anonymous nodes were previously creating duplicate stacking contexts, one for each node in the anonymous node chain. This change eliminates that for tables. Additionally the use of stacking context ids based on node addresses is no longer necessary since stacking contexts no longer control scrolling. This is the first step in eliminating the dependency between node addresses and ClipScrollNodes which causes issues like #16425. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [x] These changes do not require tests because they are covered by existing tests. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18921) <!-- Reviewable:end -->
This commit is contained in:
commit
865b9aea35
9 changed files with 72 additions and 42 deletions
|
@ -1670,20 +1670,6 @@ impl BlockFlow {
|
|||
self.base.flags = flags
|
||||
}
|
||||
|
||||
pub fn block_stacking_context_type(&self) -> BlockStackingContextType {
|
||||
if self.fragment.establishes_stacking_context() {
|
||||
return BlockStackingContextType::StackingContext
|
||||
}
|
||||
|
||||
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
|
||||
self.fragment.style.get_box().position != position::T::static_ ||
|
||||
self.base.flags.is_float() {
|
||||
BlockStackingContextType::PseudoStackingContext
|
||||
} else {
|
||||
BlockStackingContextType::NonstackingContext
|
||||
}
|
||||
}
|
||||
|
||||
pub fn overflow_style_may_require_clip_scroll_node(&self) -> bool {
|
||||
match (self.fragment.style().get_box().overflow_x,
|
||||
self.fragment.style().get_box().overflow_y) {
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -11,7 +11,7 @@ use block::{BlockFlow, CandidateBSizeIterator, ISizeAndMarginsComputer};
|
|||
use block::{ISizeConstraintInput, ISizeConstraintSolution};
|
||||
use context::LayoutContext;
|
||||
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode};
|
||||
use display_list_builder::{DisplayListBuildState, StackingContextCollectionFlags};
|
||||
use display_list_builder::{DisplayListBuildState, NEVER_CREATES_STACKING_CONTEXT};
|
||||
use display_list_builder::StackingContextCollectionState;
|
||||
use euclid::Point2D;
|
||||
use flow;
|
||||
|
@ -504,8 +504,8 @@ impl Flow for TableFlow {
|
|||
}
|
||||
|
||||
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
|
||||
self.block_flow.collect_stacking_contexts_for_block(state,
|
||||
StackingContextCollectionFlags::empty());
|
||||
// Stacking contexts are collected by the table wrapper.
|
||||
self.block_flow.collect_stacking_contexts_for_block(state, NEVER_CREATES_STACKING_CONTEXT);
|
||||
}
|
||||
|
||||
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue