mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #20892 - gw3583:update-wr, r=mbrubeck
Update WR (transaction API change) <!-- 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/20892) <!-- Reviewable:end -->
This commit is contained in:
commit
e2fca1b228
57 changed files with 359 additions and 121 deletions
|
@ -73,14 +73,19 @@ use style_traits::cursor::CursorKind;
|
|||
use table_cell::CollapsedBordersForCell;
|
||||
use webrender_api::{self, BorderRadius, BorderSide, BoxShadowClipMode, ColorF, ExternalScrollId};
|
||||
use webrender_api::{FilterOp, GlyphInstance, ImageRendering, LayoutRect, LayoutSize};
|
||||
use webrender_api::{LayoutTransform, LayoutVector2D, LineStyle, NormalBorder, ScrollPolicy};
|
||||
use webrender_api::{ScrollSensitivity, StickyOffsetBounds};
|
||||
use webrender_api::{LayoutTransform, LayoutVector2D, LineStyle, NormalBorder, ScrollSensitivity};
|
||||
use webrender_api::StickyOffsetBounds;
|
||||
|
||||
fn establishes_containing_block_for_absolute(
|
||||
flags: StackingContextCollectionFlags,
|
||||
positioning: StylePosition,
|
||||
established_reference_frame: bool,
|
||||
) -> bool {
|
||||
!flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK) &&
|
||||
if established_reference_frame {
|
||||
return true;
|
||||
}
|
||||
|
||||
!flags.contains(StackingContextCollectionFlags::POSITION_NEVER_CREATES_CONTAINING_BLOCK) &&
|
||||
StylePosition::Static != positioning
|
||||
}
|
||||
|
||||
|
@ -576,6 +581,12 @@ pub trait FragmentDisplayListBuilding {
|
|||
state: &mut StackingContextCollectionState,
|
||||
) -> bool;
|
||||
|
||||
fn create_stacking_context_for_inline_block(
|
||||
&mut self,
|
||||
base: &BaseFlow,
|
||||
state: &mut StackingContextCollectionState,
|
||||
) -> bool;
|
||||
|
||||
/// Adds the display items necessary to paint the background of this fragment to the display
|
||||
/// list if necessary.
|
||||
fn build_display_list_for_background_if_applicable(
|
||||
|
@ -760,7 +771,6 @@ pub trait FragmentDisplayListBuilding {
|
|||
&self,
|
||||
id: StackingContextId,
|
||||
base_flow: &BaseFlow,
|
||||
scroll_policy: ScrollPolicy,
|
||||
context_type: StackingContextType,
|
||||
established_reference_frame: Option<ClipScrollNodeIndex>,
|
||||
parent_clipping_and_scrolling: ClippingAndScrolling,
|
||||
|
@ -817,6 +827,35 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_stacking_context_for_inline_block(
|
||||
&mut self,
|
||||
base: &BaseFlow,
|
||||
state: &mut StackingContextCollectionState,
|
||||
) -> bool {
|
||||
self.stacking_context_id = state.allocate_stacking_context_info(StackingContextType::Real);
|
||||
|
||||
let established_reference_frame = if self.can_establish_reference_frame() {
|
||||
// WebRender currently creates reference frames automatically, so just add
|
||||
// a placeholder node to allocate a ClipScrollNodeIndex for this reference frame.
|
||||
self.established_reference_frame =
|
||||
Some(state.add_clip_scroll_node(ClipScrollNode::placeholder()));
|
||||
self.established_reference_frame
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let current_stacking_context_id = state.current_stacking_context_id;
|
||||
let stacking_context = self.create_stacking_context(
|
||||
self.stacking_context_id,
|
||||
&base,
|
||||
StackingContextType::Real,
|
||||
established_reference_frame,
|
||||
state.current_clipping_and_scrolling,
|
||||
);
|
||||
state.add_stacking_context(current_stacking_context_id, stacking_context);
|
||||
true
|
||||
}
|
||||
|
||||
fn build_display_list_for_background_if_applicable(
|
||||
&self,
|
||||
state: &mut DisplayListBuildState,
|
||||
|
@ -1563,6 +1602,11 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
display_list_section: DisplayListSection,
|
||||
clip: Rect<Au>,
|
||||
) {
|
||||
let previous_clipping_and_scrolling = state.current_clipping_and_scrolling;
|
||||
if let Some(index) = self.established_reference_frame {
|
||||
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(index);
|
||||
}
|
||||
|
||||
self.restyle_damage.remove(ServoRestyleDamage::REPAINT);
|
||||
self.build_display_list_no_damage(
|
||||
state,
|
||||
|
@ -1570,7 +1614,9 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
border_painting_mode,
|
||||
display_list_section,
|
||||
clip,
|
||||
)
|
||||
);
|
||||
|
||||
state.current_clipping_and_scrolling = previous_clipping_and_scrolling;
|
||||
}
|
||||
|
||||
fn build_display_list_no_damage(
|
||||
|
@ -1887,7 +1933,6 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
&self,
|
||||
id: StackingContextId,
|
||||
base_flow: &BaseFlow,
|
||||
scroll_policy: ScrollPolicy,
|
||||
context_type: StackingContextType,
|
||||
established_reference_frame: Option<ClipScrollNodeIndex>,
|
||||
parent_clipping_and_scrolling: ClippingAndScrolling,
|
||||
|
@ -1931,7 +1976,6 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
self.transform_matrix(&border_box),
|
||||
self.style().get_used_transform_style().to_layout(),
|
||||
self.perspective_matrix(&border_box),
|
||||
scroll_policy,
|
||||
parent_clipping_and_scrolling,
|
||||
established_reference_frame,
|
||||
)
|
||||
|
@ -2128,7 +2172,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
bitflags! {
|
||||
pub struct StackingContextCollectionFlags: u8 {
|
||||
/// This flow never establishes a containing block.
|
||||
const NEVER_CREATES_CONTAINING_BLOCK = 0b001;
|
||||
const POSITION_NEVER_CREATES_CONTAINING_BLOCK = 0b001;
|
||||
/// This flow never creates a ClipScrollNode.
|
||||
const NEVER_CREATES_CLIP_SCROLL_NODE = 0b010;
|
||||
/// This flow never creates a stacking context.
|
||||
|
@ -2406,7 +2450,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
flags,
|
||||
);
|
||||
|
||||
if establishes_containing_block_for_absolute(flags, self.positioning()) {
|
||||
if establishes_containing_block_for_absolute(
|
||||
flags,
|
||||
self.positioning(),
|
||||
established_reference_frame.is_some()
|
||||
) {
|
||||
state.containing_block_clipping_and_scrolling = state.current_clipping_and_scrolling;
|
||||
}
|
||||
|
||||
|
@ -2495,7 +2543,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
|
||||
// We keep track of our position so that any stickily positioned elements can
|
||||
// properly determine the extent of their movement relative to scrolling containers.
|
||||
if !flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK) {
|
||||
if !flags.contains(StackingContextCollectionFlags::POSITION_NEVER_CREATES_CONTAINING_BLOCK) {
|
||||
let border_box = if self.fragment.establishes_stacking_context() {
|
||||
stacking_relative_border_box
|
||||
} else {
|
||||
|
@ -2713,7 +2761,6 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
let new_context = self.fragment.create_stacking_context(
|
||||
self.base.stacking_context_id,
|
||||
&self.base,
|
||||
ScrollPolicy::Scrollable,
|
||||
stacking_context_type,
|
||||
None,
|
||||
parent_clipping_and_scrolling,
|
||||
|
@ -2747,7 +2794,6 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
let stacking_context = self.fragment.create_stacking_context(
|
||||
self.base.stacking_context_id,
|
||||
&self.base,
|
||||
ScrollPolicy::Scrollable,
|
||||
StackingContextType::Real,
|
||||
established_reference_frame,
|
||||
parent_clipping_and_scrolling,
|
||||
|
@ -2866,37 +2912,34 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
|||
.cloned()
|
||||
.unwrap_or_else(Rect::max_rect);
|
||||
|
||||
let previous_cb_clipping_and_scrolling = state.containing_block_clipping_and_scrolling;
|
||||
|
||||
for fragment in self.fragments.fragments.iter_mut() {
|
||||
let previous_cb_clipping_and_scrolling = state.containing_block_clipping_and_scrolling;
|
||||
state.containing_block_clipping_and_scrolling = previous_cb_clipping_and_scrolling;
|
||||
|
||||
if establishes_containing_block_for_absolute(
|
||||
StackingContextCollectionFlags::empty(),
|
||||
fragment.style.get_box().position,
|
||||
false,
|
||||
) {
|
||||
state.containing_block_clipping_and_scrolling =
|
||||
state.current_clipping_and_scrolling;
|
||||
}
|
||||
|
||||
// We clear this here, but it might be set again if we create a stacking context for
|
||||
// this fragment.
|
||||
fragment.established_reference_frame = None;
|
||||
|
||||
if !fragment.collect_stacking_contexts_for_blocklike_fragment(state) {
|
||||
if fragment.establishes_stacking_context() {
|
||||
fragment.stacking_context_id =
|
||||
state.allocate_stacking_context_info(StackingContextType::Real);
|
||||
|
||||
let current_stacking_context_id = state.current_stacking_context_id;
|
||||
let stacking_context = fragment.create_stacking_context(
|
||||
fragment.stacking_context_id,
|
||||
&self.base,
|
||||
ScrollPolicy::Scrollable,
|
||||
StackingContextType::Real,
|
||||
None,
|
||||
state.current_clipping_and_scrolling,
|
||||
);
|
||||
|
||||
state.add_stacking_context(current_stacking_context_id, stacking_context);
|
||||
} else {
|
||||
if !fragment.establishes_stacking_context() {
|
||||
fragment.stacking_context_id = state.current_stacking_context_id;
|
||||
} else {
|
||||
fragment.create_stacking_context_for_inline_block(&self.base, state);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the containing block clipping and scrolling before each loop iteration,
|
||||
// so we don't pollute subsequent fragments.
|
||||
state.containing_block_clipping_and_scrolling = previous_cb_clipping_and_scrolling;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@ use webrender_api::{BorderRadius, BorderWidths, BoxShadowClipMode, ClipMode, Col
|
|||
use webrender_api::{ComplexClipRegion, ExtendMode, ExternalScrollId, FilterOp, FontInstanceKey};
|
||||
use webrender_api::{GlyphInstance, GradientStop, ImageKey, ImageRendering, LayoutPoint};
|
||||
use webrender_api::{LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D, LineStyle};
|
||||
use webrender_api::{MixBlendMode, NinePatchBorder, NormalBorder, ScrollPolicy, ScrollSensitivity};
|
||||
use webrender_api::{Shadow, StickyOffsetBounds, TransformStyle};
|
||||
use webrender_api::{MixBlendMode, NinePatchBorder, NormalBorder, ScrollSensitivity, Shadow};
|
||||
use webrender_api::{StickyOffsetBounds, TransformStyle};
|
||||
|
||||
pub use style::dom::OpaqueNode;
|
||||
|
||||
|
@ -203,9 +203,6 @@ pub struct StackingContext {
|
|||
/// The perspective matrix to be applied to children.
|
||||
pub perspective: Option<LayoutTransform>,
|
||||
|
||||
/// The scroll policy of this layer.
|
||||
pub scroll_policy: ScrollPolicy,
|
||||
|
||||
/// The clip and scroll info for this StackingContext.
|
||||
pub parent_clipping_and_scrolling: ClippingAndScrolling,
|
||||
|
||||
|
@ -227,7 +224,6 @@ impl StackingContext {
|
|||
transform: Option<LayoutTransform>,
|
||||
transform_style: TransformStyle,
|
||||
perspective: Option<LayoutTransform>,
|
||||
scroll_policy: ScrollPolicy,
|
||||
parent_clipping_and_scrolling: ClippingAndScrolling,
|
||||
established_reference_frame: Option<ClipScrollNodeIndex>,
|
||||
) -> StackingContext {
|
||||
|
@ -242,7 +238,6 @@ impl StackingContext {
|
|||
transform,
|
||||
transform_style,
|
||||
perspective,
|
||||
scroll_policy,
|
||||
parent_clipping_and_scrolling,
|
||||
established_reference_frame,
|
||||
}
|
||||
|
@ -261,7 +256,6 @@ impl StackingContext {
|
|||
None,
|
||||
TransformStyle::Flat,
|
||||
None,
|
||||
ScrollPolicy::Scrollable,
|
||||
ClippingAndScrolling::simple(ClipScrollNodeIndex::root_scroll_node()),
|
||||
None,
|
||||
)
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
// This might be achieved by sharing types between WR and Servo display lists, or
|
||||
// completely converting layout to directly generate WebRender display lists, for example.
|
||||
|
||||
use display_list::items::{BorderDetails, ClipScrollNode};
|
||||
use display_list::items::{ClipScrollNodeIndex, ClipScrollNodeType, DisplayItem};
|
||||
use display_list::items::{DisplayList, StackingContextType};
|
||||
use display_list::items::{BorderDetails, ClipScrollNode, ClipScrollNodeIndex, ClipScrollNodeType};
|
||||
use display_list::items::{DisplayItem, DisplayList, StackingContextType};
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use webrender_api::{self, ClipAndScrollInfo, ClipId, DisplayListBuilder, GlyphRasterSpace};
|
||||
use webrender_api::LayoutPoint;
|
||||
|
||||
pub trait WebRenderDisplayListConverter {
|
||||
fn convert_to_webrender(&self, pipeline_id: PipelineId) -> DisplayListBuilder;
|
||||
|
@ -213,29 +213,42 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
|||
builder.pop_all_shadows();
|
||||
},
|
||||
DisplayItem::Iframe(ref item) => {
|
||||
builder.push_iframe(&self.prim_info(), item.iframe.to_webrender());
|
||||
builder.push_iframe(&self.prim_info(), item.iframe.to_webrender(), true);
|
||||
},
|
||||
DisplayItem::PushStackingContext(ref item) => {
|
||||
let stacking_context = &item.stacking_context;
|
||||
debug_assert_eq!(stacking_context.context_type, StackingContextType::Real);
|
||||
|
||||
let reference_frame_clip_id = builder.push_stacking_context(
|
||||
&webrender_api::LayoutPrimitiveInfo::new(stacking_context.bounds),
|
||||
let mut info = webrender_api::LayoutPrimitiveInfo::new(stacking_context.bounds);
|
||||
if let Some(frame_index) = stacking_context.established_reference_frame {
|
||||
debug_assert!(
|
||||
stacking_context.transform.is_some() ||
|
||||
stacking_context.perspective.is_some()
|
||||
);
|
||||
|
||||
let clip_id = builder.push_reference_frame(
|
||||
&info.clone(),
|
||||
stacking_context.transform.map(Into::into),
|
||||
stacking_context.perspective,
|
||||
);
|
||||
clip_ids[frame_index.to_index()] = Some(clip_id);
|
||||
|
||||
info.rect.origin = LayoutPoint::zero();
|
||||
info.clip_rect.origin = LayoutPoint::zero();
|
||||
builder.push_clip_id(clip_id);
|
||||
}
|
||||
|
||||
builder.push_stacking_context(
|
||||
&info,
|
||||
None,
|
||||
stacking_context.scroll_policy,
|
||||
stacking_context.transform.map(Into::into),
|
||||
stacking_context.transform_style,
|
||||
stacking_context.perspective,
|
||||
stacking_context.mix_blend_mode,
|
||||
stacking_context.filters.clone(),
|
||||
GlyphRasterSpace::Screen,
|
||||
);
|
||||
|
||||
match (reference_frame_clip_id, stacking_context.established_reference_frame) {
|
||||
(Some(webrender_id), Some(frame_index)) =>
|
||||
clip_ids[frame_index.to_index()] = Some(webrender_id),
|
||||
(None, None) => {},
|
||||
_ => warn!("Mismatch between reference frame establishment!"),
|
||||
if stacking_context.established_reference_frame.is_some() {
|
||||
builder.pop_clip_id();
|
||||
}
|
||||
},
|
||||
DisplayItem::PopStackingContext(_) => builder.pop_stacking_context(),
|
||||
|
|
|
@ -11,7 +11,7 @@ use app_units::Au;
|
|||
use canvas_traits::canvas::{CanvasMsg, CanvasId};
|
||||
use context::{LayoutContext, with_thread_local_font_context};
|
||||
use display_list::ToLayout;
|
||||
use display_list::items::{BLUR_INFLATION_FACTOR, OpaqueNode};
|
||||
use display_list::items::{BLUR_INFLATION_FACTOR, ClipScrollNodeIndex, OpaqueNode};
|
||||
use euclid::{Point2D, Vector2D, Rect, Size2D};
|
||||
use floats::ClearType;
|
||||
use flow::{GetBaseFlow, ImmutableFlowUtils};
|
||||
|
@ -152,6 +152,11 @@ pub struct Fragment {
|
|||
/// to 0, but it assigned during the collect_stacking_contexts phase of display
|
||||
/// list construction.
|
||||
pub stacking_context_id: StackingContextId,
|
||||
|
||||
/// The indices of this Fragment's ClipScrollNode. If this fragment doesn't have a
|
||||
/// `established_reference_frame` assigned, it will use the `clipping_and_scrolling` of the
|
||||
/// parent block.
|
||||
pub established_reference_frame: Option<ClipScrollNodeIndex>,
|
||||
}
|
||||
|
||||
impl Serialize for Fragment {
|
||||
|
@ -633,6 +638,7 @@ impl Fragment {
|
|||
flags: FragmentFlags::empty(),
|
||||
debug_id: DebugId::new(),
|
||||
stacking_context_id: StackingContextId::root(),
|
||||
established_reference_frame: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,6 +668,7 @@ impl Fragment {
|
|||
flags: FragmentFlags::empty(),
|
||||
debug_id: DebugId::new(),
|
||||
stacking_context_id: StackingContextId::root(),
|
||||
established_reference_frame: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -687,6 +694,7 @@ impl Fragment {
|
|||
flags: FragmentFlags::empty(),
|
||||
debug_id: DebugId::new(),
|
||||
stacking_context_id: StackingContextId::root(),
|
||||
established_reference_frame: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -715,6 +723,7 @@ impl Fragment {
|
|||
flags: FragmentFlags::empty(),
|
||||
debug_id: self.debug_id.clone(),
|
||||
stacking_context_id: StackingContextId::root(),
|
||||
established_reference_frame: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ impl Flow for TableRowGroupFlow {
|
|||
|
||||
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
|
||||
self.block_flow.collect_stacking_contexts_for_block(state,
|
||||
StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK);
|
||||
StackingContextCollectionFlags::POSITION_NEVER_CREATES_CONTAINING_BLOCK);
|
||||
}
|
||||
|
||||
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {
|
||||
|
|
|
@ -464,7 +464,7 @@ impl Flow for TableWrapperFlow {
|
|||
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
|
||||
self.block_flow.collect_stacking_contexts_for_block(
|
||||
state,
|
||||
StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK |
|
||||
StackingContextCollectionFlags::POSITION_NEVER_CREATES_CONTAINING_BLOCK |
|
||||
StackingContextCollectionFlags::NEVER_CREATES_CLIP_SCROLL_NODE);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,5 +10,5 @@ extern crate layout;
|
|||
use layout::Fragment;
|
||||
use layout::SpecificFragmentInfo;
|
||||
|
||||
size_of_test!(test_size_of_fragment, Fragment, 160);
|
||||
size_of_test!(test_size_of_fragment, Fragment, 176);
|
||||
size_of_test!(test_size_of_specific_fragment_info, SpecificFragmentInfo, 24);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue