Bug 1223479 - Fix displayport size calculation on fennec. r=kats
authorJamie Nicol <jnicol@mozilla.com>
Wed, 11 Nov 2015 09:38:12 +0000
changeset 308262 1b812b3dc8aaa86c7e94476845cc3bc1a10609e0
parent 308261 0f549771f1c9ac61c67b0aadf88a6b5e15ef2051
child 308263 a0eedfc2faec5f0239a8b9757508b8ea22352f34
push id7450
push userahalberstadt@mozilla.com
push dateWed, 11 Nov 2015 20:09:05 +0000
reviewerskats
bugs1223479
milestone45.0a1
Bug 1223479 - Fix displayport size calculation on fennec. r=kats The displayport was accidentally being calculated as too large. This was leading to a large number of tiles existing at once, causing very high memory usage.
layout/base/nsLayoutUtils.cpp
mobile/android/base/gfx/DisplayPortCalculator.java
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1062,22 +1062,16 @@ GetDisplayPortFromMarginsData(nsIContent
 
       float left = std::min(margins.left, float(budget));
       float right = std::min(margins.right, budget - left);
       screenRect.x -= left;
       screenRect.width += left + right;
     }
   }
 
-  // Inflate the rectangle by 1 so that we always push to the next tile
-  // boundary. This is desirable to stop from having a rectangle with a
-  // moving origin occasionally being smaller when it coincidentally lines
-  // up to tile boundaries.
-  screenRect.Inflate(1);
-
   ScreenPoint scrollPosScreen = LayoutDevicePoint::FromAppUnits(scrollPos, auPerDevPixel)
                               * res;
 
   // Round-out the display port to the nearest alignment (tiles)
   screenRect += scrollPosScreen;
   float x = alignment.width * floor(screenRect.x / alignment.width);
   float y = alignment.height * floor(screenRect.y / alignment.height);
   float w = alignment.width * ceil(screenRect.width / alignment.width + 1);
