Bug 729528 - Move displayport calculation and comparison code into a DisplayPortCalculator class. No functional changes intended. r=Cwiiis

This commit is contained in:
Kartikaya Gupta 2012-03-26 13:15:50 -04:00
parent f6e6bb3982
commit 53cd348221
4 changed files with 106 additions and 89 deletions

View File

@ -120,6 +120,7 @@ FENNEC_JAVA_FILES = \
gfx/CairoImage.java \
gfx/CairoUtils.java \
gfx/CheckerboardImage.java \
gfx/DisplayPortCalculator.java \
gfx/DisplayPortMetrics.java \
gfx/FlexibleGLSurfaceView.java \
gfx/FloatSize.java \

View File

@ -0,0 +1,101 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.gfx;
import android.graphics.RectF;
import org.mozilla.gecko.FloatUtils;
final class DisplayPortCalculator {
private static final String LOGTAG = "GeckoDisplayPortCalculator";
private static final int DEFAULT_DISPLAY_PORT_MARGIN = 300;
/* If the visible rect is within the danger zone (measured in pixels from each edge of a tile),
* we start aggressively redrawing to minimize checkerboarding. */
private static final int DANGER_ZONE_X = 75;
private static final int DANGER_ZONE_Y = 150;
static DisplayPortMetrics calculate(ImmutableViewportMetrics metrics) {
float desiredXMargins = 2 * DEFAULT_DISPLAY_PORT_MARGIN;
float desiredYMargins = 2 * DEFAULT_DISPLAY_PORT_MARGIN;
// 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). we simultaneously need to make
// the display port as large as possible so that we redraw less.
// figure out how much of the desired buffer amount we can actually use on the horizontal axis
float xBufferAmount = Math.min(desiredXMargins, metrics.pageSizeWidth - metrics.getWidth());
// if we reduced the buffer amount on the horizontal axis, we should take that saved memory and
// use it on the vertical axis
float savedPixels = (desiredXMargins - xBufferAmount) * (metrics.getHeight() + desiredYMargins);
float extraYAmount = (float)Math.floor(savedPixels / (metrics.getWidth() + xBufferAmount));
float yBufferAmount = Math.min(desiredYMargins + extraYAmount, metrics.pageSizeHeight - metrics.getHeight());
// and the reverse - if we shrunk the buffer on the vertical axis we can add it to the horizontal
if (xBufferAmount == desiredXMargins && yBufferAmount < desiredYMargins) {
savedPixels = (desiredYMargins - yBufferAmount) * (metrics.getWidth() + xBufferAmount);
float extraXAmount = (float)Math.floor(savedPixels / (metrics.getHeight() + yBufferAmount));
xBufferAmount = Math.min(xBufferAmount + extraXAmount, metrics.pageSizeWidth - metrics.getWidth());
}
// and now calculate the display port margins based on how much buffer we've decided to use and
// the page bounds, ensuring we use all of the available buffer amounts on one side or the other
// on any given axis. (i.e. if we're scrolled to the top of the page, the vertical buffer is
// entirely below the visible viewport, but if we're halfway down the page, the vertical buffer
// is split).
float leftMargin = Math.min(DEFAULT_DISPLAY_PORT_MARGIN, metrics.viewportRectLeft);
float rightMargin = Math.min(DEFAULT_DISPLAY_PORT_MARGIN, metrics.pageSizeWidth - (metrics.viewportRectLeft + metrics.getWidth()));
if (leftMargin < DEFAULT_DISPLAY_PORT_MARGIN) {
rightMargin = xBufferAmount - leftMargin;
} else if (rightMargin < DEFAULT_DISPLAY_PORT_MARGIN) {
leftMargin = xBufferAmount - rightMargin;
} else if (!FloatUtils.fuzzyEquals(leftMargin + rightMargin, xBufferAmount)) {
float delta = xBufferAmount - leftMargin - rightMargin;
leftMargin += delta / 2;
rightMargin += delta / 2;
}
float topMargin = Math.min(DEFAULT_DISPLAY_PORT_MARGIN, metrics.viewportRectTop);
float bottomMargin = Math.min(DEFAULT_DISPLAY_PORT_MARGIN, metrics.pageSizeHeight - (metrics.viewportRectTop + metrics.getHeight()));
if (topMargin < DEFAULT_DISPLAY_PORT_MARGIN) {
bottomMargin = yBufferAmount - topMargin;
} else if (bottomMargin < DEFAULT_DISPLAY_PORT_MARGIN) {
topMargin = yBufferAmount - bottomMargin;
} else if (!FloatUtils.fuzzyEquals(topMargin + bottomMargin, yBufferAmount)) {
float delta = yBufferAmount - topMargin - bottomMargin;
topMargin += delta / 2;
bottomMargin += delta / 2;
}
// note that unless the viewport size changes, or the page dimensions change (either because of
// content changes or zooming), the size of the display port should remain constant. this
// is intentional to avoid re-creating textures and all sorts of other reallocations in the
// draw and composition code.
return new DisplayPortMetrics(metrics.viewportRectLeft - leftMargin,
metrics.viewportRectTop - topMargin,
metrics.viewportRectRight + rightMargin,
metrics.viewportRectBottom + bottomMargin,
metrics.zoomFactor);
}
// Returns true if a checkerboard is about to be visible.
static boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, DisplayPortMetrics displayPort) {
if (displayPort == null) {
return true;
}
// Increase the size of the viewport (and clamp to page boundaries), and
// intersect it with the tile's displayport to determine whether we're
// close to checkerboarding.
FloatSize pageSize = metrics.getPageSize();
RectF adjustedViewport = RectUtils.expand(metrics.getViewport(), DANGER_ZONE_X, DANGER_ZONE_Y);
if (adjustedViewport.top < 0) adjustedViewport.top = 0;
if (adjustedViewport.left < 0) adjustedViewport.left = 0;
if (adjustedViewport.right > pageSize.width) adjustedViewport.right = pageSize.width;
if (adjustedViewport.bottom > pageSize.height) adjustedViewport.bottom = pageSize.height;
return !displayPort.contains(adjustedViewport);
}
}

