Bug 775451: Reduce diagonal checkerboarding r=cjones

This commit is contained in:
Doug Sherk 2012-08-08 13:38:23 -07:00
parent 8ce9e4027f
commit 0386b95cee
2 changed files with 45 additions and 23 deletions

View File

@ -449,11 +449,8 @@ float AsyncPanZoomController::PanDistance() {
return NS_hypot(mX.PanDistance(), mY.PanDistance());
}
const nsPoint AsyncPanZoomController::GetVelocityVector() {
return nsPoint(
mX.GetVelocity(),
mY.GetVelocity()
);
const gfx::Point AsyncPanZoomController::GetVelocityVector() {
return gfx::Point(mX.GetVelocity(), mY.GetVelocity());
}
void AsyncPanZoomController::StartPanning(const MultiTouchInput& aEvent) {
@ -607,13 +604,30 @@ void AsyncPanZoomController::ScaleWithFocus(float aScale, const nsIntPoint& aFoc
mFrameMetrics = metrics;
}
bool AsyncPanZoomController::EnlargeDisplayPortAlongAxis(float aViewport,
float aVelocity,
float* aDisplayPortOffset,
float* aDisplayPortLength)
{
const float MIN_SKATE_SIZE_MULTIPLIER = 2.0f;
const float MAX_SKATE_SIZE_MULTIPLIER = 4.0f;
if (fabsf(aVelocity) > MIN_SKATE_SPEED) {
*aDisplayPortLength = aViewport * clamped(fabsf(aVelocity),
MIN_SKATE_SIZE_MULTIPLIER, MAX_SKATE_SIZE_MULTIPLIER);
*aDisplayPortOffset = aVelocity > 0 ? 0 : aViewport - *aDisplayPortLength;
return true;
}
return false;
}
const nsIntRect AsyncPanZoomController::CalculatePendingDisplayPort() {
float scale = mFrameMetrics.mResolution.width;
nsIntRect viewport = mFrameMetrics.mViewport;
viewport.ScaleRoundIn(1 / scale);
nsIntPoint scrollOffset = mFrameMetrics.mViewportScrollOffset;
nsPoint velocity = GetVelocityVector();
gfx::Point velocity = GetVelocityVector();
// The displayport is relative to the current scroll offset. Here's a little
// diagram to make it easier to see:
@ -640,28 +654,25 @@ const nsIntRect AsyncPanZoomController::CalculatePendingDisplayPort() {
// and far top, it is clear that this distance is 1/4 of the displayport's
// height/width dimension.
const float STATIONARY_SIZE_MULTIPLIER = 2.0f;
const float SKATE_SIZE_MULTIPLIER = 3.0f;
gfx::Rect displayPort(0, 0,
viewport.width * STATIONARY_SIZE_MULTIPLIER,
viewport.height * STATIONARY_SIZE_MULTIPLIER);
// Iff there's motion along only one axis of movement, and it's above a
// threshold, then we want to paint a larger area in the direction of that
// motion so that it's less likely to checkerboard. Also note that the other
// axis doesn't need its displayport enlarged beyond the viewport dimension,
// since it is impossible for it to checkerboard along that axis until motion
// begins on it.
if (fabsf(velocity.x) > MIN_SKATE_SPEED && fabsf(velocity.y) < MIN_SKATE_SPEED) {
displayPort.height = viewport.height;
displayPort.width = viewport.width * SKATE_SIZE_MULTIPLIER;
displayPort.x = velocity.x > 0 ? 0 : viewport.width - displayPort.width;
} else if (fabsf(velocity.x) < MIN_SKATE_SPEED && fabsf(velocity.y) > MIN_SKATE_SPEED) {
displayPort.width = viewport.width;
displayPort.height = viewport.height * SKATE_SIZE_MULTIPLIER;
displayPort.y = velocity.y > 0 ? 0 : viewport.height - displayPort.height;
} else {
// If there's motion along an axis of movement, and it's above a threshold,
// then we want to paint a larger area in the direction of that motion so that
// it's less likely to checkerboard.
bool enlargedX = EnlargeDisplayPortAlongAxis(
viewport.width, velocity.x, &displayPort.x, &displayPort.width);
bool enlargedY = EnlargeDisplayPortAlongAxis(
viewport.height, velocity.y, &displayPort.y, &displayPort.height);
if (!enlargedX && !enlargedY) {
displayPort.x = -displayPort.width / 4;
displayPort.y = -displayPort.height / 4;
} else if (!enlargedX) {
displayPort.width = viewport.width;
} else if (!enlargedY) {
displayPort.height = viewport.height;
}
gfx::Rect shiftedDisplayPort = displayPort;

View File

@ -291,7 +291,7 @@ protected:
/**
* Gets a vector of the velocities of each axis.
*/
const nsPoint GetVelocityVector();
const gfx::Point GetVelocityVector();
/**
* Gets a reference to the first SingleTouchData from a MultiTouchInput. This
@ -326,6 +326,17 @@ protected:
*/
const nsIntRect CalculatePendingDisplayPort();
/**
* Attempts to enlarge the displayport along a single axis. Returns whether or
* not the displayport was enlarged. This will fail in circumstances where the
* velocity along that axis is not high enough to need any changes. The
* displayport metrics are expected to be passed into |aDisplayPortOffset| and
* |aDisplayPortLength|. If enlarged, these will be updated with the new
* metrics.
*/
bool EnlargeDisplayPortAlongAxis(float aViewport, float aVelocity,
float* aDisplayPortOffset, float* aDisplayPortLength);
/**
* Utility function to send updated FrameMetrics to Gecko so that it can paint
* the displayport area. Calls into GeckoContentController to do the actual