mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 776226: Improve displayport sizing, account for velocity, and properly clip edges r=cjones
This commit is contained in:
parent
1d205454ca
commit
ffe8a7b8f4
@ -31,6 +31,12 @@ static const PRInt32 PAN_REPAINT_INTERVAL = 250;
|
||||
*/
|
||||
static const PRInt32 FLING_REPAINT_INTERVAL = 75;
|
||||
|
||||
/**
|
||||
* Minimum amount of speed along an axis before we begin painting far ahead by
|
||||
* adjusting the displayport.
|
||||
*/
|
||||
static const float MIN_SKATE_SPEED = 0.5f;
|
||||
|
||||
AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoContentController,
|
||||
GestureBehavior aGestures)
|
||||
: mGeckoContentController(aGeckoContentController),
|
||||
@ -564,15 +570,8 @@ const nsIntRect AsyncPanZoomController::CalculatePendingDisplayPort() {
|
||||
nsIntRect viewport = mFrameMetrics.mViewport;
|
||||
viewport.ScaleRoundIn(1 / scale);
|
||||
|
||||
const float SIZE_MULTIPLIER = 2.0f;
|
||||
nsIntPoint scrollOffset = mFrameMetrics.mViewportScrollOffset;
|
||||
gfx::Rect contentRect = mFrameMetrics.mCSSContentRect;
|
||||
|
||||
// Paint a larger portion of the screen than just what we can see. This makes
|
||||
// it less likely that we'll checkerboard when panning around and Gecko hasn't
|
||||
// repainted yet.
|
||||
float desiredWidth = viewport.width * SIZE_MULTIPLIER,
|
||||
desiredHeight = viewport.height * SIZE_MULTIPLIER;
|
||||
nsPoint velocity = GetVelocityVector();
|
||||
|
||||
// The displayport is relative to the current scroll offset. Here's a little
|
||||
// diagram to make it easier to see:
|
||||
@ -598,32 +597,40 @@ const nsIntRect AsyncPanZoomController::CalculatePendingDisplayPort() {
|
||||
// viewport marks the current scroll offset. From the @ symbol to the far left
|
||||
// and far top, it is clear that this distance is 1/4 of the displayport's
|
||||
// height/width dimension.
|
||||
gfx::Rect displayPort(-desiredWidth / 4, -desiredHeight / 4, desiredWidth, desiredHeight);
|
||||
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);
|
||||
|
||||
// Check if the desired boundaries go over the CSS page rect along the top or
|
||||
// left. If they do, shift them to the right or down.
|
||||
float oldDisplayPortX = displayPort.x, oldDisplayPortY = displayPort.y;
|
||||
if (displayPort.X() + scrollOffset.x < contentRect.X()) {
|
||||
displayPort.x = contentRect.X() - scrollOffset.x;
|
||||
}
|
||||
if (displayPort.Y() + scrollOffset.y < contentRect.Y()) {
|
||||
displayPort.y = contentRect.Y() - scrollOffset.y;
|
||||
// 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 {
|
||||
displayPort.x = -displayPort.width / 4;
|
||||
displayPort.y = -displayPort.height / 4;
|
||||
}
|
||||
|
||||
// We don't need to paint the extra area that was going to overlap with the
|
||||
// content rect. Subtract out this extra width or height.
|
||||
displayPort.width -= displayPort.x - oldDisplayPortX;
|
||||
displayPort.height -= displayPort.y - oldDisplayPortY;
|
||||
|
||||
// Check if the desired boundaries go over the CSS page rect along the right
|
||||
// or bottom. If they do, subtract out some height or width such that they
|
||||
// perfectly align with the end of the CSS page rect.
|
||||
if (displayPort.XMost() + scrollOffset.x > contentRect.XMost()) {
|
||||
displayPort.width = NS_MAX(0.0f, contentRect.XMost() - (displayPort.X() + scrollOffset.x));
|
||||
}
|
||||
if (displayPort.YMost() + scrollOffset.y > contentRect.YMost()) {
|
||||
displayPort.height = NS_MAX(0.0f, contentRect.YMost() - (displayPort.Y() + scrollOffset.y));
|
||||
}
|
||||
gfx::Rect shiftedDisplayPort = displayPort;
|
||||
// Both the scroll offset and displayport are in CSS pixels. We're scaling
|
||||
// the scroll offset because Gecko will internally scale the displayport by
|
||||
// the resolution, so we'll get clipping at the far bottom or far right if we
|
||||
// directly get the intersection of the displayport offset by the scroll
|
||||
// offset and the CSS content rect.
|
||||
shiftedDisplayPort.MoveBy(scrollOffset.x / scale, scrollOffset.y / scale);
|
||||
displayPort = shiftedDisplayPort.Intersect(mFrameMetrics.mCSSContentRect);
|
||||
displayPort.MoveBy(-scrollOffset.x / scale, -scrollOffset.y / scale);
|
||||
|
||||
// Round the displayport so we don't get any truncation, then get the nsIntRect
|
||||
// from this.
|
||||
|
Loading…
Reference in New Issue
Block a user