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 147214 890f8c06d8aa
parent 147213 15151e852274
child 147215 f824604ba8dc
push id33809
push usertnikkel@gmail.com
push dateSun, 15 Sep 2013 00:05:34 +0000
treeherdermozilla-inbound@daa9550337ab [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;