[PATCH libinput] touchpad: drop the double normalization

Peter Hutterer peter.hutterer at who-t.net
Wed Jan 10 03:21:58 UTC 2018


Previously, touchpad deltas were converted to 1000-dpi normalized coordinates
and handled from there. This changed in bdd4264d6150f4a6248eec7e1fbf (1.6)
when the filter functions started taking device coordinates instead. Since
then, we used to convert the device delta to normalized coordinates, then
(often immediately) convert back to device coordinates, albeit for equal x/y
resolution. This isn't necessary, we can just convert the device coordinates
to x/y-equal resolution device coordinates and pass those on.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad-edge-scroll.c |  8 ++++--
 src/evdev-mt-touchpad-gestures.c    | 53 +++++++++++++++++++++----------------
 src/evdev-mt-touchpad.c             | 33 ++++++++++++-----------
 src/evdev-mt-touchpad.h             | 19 ++++++-------
 4 files changed, 63 insertions(+), 50 deletions(-)

diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c
index cab9a87d..eb47ce73 100644
--- a/src/evdev-mt-touchpad-edge-scroll.c
+++ b/src/evdev-mt-touchpad-edge-scroll.c
@@ -376,6 +376,8 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
 	struct tp_touch *t;
 	enum libinput_pointer_axis axis;
 	double *delta;
+	struct device_coords raw;
+	struct device_float_coords fraw;
 	struct normalized_coords normalized, tmp;
 	const struct normalized_coords zero = { 0.0, 0.0 };
 	const struct discrete_coords zero_discrete = { 0.0, 0.0 };
@@ -417,9 +419,11 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
 				continue; /* Don't know direction yet, skip */
 		}
 
-		normalized = tp_get_delta(t);
+		raw = tp_get_delta(t);
+		fraw.x = raw.x;
+		fraw.y = raw.y;
 		/* scroll is not accelerated */
-		normalized = tp_filter_motion_unaccelerated(tp, &normalized, time);
+		normalized = tp_filter_motion_unaccelerated(tp, &fraw, time);
 
 		switch (t->scroll.edge_state) {
 		case EDGE_SCROLL_TOUCH_STATE_NONE:
diff --git a/src/evdev-mt-touchpad-gestures.c b/src/evdev-mt-touchpad-gestures.c
index 37d98fdc..37682fb4 100644
--- a/src/evdev-mt-touchpad-gestures.c
+++ b/src/evdev-mt-touchpad-gestures.c
@@ -45,13 +45,12 @@ gesture_state_to_str(enum tp_gesture_state state)
 	return NULL;
 }
 
-static struct normalized_coords
+static struct device_float_coords
 tp_get_touches_delta(struct tp_dispatch *tp, bool average)
 {
 	struct tp_touch *t;
 	unsigned int i, nactive = 0;
-	struct normalized_coords normalized;
-	struct normalized_coords delta = {0.0, 0.0};
+	struct device_float_coords delta = {0.0, 0.0};
 
 	for (i = 0; i < tp->num_slots; i++) {
 		t = &tp->touches[i];
@@ -62,10 +61,12 @@ tp_get_touches_delta(struct tp_dispatch *tp, bool average)
 		nactive++;
 
 		if (t->dirty) {
-			normalized = tp_get_delta(t);
+			struct device_coords d;
 
-			delta.x += normalized.x;
-			delta.y += normalized.y;
+			d = tp_get_delta(t);
+
+			delta.x += d.x;
+			delta.y += d.y;
 		}
 	}
 
@@ -78,13 +79,13 @@ tp_get_touches_delta(struct tp_dispatch *tp, bool average)
 	return delta;
 }
 
-static inline struct normalized_coords
+static inline struct device_float_coords
 tp_get_combined_touches_delta(struct tp_dispatch *tp)
 {
 	return tp_get_touches_delta(tp, false);
 }
 
