Auto merge of #20214 - mrobinson:stop-using-using-localclip-roundedrect, r=glennw

Stop using LocalClip::RoundedRect

We would like to remove this functionality from WebRender, so convert
its use to clip scroll nodes. This change also removes the redundant
BlocBlockStackingContextType in favor of Option<StackingContextType>,
which is just as expressive. This simplifies the code a bit.

<!-- 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 should not change behavior.

<!-- 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/20214)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-03-06 15:53:11 -05:00 committed by GitHub
commit 26d2e77410
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 135 additions and 120 deletions

View file

@ -3109,11 +3109,3 @@ impl ISizeAndMarginsComputer for InlineFlexItem {
fragment.margin.inline_end) fragment.margin.inline_end)
} }
} }
/// A stacking context, a pseudo-stacking context, or a non-stacking context.
#[derive(Clone, Copy, PartialEq)]
pub enum BlockStackingContextType {
NonstackingContext,
PseudoStackingContext,
StackingContext,
}

View file

@ -11,7 +11,7 @@
#![deny(unsafe_code)] #![deny(unsafe_code)]
use app_units::{Au, AU_PER_PX}; use app_units::{Au, AU_PER_PX};
use block::{BlockFlow, BlockStackingContextType}; use block::BlockFlow;
use canvas_traits::canvas::{CanvasMsg, FromLayoutMsg}; use canvas_traits::canvas::{CanvasMsg, FromLayoutMsg};
use context::LayoutContext; use context::LayoutContext;
use display_list::ToLayout; use display_list::ToLayout;
@ -73,11 +73,10 @@ use style_traits::CSSPixel;
use style_traits::ToCss; use style_traits::ToCss;
use style_traits::cursor::CursorKind; use style_traits::cursor::CursorKind;
use table_cell::CollapsedBordersForCell; use table_cell::CollapsedBordersForCell;
use webrender_api::{self, BorderRadius, BorderSide, BoxShadowClipMode, ClipMode, ColorF}; use webrender_api::{self, BorderRadius, BorderSide, BoxShadowClipMode, ColorF, ExternalScrollId};
use webrender_api::{ComplexClipRegion, ExternalScrollId, FilterOp, GlyphInstance}; use webrender_api::{FilterOp, GlyphInstance, ImageRendering, LayoutRect, LayoutSize};
use webrender_api::{ImageRendering, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D}; use webrender_api::{LayoutTransform, LayoutVector2D, LineStyle, LocalClip, NormalBorder};
use webrender_api::{LineStyle, LocalClip, NormalBorder, ScrollPolicy}; use webrender_api::{ScrollPolicy, ScrollSensitivity, StickyOffsetBounds};
use webrender_api::{ScrollSensitivity, StickyOffsetBounds};
fn establishes_containing_block_for_absolute( fn establishes_containing_block_for_absolute(
flags: StackingContextCollectionFlags, flags: StackingContextCollectionFlags,
@ -162,13 +161,15 @@ pub struct InlineNodeBorderInfo {
struct StackingContextInfo { struct StackingContextInfo {
children: Vec<StackingContext>, children: Vec<StackingContext>,
clip_scroll_nodes: Vec<ClipScrollNodeIndex>, clip_scroll_nodes: Vec<ClipScrollNodeIndex>,
real_stacking_context_id: StackingContextId,
} }
impl StackingContextInfo { impl StackingContextInfo {
fn new() -> StackingContextInfo { fn new(real_stacking_context_id: StackingContextId) -> StackingContextInfo {
StackingContextInfo { StackingContextInfo {
children: Vec::new(), children: Vec::new(),
clip_scroll_nodes: Vec::new(), clip_scroll_nodes: Vec::new(),
real_stacking_context_id,
} }
} }
@ -236,10 +237,16 @@ impl StackingContextCollectionState {
), ),
}; };
let mut stacking_context_info = FnvHashMap::default();
stacking_context_info.insert(
StackingContextId::root(),
StackingContextInfo::new(StackingContextId::root())
);
StackingContextCollectionState { StackingContextCollectionState {
pipeline_id: pipeline_id, pipeline_id: pipeline_id,
root_stacking_context: StackingContext::root(), root_stacking_context: StackingContext::root(),
stacking_context_info: FnvHashMap::default(), stacking_context_info,
clip_scroll_nodes: vec![root_node], clip_scroll_nodes: vec![root_node],
current_stacking_context_id: StackingContextId::root(), current_stacking_context_id: StackingContextId::root(),
current_real_stacking_context_id: StackingContextId::root(), current_real_stacking_context_id: StackingContextId::root(),
@ -252,9 +259,25 @@ impl StackingContextCollectionState {
} }
} }
fn generate_stacking_context_id(&mut self) -> StackingContextId { fn allocate_stacking_context_info(
&mut self,
stacking_context_type: StackingContextType
) -> StackingContextId {
let next_stacking_context_id = self.next_stacking_context_id.next(); let next_stacking_context_id = self.next_stacking_context_id.next();
mem::replace(&mut self.next_stacking_context_id, next_stacking_context_id) let allocated_id =
mem::replace(&mut self.next_stacking_context_id, next_stacking_context_id);
let real_stacking_context_id = match stacking_context_type {
StackingContextType::Real => allocated_id,
_ => self.current_real_stacking_context_id,
};
self.stacking_context_info.insert(
allocated_id,
StackingContextInfo::new(real_stacking_context_id)
);
allocated_id
} }
fn add_stacking_context( fn add_stacking_context(
@ -262,10 +285,7 @@ impl StackingContextCollectionState {
parent_id: StackingContextId, parent_id: StackingContextId,
stacking_context: StackingContext, stacking_context: StackingContext,
) { ) {
let info = self.stacking_context_info self.stacking_context_info.get_mut(&parent_id).unwrap().children.push(stacking_context);
.entry(parent_id)
.or_insert(StackingContextInfo::new());
info.children.push(stacking_context);
} }
fn add_clip_scroll_node(&mut self, clip_scroll_node: ClipScrollNode) -> ClipScrollNodeIndex { fn add_clip_scroll_node(&mut self, clip_scroll_node: ClipScrollNode) -> ClipScrollNodeIndex {
@ -275,10 +295,11 @@ impl StackingContextCollectionState {
// the scroll root before it is defined. // the scroll root before it is defined.
self.clip_scroll_nodes.push(clip_scroll_node); self.clip_scroll_nodes.push(clip_scroll_node);
let index = ClipScrollNodeIndex(self.clip_scroll_nodes.len() - 1); let index = ClipScrollNodeIndex(self.clip_scroll_nodes.len() - 1);
let info = self.stacking_context_info self.stacking_context_info
.entry(self.current_real_stacking_context_id) .get_mut(&self.current_real_stacking_context_id)
.or_insert(StackingContextInfo::new()); .unwrap()
info.clip_scroll_nodes.push(index); .clip_scroll_nodes
.push(index);
index index
} }
} }
@ -390,6 +411,34 @@ impl<'a> DisplayListBuildState<'a> {
) )
} }
fn add_late_clip_node(&mut self, rect: LayoutRect, radii: BorderRadius) -> ClipScrollNodeIndex {
let mut clip = ClippingRegion::from_rect(rect);
clip.intersect_with_rounded_rect(rect, radii);
let node = ClipScrollNode {
parent_index: self.current_clipping_and_scrolling.scrolling,
clip,
content_rect: LayoutRect::zero(), // content_rect isn't important for clips.
node_type: ClipScrollNodeType::Clip,
};
// We want the scroll root to be defined before any possible item that could use it,
// so we make sure that it is added to the beginning of the parent "real" (non-pseudo)
// stacking context. This ensures that item reordering will not result in an item using
// the scroll root before it is defined.
self.clip_scroll_nodes.push(node);
let index = ClipScrollNodeIndex(self.clip_scroll_nodes.len() - 1);
let real_stacking_context_id =
self.stacking_context_info[&self.current_stacking_context_id].real_stacking_context_id;
self.stacking_context_info
.get_mut(&real_stacking_context_id)
.unwrap()
.clip_scroll_nodes
.push(index);
index
}
pub fn to_display_list(mut self) -> DisplayList { pub fn to_display_list(mut self) -> DisplayList {
let mut list = Vec::new(); 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());
@ -413,9 +462,7 @@ impl<'a> DisplayListBuildState<'a> {
child_items.sort_by(|a, b| a.base().section.cmp(&b.base().section)); child_items.sort_by(|a, b| a.base().section.cmp(&b.base().section));
child_items.reverse(); child_items.reverse();
let mut info = self.stacking_context_info let mut info = self.stacking_context_info.remove(&stacking_context.id).unwrap();
.remove(&stacking_context.id)
.unwrap_or_else(StackingContextInfo::new);
info.children.sort(); info.children.sort();
@ -801,18 +848,15 @@ impl FragmentDisplayListBuilding for Fragment {
}, },
} }
let clip = if !border_radii.is_zero() { let previous_clipping_and_scrolling = state.current_clipping_and_scrolling;
LocalClip::RoundedRect( if !border_radii.is_zero() {
bounds.to_layout(), let clip_id = state.add_late_clip_node(bounds.to_layout(), border_radii);
ComplexClipRegion::new(bounds.to_layout(), border_radii, ClipMode::Clip), state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
) }
} else {
LocalClip::Rect(bounds.to_layout())
};
let base = state.create_base_display_item( let base = state.create_base_display_item(
&bounds, &bounds,
clip, LocalClip::Rect(bounds.to_layout()),
self.node, self.node,
style.get_cursor(CursorKind::Default), style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
@ -822,6 +866,8 @@ impl FragmentDisplayListBuilding for Fragment {
color: background_color.to_layout(), color: background_color.to_layout(),
}))); })));
state.current_clipping_and_scrolling = previous_clipping_and_scrolling;
// The background image is painted on top of the background color. // The background image is painted on top of the background color.
// Implements background image, per spec: // Implements background image, per spec:
// http://www.w3.org/TR/CSS21/colors.html#background // http://www.w3.org/TR/CSS21/colors.html#background
@ -1608,25 +1654,31 @@ impl FragmentDisplayListBuilding for Fragment {
stacking_relative_border_box: &Rect<Au>, stacking_relative_border_box: &Rect<Au>,
clip: &Rect<Au>, clip: &Rect<Au>,
) { ) {
let previous_clipping_and_scrolling = state.current_clipping_and_scrolling;
// Compute the context box position relative to the parent stacking context. // Compute the context box position relative to the parent stacking context.
let stacking_relative_content_box = let stacking_relative_content_box =
self.stacking_relative_content_box(stacking_relative_border_box); self.stacking_relative_content_box(stacking_relative_border_box);
let create_base_display_item = |state: &mut DisplayListBuildState| {
let layout_rect = stacking_relative_border_box.to_layout();
// Adjust the clipping region as necessary to account for `border-radius`. // Adjust the clipping region as necessary to account for `border-radius`.
let build_local_clip = |style: &ComputedValues| { let radii =
let radii = build_border_radius_for_inner_rect(&stacking_relative_border_box, style); build_border_radius_for_inner_rect(&stacking_relative_border_box, &self.style);
if !radii.is_zero() { if !radii.is_zero() {
LocalClip::RoundedRect( let clip_id = state.add_late_clip_node(layout_rect, radii);
stacking_relative_border_box.to_layout(), state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
ComplexClipRegion::new(
stacking_relative_content_box.to_layout(),
radii,
ClipMode::Clip,
),
)
} else {
LocalClip::Rect(stacking_relative_border_box.to_layout())
} }
state.create_base_display_item(
&stacking_relative_content_box,
LocalClip::Rect(layout_rect),
self.node,
self.style.get_cursor(CursorKind::Default),
DisplayListSection::Content,
)
}; };
match self.specific { match self.specific {
@ -1707,15 +1759,9 @@ impl FragmentDisplayListBuilding for Fragment {
None => return warn!("No pipeline id for iframe {}.", browsing_context_id), None => return warn!("No pipeline id for iframe {}.", browsing_context_id),
}; };
let base = state.create_base_display_item( let base = create_base_display_item(state);
&stacking_relative_content_box,
build_local_clip(&self.style),
self.node,
self.style.get_cursor(CursorKind::Default),
DisplayListSection::Content,
);
let item = DisplayItem::Iframe(Box::new(IframeDisplayItem { let item = DisplayItem::Iframe(Box::new(IframeDisplayItem {
base: base, base,
iframe: pipeline_id, iframe: pipeline_id,
})); }));
@ -1730,15 +1776,9 @@ impl FragmentDisplayListBuilding for Fragment {
SpecificFragmentInfo::Image(ref image_fragment) => { SpecificFragmentInfo::Image(ref image_fragment) => {
// Place the image into the display list. // Place the image into the display list.
if let Some(ref image) = image_fragment.image { if let Some(ref image) = image_fragment.image {
let base = state.create_base_display_item( let base = create_base_display_item(state);
&stacking_relative_content_box,
build_local_clip(&self.style),
self.node,
self.style.get_cursor(CursorKind::Default),
DisplayListSection::Content,
);
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem { state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
base: base, base,
webrender_image: WebRenderImageInfo::from_image(image), webrender_image: WebRenderImageInfo::from_image(image),
stretch_size: stacking_relative_content_box.size.to_layout(), stretch_size: stacking_relative_content_box.size.to_layout(),
tile_spacing: LayoutSize::zero(), tile_spacing: LayoutSize::zero(),
@ -1765,15 +1805,9 @@ impl FragmentDisplayListBuilding for Fragment {
}, },
}; };
let base = state.create_base_display_item( let base = create_base_display_item(state);
&stacking_relative_content_box,
build_local_clip(&self.style),
self.node,
self.style.get_cursor(CursorKind::Default),
DisplayListSection::Content,
);
let display_item = DisplayItem::Image(Box::new(ImageDisplayItem { let display_item = DisplayItem::Image(Box::new(ImageDisplayItem {
base: base, base,
webrender_image: WebRenderImageInfo { webrender_image: WebRenderImageInfo {
width: computed_width as u32, width: computed_width as u32,
height: computed_height as u32, height: computed_height as u32,
@ -1794,6 +1828,8 @@ impl FragmentDisplayListBuilding for Fragment {
panic!("Shouldn't see table column fragments here.") panic!("Shouldn't see table column fragments here.")
}, },
} }
state.current_clipping_and_scrolling = previous_clipping_and_scrolling;
} }
fn create_stacking_context( fn create_stacking_context(
@ -2061,7 +2097,7 @@ pub trait BlockFlowDisplayListBuilding {
&mut self, &mut self,
state: &mut StackingContextCollectionState, state: &mut StackingContextCollectionState,
preserved_state: &mut SavedStackingContextCollectionState, preserved_state: &mut SavedStackingContextCollectionState,
stacking_context_type: BlockStackingContextType, stacking_context_type: Option<StackingContextType>,
flags: StackingContextCollectionFlags, flags: StackingContextCollectionFlags,
) -> ClippingAndScrolling; ) -> ClippingAndScrolling;
fn setup_clip_scroll_node_for_position( fn setup_clip_scroll_node_for_position(
@ -2082,6 +2118,7 @@ pub trait BlockFlowDisplayListBuilding {
); );
fn create_pseudo_stacking_context_for_block( fn create_pseudo_stacking_context_for_block(
&mut self, &mut self,
stacking_context_type: StackingContextType,
parent_stacking_context_id: StackingContextId, parent_stacking_context_id: StackingContextId,
parent_clip_and_scroll_info: ClippingAndScrolling, parent_clip_and_scroll_info: ClippingAndScrolling,
state: &mut StackingContextCollectionState, state: &mut StackingContextCollectionState,
@ -2108,10 +2145,10 @@ pub trait BlockFlowDisplayListBuilding {
background: &style_structs::Background, background: &style_structs::Background,
background_color: RGBA); background_color: RGBA);
fn block_stacking_context_type( fn stacking_context_type(
&self, &self,
flags: StackingContextCollectionFlags, flags: StackingContextCollectionFlags,
) -> BlockStackingContextType; ) -> Option<StackingContextType>;
} }
/// This structure manages ensuring that modification to StackingContextCollectionState is /// This structure manages ensuring that modification to StackingContextCollectionState is
@ -2267,15 +2304,14 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
) { ) {
let mut preserved_state = SavedStackingContextCollectionState::new(state); let mut preserved_state = SavedStackingContextCollectionState::new(state);
let block_stacking_context_type = self.block_stacking_context_type(flags); let stacking_context_type = self.stacking_context_type(flags);
self.base.stacking_context_id = match block_stacking_context_type { self.base.stacking_context_id = match stacking_context_type {
BlockStackingContextType::NonstackingContext => state.current_stacking_context_id, None => state.current_stacking_context_id,
BlockStackingContextType::PseudoStackingContext | Some(sc_type) => state.allocate_stacking_context_info(sc_type),
BlockStackingContextType::StackingContext => state.generate_stacking_context_id(),
}; };
state.current_stacking_context_id = self.base.stacking_context_id; state.current_stacking_context_id = self.base.stacking_context_id;
if block_stacking_context_type == BlockStackingContextType::StackingContext { if stacking_context_type == Some(StackingContextType::Real) {
state.current_real_stacking_context_id = self.base.stacking_context_id; state.current_real_stacking_context_id = self.base.stacking_context_id;
} }
@ -2286,7 +2322,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
let containing_clipping_and_scrolling = self.setup_clipping_for_block( let containing_clipping_and_scrolling = self.setup_clipping_for_block(
state, state,
&mut preserved_state, &mut preserved_state,
block_stacking_context_type, stacking_context_type,
flags, flags,
); );
@ -2294,19 +2330,18 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
state.containing_block_clipping_and_scrolling = state.current_clipping_and_scrolling; state.containing_block_clipping_and_scrolling = state.current_clipping_and_scrolling;
} }
match block_stacking_context_type { match stacking_context_type {
BlockStackingContextType::NonstackingContext => { None => self.base.collect_stacking_contexts_for_children(state),
self.base.collect_stacking_contexts_for_children(state); Some(StackingContextType::Real) => {
}, self.create_real_stacking_context_for_block(
BlockStackingContextType::PseudoStackingContext => {
self.create_pseudo_stacking_context_for_block(
preserved_state.stacking_context_id, preserved_state.stacking_context_id,
containing_clipping_and_scrolling, containing_clipping_and_scrolling,
state, state,
); );
}, },
BlockStackingContextType::StackingContext => { Some(stacking_context_type) => {
self.create_real_stacking_context_for_block( self.create_pseudo_stacking_context_for_block(
stacking_context_type,
preserved_state.stacking_context_id, preserved_state.stacking_context_id,
containing_clipping_and_scrolling, containing_clipping_and_scrolling,
state, state,
@ -2321,7 +2356,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
&mut self, &mut self,
state: &mut StackingContextCollectionState, state: &mut StackingContextCollectionState,
preserved_state: &mut SavedStackingContextCollectionState, preserved_state: &mut SavedStackingContextCollectionState,
stacking_context_type: BlockStackingContextType, stacking_context_type: Option<StackingContextType>,
flags: StackingContextCollectionFlags, flags: StackingContextCollectionFlags,
) -> ClippingAndScrolling { ) -> ClippingAndScrolling {
// If this block is absolutely positioned, we should be clipped and positioned by // If this block is absolutely positioned, we should be clipped and positioned by
@ -2347,7 +2382,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
self.stacking_relative_border_box(CoordinateSystem::Parent) self.stacking_relative_border_box(CoordinateSystem::Parent)
}; };
if stacking_context_type == BlockStackingContextType::StackingContext { if stacking_context_type == Some(StackingContextType::Real) {
self.transform_clip_to_coordinate_space(state, preserved_state); self.transform_clip_to_coordinate_space(state, preserved_state);
} }
@ -2578,26 +2613,16 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
fn create_pseudo_stacking_context_for_block( fn create_pseudo_stacking_context_for_block(
&mut self, &mut self,
stacking_context_type: StackingContextType,
parent_stacking_context_id: StackingContextId, parent_stacking_context_id: StackingContextId,
parent_clipping_and_scrolling: ClippingAndScrolling, parent_clipping_and_scrolling: ClippingAndScrolling,
state: &mut StackingContextCollectionState, state: &mut StackingContextCollectionState,
) { ) {
let creation_mode = if self.base
.flags
.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) ||
self.fragment.style.get_box().position != StylePosition::Static
{
StackingContextType::PseudoPositioned
} else {
assert!(self.base.flags.is_float());
StackingContextType::PseudoFloat
};
let new_context = self.fragment.create_stacking_context( let new_context = self.fragment.create_stacking_context(
self.base.stacking_context_id, self.base.stacking_context_id,
&self.base, &self.base,
ScrollPolicy::Scrollable, ScrollPolicy::Scrollable,
creation_mode, stacking_context_type,
parent_clipping_and_scrolling, parent_clipping_and_scrolling,
); );
state.add_stacking_context(parent_stacking_context_id, new_context); state.add_stacking_context(parent_stacking_context_id, new_context);
@ -2694,34 +2719,31 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
} }
#[inline] #[inline]
fn block_stacking_context_type( fn stacking_context_type(
&self, &self,
flags: StackingContextCollectionFlags, flags: StackingContextCollectionFlags,
) -> BlockStackingContextType { ) -> Option<StackingContextType>{
if flags.contains(StackingContextCollectionFlags::NEVER_CREATES_STACKING_CONTEXT) { if flags.contains(StackingContextCollectionFlags::NEVER_CREATES_STACKING_CONTEXT) {
return BlockStackingContextType::NonstackingContext; return None;
} }
if self.fragment.establishes_stacking_context() { if self.fragment.establishes_stacking_context() {
return BlockStackingContextType::StackingContext; return Some(StackingContextType::Real);
} }
if self.base if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
.flags return Some(StackingContextType::PseudoPositioned);
.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED)
{
return BlockStackingContextType::PseudoStackingContext;
} }
if self.fragment.style.get_box().position != StylePosition::Static { if self.fragment.style.get_box().position != StylePosition::Static {
return BlockStackingContextType::PseudoStackingContext; return Some(StackingContextType::PseudoPositioned);
} }
if self.base.flags.is_float() { if self.base.flags.is_float() {
return BlockStackingContextType::PseudoStackingContext; return Some(StackingContextType::PseudoFloat);
} }
BlockStackingContextType::NonstackingContext None
} }
} }
@ -2757,7 +2779,8 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
if !fragment.collect_stacking_contexts_for_blocklike_fragment(state) { if !fragment.collect_stacking_contexts_for_blocklike_fragment(state) {
if fragment.establishes_stacking_context() { if fragment.establishes_stacking_context() {
fragment.stacking_context_id = state.generate_stacking_context_id(); fragment.stacking_context_id =
state.allocate_stacking_context_info(StackingContextType::Real);
let current_stacking_context_id = state.current_stacking_context_id; let current_stacking_context_id = state.current_stacking_context_id;
let stacking_context = fragment.create_stacking_context( let stacking_context = fragment.create_stacking_context(