/** * Returns true if this client is fine with performing a redraw operation or false if it would * prefer that the action didn't take place. */ private boolean getRedrawHint() { if (mForceRedraw) { mForceRedraw = false; return true; } if (!mPanZoomController.getRedrawHint()) { return false; } return DisplayPortCalculator.aboutToCheckerboard( mViewportMetrics, mPanZoomController.getVelocityVector(), mDisplayPort); }
// This is called on the Gecko thread to determine if we're still interested // in the update of this display-port to continue. We can return true here // to abort the current update and continue with any subsequent ones. This // is useful for slow-to-render pages when the display-port starts lagging // behind enough that continuing to draw it is wasted effort. 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; ImmutableViewportMetrics viewportMetrics = mViewportMetrics; mProgressiveUpdateData.setViewport(viewportMetrics); mProgressiveUpdateData.abort = false; // Always abort updates if the resolution has changed. There's no use // in drawing at the incorrect resolution. if (!FloatUtils.fuzzyEquals(resolution, viewportMetrics.zoomFactor)) { Log.d(LOGTAG, "Aborting draw due to resolution change"); mProgressiveUpdateData.abort = true; 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 // check that values are within a couple of pixels of the // display-port bounds. // Never abort drawing if we can't be sure we've sent a more recent // 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 (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). // XXX This makes the assumption that we never let the visible area of // the page fall outside of the display-port. if (Math.max(viewportMetrics.viewportRectLeft, viewportMetrics.pageRectLeft) + 1 < x || Math.max(viewportMetrics.viewportRectTop, viewportMetrics.pageRectTop) + 1 < y || Math.min(viewportMetrics.viewportRectRight, viewportMetrics.pageRectRight) - 1 > x + width || Math.min(viewportMetrics.viewportRectBottom, viewportMetrics.pageRectBottom) - 1 > y + height) { Log.d(LOGTAG, "Aborting update due to viewport not in display-port"); mProgressiveUpdateData.abort = true; return mProgressiveUpdateData; } // Abort drawing stale low-precision content if there's a more recent // display-port in the pipeline. if (lowPrecision && !aHasPendingNewThebesContent) { mProgressiveUpdateData.abort = true; } return mProgressiveUpdateData; }