[PATCH 15/27] Input: Widen pointer acceleration types to double

Daniel Stone daniel at fooishbar.org
Fri Jun 3 07:59:51 PDT 2011


This widens most of ptrveloc.[ch] to double from float: I would have
loved to have done it in smaller chunks, but the code's fairly
intractable, so.

Signed-off-by: Daniel Stone <daniel at fooishbar.org>
---
 dix/ptrveloc.c     |  213 ++++++++++++++++++++++++++--------------------------
 include/ptrveloc.h |   32 ++++----
 2 files changed, 121 insertions(+), 124 deletions(-)

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index dfccf15..92e75b6 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -63,9 +63,9 @@
 /* fwds */
 int
 SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
-static float
-SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, float velocity,
-                    float threshold, float acc);
+static double
+SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity,
+                    double threshold, double acc);
 static PointerAccelerationProfileFunc
 GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
 static BOOL
@@ -452,11 +452,11 @@ enum directions {
  * this movement.
  */
 static int
-DoGetDirection(int dx, int dy){
+DoGetDirection(double dx, double dy){
     int dir = 0;
 
     /* on insignificant mickeys, flag 135 degrees */
-    if(abs(dx) < 2 && abs(dy) < 2){
+    if(fabs(dx) < 2 && fabs(dy) < 2){
         /* first check diagonal cases */
         if(dx > 0 && dy > 0)
             dir = E | SE | S;
@@ -478,14 +478,10 @@ DoGetDirection(int dx, int dy){
         else
             dir = UNDEFINED; /* shouldn't happen */
     } else { /* compute angle and set appropriate flags */
-        float r;
+        double r;
         int i1, i2;
 
-#ifdef _ISOC99_SOURCE
-        r = atan2f(dy, dx);
-#else
         r = atan2(dy, dx);
-#endif
         /* find direction.
          *
          * Add 360° to avoid r become negative since C has no well-defined
@@ -521,16 +517,18 @@ DoGetDirection(int dx, int dy){
  * this movement.
  */
 static int
-GetDirection(int dx, int dy){
+GetDirection(double dx, double dy){
     static int cache[DIRECTION_CACHE_SIZE][DIRECTION_CACHE_SIZE];
     int dir;
-    if (abs(dx) <= DIRECTION_CACHE_RANGE &&
-	abs(dy) <= DIRECTION_CACHE_RANGE) {
+    if (fabs(dx) <= DIRECTION_CACHE_RANGE &&
+	fabs(dy) <= DIRECTION_CACHE_RANGE) {
 	/* cacheable */
-	dir = cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy];
+	dir = cache[DIRECTION_CACHE_RANGE+lrint(floor(dx))]
+                   [DIRECTION_CACHE_RANGE+lrint(floor(dy))];
 	if(dir == 0) {
 	    dir = DoGetDirection(dx, dy);
-	    cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy] = dir;
+	    cache[DIRECTION_CACHE_RANGE+lrint(floor(dx))]
+                 [DIRECTION_CACHE_RANGE+lrint(floor(dy))] = dir;
 	}
     }else{
 	/* non-cacheable */
@@ -553,7 +551,7 @@ GetDirection(int dx, int dy){
  * 0/0 and set it as the current one.
  */
 static inline void
-FeedTrackers(DeviceVelocityPtr vel, int dx, int dy, int cur_t)
+FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t)
 {
     int n;
     for(n = 0; n < vel->num_tracker; n++){
@@ -561,8 +559,8 @@ FeedTrackers(DeviceVelocityPtr vel, int dx, int dy, int cur_t)
 	vel->tracker[n].dy += dy;
     }
     n = (vel->cur_tracker + 1) % vel->num_tracker;
-    vel->tracker[n].dx = 0;
-    vel->tracker[n].dy = 0;
+    vel->tracker[n].dx = 0.0;
+    vel->tracker[n].dy = 0.0;
     vel->tracker[n].time = cur_t;
     vel->tracker[n].dir = GetDirection(dx, dy);
     DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n",
@@ -674,11 +672,11 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t){
 BOOL
 ProcessVelocityData2D(
     DeviceVelocityPtr vel,
-    int dx,
-    int dy,
+    double dx,
+    double dy,
     int time)
 {
-    float velocity;
+    double velocity;
 
     vel->last_velocity = vel->velocity;
 
@@ -694,12 +692,12 @@ ProcessVelocityData2D(
  * this flattens significant ( > 1) mickeys a little bit for more steady
  * constant-velocity response
  */
-static inline float
-ApplySimpleSoftening(int prev_delta, int delta)
+static inline double
+ApplySimpleSoftening(double prev_delta, double delta)
 {
-    float result = delta;
+    double result = delta;
 
-    if (delta < -1 || delta > 1) {
+    if (delta < -1.0 || delta > 1.0) {
 	if (delta > prev_delta)
 	    result -= 0.5;
 	else if (delta < prev_delta)
@@ -718,8 +716,8 @@ ApplySimpleSoftening(int prev_delta, int delta)
 static void
 ApplySoftening(
         DeviceVelocityPtr vel,
-        float* fdx,
-        float* fdy)
+        double* fdx,
+        double* fdy)
 {
     if (vel->use_softening) {
         *fdx = ApplySimpleSoftening(vel->last_dx, *fdx);
@@ -728,7 +726,7 @@ ApplySoftening(
 }
 
 static void
-ApplyConstantDeceleration(DeviceVelocityPtr vel, float *fdx, float *fdy)
+ApplyConstantDeceleration(DeviceVelocityPtr vel, double *fdx, double *fdy)
 {
     *fdx *= vel->const_acceleration;
     *fdy *= vel->const_acceleration;
@@ -737,15 +735,15 @@ ApplyConstantDeceleration(DeviceVelocityPtr vel, float *fdx, float *fdy)
 /*
  * compute the acceleration for given velocity and enforce min_acceleartion
  */
-float
+double
 BasicComputeAcceleration(
     DeviceIntPtr dev,
     DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc){
+    double velocity,
+    double threshold,
+    double acc){
 
-    float result;
+    double result;
     result = vel->Profile(dev, vel, velocity, threshold, acc);
 
     /* enforce min_acceleration */
@@ -763,9 +761,9 @@ static float
 ComputeAcceleration(
     DeviceIntPtr dev,
     DeviceVelocityPtr vel,
-    float threshold,
-    float acc){
-    float result;
+    double threshold,
+    double acc){
+    double result;
 
     if(vel->velocity <= 0){
 	DebugAccelF("(dix ptracc) profile skipped\n");
@@ -808,13 +806,13 @@ ComputeAcceleration(
 /**
  * Polynomial function similar previous one, but with f(1) = 1
  */
-static float
+static double
 PolynomialAccelerationProfile(
     DeviceIntPtr dev,
     DeviceVelocityPtr vel,
-    float velocity,
-    float ignored,
-    float acc)
+    double velocity,
+    double ignored,
+    double acc)
 {
    return pow(velocity, (acc - 1.0) * 0.5);
 }
@@ -824,13 +822,13 @@ PolynomialAccelerationProfile(
  * returns acceleration for velocity.
  * This profile selects the two functions like the old scheme did
  */
-static float
+static double
 ClassicProfile(
     DeviceIntPtr dev,
     DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
+    double velocity,
+    double threshold,
+    double acc)
 {
     if (threshold > 0) {
 	return SimpleSmoothProfile (dev,
@@ -856,15 +854,15 @@ ClassicProfile(
  * This has the expense of overall response dependency on min-acceleration.
  * In effect, min_acceleration mimics const_acceleration in this profile.
  */
-static float
+static double
 PowerProfile(
     DeviceIntPtr dev,
     DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
+    double velocity,
+    double threshold,
+    double acc)
 {
-    float vel_dist;
+    double vel_dist;
 
     acc = (acc-1.0) * 0.1f + 1.0; /* without this, acc of 2 is unuseable */
 
@@ -882,11 +880,11 @@ PowerProfile(
  *  - starts faster than a sinoid
  *  - smoothness C1 (Cinf if you dare to ignore endpoints)
  */
-static inline float
-CalcPenumbralGradient(float x){
+static inline double
+CalcPenumbralGradient(double x){
     x *= 2.0f;
     x -= 1.0f;
-    return 0.5f + (x * sqrt(1.0f - x*x) + asin(x))/M_PI;
+    return 0.5f + (x * sqrt(1.0 - x*x) + asin(x))/M_PI;
 }
 
 
@@ -894,13 +892,13 @@ CalcPenumbralGradient(float x){
  * acceleration function similar to classic accelerated/unaccelerated,
  * but with smooth transition in between (and towards zero for adaptive dec.).
  */
-static float
+static double
 SimpleSmoothProfile(
     DeviceIntPtr dev,
     DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
+    double velocity,
+    double threshold,
+    double acc)
 {
     if(velocity < 1.0f)
         return CalcPenumbralGradient(0.5 + velocity*0.5) * 2.0f - 1.0f;
@@ -920,15 +918,15 @@ SimpleSmoothProfile(
  * This profile uses the first half of the penumbral gradient as a start
  * and then scales linearly.
  */
-static float
+static double
 SmoothLinearProfile(
     DeviceIntPtr dev,
     DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
+    double velocity,
+    double threshold,
+    double acc)
 {
-    float res, nv;
+    double res, nv;
 
     if(acc > 1.0f)
         acc -= 1.0f; /*this is so acc = 1 is no acceleration */
@@ -955,15 +953,15 @@ SmoothLinearProfile(
  * From 0 to threshold, the response graduates smoothly from min_accel to
  * acceleration. Beyond threshold it is exactly the specified acceleration.
  */
-static float
+static double
 SmoothLimitedProfile(
     DeviceIntPtr dev,
     DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
+    double velocity,
+    double threshold,
+    double acc)
 {
-    float res;
+    double res;
 
     if(velocity >= threshold || threshold == 0.0f)
 	return acc;
@@ -976,24 +974,24 @@ SmoothLimitedProfile(
 }
 
 
-static float
+static double
 LinearProfile(
     DeviceIntPtr dev,
     DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
+    double velocity,
+    double threshold,
+    double acc)
 {
     return acc * velocity;
 }
 
-static float
+static double
 NoProfile(
     DeviceIntPtr dev,
     DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
+    double velocity,
+    double threshold,
+    double acc)
 {
     return 1.0f;
 }
@@ -1119,7 +1117,8 @@ acceleratePointerPredictable(
     ValuatorMask* val,
     CARD32 evtime)
 {
-    int dx = 0, dy = 0, tmpi;
+    double dx = 0, dy = 0;
+    int tmpi;
     DeviceVelocityPtr velocitydata = GetDevicePredictableAccelData(dev);
     Bool soften = TRUE;
 
@@ -1146,27 +1145,24 @@ acceleratePointerPredictable(
         }
 
         if (dev->ptrfeed && dev->ptrfeed->ctrl.num) {
-            float mult;
+            double mult;
 
             /* invoke acceleration profile to determine acceleration */
             mult = ComputeAcceleration (dev, velocitydata,
-                                        dev->ptrfeed->ctrl.threshold,
-                                        (float)dev->ptrfeed->ctrl.num /
-                                            (float)dev->ptrfeed->ctrl.den);
+					dev->ptrfeed->ctrl.threshold,
+					(double)dev->ptrfeed->ctrl.num /
+					(double)dev->ptrfeed->ctrl.den);
 
             if(mult != 1.0f || velocitydata->const_acceleration != 1.0f) {
-                float fdx = dx,
-                      fdy = dy;
-
                 if (mult > 1.0f && soften)
-                    ApplySoftening(velocitydata, &fdx, &fdy);
-                ApplyConstantDeceleration(velocitydata, &fdx, &fdy);
+                    ApplySoftening(velocitydata, &dx, &dy);
+                ApplyConstantDeceleration(velocitydata, &dx, &dy);
 
                 /* Calculate the new delta (with accel) and drop it back
                  * into the valuator masks */
                 if (dx) {
-                    float tmp;
-                    tmp = mult * fdx + dev->last.remainder[0];
+                    double tmp;
+                    tmp = mult * dx + dev->last.remainder[0];
                     /* Since it may not be apparent: lrintf() does not offer
                      * strong statements about rounding; however because we
                      * process each axis conditionally, there's no danger
@@ -1174,17 +1170,17 @@ acceleratePointerPredictable(
                      * makes it faster on the average target. */
                     tmpi = lrintf(tmp);
                     valuator_mask_set(val, 0, tmpi);
-                    dev->last.remainder[0] = tmp - (float)tmpi;
+                    dev->last.remainder[0] = tmp - (double)tmpi;
                 }
                 if (dy) {
-                    float tmp;
-                    tmp = mult * fdy + dev->last.remainder[1];
+                    double tmp;
+                    tmp = mult * dy + dev->last.remainder[1];
                     tmpi = lrintf(tmp);
                     valuator_mask_set(val, 1, tmpi);
-                    dev->last.remainder[1] = tmp - (float)tmpi;
+                    dev->last.remainder[1] = tmp - (double)tmpi;
                 }
                 DebugAccelF("pos (%i | %i) remainders x: %.3f y: %.3f delta x:%.3f y:%.3f\n",
-                            *px, *py, dev->last.remainder[0], dev->last.remainder[1], fdx, fdy);
+                            *px, *py, dev->last.remainder[0], dev->last.remainder[1], dx, dy);
             }
         }
     }
@@ -1205,8 +1201,9 @@ acceleratePointerLightweight(
     ValuatorMask* val,
     CARD32 ignored)
 {
-    float mult = 0.0, tmpf;
-    int dx = 0, dy = 0, tmpi;
+    double mult = 0.0, tmpf;
+    double dx = 0.0, dy = 0.0;
+    int tmpi;
 
     if (valuator_mask_isset(val, 0)) {
         dx = valuator_mask_get(val, 0);
@@ -1223,45 +1220,45 @@ acceleratePointerLightweight(
         /* modeled from xf86Events.c */
         if (dev->ptrfeed->ctrl.threshold) {
             if ((abs(dx) + abs(dy)) >= dev->ptrfeed->ctrl.threshold) {
-                tmpf = ((float)dx *
-                        (float)(dev->ptrfeed->ctrl.num)) /
-                       (float)(dev->ptrfeed->ctrl.den) +
+                tmpf = ((double)dx *
+                        (double)(dev->ptrfeed->ctrl.num)) /
+                       (double)(dev->ptrfeed->ctrl.den) +
                        dev->last.remainder[0];
                 if (dx) {
                     tmpi = (int) tmpf;
                     valuator_mask_set(val, 0, tmpi);
-                    dev->last.remainder[0] = tmpf - (float)tmpi;
+                    dev->last.remainder[0] = tmpf - (double)tmpi;
                 }
 
-                tmpf = ((float)dy *
-                        (float)(dev->ptrfeed->ctrl.num)) /
-                       (float)(dev->ptrfeed->ctrl.den) +
+                tmpf = ((double)dy *
+                        (double)(dev->ptrfeed->ctrl.num)) /
+                       (double)(dev->ptrfeed->ctrl.den) +
                        dev->last.remainder[1];
                 if (dy) {
                     tmpi = (int) tmpf;
                     valuator_mask_set(val, 1, tmpi);
-                    dev->last.remainder[1] = tmpf - (float)tmpi;
+                    dev->last.remainder[1] = tmpf - (double)tmpi;
                 }
             }
         }
         else {
-            mult = pow((float)dx * (float)dx + (float)dy * (float)dy,
-                       ((float)(dev->ptrfeed->ctrl.num) /
-                        (float)(dev->ptrfeed->ctrl.den) - 1.0) /
+	    mult = pow((double)dx * (double)dx + (double)dy * (double)dy,
+                       ((double)(dev->ptrfeed->ctrl.num) /
+                        (double)(dev->ptrfeed->ctrl.den) - 1.0) /
                        2.0) / 2.0;
             if (dx) {
-                tmpf = mult * (float)dx +
+                tmpf = mult * (double)dx +
                        dev->last.remainder[0];
                 tmpi = (int) tmpf;
                 valuator_mask_set(val, 0, tmpi);
-                dev->last.remainder[0] = tmpf - (float)tmpi;
+                dev->last.remainder[0] = tmpf - (double)tmpi;
             }
             if (dy) {
-                tmpf = mult * (float)dy +
+                tmpf = mult * (double)dy +
                        dev->last.remainder[1];
                 tmpi = (int)tmpf;
                 valuator_mask_set(val, 1, tmpi);
-                dev->last.remainder[1] = tmpf - (float)tmpi;
+                dev->last.remainder[1] = tmpf - (double)tmpi;
             }
         }
     }
diff --git a/include/ptrveloc.h b/include/ptrveloc.h
index 6ca309c..4f76b00 100644
--- a/include/ptrveloc.h
+++ b/include/ptrveloc.h
@@ -47,9 +47,9 @@ struct _DeviceVelocityRec;
  * profile
  * returns actual acceleration depending on velocity, acceleration control,...
  */
-typedef float (*PointerAccelerationProfileFunc)
+typedef double (*PointerAccelerationProfileFunc)
               (DeviceIntPtr dev, struct _DeviceVelocityRec* vel,
-               float velocity, float threshold, float accelCoeff);
+               double velocity, double threshold, double accelCoeff);
 
 /**
  * a motion history, with just enough information to
@@ -57,8 +57,8 @@ typedef float (*PointerAccelerationProfileFunc)
  * a more or less straight line
  */
 typedef struct _MotionTracker {
-    int dx, dy;     /* accumulated delta for each axis */
-    int time;         /* time of creation */
+    double dx, dy;  /* accumulated delta for each axis */
+    int time;       /* time of creation */
     int dir;        /* initial direction bitfield */
 } MotionTracker, *MotionTrackerPtr;
 
@@ -69,17 +69,17 @@ typedef struct _DeviceVelocityRec {
     MotionTrackerPtr tracker;
     int num_tracker;
     int cur_tracker;        /* current index */
-    float   velocity;       /* velocity as guessed by algorithm */
-    float   last_velocity;  /* previous velocity estimate */
-    int     last_dx;      /* last time-difference */
-    int     last_dy ;     /* phase of last/current estimate */
-    float   corr_mul;       /* config: multiply this into velocity */
-    float   const_acceleration;  /* config: (recipr.) const deceleration */
-    float   min_acceleration;    /* config: minimum acceleration */
+    double  velocity;       /* velocity as guessed by algorithm */
+    double  last_velocity;  /* previous velocity estimate */
+    double  last_dx;        /* last time-difference */
+    double  last_dy;        /* phase of last/current estimate */
+    double  corr_mul;       /* config: multiply this into velocity */
+    double  const_acceleration;  /* config: (recipr.) const deceleration */
+    double  min_acceleration;    /* config: minimum acceleration */
     short   reset_time;     /* config: reset non-visible state after # ms */
     short   use_softening;  /* config: use softening of mouse values */
-    float   max_rel_diff;   /* config: max. relative difference */
-    float   max_diff;       /* config: max. difference */
+    double  max_rel_diff;   /* config: max. relative difference */
+    double  max_diff;       /* config: max. difference */
     int     initial_range;  /* config: max. offset used as initial velocity */
     Bool    average_accel;  /* config: average acceleration over velocity */
     PointerAccelerationProfileFunc Profile;
@@ -107,11 +107,11 @@ extern _X_EXPORT void
 InitTrackers(DeviceVelocityPtr vel, int ntracker);
 
 extern _X_EXPORT BOOL
-ProcessVelocityData2D(DeviceVelocityPtr vel, int dx, int dy, int time);
+ProcessVelocityData2D(DeviceVelocityPtr vel, double dx, double dy, int time);
 
-extern _X_EXPORT float
+extern _X_EXPORT double
 BasicComputeAcceleration(DeviceIntPtr dev, DeviceVelocityPtr vel,
-    float velocity, float threshold, float acc);
+    double velocity, double threshold, double acc);
 
 extern _X_EXPORT void
 FreeVelocityData(DeviceVelocityPtr vel);
-- 
1.7.5.3



More information about the xorg-devel mailing list