Bug 847223. Part 4. Tweak the ExpandRect function to not expand in a direction that we cannot scroll. r=mats
authorTimothy Nikkel <tnikkel@gmail.com>
Sat, 14 Sep 2013 19:05:04 -0500
changeset 160151 890f8c06d8aaabff2877ba0e80587319196719da
parent 160150 15151e852274a7808332612ed7dc951f26f3c2c0
child 160152 f824604ba8dc9f7a125d718e0f04420d9183420b
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats
bugs847223
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 847223. Part 4. Tweak the ExpandRect function to not expand in a direction that we cannot scroll. r=mats
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2158,21 +2158,43 @@ nsGfxScrollFrameInner::EnsureImageVisPre
       "layout.imagevisibility.amountscrollbeforeupdatehorizontal", 2);
     Preferences::AddIntVarCache(&sVertScrollFraction,
       "layout.imagevisibility.amountscrollbeforeupdatevertical", 2);
 
     sImageVisPrefsCached = true;
   }
 }
 
-/* static */ nsRect
-nsGfxScrollFrameInner::ExpandRect(const nsRect& aRect)
+nsRect
+nsGfxScrollFrameInner::ExpandRect(const nsRect& aRect) const
 {
+  // We don't want to expand a rect in a direction that we can't scroll, so we
+  // check the scroll range.
+  nsRect scrollRange = GetScrollRangeForClamping();
+  nsPoint scrollPos = GetScrollPosition();
+  nsMargin expand(0, 0, 0, 0);
+
+  nscoord vertShift = sVertExpandScrollPort * aRect.height;
+  if (scrollRange.y < scrollPos.y) {
+    expand.top = vertShift;
+  }
+  if (scrollPos.y < scrollRange.YMost()) {
+    expand.bottom = vertShift;
+  }
+
+  nscoord horzShift = sHorzExpandScrollPort * aRect.width;
+  if (scrollRange.x < scrollPos.x) {
+    expand.left = horzShift;
+  }
+  if (scrollPos.x < scrollRange.XMost()) {
+    expand.right = horzShift;
+  }
+
   nsRect rect = aRect;
-  rect.Inflate(sHorzExpandScrollPort * aRect.width, sVertExpandScrollPort * aRect.height);
+  rect.Inflate(expand);
   return rect;
 }
 
 void
 nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                         const nsRect&           aDirtyRect,
                                         const nsDisplayListSet& aLists)
 {
@@ -2243,18 +2265,19 @@ nsGfxScrollFrameInner::BuildDisplayList(
     nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &displayPort) &&
     !aBuilder->IsForEventDelivery();
   if (usingDisplayport) {
     dirtyRect = displayPort;
   }
 
   if (aBuilder->IsForImageVisibility()) {
     // We expand the dirty rect to catch images just outside of the scroll port.
-    // We could be smarter and not expand the dirty rect in a direction in which
-    // we are not able to scroll.
+    // We use the dirty rect instead of the whole scroll port to prevent
+    // too much expansion in the presence of very large (bigger than the
+    // viewport) scroll ports.
     dirtyRect = ExpandRect(dirtyRect);
   }
 
   nsDisplayListCollection set;
   {
     DisplayListClipState::AutoSaveRestore clipState(aBuilder);
 
     if (usingDisplayport) {
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -397,17 +397,17 @@ protected:
   /**
    * @note This method might destroy the frame, pres shell and other objects.
    */
   void ScrollToWithOrigin(nsPoint aScrollPosition,
                           nsIScrollableFrame::ScrollMode aMode,
                           nsIAtom *aOrigin, // nullptr indicates "other" origin
                           const nsRect* aRange);
 
-  static nsRect ExpandRect(const nsRect& aRect);
+  nsRect ExpandRect(const nsRect& aRect) const;
   static void EnsureImageVisPrefsCached();
   static bool sImageVisPrefsCached;
   // The number of scrollports wide/high to expand when looking for images.
   static uint32_t sHorzExpandScrollPort;
   static uint32_t sVertExpandScrollPort;
   // The fraction of the scrollport we allow to scroll by before we schedule
   // an update of image visibility.
   static int32_t sHorzScrollFraction;