From 4913fd7a4806e54ebe4eb7f5f3f1d2fa3b8fdbdb Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 19 Sep 2014 11:10:17 +1000 Subject: [PATCH] Replace pointer acceleration with a much simpler linear one We ran a userstudy, evaluating three different accel methods. Detailed results are available at: http://www.who-t.net/publications/hutterer2014_libinput_ptraccel_study.pdf We found that there was little difference between the method we had in libinput 0.6 and this three-line function. Users didn't really notice a difference, but measured data suggests that it has slight advantages in some use-cases. The method proposed here is the one labeled "linear" in the paper, its profile looks roughly like this: _____________ / ____/ / / where the x axis is the speed, y is the acceleration factor. The first plateau is at the acceleration factor 1 (i.e. unaccelerated movement), the second plateau is at the max acceleration factor. The threshold in the code defines where and how long the plateau is. Differences to the previous accel function: - both inclines are linear rather than curved - the second incline is less steep than the current method From a maintainer's point-of-view, this function is significantly easier to understand and manipulate than the previous one. Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- src/evdev-mt-touchpad.c | 2 +- src/evdev.c | 2 +- src/filter.c | 47 ++++++++++------------------------------- src/filter.h | 13 ++++-------- 4 files changed, 17 insertions(+), 47 deletions(-) diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 86923330..76535d04 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -845,7 +845,7 @@ tp_init_accel(struct tp_dispatch *tp, double diagonal) } accel = create_pointer_accelator_filter( - pointer_accel_profile_smooth_simple); + pointer_accel_profile_linear); if (accel == NULL) return -1; diff --git a/src/evdev.c b/src/evdev.c index 4e9db2fb..de7ee16c 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -865,7 +865,7 @@ configure_pointer_acceleration(struct evdev_device *device) { device->pointer.filter = create_pointer_accelator_filter( - pointer_accel_profile_smooth_simple); + pointer_accel_profile_linear); if (!device->pointer.filter) return -1; diff --git a/src/filter.c b/src/filter.c index d65adfb7..804058a4 100644 --- a/src/filter.c +++ b/src/filter.c @@ -270,41 +270,16 @@ calc_penumbral_gradient(double x) } double -pointer_accel_profile_smooth_simple(struct motion_filter *filter, - void *data, - double velocity, /* units/ms */ - uint64_t time) +pointer_accel_profile_linear(struct motion_filter *filter, + void *data, + double speed_in, + uint64_t time) { - double threshold = DEFAULT_THRESHOLD; /* units/ms */ - double accel = DEFAULT_ACCELERATION; /* unitless factor */ - double smooth_accel_coefficient; /* unitless factor */ - double factor; /* unitless factor */ - - if (threshold < 0.1) - threshold = 0.1; - if (accel < 1.0) - accel = 1.0; - - /* We use units/ms as velocity but it has no real meaning unless all - devices have the same resolution. For touchpads, we normalize to - 400dpi (15.75 units/mm), but the resolution on USB mice is all - over the place. Though most mice these days have either 400 - dpi (15.75 units/mm), 800 dpi or 1000dpi, excluding gaming mice - that can usually adjust it on the fly anyway and currently go up - to 8200dpi. - */ - if (velocity < (threshold / 2.0)) - return calc_penumbral_gradient(0.5 + velocity / threshold) * 2.0 - 1.0; - - if (velocity <= threshold) - return 1.0; - - factor = velocity/threshold; - if (factor >= accel) - return accel; - - /* factor is between 1.0 and accel, scale this to 0.0 - 1.0 */ - factor = (factor - 1.0) / (accel - 1.0); - smooth_accel_coefficient = calc_penumbral_gradient(factor); - return 1.0 + (smooth_accel_coefficient * (accel - 1.0)); + double s1, s2; + const int max_accel = DEFAULT_ACCELERATION; + + s1 = min(1, speed_in * 5); + s2 = 1 + (speed_in - DEFAULT_THRESHOLD) * 1.1; + + return min(max_accel, s2 > 1 ? s2 : s1); } diff --git a/src/filter.h b/src/filter.h index 85534952..be48838c 100644 --- a/src/filter.h +++ b/src/filter.h @@ -65,14 +65,9 @@ create_pointer_accelator_filter(accel_profile_func_t filter); * Pointer acceleration profiles. */ -/* - * Profile similar which is similar to nonaccelerated but with a smooth - * transition between accelerated and non-accelerated. - */ double -pointer_accel_profile_smooth_simple(struct motion_filter *filter, - void *data, - double velocity, - uint64_t time); - +pointer_accel_profile_linear(struct motion_filter *filter, + void *data, + double speed_in, + uint64_t time); #endif /* FILTER_H */ -- 2.34.1