[PATCH 16/27] Input: Convert acceleration code to using ValuatorMask

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


Instead of passing a set of int* to the acceleration code, pass it a
mask instead, which avoids an unfortunate loss of precision.

Signed-off-by: Daniel Stone <daniel at fooishbar.org>
---
 dix/getevents.c |   41 +++++++++++++++++-----------
 dix/ptrveloc.c  |   82 ++++++++++++++++---------------------------------------
 2 files changed, 49 insertions(+), 74 deletions(-)

diff --git a/dix/getevents.c b/dix/getevents.c
index b796000..2f8e137 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -727,17 +727,19 @@ moveAbsolute(DeviceIntPtr dev, int *x_out, int *y_out, ValuatorMask *mask)
 
     for (i = 0; i < valuator_mask_size(mask); i++)
     {
+        double val;
         if (valuator_mask_isset(mask, i))
-        {
-            double val = valuator_mask_get_double(mask, i);
-            clipAxis(dev, i, &val);
-            dev->last.valuators[i] = val;
-            valuator_mask_set_double(mask, i, val);
-        }
+            val = valuator_mask_get_double(mask, i);
+        else
+            val = dev->last.valuators[i] + dev->last.remainder[i];
+        clipAxis(dev, i, &val);
+        dev->last.valuators[i] = floor(val);
+        dev->last.remainder[i] = val - floor(val);
+        valuator_mask_set_double(mask, i, val);
     }
 
-    *x_out = round_towards_zero(x);
-    *y_out = round_towards_zero(y);
+    *x_out = dev->last.valuators[0];
+    *y_out = dev->last.valuators[1];
 }
 
 /**
@@ -759,15 +761,16 @@ moveRelative(DeviceIntPtr dev, int *x_out, int *y_out, ValuatorMask *mask)
     {
         if (valuator_mask_isset(mask, i))
         {
-            double val = dev->last.valuators[i];
+            double val = dev->last.valuators[i] + dev->last.remainder[i];
             val += valuator_mask_get_double(mask, i);
             /* x & y need to go over the limits to cross screens if the SD
              * isn't currently attached; otherwise, clip to screen bounds. */
             if (valuator_get_mode(dev, i) == Absolute &&
                 ((i != 0 && i != 1) || clip_xy))
                 clipAxis(dev, i, &val);
-            dev->last.valuators[i] = val;
             valuator_mask_set_double(mask, i, val);
+            dev->last.valuators[i] = val;
+            dev->last.remainder[i] = val - round_towards_zero(val);
         }
     }
 
@@ -1185,16 +1188,22 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons
         /* x and y are only set, but not used, by moveAbsolute */
         moveAbsolute(pDev, &x, &y, &mask);
     } else {
-        if (flags & POINTER_ACCELERATE) {
+        if (flags & POINTER_ACCELERATE)
             accelPointer(pDev, &mask, ms);
-            /* The pointer acceleration code modifies the fractional part
-             * in-place, so we need to extract this information first */
-            x_frac = pDev->last.remainder[0];
-            y_frac = pDev->last.remainder[1];
-        }
         moveRelative(pDev, &x, &y, &mask);
     }
 
+    if (valuator_mask_isset(&mask, 0))
+    {
+        x_frac = valuator_mask_get_double(&mask, 0);
+        x_frac -= round_towards_zero(x_frac);
+    }
+    if (valuator_mask_isset(&mask, 1))
+    {
+        y_frac = valuator_mask_get_double(&mask, 1);
+        y_frac -= round_towards_zero(y_frac);
+    }
+
     set_raw_valuators(raw, &mask, raw->valuators.data,
                       raw->valuators.data_frac);
 
diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 92e75b6..c4b916e 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -1118,11 +1118,10 @@ acceleratePointerPredictable(
     CARD32 evtime)
 {
     double dx = 0, dy = 0;
-    int tmpi;
     DeviceVelocityPtr velocitydata = GetDevicePredictableAccelData(dev);
     Bool soften = TRUE;
 
-    if (!velocitydata)
+    if (valuator_mask_num_valuators(val) == 0 || !velocitydata)
         return;
 
     if (velocitydata->statistics.profile_number == AccelProfileNone &&
@@ -1131,11 +1130,11 @@ acceleratePointerPredictable(
     }
 
     if (valuator_mask_isset(val, 0)) {
-        dx = valuator_mask_get(val, 0);
+        dx = valuator_mask_get_double(val, 0);
     }
 
     if (valuator_mask_isset(val, 1)) {
-        dy = valuator_mask_get(val, 1);
+        dy = valuator_mask_get_double(val, 1);
     }
 
     if (dx || dy){
@@ -1158,29 +1157,12 @@ acceleratePointerPredictable(
                     ApplySoftening(velocitydata, &dx, &dy);
                 ApplyConstantDeceleration(velocitydata, &dx, &dy);
 
-                /* Calculate the new delta (with accel) and drop it back
-                 * into the valuator masks */
-                if (dx) {
-                    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
-                     * of a toggling remainder. Its lack of guarantees likely
-                     * makes it faster on the average target. */
-                    tmpi = lrintf(tmp);
-                    valuator_mask_set(val, 0, tmpi);
-                    dev->last.remainder[0] = tmp - (double)tmpi;
-                }
-                if (dy) {
-                    double tmp;
-                    tmp = mult * dy + dev->last.remainder[1];
-                    tmpi = lrintf(tmp);
-                    valuator_mask_set(val, 1, 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], dx, dy);
+                if (dx)
+                    valuator_mask_set_double(val, 0, mult * dx);
+                if (dy)
+                    valuator_mask_set_double(val, 1, mult * dy);
+                DebugAccelF("pos (%i | %i) delta x:%.3f y:%.3f\n", mult * dx,
+                            mult * dy);
             }
         }
     }
@@ -1203,7 +1185,6 @@ acceleratePointerLightweight(
 {
     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);
@@ -1213,53 +1194,38 @@ acceleratePointerLightweight(
         dy = valuator_mask_get(val, 1);
     }
 
+    if (valuator_mask_num_valuators(val) == 0)
+        return;
+
     if (!dx && !dy)
         return;
 
     if (dev->ptrfeed && dev->ptrfeed->ctrl.num) {
         /* modeled from xf86Events.c */
         if (dev->ptrfeed->ctrl.threshold) {
-            if ((abs(dx) + abs(dy)) >= dev->ptrfeed->ctrl.threshold) {
-                tmpf = ((double)dx *
-                        (double)(dev->ptrfeed->ctrl.num)) /
-                       (double)(dev->ptrfeed->ctrl.den) +
-                       dev->last.remainder[0];
+            if ((fabs(dx) + fabs(dy)) >= dev->ptrfeed->ctrl.threshold) {
                 if (dx) {
-                    tmpi = (int) tmpf;
-                    valuator_mask_set(val, 0, tmpi);
-                    dev->last.remainder[0] = tmpf - (double)tmpi;
+                    tmpf = (dx * (double)(dev->ptrfeed->ctrl.num)) /
+                           (double)(dev->ptrfeed->ctrl.den);
+                    valuator_mask_set_double(val, 0, tmpf);
                 }
 
-                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 - (double)tmpi;
+                    tmpf = (dy * (double)(dev->ptrfeed->ctrl.num)) /
+                           (double)(dev->ptrfeed->ctrl.den);
+                    valuator_mask_set_double(val, 1, tmpf);
                 }
             }
         }
         else {
-	    mult = pow((double)dx * (double)dx + (double)dy * (double)dy,
+	    mult = pow(dx * dx + dy * dy,
                        ((double)(dev->ptrfeed->ctrl.num) /
                         (double)(dev->ptrfeed->ctrl.den) - 1.0) /
                        2.0) / 2.0;
-            if (dx) {
-                tmpf = mult * (double)dx +
-                       dev->last.remainder[0];
-                tmpi = (int) tmpf;
-                valuator_mask_set(val, 0, tmpi);
-                dev->last.remainder[0] = tmpf - (double)tmpi;
-            }
-            if (dy) {
-                tmpf = mult * (double)dy +
-                       dev->last.remainder[1];
-                tmpi = (int)tmpf;
-                valuator_mask_set(val, 1, tmpi);
-                dev->last.remainder[1] = tmpf - (double)tmpi;
-            }
+            if (dx)
+                valuator_mask_set_double(val, 0, mult * dx);
+            if (dy)
+                valuator_mask_set_double(val, 1, mult * dy);
         }
     }
 }
-- 
1.7.5.3



More information about the xorg-devel mailing list