From f37fa0cf6d0bac9665331ea7d7199f9825ada0f3 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Mon, 30 Oct 2017 10:15:30 +0100 Subject: [PATCH] Update WR to use the new sticky positioning API --- Cargo.lock | 10 ++--- components/gfx/display_list/mod.rs | 11 ++++- components/layout/display_list_builder.rs | 49 +++++++++++++---------- components/layout/model.rs | 8 ++++ components/layout/webrender_helpers.rs | 10 ++++- components/malloc_size_of/lib.rs | 2 +- 6 files changed, 58 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2962a40f1199..c25798f73a88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1031,7 +1031,7 @@ dependencies = [ [[package]] name = "gamma-lut" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3624,7 +3624,7 @@ dependencies = [ [[package]] name = "webrender" version = "0.53.1" -source = "git+https://github.com/servo/webrender#9110e7498fbe9e9d58c480c6ccae0f1461e3dbfb" +source = "git+https://github.com/servo/webrender#f80760ffc8d073f90c7b2b29ded28a6f8879e63f" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3637,7 +3637,7 @@ dependencies = [ "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "gamma-lut 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "gamma-lut 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3652,7 +3652,7 @@ dependencies = [ [[package]] name = "webrender_api" version = "0.53.1" -source = "git+https://github.com/servo/webrender#9110e7498fbe9e9d58c480c6ccae0f1461e3dbfb" +source = "git+https://github.com/servo/webrender#f80760ffc8d073f90c7b2b29ded28a6f8879e63f" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3880,7 +3880,7 @@ dependencies = [ "checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3" "checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a" "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -"checksum gamma-lut 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dd65074503368cef99b98844012adfed8d7f99ff3e1e6d05e9055232f2d59dc9" +"checksum gamma-lut 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "250cfe9e6ad3057a290c2107a60c1c6c74ac57b5095e46b8a5c0bc5626d72857" "checksum gaol 0.0.1 (git+https://github.com/servo/gaol)" = "" "checksum gcc 0.3.47 (registry+https://github.com/rust-lang/crates.io-index)" = "5773372df827453bc38d4fd8efe425c7f28b1f54468816183fc8716cfb90bd30" "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index 30d683d6cc09..9c8ef998fbfc 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -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; @@ -321,10 +321,17 @@ impl fmt::Debug for StackingContext { } } +#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] +pub struct StickyFrameData { + pub margins: SideOffsets2D>, + 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, } diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index c34f65a5791d..de15a2f76d97 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -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; @@ -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 { @@ -2734,27 +2734,32 @@ 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 { - 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 { @@ -2762,7 +2767,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { 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), }, ); diff --git a/components/layout/model.rs b/components/layout/model.rs index 02cae69fa21e..9d0d4c69926d 100644 --- a/components/layout/model.rs +++ b/components/layout/model.rs @@ -424,6 +424,14 @@ impl MaybeAuto { } } + #[inline] + pub fn to_option(&self) -> Option { + match *self { + MaybeAuto::Specified(value) => Some(value), + MaybeAuto::Auto => None, + } + } + #[inline] pub fn specified_or_default(&self, default: Au) -> Au { match *self { diff --git a/components/layout/webrender_helpers.rs b/components/layout/webrender_helpers.rs index 4ed2125fea5d..4f491aa91d6f 100644 --- a/components/layout/webrender_helpers.rs +++ b/components/layout/webrender_helpers.rs @@ -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 } diff --git a/components/malloc_size_of/lib.rs b/components/malloc_size_of/lib.rs index babb393cc9a9..d3ec9d52a235 100644 --- a/components/malloc_size_of/lib.rs +++ b/components/malloc_size_of/lib.rs @@ -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);