[PATCH libinput v2] evdev-mt-touchpad: Switch to smooth simple acceleration code from filter.c

Hans de Goede hdegoede at redhat.com
Tue Jul 1 05:53:18 PDT 2014


The old touchpad accel code was clamping touchpad acceleration between
0.2 and 0.4, and on the test devices I have the constant_factor ended up
such that in practice the accel was almost always 0.2, so rather than having
a velocity based acceleration curve, in essence it was just always using an
acceleration of 0.2 .

This commit introduces actual velocity based acceleration based on the
recently added smooth simple acceleration code from filter.c .

Before feeding motion events to filter.c, they first get adjusted for touchpad
resolution. For touchpads where the driver does not provide resolution info,
scale based on the diagonal-size in units instead.

While at it rename's tp_init_accel's dispatch parameter from touchpad to tp
to be consistent with all other functions.

Since the acceleration is also used for scrolling also adjust the scroll
start threshold for these changes.

Note that switching to the smooth simple accel code, as an added bonus gives
the tp code an accel profile with a threshold and a speed parameter, which
is exactly what is needed for the upcoming configuration interface support.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>

--

Changes since v1:
-Use resolution info where available instead of always scaling by diagonal
---
 src/evdev-mt-touchpad.c | 78 +++++++++++++++++--------------------------------
 src/evdev-mt-touchpad.h |  4 ---
 2 files changed, 26 insertions(+), 56 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 9e858f1..e5289b9 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -28,9 +28,7 @@
 
 #include "evdev-mt-touchpad.h"
 
-#define DEFAULT_CONSTANT_ACCEL_NUMERATOR 100
-#define DEFAULT_MIN_ACCEL_FACTOR 0.20
-#define DEFAULT_MAX_ACCEL_FACTOR 0.40
+#define DEFAULT_ACCEL_NUMERATOR 1200.0
 #define DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR 700.0
 
 static inline int
@@ -46,27 +44,6 @@ tp_hysteresis(int in, int center, int margin)
 		return center + diff + margin;
 }
 
-static double
-tp_accel_profile(struct motion_filter *filter,
-		 void *data,
-		 double velocity,
-		 uint64_t time)
-{
-	struct tp_dispatch *tp =
-		(struct tp_dispatch *) data;
-
-	double accel_factor;
-
-	accel_factor = velocity * tp->accel.constant_factor;
-
-	if (accel_factor > tp->accel.max_factor)
-		accel_factor = tp->accel.max_factor;
-	else if (accel_factor < tp->accel.min_factor)
-		accel_factor = tp->accel.min_factor;
-
-	return accel_factor;
-}
-
 static inline struct tp_motion *
 tp_motion_history_offset(struct tp_touch *t, int offset)
 {
@@ -464,11 +441,11 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
 
 	tp_filter_motion(tp, &dx, &dy, time);
 
-	/* Require at least three px scrolling to start */
-	if (dy <= -3.0 || dy >= 3.0)
+	/* Require at least five px scrolling to start */
+	if (dy <= -5.0 || dy >= 5.0)
 		tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
 
-	if (dx <= -3.0 || dx >= 3.0)
+	if (dx <= -5.0 || dx >= 5.0)
 		tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
 
 	if (dy != 0.0 &&
@@ -665,9 +642,10 @@ tp_init_slots(struct tp_dispatch *tp,
 	return 0;
 }
 
-static void
-calculate_scale_coefficients(struct tp_dispatch *tp)
+static int
+tp_init_accel(struct tp_dispatch *tp, double diagonal)
 {
+	struct motion_filter *accel;
 	int res_x, res_y;
 
 	if (tp->has_mt) {
@@ -682,35 +660,31 @@ calculate_scale_coefficients(struct tp_dispatch *tp)
 						    ABS_Y);
 	}
 
-	if (res_x <= 0 || res_y <= 0) {
-		tp->accel.x_scale_coeff = 1.0;
-		tp->accel.y_scale_coeff = 1.0;
-	} else if (res_x > res_y) {
-		tp->accel.x_scale_coeff = res_y / (double) res_x;
-		tp->accel.y_scale_coeff = 1.0f;
+	/*
+	 * Not all touchpads report the same amount of units/mm (resolution).
+	 * Normalize motion events to a resolution of 10 units/mm as base
+	 * (unaccellerated) speed. This also evens out any differences in x
+	 * and y resolution, so that a circle on the touchpad does not turn
+	 * into an elipse on the screen.
+	 */
+	if (res_x > 1 && res_y > 1) {
+		tp->accel.y_scale_coeff = 10.0 / res_x;
+		tp->accel.x_scale_coeff = 10.0 / res_y;
 	} else {
-		tp->accel.y_scale_coeff = res_x / (double) res_y;
-		tp->accel.x_scale_coeff = 1.0f;
+	/*
+	 * For touchpads where the driver does not provide resolution, fall
+	 * back to scaling motion events based on the diagonal size in units.
+	 */
+		tp->accel.x_scale_coeff = DEFAULT_ACCEL_NUMERATOR / diagonal;
+		tp->accel.y_scale_coeff = DEFAULT_ACCEL_NUMERATOR / diagonal;
 	}
-}
-
-static int
-tp_init_accel(struct tp_dispatch *touchpad, double diagonal)
-{
-	struct motion_filter *accel;
-
-	calculate_scale_coefficients(touchpad);
-
-	touchpad->accel.constant_factor =
-		DEFAULT_CONSTANT_ACCEL_NUMERATOR / diagonal;
-	touchpad->accel.min_factor = DEFAULT_MIN_ACCEL_FACTOR;
-	touchpad->accel.max_factor = DEFAULT_MAX_ACCEL_FACTOR;
 
-	accel = create_pointer_accelator_filter(tp_accel_profile);
+	accel = create_pointer_accelator_filter(
+			pointer_accel_profile_smooth_simple);
 	if (accel == NULL)
 		return -1;
 
-	touchpad->filter = accel;
+	tp->filter = accel;
 
 	return 0;
 }
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 7afb3c4..051a7eb 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -152,10 +152,6 @@ struct tp_dispatch {
 	struct motion_filter *filter;
 
 	struct {
-		double constant_factor;
-		double min_factor;
-		double max_factor;
-
 		double x_scale_coeff;
 		double y_scale_coeff;
 	} accel;
-- 
2.0.0



More information about the wayland-devel mailing list