mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 826489 - Add preference based settings to AsyncZoomPanController. r=drs
This commit is contained in:
parent
bef2790ef8
commit
9a7f8ed729
@ -24,7 +24,13 @@ using namespace mozilla::css;
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
const float AsyncPanZoomController::TOUCH_START_TOLERANCE = 1.0f/16.0f;
|
||||
/**
|
||||
* Constant describing the tolerance in distance we use, multiplied by the
|
||||
* device DPI, before we start panning the screen. This is to prevent us from
|
||||
* accidentally processing taps as touch moves, and from very short/accidental
|
||||
* touches moving the screen.
|
||||
*/
|
||||
static float gTouchStartTolerance = 1.0f/16.0f;
|
||||
|
||||
static const float EPSILON = 0.0001;
|
||||
|
||||
@ -32,19 +38,19 @@ static const float EPSILON = 0.0001;
|
||||
* Maximum amount of time while panning before sending a viewport change. This
|
||||
* will asynchronously repaint the page. It is also forced when panning stops.
|
||||
*/
|
||||
static const int32_t PAN_REPAINT_INTERVAL = 250;
|
||||
static int32_t gPanRepaintInterval = 250;
|
||||
|
||||
/**
|
||||
* Maximum amount of time flinging before sending a viewport change. This will
|
||||
* asynchronously repaint the page.
|
||||
*/
|
||||
static const int32_t FLING_REPAINT_INTERVAL = 75;
|
||||
static int32_t gFlingRepaintInterval = 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.7f;
|
||||
static float gMinSkateSpeed = 0.7f;
|
||||
|
||||
/**
|
||||
* Duration of a zoom to animation.
|
||||
@ -72,13 +78,68 @@ static const double MIN_ZOOM = 0.125;
|
||||
* time, we will just pretend that content did not preventDefault any touch
|
||||
* events we dispatched to it.
|
||||
*/
|
||||
static const int TOUCH_LISTENER_TIMEOUT = 300;
|
||||
static int gTouchListenerTimeout = 300;
|
||||
|
||||
/**
|
||||
* Number of samples to store of how long it took to paint after the previous
|
||||
* requests.
|
||||
*/
|
||||
static const int NUM_PAINT_DURATION_SAMPLES = 3;
|
||||
static int gNumPaintDurationSamples = 3;
|
||||
|
||||
/** The multiplier we apply to a dimension's length if it is skating. That is,
|
||||
* if it's going above sMinSkateSpeed. We prefer to increase the size of the
|
||||
* Y axis because it is more natural in the case that a user is reading a page
|
||||
* that scrolls up/down. Note that one, both or neither of these may be used
|
||||
* at any instant.
|
||||
*/
|
||||
static float gXSkateSizeMultiplier = 3.0f;
|
||||
static float gYSkateSizeMultiplier = 3.5f;
|
||||
|
||||
/** The multiplier we apply to a dimension's length if it is stationary. We
|
||||
* prefer to increase the size of the Y axis because it is more natural in the
|
||||
* case that a user is reading a page that scrolls up/down. Note that one,
|
||||
* both or neither of these may be used at any instant.
|
||||
*/
|
||||
static float gXStationarySizeMultiplier = 1.5f;
|
||||
static float gYStationarySizeMultiplier = 2.5f;
|
||||
|
||||
static void ReadAZPCPrefs()
|
||||
{
|
||||
Preferences::AddIntVarCache(&gPanRepaintInterval, "gfx.azpc.pan_repaint_interval", gPanRepaintInterval);
|
||||
Preferences::AddIntVarCache(&gFlingRepaintInterval, "gfx.azpc.fling_repaint_interval", gFlingRepaintInterval);
|
||||
Preferences::AddFloatVarCache(&gMinSkateSpeed, "gfx.azpc.min_skate_speed", gMinSkateSpeed);
|
||||
Preferences::AddIntVarCache(&gTouchListenerTimeout, "gfx.azpc.touch_listener_timeout", gTouchListenerTimeout);
|
||||
Preferences::AddIntVarCache(&gNumPaintDurationSamples, "gfx.azpc.num_paint_duration_samples", gNumPaintDurationSamples);
|
||||
Preferences::AddFloatVarCache(&gTouchStartTolerance, "gfx.azpc.touch_start_tolerance", gTouchStartTolerance);
|
||||
Preferences::AddFloatVarCache(&gXSkateSizeMultiplier, "gfx.azpc.x_skate_size_multiplier", gXSkateSizeMultiplier);
|
||||
Preferences::AddFloatVarCache(&gYSkateSizeMultiplier, "gfx.azpc.y_skate_size_multiplier", gYSkateSizeMultiplier);
|
||||
Preferences::AddFloatVarCache(&gXStationarySizeMultiplier, "gfx.azpc.x_stationary_size_multiplier", gXStationarySizeMultiplier);
|
||||
Preferences::AddFloatVarCache(&gYStationarySizeMultiplier, "gfx.azpc.y_stationary_size_multiplier", gYStationarySizeMultiplier);
|
||||
}
|
||||
|
||||
class ReadAZPCPref MOZ_FINAL : public nsRunnable {
|
||||
public:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
ReadAZPCPrefs();
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
static void InitAZPCPrefs()
|
||||
{
|
||||
static bool sInitialized = false;
|
||||
if (sInitialized)
|
||||
return;
|
||||
|
||||
sInitialized = true;
|
||||
if (NS_IsMainThread()) {
|
||||
ReadAZPCPrefs();
|
||||
} else {
|
||||
// We have to dispatch an event to the main thread to read the pref.
|
||||
NS_DispatchToMainThread(new ReadAZPCPref());
|
||||
}
|
||||
}
|
||||
|
||||
AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoContentController,
|
||||
GestureBehavior aGestures)
|
||||
@ -106,6 +167,9 @@ AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoCon
|
||||
mDelayPanning(false)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
InitAZPCPrefs();
|
||||
|
||||
if (aGestures == USE_GESTURE_DETECTOR) {
|
||||
mGestureEventListener = new GestureEventListener(this);
|
||||
}
|
||||
@ -127,6 +191,12 @@ AsyncPanZoomController::~AsyncPanZoomController() {
|
||||
|
||||
}
|
||||
|
||||
/* static */float
|
||||
AsyncPanZoomController::GetTouchStartTolerance()
|
||||
{
|
||||
return gTouchStartTolerance;
|
||||
}
|
||||
|
||||
static gfx::Point
|
||||
WidgetSpaceToCompensatedViewportSpace(const gfx::Point& aPoint,
|
||||
gfxFloat aCurrentZoom)
|
||||
@ -231,7 +301,7 @@ nsEventStatus AsyncPanZoomController::ReceiveInputEvent(const InputData& aEvent)
|
||||
MessageLoop::current()->PostDelayedTask(
|
||||
FROM_HERE,
|
||||
mTouchListenerTimeoutTask,
|
||||
TOUCH_LISTENER_TIMEOUT);
|
||||
gTouchListenerTimeout);
|
||||
}
|
||||
}
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
@ -263,7 +333,7 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent)
|
||||
MessageLoop::current()->PostDelayedTask(
|
||||
FROM_HERE,
|
||||
mTouchListenerTimeoutTask,
|
||||
TOUCH_LISTENER_TIMEOUT);
|
||||
gTouchListenerTimeout);
|
||||
}
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
@ -364,7 +434,7 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent)
|
||||
return nsEventStatus_eIgnore;
|
||||
|
||||
case TOUCHING: {
|
||||
float panThreshold = TOUCH_START_TOLERANCE * mDPI;
|
||||
float panThreshold = gTouchStartTolerance * mDPI;
|
||||
UpdateWithTouchAtDevicePoint(aEvent);
|
||||
|
||||
if (PanDistance() < panThreshold) {
|
||||
@ -697,7 +767,7 @@ void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
|
||||
ScheduleComposite();
|
||||
|
||||
TimeDuration timePaintDelta = TimeStamp::Now() - mPreviousPaintStartTime;
|
||||
if (timePaintDelta.ToMilliseconds() > PAN_REPAINT_INTERVAL) {
|
||||
if (timePaintDelta.ToMilliseconds() > gPanRepaintInterval) {
|
||||
RequestContentRepaint();
|
||||
}
|
||||
}
|
||||
@ -734,7 +804,7 @@ bool AsyncPanZoomController::DoFling(const TimeDuration& aDelta) {
|
||||
mY.GetDisplacementForDuration(inverseResolution, aDelta)
|
||||
));
|
||||
TimeDuration timePaintDelta = TimeStamp::Now() - mPreviousPaintStartTime;
|
||||
if (timePaintDelta.ToMilliseconds() > FLING_REPAINT_INTERVAL) {
|
||||
if (timePaintDelta.ToMilliseconds() > gFlingRepaintInterval) {
|
||||
RequestContentRepaint();
|
||||
}
|
||||
|
||||
@ -803,7 +873,7 @@ bool AsyncPanZoomController::EnlargeDisplayPortAlongAxis(float aSkateSizeMultipl
|
||||
float* aDisplayPortOffset,
|
||||
float* aDisplayPortLength)
|
||||
{
|
||||
if (fabsf(aVelocity) > MIN_SKATE_SPEED) {
|
||||
if (fabsf(aVelocity) > gMinSkateSpeed) {
|
||||
// Enlarge the area we paint.
|
||||
*aDisplayPortLength = aCompositionBounds * aSkateSizeMultiplier;
|
||||
// Position the area we paint such that all of the excess that extends past
|
||||
@ -835,21 +905,6 @@ const gfx::Rect AsyncPanZoomController::CalculatePendingDisplayPort(
|
||||
const gfx::Point& aAcceleration,
|
||||
double aEstimatedPaintDuration)
|
||||
{
|
||||
// The multiplier we apply to a dimension's length if it is skating. That is,
|
||||
// if it's going above MIN_SKATE_SPEED. We prefer to increase the size of the
|
||||
// Y axis because it is more natural in the case that a user is reading a page
|
||||
// that scrolls up/down. Note that one, both or neither of these may be used
|
||||
// at any instant.
|
||||
const float X_SKATE_SIZE_MULTIPLIER = 3.0f;
|
||||
const float Y_SKATE_SIZE_MULTIPLIER = 3.5f;
|
||||
|
||||
// The multiplier we apply to a dimension's length if it is stationary. We
|
||||
// prefer to increase the size of the Y axis because it is more natural in the
|
||||
// case that a user is reading a page that scrolls up/down. Note that one,
|
||||
// both or neither of these may be used at any instant.
|
||||
const float X_STATIONARY_SIZE_MULTIPLIER = 1.5f;
|
||||
const float Y_STATIONARY_SIZE_MULTIPLIER = 2.5f;
|
||||
|
||||
// If we don't get an estimated paint duration, we probably don't have any
|
||||
// data. In this case, we're dealing with either a stationary frame or a first
|
||||
// paint. In either of these cases, we can just assume it'll take 1 second to
|
||||
@ -866,18 +921,18 @@ const gfx::Rect AsyncPanZoomController::CalculatePendingDisplayPort(
|
||||
gfx::Point scrollOffset = aFrameMetrics.mScrollOffset;
|
||||
|
||||
gfx::Rect displayPort(0, 0,
|
||||
compositionBounds.width * X_STATIONARY_SIZE_MULTIPLIER,
|
||||
compositionBounds.height * Y_STATIONARY_SIZE_MULTIPLIER);
|
||||
compositionBounds.width * gXStationarySizeMultiplier,
|
||||
compositionBounds.height * gYStationarySizeMultiplier);
|
||||
|
||||
// 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(
|
||||
X_SKATE_SIZE_MULTIPLIER, estimatedPaintDuration,
|
||||
gXSkateSizeMultiplier, estimatedPaintDuration,
|
||||
compositionBounds.width, aVelocity.x, aAcceleration.x,
|
||||
&displayPort.x, &displayPort.width);
|
||||
bool enlargedY = EnlargeDisplayPortAlongAxis(
|
||||
Y_SKATE_SIZE_MULTIPLIER, estimatedPaintDuration,
|
||||
gYSkateSizeMultiplier, estimatedPaintDuration,
|
||||
compositionBounds.height, aVelocity.y, aAcceleration.y,
|
||||
&displayPort.y, &displayPort.height);
|
||||
|
||||
@ -1162,7 +1217,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
|
||||
if (mWaitingForContentToPaint) {
|
||||
// Remove the oldest sample we have if adding a new sample takes us over our
|
||||
// desired number of samples.
|
||||
if (mPreviousPaintDurations.Length() >= NUM_PAINT_DURATION_SAMPLES) {
|
||||
if (mPreviousPaintDurations.Length() >= gNumPaintDurationSamples) {
|
||||
mPreviousPaintDurations.RemoveElementAt(0);
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
* accidentally processing taps as touch moves, and from very short/accidental
|
||||
* touches moving the screen.
|
||||
*/
|
||||
static const float TOUCH_START_TOLERANCE;
|
||||
static float GetTouchStartTolerance();
|
||||
|
||||
AsyncPanZoomController(GeckoContentController* aController,
|
||||
GestureBehavior aGestures = DEFAULT_GESTURES);
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "Axis.h"
|
||||
#include "AsyncPanZoomController.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -18,18 +19,18 @@ static const float EPSILON = 0.0001f;
|
||||
* or we get a touch point very far away from the previous position for some
|
||||
* reason.
|
||||
*/
|
||||
static const float MAX_EVENT_ACCELERATION = 999.0f;
|
||||
static float gMaxEventAcceleration = 999.0f;
|
||||
|
||||
/**
|
||||
* Amount of friction applied during flings.
|
||||
*/
|
||||
static const float FLING_FRICTION = 0.007f;
|
||||
static float gFlingFriction = 0.007f;
|
||||
|
||||
/**
|
||||
* Threshold for velocity beneath which we turn off any acceleration we had
|
||||
* during repeated flings.
|
||||
*/
|
||||
static const float VELOCITY_THRESHOLD = 0.14f;
|
||||
static float gVelocityThreshold = 0.14f;
|
||||
|
||||
/**
|
||||
* Amount of acceleration we multiply in each time the user flings in one
|
||||
@ -39,14 +40,47 @@ static const float VELOCITY_THRESHOLD = 0.14f;
|
||||
* slow down enough, or if they put their finger down without moving it for a
|
||||
* moment (or in the opposite direction).
|
||||
*/
|
||||
static const float ACCELERATION_MULTIPLIER = 1.125f;
|
||||
static float gAccelerationMultiplier = 1.125f;
|
||||
|
||||
/**
|
||||
* When flinging, if the velocity goes below this number, we just stop the
|
||||
* animation completely. This is to prevent asymptotically approaching 0
|
||||
* velocity and rerendering unnecessarily.
|
||||
*/
|
||||
static const float FLING_STOPPED_THRESHOLD = 0.01f;
|
||||
static float gFlingStoppedThreshold = 0.01f;
|
||||
|
||||
static void ReadAxisPrefs()
|
||||
{
|
||||
Preferences::AddFloatVarCache(&gMaxEventAcceleration, "gfx.axis.max_event_acceleration", gMaxEventAcceleration);
|
||||
Preferences::AddFloatVarCache(&gFlingFriction, "gfx.axis.fling_friction", gFlingFriction);
|
||||
Preferences::AddFloatVarCache(&gVelocityThreshold, "gfx.axis.velocity_threshold", gVelocityThreshold);
|
||||
Preferences::AddFloatVarCache(&gAccelerationMultiplier, "gfx.axis.acceleration_multiplier", gAccelerationMultiplier);
|
||||
Preferences::AddFloatVarCache(&gFlingStoppedThreshold, "gfx.axis.fling_stopped_threshold", gFlingStoppedThreshold);
|
||||
}
|
||||
|
||||
class ReadAxisPref MOZ_FINAL : public nsRunnable {
|
||||
public:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
ReadAxisPrefs();
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
static void InitAxisPrefs()
|
||||
{
|
||||
static bool sInitialized = false;
|
||||
if (sInitialized)
|
||||
return;
|
||||
|
||||
sInitialized = true;
|
||||
if (NS_IsMainThread()) {
|
||||
ReadAxisPrefs();
|
||||
} else {
|
||||
// We have to dispatch an event to the main thread to read the pref.
|
||||
NS_DispatchToMainThread(new ReadAxisPref());
|
||||
}
|
||||
}
|
||||
|
||||
Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController)
|
||||
: mPos(0.0f),
|
||||
@ -54,14 +88,14 @@ Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController)
|
||||
mAcceleration(0),
|
||||
mAsyncPanZoomController(aAsyncPanZoomController)
|
||||
{
|
||||
|
||||
InitAxisPrefs();
|
||||
}
|
||||
|
||||
void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, const TimeDuration& aTimeDelta) {
|
||||
float newVelocity = (mPos - aPos) / aTimeDelta.ToMilliseconds();
|
||||
|
||||
bool curVelocityIsLow = fabsf(newVelocity) < 0.01f;
|
||||
bool curVelocityBelowThreshold = fabsf(newVelocity) < VELOCITY_THRESHOLD;
|
||||
bool curVelocityBelowThreshold = fabsf(newVelocity) < gVelocityThreshold;
|
||||
bool directionChange = (mVelocity > 0) != (newVelocity > 0);
|
||||
|
||||
// If we've changed directions, or the current velocity threshold, stop any
|
||||
@ -75,7 +109,7 @@ void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, const TimeDuration& aTimeD
|
||||
if (curVelocityIsLow || (directionChange && fabs(newVelocity) - EPSILON <= 0.0f)) {
|
||||
mVelocity = newVelocity;
|
||||
} else {
|
||||
float maxChange = fabsf(mVelocity * aTimeDelta.ToMilliseconds() * MAX_EVENT_ACCELERATION);
|
||||
float maxChange = fabsf(mVelocity * aTimeDelta.ToMilliseconds() * gMaxEventAcceleration);
|
||||
mVelocity = NS_MIN(mVelocity + maxChange, NS_MAX(mVelocity - maxChange, newVelocity));
|
||||
}
|
||||
|
||||
@ -89,7 +123,7 @@ void Axis::StartTouch(int32_t aPos) {
|
||||
}
|
||||
|
||||
float Axis::GetDisplacementForDuration(float aScale, const TimeDuration& aDelta) {
|
||||
if (fabsf(mVelocity) < VELOCITY_THRESHOLD) {
|
||||
if (fabsf(mVelocity) < gVelocityThreshold) {
|
||||
mAcceleration = 0;
|
||||
}
|
||||
|
||||
@ -121,14 +155,14 @@ void Axis::CancelTouch() {
|
||||
}
|
||||
|
||||
bool Axis::FlingApplyFrictionOrCancel(const TimeDuration& aDelta) {
|
||||
if (fabsf(mVelocity) <= FLING_STOPPED_THRESHOLD) {
|
||||
if (fabsf(mVelocity) <= gFlingStoppedThreshold) {
|
||||
// If the velocity is very low, just set it to 0 and stop the fling,
|
||||
// otherwise we'll just asymptotically approach 0 and the user won't
|
||||
// actually see any changes.
|
||||
mVelocity = 0.0f;
|
||||
return false;
|
||||
} else {
|
||||
mVelocity *= NS_MAX(1.0f - FLING_FRICTION * aDelta.ToMilliseconds(), 0.0);
|
||||
mVelocity *= NS_MAX(1.0f - gFlingFriction * aDelta.ToMilliseconds(), 0.0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -226,7 +260,7 @@ float Axis::GetVelocity() {
|
||||
}
|
||||
|
||||
float Axis::GetAccelerationFactor() {
|
||||
return powf(ACCELERATION_MULTIPLIER, NS_MAX(0, (mAcceleration - 4) * 3));
|
||||
return powf(gAccelerationMultiplier, NS_MAX(0, (mAcceleration - 4) * 3));
|
||||
}
|
||||
|
||||
float Axis::GetCompositionEnd() {
|
||||
|
@ -105,7 +105,7 @@ nsEventStatus GestureEventListener::HandleInputEvent(const InputData& aEvent)
|
||||
nsIntPoint touch = (nsIntPoint&)event.mTouches[0].mScreenPoint;
|
||||
if (mTouches.Length() == 1 &&
|
||||
NS_hypot(mTouchStartPosition.x - touch.x, mTouchStartPosition.y - touch.y) >
|
||||
mAsyncPanZoomController->GetDPI() * AsyncPanZoomController::TOUCH_START_TOLERANCE)
|
||||
mAsyncPanZoomController->GetDPI() * mAsyncPanZoomController->GetTouchStartTolerance())
|
||||
{
|
||||
HandleTapCancel(event);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user