Bug 729528 - Add an alternate strategy with a margin that is a multiple of view-size and shifts it with velocity bias. r=Cwiiis
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 26 Mar 2012 13:15:50 -0400
changeset 93642 ac5aed81d6e32165ea71d8ed7fc20070945bc857
parent 93641 7db6f151bded3b330f861051ac3fce230fbe7d75
child 93643 c69c54b0bb113a3dbc648e82f127b3687c39cc19
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersCwiiis
bugs729528
milestone14.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 729528 - Add an alternate strategy with a margin that is a multiple of view-size and shifts it with velocity bias. r=Cwiiis
mobile/android/base/gfx/DisplayPortCalculator.java
--- a/mobile/android/base/gfx/DisplayPortCalculator.java
+++ b/mobile/android/base/gfx/DisplayPortCalculator.java
@@ -140,16 +140,94 @@ final class DisplayPortCalculator {
             if (adjustedViewport.right > pageSize.width) adjustedViewport.right = pageSize.width;
             if (adjustedViewport.bottom > pageSize.height) adjustedViewport.bottom = pageSize.height;
 
             return !displayPort.contains(adjustedViewport);
         }
     }
 
     /**
+     * This class implements the variation with a small fixed-size margin with velocity bias.
+     * In this variation, the default margins are pretty small relative to the view size, but
+     * they are affected by the panning velocity. Specifically, if we are panning on one axis,
+     * we remove the margins on the other axis because we are likely axis-locked. Also once
+     * we are panning in one direction above a certain threshold velocity, we shift the buffer
+     * so that it is entirely in the direction of the pan.
+     */
+    private static class VelocityBiasStrategy implements DisplayPortStrategy {
+        /* The size of the margin as a fraction of view size */
+        private static final float SIZE_MULTIPLIER = 0.2f;
+        /* The velocity above which we apply the velocity bias */
+        private static final float VELOCITY_THRESHOLD = GeckoAppShell.getDpi() / 32f;
+
+        public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) {
+            // by default we apply margins that are a fraction of the view size
+            float desiredXMargins = metrics.getWidth() * SIZE_MULTIPLIER;
+            float desiredYMargins = metrics.getHeight() * SIZE_MULTIPLIER;
+
+            // but if we're panning on one axis, set the margins for the other axis to zero since we are likely
+            // axis locked and won't be displaying that extra area.
+            if (Math.abs(velocity.x) > VELOCITY_THRESHOLD && FloatUtils.fuzzyEquals(velocity.y, 0)) {
+                desiredYMargins = 0;
+            } else if (Math.abs(velocity.y) > VELOCITY_THRESHOLD && FloatUtils.fuzzyEquals(velocity.x, 0)) {
+                desiredXMargins = 0;
+            }
+
+            // we need to avoid having a display port that is larger than the page, or we will end up
+            // painting things outside the page bounds (bug 729169).
+
+            // figure out how much of the desired buffer amount we can actually use on the two axes
+            float xBufferAmount = Math.min(desiredXMargins, metrics.pageSizeWidth - metrics.getWidth());
+            float yBufferAmount = Math.min(desiredYMargins, metrics.pageSizeHeight - metrics.getHeight());
+
+            // if we're panning above the VELOCITY_THRESHOLD on an axis, shift the margin so that it
+            // is entirely in the direction of panning. Otherwise, split the margin evenly on both sides of
+            // the display port.
+            float leftMargin, rightMargin;
+            if (velocity.x > VELOCITY_THRESHOLD) {
+                rightMargin = Math.min(xBufferAmount, metrics.pageSizeWidth - (metrics.viewportRectLeft + metrics.getWidth()));
+                leftMargin = xBufferAmount - rightMargin;
+            } else if (velocity.x < -VELOCITY_THRESHOLD) {
+                leftMargin = Math.min(xBufferAmount, metrics.viewportRectLeft);
+                rightMargin = xBufferAmount - leftMargin;
+            } else {
+                leftMargin = Math.min(xBufferAmount / 2.0f, metrics.viewportRectLeft);
+                rightMargin = xBufferAmount - leftMargin;
+            }
+
+            float topMargin, bottomMargin;
+            if (velocity.y > VELOCITY_THRESHOLD) {
+                bottomMargin = Math.min(yBufferAmount, metrics.pageSizeHeight - (metrics.viewportRectTop + metrics.getHeight()));
+                topMargin = yBufferAmount - bottomMargin;
+            } else if (velocity.y < -VELOCITY_THRESHOLD) {
+                topMargin = Math.min(yBufferAmount, metrics.viewportRectTop);
+                bottomMargin = yBufferAmount - topMargin;
+            } else {
+                topMargin = Math.min(yBufferAmount / 2.0f, metrics.viewportRectTop);
+                bottomMargin = yBufferAmount - topMargin;
+            }
+
+            return new DisplayPortMetrics(metrics.viewportRectLeft - leftMargin,
+                    metrics.viewportRectTop - topMargin,
+                    metrics.viewportRectRight + rightMargin,
+                    metrics.viewportRectBottom + bottomMargin,
+                    metrics.zoomFactor);
+        }
+
+        public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
+            // Since we have such a small margin, we want to be drawing more aggressively. At the start of a
+            // pan the velocity is going to be large so we're almost certainly going to go into checkerboard
+            // on every frame, so drawing all the time seems like the right thing. At the end of the pan we
+            // want to re-center the displayport and draw stuff on all sides, so again we don't want to throttle
+            // there. When we're not panning we're not drawing anyway so it doesn't make a difference there.
+            return true;
+        }
+    }
+
+    /**
      * This class implements the variation where we draw more of the page at low resolution while panning.
      * In this variation, as we pan faster, we increase the page area we are drawing, but reduce the draw
      * resolution to compensate. This results in the same device-pixel area drawn; the compositor then
      * scales this up to the viewport zoom level. This results in a large area of the page drawn but it
      * looks blurry. The assumption is that drawing extra that we never display is better than checkerboarding,
      * where we draw less but never even show it on the screen.
      */
     private static class DynamicResolutionStrategy implements DisplayPortStrategy {