Bug 1191539 - DisplayPort should ForceInside frameRect to match compositor DisplayPort. r=kats
authorBenoit Girard <b56girard@gmail.com>
Wed, 09 Sep 2015 14:41:38 -0400
changeset 295012 a259b679e13556208f53378ad0b1ad312c68c672
parent 295011 01cf8bf2f3d71fae16dfd2dd52ffd3706edfa910
child 295013 0f4a1154350dbbc238e693ea1f683b43b2108c30
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1191539
milestone43.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 1191539 - DisplayPort should ForceInside frameRect to match compositor DisplayPort. r=kats
layout/base/nsLayoutUtils.cpp
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -915,16 +915,19 @@ GetDisplayPortFromMarginsData(nsIContent
     // coordinate space, so it doesn't include the local resolution.
     float localRes = presContext->PresShell()->GetResolution();
     parentRes.xScale /= localRes;
     parentRes.yScale /= localRes;
   }
   ScreenRect screenRect = LayoutDeviceRect::FromAppUnits(base, auPerDevPixel)
                         * parentRes;
 
+  nsRect expandedScrollableRect =
+    nsLayoutUtils::CalculateExpandedScrollableRect(frame);
+
   if (gfxPrefs::LayersTilesEnabled()) {
     // Note on the correctness of applying the alignment in Screen space:
     //   The correct space to apply the alignment in would be Layer space, but
     //   we don't necessarily know the scale to convert to Layer space at this
     //   point because Layout may not yet have chosen the resolution at which to
     //   render (it chooses that in FrameLayerBuilder, but this can be called
     //   during display list building). Therefore, we perform the alignment in
     //   Screen space, which basically assumes that Layout chose to render at
@@ -950,22 +953,30 @@ GetDisplayPortFromMarginsData(nsIContent
     if (alignmentY == 0) {
       alignmentY = 1;
     }
 
     ScreenPoint scrollPosScreen = LayoutDevicePoint::FromAppUnits(scrollPos, auPerDevPixel)
                                 * res;
 
     screenRect += scrollPosScreen;
+    // Round-out the display port to the nearest alignment (tiles)
     float x = alignmentX * floor(screenRect.x / alignmentX);
     float y = alignmentY * floor(screenRect.y / alignmentY);
-    float w = alignmentX * ceil(screenRect.XMost() / alignmentX) - x;
-    float h = alignmentY * ceil(screenRect.YMost() / alignmentY) - y;
+    float w = alignmentX * ceil(screenRect.width / alignmentX + 1);
+    float h = alignmentY * ceil(screenRect.height / alignmentY + 1);
     screenRect = ScreenRect(x, y, w, h);
     screenRect -= scrollPosScreen;
+
+    ScreenRect screenExpScrollableRect =
+      LayoutDeviceRect::FromAppUnits(expandedScrollableRect,
+                                     auPerDevPixel) * res;
+
+    // Make sure the displayport remains within the scrollable rect.
+    screenRect = screenRect.ForceInside(screenExpScrollableRect - scrollPosScreen);
   } else {
     nscoord maxSizeInAppUnits = GetMaxDisplayPortSize(aContent);
     if (maxSizeInAppUnits == nscoord_MAX) {
       // Pick a safe maximum displayport size for sanity purposes. This is the
       // lowest maximum texture size on tileless-platforms (Windows, D3D10).
       maxSizeInAppUnits = presContext->DevPixelsToAppUnits(8192);
     }
 
@@ -996,17 +1007,16 @@ GetDisplayPortFromMarginsData(nsIContent
 
   // Convert the aligned rect back into app units.
   nsRect result = LayoutDeviceRect::ToAppUnits(screenRect / res, auPerDevPixel);
 
   // Expand it for the low-res buffer if needed
   result = ApplyRectMultiplier(result, aMultiplier);
 
   // Finally, clamp it to the expanded scrollable rect.
-  nsRect expandedScrollableRect = nsLayoutUtils::CalculateExpandedScrollableRect(frame);
   result = expandedScrollableRect.Intersect(result + scrollPos) - scrollPos;
 
   return result;
 }
 
 static bool
 GetDisplayPortImpl(nsIContent* aContent, nsRect *aResult, float aMultiplier)
 {