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

Simon Thum simon.thum at gmx.de
Sun Jun 5 08:25:52 PDT 2011


On 06/03/2011 04:59 PM, Daniel Stone wrote:
> 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>
While I don't oppose it, I would like to mention the velocity estimation
is quite sensible to stuff being integer. See the solution I proposed
earlier that day (predating awareness of this marvellous patchset).

Therefore I'd be grateful if you leave GetDirection & its cousin on ints.

The smoothing part is also quite pointless on doubles, except if you're
assuming they're really ints/mickeys.

Also, some of the float literals are still there.

Cheers,

Simon


> ---
>  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);



More information about the xorg-devel mailing list