Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 576768ca authored by Jeff Brown's avatar Jeff Brown Committed by Android Git Automerger
Browse files

am 8186a5f0: am 10c3f367: Merge "Implement pointer acceleration." into honeycomb-mr2

* commit '8186a5f065fac2b82c90cd18d79cd234bc221402':
  Implement pointer acceleration.
parents 752bc2f7 ee6acaca
Loading
Loading
Loading
Loading
+81 −0
Original line number Original line Diff line number Diff line
@@ -627,6 +627,87 @@ private:
    int32_t mActivePointerId;
    int32_t mActivePointerId;
};
};



/*
 * Specifies parameters that govern pointer or wheel acceleration.
 */
struct VelocityControlParameters {
    // A scale factor that is multiplied with the raw velocity deltas
    // prior to applying any other velocity control factors.  The scale
    // factor should be used to adapt the input device resolution
    // (eg. counts per inch) to the output device resolution (eg. pixels per inch).
    //
    // Must be a positive value.
    // Default is 1.0 (no scaling).
    float scale;

    // The scaled speed at which acceleration begins to be applied.
    // This value establishes the upper bound of a low speed regime for
    // small precise motions that are performed without any acceleration.
    //
    // Must be a non-negative value.
    // Default is 0.0 (no low threshold).
    float lowThreshold;

    // The scaled speed at which maximum acceleration is applied.
    // The difference between highThreshold and lowThreshold controls
    // the range of speeds over which the acceleration factor is interpolated.
    // The wider the range, the smoother the acceleration.
    //
    // Must be a non-negative value greater than or equal to lowThreshold.
    // Default is 0.0 (no high threshold).
    float highThreshold;

    // The acceleration factor.
    // When the speed is above the low speed threshold, the velocity will scaled
    // by an interpolated value between 1.0 and this amount.
    //
    // Must be a positive greater than or equal to 1.0.
    // Default is 1.0 (no acceleration).
    float acceleration;

    VelocityControlParameters() :
            scale(1.0f), lowThreshold(0.0f), highThreshold(0.0f), acceleration(1.0f) {
    }

    VelocityControlParameters(float scale, float lowThreshold,
            float highThreshold, float acceleration) :
            scale(scale), lowThreshold(lowThreshold),
            highThreshold(highThreshold), acceleration(acceleration) {
    }
};

/*
 * Implements mouse pointer and wheel speed control and acceleration.
 */
class VelocityControl {
public:
    VelocityControl();

    /* Sets the various parameters. */
    void setParameters(const VelocityControlParameters& parameters);

    /* Resets the current movement counters to zero.
     * This has the effect of nullifying any acceleration. */
    void reset();

    /* Translates a raw movement delta into an appropriately
     * scaled / accelerated delta based on the current velocity. */
    void move(nsecs_t eventTime, float* deltaX, float* deltaY);

private:
    // If no movements are received within this amount of time,
    // we assume the movement has stopped and reset the movement counters.
    static const nsecs_t STOP_TIME = 500 * 1000000; // 500 ms

    VelocityControlParameters mParameters;

    nsecs_t mLastMovementTime;
    VelocityTracker::Position mRawPosition;
    VelocityTracker mVelocityTracker;
};


/*
/*
 * Describes the characteristics and capabilities of an input device.
 * Describes the characteristics and capabilities of an input device.
 */
 */
+89 −0
Original line number Original line Diff line number Diff line
@@ -13,6 +13,10 @@
// Log debug messages about velocity tracking.
// Log debug messages about velocity tracking.
#define DEBUG_VELOCITY 0
#define DEBUG_VELOCITY 0


// Log debug messages about acceleration.
#define DEBUG_ACCELERATION 0


#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <unistd.h>
#include <ctype.h>
#include <ctype.h>
@@ -20,6 +24,7 @@
#include <ui/Input.h>
#include <ui/Input.h>


#include <math.h>
#include <math.h>
#include <limits.h>


#ifdef HAVE_ANDROID_OS
#ifdef HAVE_ANDROID_OS
#include <binder/Parcel.h>
#include <binder/Parcel.h>
@@ -670,6 +675,11 @@ bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {


// --- VelocityTracker ---
// --- VelocityTracker ---


const uint32_t VelocityTracker::HISTORY_SIZE;
const nsecs_t VelocityTracker::MAX_AGE;
const nsecs_t VelocityTracker::MIN_WINDOW;
const nsecs_t VelocityTracker::MIN_DURATION;

VelocityTracker::VelocityTracker() {
VelocityTracker::VelocityTracker() {
    clear();
    clear();
}
}
@@ -879,6 +889,85 @@ bool VelocityTracker::getVelocity(uint32_t id, float* outVx, float* outVy) const
}
}




// --- VelocityControl ---

const nsecs_t VelocityControl::STOP_TIME;

VelocityControl::VelocityControl() {
    reset();
}

void VelocityControl::setParameters(const VelocityControlParameters& parameters) {
    mParameters = parameters;
    reset();
}

void VelocityControl::reset() {
    mLastMovementTime = LLONG_MIN;
    mRawPosition.x = 0;
    mRawPosition.y = 0;
    mVelocityTracker.clear();
}

void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) {
    if ((deltaX && *deltaX) || (deltaY && *deltaY)) {
        if (eventTime >= mLastMovementTime + STOP_TIME) {
#if DEBUG_ACCELERATION
            LOGD("VelocityControl: stopped, last movement was %0.3fms ago",
                    (eventTime - mLastMovementTime) * 0.000001f);
#endif
            reset();
        }

        mLastMovementTime = eventTime;
        if (deltaX) {
            mRawPosition.x += *deltaX;
        }
        if (deltaY) {
            mRawPosition.y += *deltaY;
        }
        mVelocityTracker.addMovement(eventTime, BitSet32(BitSet32::valueForBit(0)), &mRawPosition);

        float vx, vy;
        float scale = mParameters.scale;
        if (mVelocityTracker.getVelocity(0, &vx, &vy)) {
            float speed = hypotf(vx, vy) * scale;
            if (speed >= mParameters.highThreshold) {
                // Apply full acceleration above the high speed threshold.
                scale *= mParameters.acceleration;
            } else if (speed > mParameters.lowThreshold) {
                // Linearly interpolate the acceleration to apply between the low and high
                // speed thresholds.
                scale *= 1 + (speed - mParameters.lowThreshold)
                        / (mParameters.highThreshold - mParameters.lowThreshold)
                        * (mParameters.acceleration - 1);
            }

#if DEBUG_ACCELERATION
            LOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): "
                    "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f",
                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
                    mParameters.acceleration,
                    vx, vy, speed, scale / mParameters.scale);
#endif
        } else {
#if DEBUG_ACCELERATION
            LOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity",
                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
                    mParameters.acceleration);
#endif
        }

        if (deltaX) {
            *deltaX *= scale;
        }
        if (deltaY) {
            *deltaY *= scale;
        }
    }
}


// --- InputDeviceInfo ---
// --- InputDeviceInfo ---


InputDeviceInfo::InputDeviceInfo() {
InputDeviceInfo::InputDeviceInfo() {