Bug 814864 - Only draw low precision tiles when necessary. r=kats

Use DisplayPortCalculator.aboutToCheckerboard to determine if we're in risk of
checkerboarding while drawing tiles, and only then enable low precision
rendering. This makes sure that we don't spend time doing low precision
rendering when it isn't going to be of benefit (and thus decreases the
likelihood of the user seeing low precision tiles unnecessarily).
This commit is contained in:
Chris Lord 2012-11-29 13:08:41 +00:00
parent b989ece776
commit 9c5036e322

View File

@ -76,7 +76,9 @@ public class GeckoLayerClient
/* Used as the return value of progressiveUpdateCallback */
private final ProgressiveUpdateData mProgressiveUpdateData;
private RectF mProgressiveUpdateDisplayPort;
private DisplayPortMetrics mProgressiveUpdateDisplayPort;
private boolean mLastProgressiveUpdateWasLowPrecision;
private boolean mProgressiveUpdateWasInDanger;
/* This is written by the compositor thread and read by the UI thread. */
private volatile boolean mCompositorCreated;
@ -116,7 +118,9 @@ public class GeckoLayerClient
mDrawTimingQueue = new DrawTimingQueue();
mCurrentViewTransform = new ViewTransform(0, 0, 1);
mProgressiveUpdateData = new ProgressiveUpdateData();
mProgressiveUpdateDisplayPort = new RectF();
mProgressiveUpdateDisplayPort = new DisplayPortMetrics();
mLastProgressiveUpdateWasLowPrecision = false;
mProgressiveUpdateWasInDanger = false;
mCompositorCreated = false;
mForceRedraw = true;
@ -363,6 +367,18 @@ public class GeckoLayerClient
public ProgressiveUpdateData progressiveUpdateCallback(boolean aHasPendingNewThebesContent,
float x, float y, float width, float height,
float resolution, boolean lowPrecision) {
// Skip all low precision draws until we're at risk of checkerboarding
if (lowPrecision && !mProgressiveUpdateWasInDanger) {
mProgressiveUpdateData.abort = true;
return mProgressiveUpdateData;
}
// Reset the checkerboard risk flag
if (!lowPrecision && mLastProgressiveUpdateWasLowPrecision) {
mProgressiveUpdateWasInDanger = false;
}
mLastProgressiveUpdateWasLowPrecision = lowPrecision;
// Grab a local copy of the last display-port sent to Gecko and the
// current viewport metrics to avoid races when accessing them.
DisplayPortMetrics displayPort = mDisplayPort;
@ -378,6 +394,19 @@ public class GeckoLayerClient
return mProgressiveUpdateData;
}
// Store the high precision displayport for comparison when doing low
// precision updates.
if (!lowPrecision) {
if (!FloatUtils.fuzzyEquals(resolution, mProgressiveUpdateDisplayPort.resolution) ||
!FloatUtils.fuzzyEquals(x, mProgressiveUpdateDisplayPort.getLeft()) ||
!FloatUtils.fuzzyEquals(y, mProgressiveUpdateDisplayPort.getTop()) ||
!FloatUtils.fuzzyEquals(x + width, mProgressiveUpdateDisplayPort.getRight()) ||
!FloatUtils.fuzzyEquals(y + height, mProgressiveUpdateDisplayPort.getBottom())) {
mProgressiveUpdateDisplayPort =
new DisplayPortMetrics(x, y, x+width, y+height, resolution);
}
}
// XXX All sorts of rounding happens inside Gecko that becomes hard to
// account exactly for. Given we align the display-port to tile
// boundaries (and so they rarely vary by sub-pixel amounts), just
@ -388,16 +417,22 @@ public class GeckoLayerClient
// display-port. If we abort updating when we shouldn't, we can end up
// with blank regions on the screen and we open up the risk of entering
// an endless updating cycle.
if (!lowPrecision) {
mProgressiveUpdateDisplayPort.set(x, y, x + width, y + height);
}
if (Math.abs(displayPort.getLeft() - mProgressiveUpdateDisplayPort.left) <= 2 &&
Math.abs(displayPort.getTop() - mProgressiveUpdateDisplayPort.top) <= 2 &&
Math.abs(displayPort.getBottom() - mProgressiveUpdateDisplayPort.bottom) <= 2 &&
Math.abs(displayPort.getRight() - mProgressiveUpdateDisplayPort.right) <= 2) {
if (Math.abs(displayPort.getLeft() - mProgressiveUpdateDisplayPort.getLeft()) <= 2 &&
Math.abs(displayPort.getTop() - mProgressiveUpdateDisplayPort.getTop()) <= 2 &&
Math.abs(displayPort.getBottom() - mProgressiveUpdateDisplayPort.getBottom()) <= 2 &&
Math.abs(displayPort.getRight() - mProgressiveUpdateDisplayPort.getRight()) <= 2) {
return mProgressiveUpdateData;
}
if (!lowPrecision && !mProgressiveUpdateWasInDanger) {
// If we're not doing low precision draws and we're about to
// checkerboard, give up and move onto low precision drawing.
if (DisplayPortCalculator.aboutToCheckerboard(viewportMetrics,
mPanZoomController.getVelocityVector(), mProgressiveUpdateDisplayPort)) {
mProgressiveUpdateWasInDanger = true;
}
}
// Abort updates when the display-port no longer contains the visible
// area of the page (that is, the viewport cropped by the page
// boundaries).