View File

@ -60,8 +60,6 @@ public class GeckoLayerClient implements GeckoEventResponder,
FlexibleGLSurfaceView.Listener {
private static final String LOGTAG = "GeckoLayerClient";
private static final int DEFAULT_DISPLAY_PORT_MARGIN = 300;
private LayerController mLayerController;
private LayerRenderer mLayerRenderer;
private boolean mLayerRendererInitialized;
@ -171,75 +169,13 @@ public class GeckoLayerClient implements GeckoEventResponder,
GeckoAppShell.viewSizeChanged();
}
private static DisplayPortMetrics calculateDisplayPort(ImmutableViewportMetrics metrics) {
float desiredXMargins = 2 * DEFAULT_DISPLAY_PORT_MARGIN;
float desiredYMargins = 2 * DEFAULT_DISPLAY_PORT_MARGIN;
// 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). we simultaneously need to make
// the display port as large as possible so that we redraw less.
// figure out how much of the desired buffer amount we can actually use on the horizontal axis
float xBufferAmount = Math.min(desiredXMargins, metrics.pageSizeWidth - metrics.getWidth());
// if we reduced the buffer amount on the horizontal axis, we should take that saved memory and
// use it on the vertical axis
float savedPixels = (desiredXMargins - xBufferAmount) * (metrics.getHeight() + desiredYMargins);
float extraYAmount = (float)Math.floor(savedPixels / (metrics.getWidth() + xBufferAmount));
float yBufferAmount = Math.min(desiredYMargins + extraYAmount, metrics.pageSizeHeight - metrics.getHeight());
// and the reverse - if we shrunk the buffer on the vertical axis we can add it to the horizontal
if (xBufferAmount == desiredXMargins && yBufferAmount < desiredYMargins) {
savedPixels = (desiredYMargins - yBufferAmount) * (metrics.getWidth() + xBufferAmount);
float extraXAmount = (float)Math.floor(savedPixels / (metrics.getHeight() + yBufferAmount));
xBufferAmount = Math.min(xBufferAmount + extraXAmount, metrics.pageSizeWidth - metrics.getWidth());
}
// and now calculate the display port margins based on how much buffer we've decided to use and
// the page bounds, ensuring we use all of the available buffer amounts on one side or the other
// on any given axis. (i.e. if we're scrolled to the top of the page, the vertical buffer is
// entirely below the visible viewport, but if we're halfway down the page, the vertical buffer
// is split).
float leftMargin = Math.min(DEFAULT_DISPLAY_PORT_MARGIN, metrics.viewportRectLeft);
float rightMargin = Math.min(DEFAULT_DISPLAY_PORT_MARGIN, metrics.pageSizeWidth - (metrics.viewportRectLeft + metrics.getWidth()));
if (leftMargin < DEFAULT_DISPLAY_PORT_MARGIN) {
rightMargin = xBufferAmount - leftMargin;
} else if (rightMargin < DEFAULT_DISPLAY_PORT_MARGIN) {
leftMargin = xBufferAmount - rightMargin;
} else if (!FloatUtils.fuzzyEquals(leftMargin + rightMargin, xBufferAmount)) {
float delta = xBufferAmount - leftMargin - rightMargin;
leftMargin += delta / 2;
rightMargin += delta / 2;
}
float topMargin = Math.min(DEFAULT_DISPLAY_PORT_MARGIN, metrics.viewportRectTop);
float bottomMargin = Math.min(DEFAULT_DISPLAY_PORT_MARGIN, metrics.pageSizeHeight - (metrics.viewportRectTop + metrics.getHeight()));
if (topMargin < DEFAULT_DISPLAY_PORT_MARGIN) {
bottomMargin = yBufferAmount - topMargin;
} else if (bottomMargin < DEFAULT_DISPLAY_PORT_MARGIN) {
topMargin = yBufferAmount - bottomMargin;
} else if (!FloatUtils.fuzzyEquals(topMargin + bottomMargin, yBufferAmount)) {
float delta = yBufferAmount - topMargin - bottomMargin;
topMargin += delta / 2;
bottomMargin += delta / 2;
}
// note that unless the viewport size changes, or the page dimensions change (either because of
// content changes or zooming), the size of the display port should remain constant. this
// is intentional to avoid re-creating textures and all sorts of other reallocations in the
// draw and composition code.
return new DisplayPortMetrics(metrics.viewportRectLeft - leftMargin,
metrics.viewportRectTop - topMargin,
metrics.viewportRectRight + rightMargin,
metrics.viewportRectBottom + bottomMargin,
metrics.zoomFactor);
}
private void adjustViewport() {
ViewportMetrics viewportMetrics =
new ViewportMetrics(mLayerController.getViewportMetrics());
viewportMetrics.setViewport(viewportMetrics.getClampedViewport());
mDisplayPort = calculateDisplayPort(mLayerController.getViewportMetrics());
mDisplayPort = DisplayPortCalculator.calculate(mLayerController.getViewportMetrics());
GeckoAppShell.sendEventToGecko(GeckoEvent.createViewportEvent(viewportMetrics, mDisplayPort));
mGeckoViewport = viewportMetrics;
}
@ -281,7 +217,7 @@ public class GeckoLayerClient implements GeckoEventResponder,
}
});
mLayerController.setViewportMetrics(newMetrics);
mDisplayPort = calculateDisplayPort(mLayerController.getViewportMetrics());
mDisplayPort = DisplayPortCalculator.calculate(mLayerController.getViewportMetrics());
}
mReturnDisplayPort = mDisplayPort;
}
@ -295,7 +231,7 @@ public class GeckoLayerClient implements GeckoEventResponder,
handleViewportMessage(message, ViewportMessageType.PAGE_SIZE);
} else if ("Viewport:CalculateDisplayPort".equals(event)) {
ImmutableViewportMetrics newMetrics = new ImmutableViewportMetrics(new ViewportMetrics(message));
mReturnDisplayPort = calculateDisplayPort(newMetrics);
mReturnDisplayPort = DisplayPortCalculator.calculate(newMetrics);
} else if ("Checkerboard:Toggle".equals(event)) {
try {
boolean showChecks = message.getBoolean("value");

View File

@ -118,11 +118,6 @@ public class LayerController implements Tabs.OnTabsChangedListener {
*/
public static final IntSize MIN_BUFFER = new IntSize(512, 1024);
/* If the visible rect is within the danger zone (measured in pixels from each edge of a tile),
* we start aggressively redrawing to minimize checkerboarding. */
private static final int DANGER_ZONE_X = 75;
private static final int DANGER_ZONE_Y = 150;
/* The time limit for pages to respond with preventDefault on touchevents
* before we begin panning the page */
private int mTimeout = 200;
@ -330,23 +325,7 @@ public class LayerController implements Tabs.OnTabsChangedListener {
return false;
}
return aboutToCheckerboard();
}
// Returns true if a checkerboard is about to be visible.
private boolean aboutToCheckerboard() {
// Increase the size of the viewport (and clamp to page boundaries), and
// intersect it with the tile's displayport to determine whether we're
// close to checkerboarding.
FloatSize pageSize = getPageSize();
RectF adjustedViewport = RectUtils.expand(getViewport(), DANGER_ZONE_X, DANGER_ZONE_Y);
if (adjustedViewport.top < 0) adjustedViewport.top = 0;
if (adjustedViewport.left < 0) adjustedViewport.left = 0;
if (adjustedViewport.right > pageSize.width) adjustedViewport.right = pageSize.width;
if (adjustedViewport.bottom > pageSize.height) adjustedViewport.bottom = pageSize.height;
DisplayPortMetrics displayPort = (mLayerClient == null ? new DisplayPortMetrics() : mLayerClient.getDisplayPort());
return !displayPort.contains(adjustedViewport);
return DisplayPortCalculator.aboutToCheckerboard(mViewportMetrics, mLayerClient.getDisplayPort());
}
/**