-static inline struct normalized_coords
+static inline struct device_float_coords
 tp_get_average_touches_delta(struct tp_dispatch *tp)
 {
 	return tp_get_touches_delta(tp, true);
@@ -128,23 +129,25 @@ tp_gesture_start(struct tp_dispatch *tp, uint64_t time)
 static void
 tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
 {
-	struct normalized_coords delta, unaccel;
 	struct device_float_coords raw;
+	struct normalized_coords delta;
 
 	/* When a clickpad is clicked, combine motion of all active touches */
 	if (tp->buttons.is_clickpad && tp->buttons.state)
-		unaccel = tp_get_combined_touches_delta(tp);
+		raw = tp_get_combined_touches_delta(tp);
 	else
-		unaccel = tp_get_average_touches_delta(tp);
+		raw = tp_get_average_touches_delta(tp);
 
-	delta = tp_filter_motion(tp, &unaccel, time);
+	delta = tp_filter_motion(tp, &raw, time);
 
-	if (!normalized_is_zero(delta) || !normalized_is_zero(unaccel)) {
-		raw = tp_unnormalize_for_xaxis(tp, unaccel);
+	if (!normalized_is_zero(delta) || !device_float_is_zero(raw)) {
+		struct device_float_coords unaccel;
+
+		unaccel = tp_scale_to_xaxis(tp, raw);
 		pointer_notify_motion(&tp->device->base,
 				      time,
 				      &delta,
-				      &raw);
+				      &unaccel);
 	}
 }
 
@@ -379,15 +382,16 @@ tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time)
 static enum tp_gesture_state
 tp_gesture_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
 {
+	struct device_float_coords raw;
 	struct normalized_coords delta;
 
 	if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG)
 		return GESTURE_STATE_SCROLL;
 
-	delta = tp_get_average_touches_delta(tp);
+	raw = tp_get_average_touches_delta(tp);
 
 	/* scroll is not accelerated */
-	delta = tp_filter_motion_unaccelerated(tp, &delta, time);
+	delta = tp_filter_motion_unaccelerated(tp, &raw, time);
 
 	if (normalized_is_zero(delta))
 		return GESTURE_STATE_SCROLL;
