On Wed, Aug 05, 2015 at 04:32:35PM +1000, Peter Hutterer wrote:
> And switch to a code-flow that's a bit more self-explanatory than the current
> min/max combinations.
> 
> Signed-off-by: Peter Hutterer <[email protected]>

Much much more easy to follow now. Most of the reviewing time of this
patch was trying to re-understand and confirm the f1 f2 min max code
did what the new description explains. The new code make that a lot more
obvious.

Reviewed-by: Jonas Ådahl <[email protected]>

> ---
>  src/filter.c | 83 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 73 insertions(+), 10 deletions(-)
> 
> diff --git a/src/filter.c b/src/filter.c
> index b42db35..4f0d8d5 100644
> --- a/src/filter.c
> +++ b/src/filter.c
> @@ -421,19 +421,26 @@ pointer_accel_profile_linear_low_dpi(struct 
> motion_filter *filter,
>       struct pointer_accelerator *accel_filter =
>               (struct pointer_accelerator *)filter;
>  
> -     double f1, f2; /* unitless */
>       double max_accel = accel_filter->accel; /* unitless factor */
> -     const double threshold = accel_filter->threshold; /* units/us */
> +     double threshold = accel_filter->threshold; /* units/us */
>       const double incline = accel_filter->incline;
>       double factor; /* unitless */
>       double dpi_factor = accel_filter->dpi_factor;
>  
> +     /* dpi_factor is always < 1.0, increase max_accel, reduce
> +        the threshold so it kicks in earlier */
>       max_accel /= dpi_factor;
> +     threshold *= dpi_factor;
>  
> -     f1 = min(1, 0.3 + v_us2ms(speed_in) * 10.0);
> -     f2 = 1 + (v_us2ms(speed_in) - v_us2ms(threshold) * dpi_factor) * 
> incline;
> +     /* see pointer_accel_profile_linear for a long description */
> +     if (v_us2ms(speed_in) < 0.07)
> +             factor = 10 * v_us2ms(speed_in) + 0.3;
> +     else if (speed_in < threshold)
> +             factor = 1;
> +     else
> +             factor = incline * v_us2ms(speed_in - threshold) + 1;
>  
> -     factor = min(max_accel, f2 > 1 ? f2 : f1);
> +     factor = min(max_accel, factor);
>  
>       return factor;
>  }
> @@ -446,17 +453,67 @@ pointer_accel_profile_linear(struct motion_filter 
> *filter,
>  {
>       struct pointer_accelerator *accel_filter =
>               (struct pointer_accelerator *)filter;
> -
> -     double f1, f2; /* unitless */
>       const double max_accel = accel_filter->accel; /* unitless factor */
>       const double threshold = accel_filter->threshold; /* units/us */
>       const double incline = accel_filter->incline;
>       double factor; /* unitless */
>  
> -     f1 = min(1, 0.3 + v_us2ms(speed_in) * 10);
> -     f2 = 1 + (v_us2ms(speed_in) - v_us2ms(threshold)) * incline;
> +     /*
> +        Our acceleration function calculates a factor to accelerate input
> +        deltas with. The function is a double incline with a plateau,
> +        with a rough shape like this:
>  
> -     factor = min(max_accel, f2 > 1 ? f2 : f1);
> +       accel
> +      factor
> +        ^
> +        |        /
> +        |  _____/
> +        | /
> +        |/
> +        +-------------> speed in
> +
> +        The two inclines are linear functions in the form
> +                y = ax + b
> +                where y is speed_out
> +                      x is speed_in
> +                      a is the incline of acceleration
> +                      b is minimum acceleration factor
> +
> +        for speeds up to 0.07 u/ms, we decelerate, down to 30% of input
> +        speed.
> +                hence 1 = a * 0.07 + 0.3
> +                    0.3 = a * 0.00 + 0.3 => a := 10
> +                deceleration function is thus:
> +                     y = 10x + 0.3
> +
> +       Note:
> +       * 0.07u/ms as threshold is a result of trial-and-error and
> +         has no other intrinsic meaning.
> +       * 0.3 is chosen simply because it is above the Nyquist frequency
> +         for subpixel motion within a pixel.
> +     */
> +     if (v_us2ms(speed_in) < 0.07) {
> +             factor = 10 * v_us2ms(speed_in) + 0.3;
> +     /* up to the threshold, we keep factor 1, i.e. 1:1 movement */
> +     } else if (speed_in < threshold) {
> +             factor = 1;
> +
> +     } else {
> +     /* Acceleration function above the threshold:
> +             y = ax' + b
> +             where T is threshold
> +                   x is speed_in
> +                   x' is speed
> +             and
> +                     y(T) == 1
> +             hence 1 = ax' + 1
> +                     => x' := (x - T)
> +      */
> +             factor = incline * v_us2ms(speed_in - threshold) + 1;
> +     }
> +
> +     /* Cap at the maximum acceleration factor */
> +     factor = min(max_accel, factor);
>  
>       return factor;
>  }
> @@ -509,6 +566,12 @@ touchpad_lenovo_x230_accel_profile(struct motion_filter 
> *filter,
>                                 TP_MAGIC_LOW_RES_FACTOR; /* units/us */
>       const double incline = accel_filter->incline * TP_MAGIC_LOW_RES_FACTOR;
>  
> +     /* Note: the magic values in this function are obtained by
> +      * trial-and-error. No other meaning should be interpreted.
> +      * The calculation is a compressed form of
> +      * pointer_accel_profile_linear(), look at the git history of that
> +      * function for an explaination of what the min/max/etc. does.
> +      */
>       speed_in *= TP_MAGIC_SLOWDOWN / TP_MAGIC_LOW_RES_FACTOR;
>  
>       f1 = min(1, v_us2ms(speed_in) * 5);
> -- 
> 2.4.3
> 
> _______________________________________________
> wayland-devel mailing list
> [email protected]
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to