Commit 937e6031 authored by Peter Hutterer's avatar Peter Hutterer

touchpad: drop the double normalization

Previously, touchpad deltas were converted to 1000-dpi normalized coordinates
and handled from there. This changed in bdd4264d (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's avatarPeter Hutterer <peter.hutterer@who-t.net>
parent f5a9e38c
......@@ -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:
......
......@@ -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;
d = tp_get_delta(t);
delta.x += normalized.x;
delta.y += normalized.y;
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, &raw, time);
delta = tp_filter_motion(tp, &unaccel, time);
if (!normalized_is_zero(delta) || !device_float_is_zero(raw)) {
struct device_float_coords unaccel;
if (!normalized_is_zero(delta) || !normalized_is_zero(unaccel)) {
raw = tp_unnormalize_for_xaxis(tp, 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,
......
......@@ -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)
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment