servo: Merge #14475 - Don't scroll background and borders of overflow:scroll blocks (from mrobinson:backrounds-borders-scrolling-div); r=pcwalton
authorMartin Robinson <mrobinson@igalia.com>
Tue, 06 Dec 2016 21:22:58 -0800
changeset 369318 03dbb0844fe988ef837223f2691ccae7e526debe
parent 369317 1ba608da113c7639625000bbb9470c39f6228839
child 369319 eddbee19edbc8e7cf28bf42a099b77b91856ee6f
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspcwalton
servo: Merge #14475 - Don't scroll background and borders of overflow:scroll blocks (from mrobinson:backrounds-borders-scrolling-div); r=pcwalton <!-- 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: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> We want them to be children of the parent scrolling root instead of the scrolling root of the particular block they belong to. Also, we adjust the scroll root to only include the content region. Source-Repo: https://github.com/servo/servo Source-Revision: 900cb3b142ed6158c74f8a6d835a59dedb965f10
servo/components/layout/display_list_builder.rs
--- a/servo/components/layout/display_list_builder.rs
+++ b/servo/components/layout/display_list_builder.rs
@@ -10,17 +10,16 @@
 
 #![deny(unsafe_code)]
 
 use app_units::{AU_PER_PX, Au};
 use block::{BlockFlow, BlockStackingContextType};
 use canvas_traits::{CanvasData, CanvasMsg, FromLayoutMsg};
 use context::SharedLayoutContext;
 use euclid::{Matrix4D, Point2D, Radians, Rect, SideOffsets2D, Size2D};
-use euclid::point::TypedPoint2D;
 use flex::FlexFlow;
 use flow::{BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
 use flow_ref::FlowRef;
 use fragment::{CoordinateSystem, Fragment, ImageFragmentInfo, ScannedTextFragmentInfo};
 use fragment::SpecificFragmentInfo;
 use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDisplayItem};
 use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClippingRegion};
 use gfx::display_list::{DisplayItem, DisplayItemMetadata, DisplayList, DisplayListSection};
@@ -93,29 +92,31 @@ fn get_cyclic<T>(arr: &[T], index: usize
 
 pub struct DisplayListBuildState<'a> {
     pub shared_layout_context: &'a SharedLayoutContext,
     pub root_stacking_context: StackingContext,
     pub items: HashMap<StackingContextId, Vec<DisplayItem>>,
     pub scroll_roots: HashMap<ScrollRootId, ScrollRoot>,
     pub stacking_context_id_stack: Vec<StackingContextId>,
     pub scroll_root_id_stack: Vec<ScrollRootId>,
+    pub processing_scroll_root_element: bool,
 }
 
 impl<'a> DisplayListBuildState<'a> {
     pub fn new(shared_layout_context: &'a SharedLayoutContext,
                stacking_context_id: StackingContextId)
                -> DisplayListBuildState<'a> {
         DisplayListBuildState {
             shared_layout_context: shared_layout_context,
             root_stacking_context: StackingContext::root(),
             items: HashMap::new(),
             scroll_roots: HashMap::new(),
             stacking_context_id_stack: vec!(stacking_context_id),
             scroll_root_id_stack: vec!(ScrollRootId::root()),
+            processing_scroll_root_element: false,
         }
     }
 
     fn add_display_item(&mut self, display_item: DisplayItem) {
         let items = self.items.entry(display_item.stacking_context_id()).or_insert(Vec::new());
         items.push(display_item);
     }
 
@@ -157,25 +158,33 @@ impl<'a> DisplayListBuildState<'a> {
 
     fn create_base_display_item(&self,
                                 bounds: &Rect<Au>,
                                 clip: &ClippingRegion,
                                 node: OpaqueNode,
                                 cursor: Option<Cursor>,
                                 section: DisplayListSection)
                                 -> BaseDisplayItem {
+        let scroll_root_id = if (section == DisplayListSection::BackgroundAndBorders ||
+                                 section == DisplayListSection::BlockBackgroundsAndBorders) &&
+                                 self.processing_scroll_root_element {
+            self.parent_scroll_root_id()
+        } else {
+            self.scroll_root_id()
+        };
+
         BaseDisplayItem::new(&bounds,
                              DisplayItemMetadata {
                                  node: node,
                                  pointing: cursor,
                              },
                              &clip,
                              section,
                              self.stacking_context_id(),
-                             self.scroll_root_id())
+                             scroll_root_id)
     }
 
     pub fn to_display_list(mut self) -> DisplayList {
         let mut scroll_root_stack = Vec::new();
         scroll_root_stack.push(ScrollRootId::root());
 
         let mut list = Vec::new();
         let root_context = mem::replace(&mut self.root_stacking_context, StackingContext::root());
@@ -1972,31 +1981,35 @@ impl BlockFlowDisplayListBuilding for Bl
                 DisplayListSection::BlockBackgroundsAndBorders
             }
         } else {
             DisplayListSection::BlockBackgroundsAndBorders
         };
 
         if self.has_scrolling_overflow() {
             let size = self.base.overflow.scroll.size;
-            let mut clip = self.fragment.stacking_relative_border_box(
+            let coordinate_system = if establishes_stacking_context {
+                CoordinateSystem::Own
+            } else {
+                CoordinateSystem::Parent
+            };
+
+            let border_box = self.fragment.stacking_relative_border_box(
                 &self.base.stacking_relative_position,
                 &self.base.early_absolute_position_info.relative_containing_block_size,
                 self.base.early_absolute_position_info.relative_containing_block_mode,
-                CoordinateSystem::Parent);
-            if establishes_stacking_context {
-                clip = Rect::new(TypedPoint2D::zero(), clip.size);
-            }
+                coordinate_system);
 
             let parent_id = state.parent_scroll_root_id();
+            state.processing_scroll_root_element = true;
             state.add_scroll_root(
                 ScrollRoot {
                     id: self.base.scroll_root_id,
                     parent_id: parent_id,
-                    clip: clip,
+                    clip: self.fragment.stacking_relative_content_box(&border_box),
                     size: size,
                 }
             );
         }
 
         // Add the box that starts the block context.
         self.fragment
             .build_display_list(state,
@@ -2007,16 +2020,18 @@ impl BlockFlowDisplayListBuilding for Bl
                                 self.base
                                     .early_absolute_position_info
                                     .relative_containing_block_mode,
                                 border_painting_mode,
                                 background_border_section,
                                 &self.base.clip);
 
         self.base.build_display_items_for_debugging_tint(state, self.fragment.node);
+
+        state.processing_scroll_root_element = false;
     }
 
     fn switch_coordinate_system_if_necessary(&mut self) {
         // Avoid overflows!
         if self.base.clip.is_max() {
             return
         }