Skip to content

Commit

Permalink
Update WR to use the new sticky positioning API
Browse files Browse the repository at this point in the history
  • Loading branch information
mrobinson committed Oct 30, 2017
1 parent 17bfe5c commit f37fa0c
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 32 deletions.
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions components/gfx/display_list/mod.rs
Expand Up @@ -34,7 +34,7 @@ use style_traits::cursor::Cursor;
use text::TextRun;
use text::glyph::ByteIndex;
use webrender_api::{self, ClipId, ColorF, GradientStop, LocalClip, MixBlendMode, ScrollPolicy};
use webrender_api::{ScrollSensitivity, StickyFrameInfo, TransformStyle};
use webrender_api::{ScrollSensitivity, StickyOffsetBounds, TransformStyle};

pub use style::dom::OpaqueNode;

Expand Down Expand Up @@ -321,10 +321,17 @@ impl fmt::Debug for StackingContext {
}
}

#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct StickyFrameData {
pub margins: SideOffsets2D<Option<f32>>,
pub vertical_offset_bounds: StickyOffsetBounds,
pub horizontal_offset_bounds: StickyOffsetBounds,
}

#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub enum ClipScrollNodeType {
ScrollFrame(ScrollSensitivity),
StickyFrame(StickyFrameInfo),
StickyFrame(StickyFrameData),
Clip,
}

Expand Down
49 changes: 27 additions & 22 deletions components/layout/display_list_builder.rs
Expand Up @@ -24,13 +24,14 @@ use fragment::SpecificFragmentInfo;
use gfx::display_list;
use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDetails, BorderDisplayItem};
use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClipScrollNode};
use gfx::display_list::{ClipScrollNodeIndex, ClippingAndScrolling, ClipScrollNodeType};
use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingAndScrolling};
use gfx::display_list::{ClippingRegion, DisplayItem, DisplayItemMetadata, DisplayList};
use gfx::display_list::{DisplayListSection, GradientDisplayItem, IframeDisplayItem, ImageBorder};
use gfx::display_list::{ImageDisplayItem, LineDisplayItem, NormalBorder, OpaqueNode};
use gfx::display_list::{PopAllTextShadowsDisplayItem, PushTextShadowDisplayItem};
use gfx::display_list::{RadialGradientDisplayItem, SolidColorDisplayItem, StackingContext};
use gfx::display_list::{StackingContextType, TextDisplayItem, TextOrientation, WebRenderImageInfo};
use gfx::display_list::{StackingContextType, StickyFrameData, TextDisplayItem, TextOrientation};
use gfx::display_list::WebRenderImageInfo;
use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
use ipc_channel::ipc;
Expand Down Expand Up @@ -73,8 +74,7 @@ use style_traits::ToCss;
use style_traits::cursor::Cursor;
use table_cell::CollapsedBordersForCell;
use webrender_api::{ClipId, ClipMode, ColorF, ComplexClipRegion, GradientStop, LineStyle};
use webrender_api::{LocalClip, RepeatMode, ScrollPolicy, ScrollSensitivity, StickyFrameInfo};
use webrender_api::StickySideConstraint;
use webrender_api::{LocalClip, RepeatMode, ScrollPolicy, ScrollSensitivity, StickyOffsetBounds};
use webrender_helpers::{ToBorderRadius, ToMixBlendMode, ToRectF, ToTransformStyle};

trait ResolvePercentage {
Expand Down Expand Up @@ -2734,35 +2734,40 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
// positioned items: just the parent block.
let constraint_rect = state.parent_stacking_relative_content_box;

let to_max_offset = |constraint_edge: Au, moving_edge: Au| -> f32 {
let to_offset_bound = |constraint_edge: Au, moving_edge: Au| -> f32 {
(constraint_edge - moving_edge).to_f32_px()
};

let to_sticky_info = |margin: MaybeAuto, max_offset: f32| -> Option<StickySideConstraint> {
match margin {
MaybeAuto::Auto => None,
MaybeAuto::Specified(value) =>
Some(StickySideConstraint { margin: value.to_f32_px(), max_offset }),
}
};
// This is the minimum negative offset and then the maximum positive offset. We just
// specify every edge, but if the corresponding margin is None, that offset has no effect.
let vertical_offset_bounds = StickyOffsetBounds::new(
to_offset_bound(constraint_rect.min_y(), border_box_in_parent.min_y() - margins.top),
to_offset_bound(constraint_rect.max_y(), border_box_in_parent.max_y()),
);
let horizontal_offset_bounds = StickyOffsetBounds::new(
to_offset_bound(constraint_rect.min_x(), border_box_in_parent.min_x() - margins.left),
to_offset_bound(constraint_rect.max_x(), border_box_in_parent.max_x()),
);

let sticky_frame_info = StickyFrameInfo::new(
to_sticky_info(sticky_position.top,
to_max_offset(constraint_rect.max_y(), border_box_in_parent.max_y())),
to_sticky_info(sticky_position.right,
to_max_offset(constraint_rect.min_x(), border_box_in_parent.min_x() - margins.left)),
to_sticky_info(sticky_position.bottom,
to_max_offset(constraint_rect.min_y(), border_box_in_parent.min_y() - margins.top)),
to_sticky_info(sticky_position.left,
to_max_offset(constraint_rect.max_x(), border_box_in_parent.max_x())));
// The margins control which edges have sticky behavior.
let sticky_frame_data = StickyFrameData {
margins: SideOffsets2D::new(
sticky_position.top.to_option().map(|v| v.to_f32_px()),
sticky_position.right.to_option().map(|v| v.to_f32_px()),
sticky_position.bottom.to_option().map(|v| v.to_f32_px()),
sticky_position.left.to_option().map(|v| v.to_f32_px()),
),
vertical_offset_bounds,
horizontal_offset_bounds
};

let new_clip_scroll_index = state.add_clip_scroll_node(
ClipScrollNode {
id: None,
parent_index: self.clipping_and_scrolling().scrolling,
clip: ClippingRegion::from_rect(border_box),
content_rect: Rect::zero(),
node_type: ClipScrollNodeType::StickyFrame(sticky_frame_info),
node_type: ClipScrollNodeType::StickyFrame(sticky_frame_data),
},
);

Expand Down
8 changes: 8 additions & 0 deletions components/layout/model.rs
Expand Up @@ -424,6 +424,14 @@ impl MaybeAuto {
}
}

#[inline]
pub fn to_option(&self) -> Option<Au> {
match *self {
MaybeAuto::Specified(value) => Some(value),
MaybeAuto::Auto => None,
}
}

#[inline]
pub fn specified_or_default(&self, default: Au) -> Au {
match *self {
Expand Down
10 changes: 8 additions & 2 deletions components/layout/webrender_helpers.rs
Expand Up @@ -540,10 +540,16 @@ impl WebRenderDisplayItemConverter for DisplayItem {
scroll_sensitivity
)
}
ClipScrollNodeType::StickyFrame(sticky_frame_info) => {
ClipScrollNodeType::StickyFrame(ref sticky_data) => {
// TODO: Add define_sticky_frame_with_parent to WebRender.
builder.push_clip_id(parent_id);
let id = builder.define_sticky_frame(node.id, item_rect, sticky_frame_info);
let id = builder.define_sticky_frame(
node.id,
item_rect,
sticky_data.margins,
sticky_data.vertical_offset_bounds,
sticky_data.horizontal_offset_bounds,
);
builder.pop_clip_id();
id
}
Expand Down
2 changes: 1 addition & 1 deletion components/malloc_size_of/lib.rs
Expand Up @@ -728,7 +728,7 @@ malloc_size_of_is_0!(webrender_api::ScrollPolicy);
#[cfg(feature = "servo")]
malloc_size_of_is_0!(webrender_api::ScrollSensitivity);
#[cfg(feature = "servo")]
malloc_size_of_is_0!(webrender_api::StickySideConstraint);
malloc_size_of_is_0!(webrender_api::StickyOffsetBounds);
#[cfg(feature = "servo")]
malloc_size_of_is_0!(webrender_api::TransformStyle);

Expand Down

0 comments on commit f37fa0c

Please sign in to comment.