@@ -404,12 +408,14 @@ tp_gesture_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
 static enum tp_gesture_state
 tp_gesture_handle_state_swipe(struct tp_dispatch *tp, uint64_t time)
 {
+	struct device_float_coords raw;
 	struct normalized_coords delta, unaccel;
 
-	unaccel = tp_get_average_touches_delta(tp);
-	delta = tp_filter_motion(tp, &unaccel, time);
+	raw = tp_get_average_touches_delta(tp);
+	delta = tp_filter_motion(tp, &raw, time);
 
-	if (!normalized_is_zero(delta) || !normalized_is_zero(unaccel)) {
+	if (!normalized_is_zero(delta) || !device_float_is_zero(raw)) {
+		unaccel = tp_normalize_delta(tp, raw);
 		tp_gesture_start(tp, time);
 		gesture_notify_swipe(&tp->device->base, time,
 				     LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
@@ -440,13 +446,14 @@ tp_gesture_handle_state_pinch(struct tp_dispatch *tp, uint64_t time)
 
 	fdelta = device_float_delta(center, tp->gesture.center);
 	tp->gesture.center = center;
-	unaccel = tp_normalize_delta(tp, fdelta);
-	delta = tp_filter_motion(tp, &unaccel, time);
 
-	if (normalized_is_zero(delta) && normalized_is_zero(unaccel) &&
+	delta = tp_filter_motion(tp, &fdelta, time);
+
+	if (normalized_is_zero(delta) && device_float_is_zero(fdelta) &&
 	    scale == tp->gesture.prev_scale && angle_delta == 0.0)
 		return GESTURE_STATE_PINCH;
 
+	unaccel = tp_normalize_delta(tp, fdelta);
 	tp_gesture_start(tp, time);
 	gesture_notify_pinch(&tp->device->base, time,
 			     LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index df0b0633..3ae1da29 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -49,17 +49,17 @@ tp_motion_history_offset(struct tp_touch *t, int offset)
 
 struct normalized_coords
 tp_filter_motion(struct tp_dispatch *tp,
-		 const struct normalized_coords *unaccelerated,
+		 const struct device_float_coords *unaccelerated,
 		 uint64_t time)
 {
 	struct device_float_coords raw;
+	const struct normalized_coords zero = { 0.0, 0.0 };
 
-	if (normalized_is_zero(*unaccelerated))
-		return *unaccelerated;
+	if (device_float_is_zero(*unaccelerated))
+		return zero;
 
-	/* Temporary solution only: convert back to raw coordinates, but
-	 * make sure we're on the same resolution for both axes */
-	raw = tp_unnormalize_for_xaxis(tp, *unaccelerated);
+	/* Convert to device units with x/y in the same resolution */
+	raw = tp_scale_to_xaxis(tp, *unaccelerated);
 
 	return filter_dispatch(tp->device->pointer.filter,
 			       &raw, tp, time);
@@ -67,17 +67,17 @@ tp_filter_motion(struct tp_dispatch *tp,
 
 struct normalized_coords
 tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
-			       const struct normalized_coords *unaccelerated,
+			       const struct device_float_coords *unaccelerated,
 			       uint64_t time)
 {
 	struct device_float_coords raw;
+	const struct normalized_coords zero = { 0.0, 0.0 };
 
-	if (normalized_is_zero(*unaccelerated))
-		return *unaccelerated;
+	if (device_float_is_zero(*unaccelerated))
+		return zero;
 
-	/* Temporary solution only: convert back to raw coordinates, but
-	 * make sure we're on the same resolution for both axes */
-	raw = tp_unnormalize_for_xaxis(tp, *unaccelerated);
+	/* Convert to device units with x/y in the same resolution */
+	raw = tp_scale_to_xaxis(tp, *unaccelerated);
 
 	return filter_dispatch_constant(tp->device->pointer.filter,
 					&raw, tp, time);
@@ -344,11 +344,11 @@ tp_stop_actions(struct tp_dispatch *tp, uint64_t time)
 	tp_tap_suspend(tp, time);
 }
 
-struct normalized_coords
+struct device_coords
 tp_get_delta(struct tp_touch *t)
 {
-	struct device_float_coords delta;
-	const struct normalized_coords zero = { 0.0, 0.0 };
+	struct device_coords delta;
+	const struct device_coords zero = { 0.0, 0.0 };
 
 	if (t->history.count <= 1)
 		return zero;
@@ -358,7 +358,7 @@ tp_get_delta(struct tp_touch *t)
 	delta.y = tp_motion_history_offset(t, 0)->point.y -
 		  tp_motion_history_offset(t, 1)->point.y;
 
-	return tp_normalize_delta(t->tp, delta);
+	return delta;
 }
 
 static void
@@ -2448,6 +2448,7 @@ tp_init_accel(struct tp_dispatch *tp)
 	 */
 	tp->accel.x_scale_coeff = (DEFAULT_MOUSE_DPI/25.4) / res_x;
 	tp->accel.y_scale_coeff = (DEFAULT_MOUSE_DPI/25.4) / res_y;
+	tp->accel.xy_scale_coeff = 1.0 * res_x/res_y;
 
 	if (tp->device->model_flags & EVDEV_MODEL_LENOVO_X230 ||
 	    tp->device->model_flags & EVDEV_MODEL_LENOVO_X220_TOUCHPAD_FW81)
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 0dee8aaa..442f34a3 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -281,6 +281,7 @@ struct tp_dispatch {
 	struct {
 		double x_scale_coeff;
 		double y_scale_coeff;
+		double xy_scale_coeff;
 	} accel;
 
 	struct {
@@ -480,32 +481,32 @@ tp_phys_delta(const struct tp_dispatch *tp,
 }
 
 /**
- * Takes a dpi-normalized set of coordinates, returns a set of coordinates
- * in the x-axis' coordinate space.
+ * Takes a set of device coordinates, returns that set of coordinates in the
+ * x-axis' resolution.
  */
 static inline struct device_float_coords
-tp_unnormalize_for_xaxis(const struct tp_dispatch *tp,
-			 struct normalized_coords delta)
+tp_scale_to_xaxis(const struct tp_dispatch *tp,
+		  struct device_float_coords delta)
 {
 	struct device_float_coords raw;
 
-	raw.x = delta.x / tp->accel.x_scale_coeff;
-	raw.y = delta.y / tp->accel.x_scale_coeff; /* <--- not a typo */
+	raw.x = delta.x;
+	raw.y = delta.y * tp->accel.xy_scale_coeff;
 
 	return raw;
 }
 
-struct normalized_coords
+struct device_coords
 tp_get_delta(struct tp_touch *t);
 
 struct normalized_coords
 tp_filter_motion(struct tp_dispatch *tp,
-		 const struct normalized_coords *unaccelerated,
+		 const struct device_float_coords *unaccelerated,
 		 uint64_t time);
 
 struct normalized_coords
 tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
-			       const struct normalized_coords *unaccelerated,
+			       const struct device_float_coords *unaccelerated,
 			       uint64_t time);
 
 bool
-- 
2.13.6



More information about the wayland-devel mailing list