--- a/mobile/android/base/gfx/DisplayPortCalculator.java
+++ b/mobile/android/base/gfx/DisplayPortCalculator.java
@@ -17,19 +17,16 @@ import android.util.Log;
 
 import java.util.HashMap;
 import java.util.Map;
 
 final class DisplayPortCalculator {
     private static final String LOGTAG = "GeckoDisplayPort";
     private static final PointF ZERO_VELOCITY = new PointF(0, 0);
 
-    // Keep this in sync with the TILEDLAYERBUFFER_TILE_SIZE defined in gfx/layers/TiledLayerBuffer.h
-    private static final int TILE_SIZE = 256;
-
     private static final String PREF_DISPLAYPORT_STRATEGY = "gfx.displayport.strategy";
     private static final String PREF_DISPLAYPORT_FM_MULTIPLIER = "gfx.displayport.strategy_fm.multiplier";
     private static final String PREF_DISPLAYPORT_FM_DANGER_X = "gfx.displayport.strategy_fm.danger_x";
     private static final String PREF_DISPLAYPORT_FM_DANGER_Y = "gfx.displayport.strategy_fm.danger_y";
     private static final String PREF_DISPLAYPORT_VB_MULTIPLIER = "gfx.displayport.strategy_vb.multiplier";
     private static final String PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD = "gfx.displayport.strategy_vb.threshold";
     private static final String PREF_DISPLAYPORT_VB_REVERSE_BUFFER = "gfx.displayport.strategy_vb.reverse_buffer";
     private static final String PREF_DISPLAYPORT_VB_DANGER_X_BASE = "gfx.displayport.strategy_vb.danger_x_base";
@@ -168,30 +165,29 @@ final class DisplayPortCalculator {
         float dangerZoneX = metrics.getWidth() * dangerZoneXMultiplier;
         float dangerZoneY = metrics.getHeight() * dangerZoneYMultiplier;
         rect = RectUtils.expand(rect, dangerZoneX, dangerZoneY);
         // clamp to page bounds
         return clampToPageBounds(rect, metrics);
     }
 
     /**
-     * Expand the given margins such that when they are applied on the viewport, the resulting rect
-     * does not have any partial tiles, except when it is clipped by the page bounds. This assumes
-     * the tiles are TILE_SIZE by TILE_SIZE and start at the origin, such that there will always be
-     * a tile at (0,0)-(TILE_SIZE,TILE_SIZE)).
+     * Calculate the display port by expanding the viewport by the specified
+     * margins, then clamping to the page size.
      */
-    private static DisplayPortMetrics getTileAlignedDisplayPortMetrics(RectF margins, float zoom, ImmutableViewportMetrics metrics) {
+    private static DisplayPortMetrics getPageClampedDisplayPortMetrics(RectF margins, float zoom, ImmutableViewportMetrics metrics) {
         float left = metrics.viewportRectLeft - margins.left;
         float top = metrics.viewportRectTop - margins.top;
         float right = metrics.viewportRectRight() + margins.right;
         float bottom = metrics.viewportRectBottom() + margins.bottom;
-        left = (float) Math.max(metrics.pageRectLeft, TILE_SIZE * Math.floor(left / TILE_SIZE));
-        top = (float) Math.max(metrics.pageRectTop, TILE_SIZE * Math.floor(top / TILE_SIZE));
-        right = (float) Math.min(metrics.pageRectRight, TILE_SIZE * Math.ceil(right / TILE_SIZE));
-        bottom = (float) Math.min(metrics.pageRectBottom, TILE_SIZE * Math.ceil(bottom / TILE_SIZE));
+        left = Math.max(metrics.pageRectLeft, left);
+        top = Math.max(metrics.pageRectTop, top);
+        right = Math.min(metrics.pageRectRight, right);
+        bottom = Math.min(metrics.pageRectBottom, bottom);
+
         return new DisplayPortMetrics(left, top, right, bottom, zoom);
     }
 
     /**
      * Adjust the given margins so if they are applied on the viewport in the metrics, the resulting rect
      * does not exceed the page bounds. This code will maintain the total margin amount for a given axis;
      * it assumes that margins.left + metrics.getWidth() + margins.right is less than or equal to
      * metrics.getPageWidth(); and the same for the y axis.
@@ -306,17 +302,17 @@ final class DisplayPortCalculator {
             // is split).
             RectF margins = new RectF();
             margins.left = horizontalBuffer / 2.0f;
             margins.right = horizontalBuffer - margins.left;
             margins.top = verticalBuffer / 2.0f;
             margins.bottom = verticalBuffer - margins.top;
             margins = shiftMarginsForPageBounds(margins, metrics);
 
-            return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
+            return getPageClampedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
         }
 
         @Override
         public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
             // Increase the size of the viewport based on the danger zone multiplier (and clamp to page
             // boundaries), and intersect it with the current displayport to determine whether we're
             // close to checkerboarding.
             RectF adjustedViewport = expandByDangerZone(metrics.getViewport(), DANGER_ZONE_X_MULTIPLIER, DANGER_ZONE_Y_MULTIPLIER, metrics);
@@ -417,17 +413,17 @@ final class DisplayPortCalculator {
             float horizontalBuffer = displayPortWidth - metrics.getWidth();
             float verticalBuffer = displayPortHeight - metrics.getHeight();
 
             // split the buffer amounts into margins based on velocity, and shift it to
             // take into account the page bounds
             RectF margins = velocityBiasedMargins(horizontalBuffer, verticalBuffer, velocity);
             margins = shiftMarginsForPageBounds(margins, metrics);
 
-            return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
+            return getPageClampedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
         }
 
         @Override
         public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
             // calculate the danger zone amounts based on the prefs
             float dangerZoneX = metrics.getWidth() * (DANGER_ZONE_BASE_X_MULTIPLIER + (velocity.x * DANGER_ZONE_INCR_X_MULTIPLIER));
             float dangerZoneY = metrics.getHeight() * (DANGER_ZONE_BASE_Y_MULTIPLIER + (velocity.y * DANGER_ZONE_INCR_Y_MULTIPLIER));
             // clamp it such that when added to the viewport, they don't exceed page size.
@@ -684,17 +680,17 @@ final class DisplayPortCalculator {
         public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) {
             float width = metrics.getWidth();
             float height = metrics.getHeight();
             mPixelArea = (int)(width * height);
 
             if (velocity.length() < VELOCITY_THRESHOLD) {
                 // if we're going slow, expand the displayport to 9x viewport size
                 RectF margins = new RectF(width, height, width, height);
-                return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
+                return getPageClampedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
             }
 
             // figure out how far we expect to be
             float minDx = velocity.x * mMinFramesToDraw;
             float minDy = velocity.y * mMinFramesToDraw;
             float maxDx = velocity.x * mMaxFramesToDraw;
             float maxDy = velocity.y * mMaxFramesToDraw;
 
@@ -709,17 +705,17 @@ final class DisplayPortCalculator {
 
             // and finally generate the displayport. the min/max stuff takes care of
             // negative velocities as well as positive.
             RectF margins = new RectF(
                 -Math.min(minDx, maxDx),
                 -Math.min(minDy, maxDy),
                 Math.max(minDx, maxDx),
                 Math.max(minDy, maxDy));
-            return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
+            return getPageClampedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
         }
 
         @Override
         public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
             // the code below is the same as in calculate() but is awkward to refactor since it has multiple outputs.
             // refer to the comments in calculate() to understand what this is doing.
             float minDx = velocity.x * mMinFramesToDraw;
             float minDy = velocity.y * mMinFramesToDraw;