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:
bors-servo 2018-06-26 17:27:31 -04:00 committed by GitHub
commit e2fca1b228
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 359 additions and 121 deletions

View file

@ -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;
}
}

View file

@ -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,
)

View file

@ -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(),

View file

@ -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,
}
}

View file

@ -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>) {

View file

@ -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);
}

View file

@ -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);