On 06/09/2011 09:57 PM, Daniel Stone wrote: > From: Derek Foreman <[email protected]> > > Use a smarter motion estimator that attempts to draw a best-fit line > through the history where possible, including taking acceleration into > account. > > Signed-off-by: Derek Foreman <[email protected]> > Reviewed-by: Daniel Stone <[email protected]> Thanks git someone improved that pile'o'junk!
Reviewed-by: Simon Thum <[email protected]> (I have a few comments though.) > --- > src/synaptics.c | 76 > +++++++++++++++++++++++++++++++++++++++++++++++++------ > 1 files changed, 68 insertions(+), 8 deletions(-) > > diff --git a/src/synaptics.c b/src/synaptics.c > index 8a6d56e..fb37030 100644 > --- a/src/synaptics.c > +++ b/src/synaptics.c > @@ -1689,6 +1689,8 @@ store_history(SynapticsPrivate *priv, int x, int y, > unsigned int millis) > priv->move_hist[idx].y = y; > priv->move_hist[idx].millis = millis; > priv->hist_index = idx; > + if (priv->count_packet_finger < SYNAPTICS_MOVE_HISTORY) > + priv->count_packet_finger++; > } > > /* > @@ -1777,6 +1779,63 @@ get_edge_speed(SynapticsPrivate *priv, const struct > SynapticsHwState *hw, > } > } > > +/* > + * Fit a line through the three most recent points in the motion > + * history and return relative co-ordinates. > + * > + * Three forms of filtering are present: > + * Acceleration - pointer accelerating too fast > + * Jerk - too great a change in pointer acceleration At this stage, perhaps it's better to talk about fingers or touch points. Pointer acceleration, I can assure, has no way of interfering here. It's all the more ambiguous since synaptics actually interacts with the server's pointer acceleration. > + * Error - hw state deviates too much from the predicted position > + * > + * Note - The current state is used for filtering, but only its time is used > + * in the delta calculation > + */ > + > +static void regress(SynapticsPrivate *priv, const struct SynapticsHwState > *hw, > + double *dx, double *dy) > +{ > + const SynapticsParameters *pars = &priv->synpara; > + int i, j; > + double ym = 0, xm = 0, tm = 0; > + double yb1n = 0, xb1n = 0, b1d = 0, xb1, yb1; > + double dista, distb, distc, vela, velb, velc, acca, accb, jerk; > + > + if (priv->count_packet_finger == 1) { > + *dx = hw->x - HIST(0).x; > + *dy = hw->y - HIST(0).y; > + return; > + } > + > + /* Determine the best fit line through the 3 most recent history entries > */ > + for (i = 0; i < MIN(priv->count_packet_finger, 3); i++) { > + ym += HIST(i).y; > + xm += HIST(i).x; > + tm += HIST_DELTA(i, 0, millis); > + } > + ym /= priv->count_packet_finger; > + tm /= priv->count_packet_finger; > + xm /= priv->count_packet_finger; > + > + for (i = 0; i < MIN(priv->count_packet_finger, 3); i++) { > + double t = HIST_DELTA(i, 0, millis); > + yb1n += (t - tm) * (HIST(i).y - ym); > + xb1n += (t - tm) * (HIST(i).x - xm); > + b1d += (t - tm) * (t - tm); > + } > + xb1 = xb1n/b1d; > + yb1 = yb1n/b1d; > + > + *dx = xb1 * (hw->millis - HIST(0).millis); > + *dy = yb1 * (hw->millis - HIST(0).millis); > + return; > + > +filtered: > + *dx = 0; > + *dy = 0; > + priv->count_packet_finger = 0; > +} > + > static void > get_delta(SynapticsPrivate *priv, const struct SynapticsHwState *hw, > edge_type edge, double *dx, double *dy) > @@ -1787,10 +1846,11 @@ get_delta(SynapticsPrivate *priv, const struct > SynapticsHwState *hw, > double tmpf; > int x_edge_speed = 0; > int y_edge_speed = 0; > + Bool outlier = FALSE; > > /* HIST is full enough: priv->count_packet_finger > 3 */ > - *dx = estimate_delta(hw->x, HIST(0).x, HIST(1).x, HIST(2).x); > - *dy = estimate_delta(hw->y, HIST(0).y, HIST(1).y, HIST(2).y); > + > + regress(priv, hw, dx, dy); > > if ((priv->tap_state == TS_DRAG) || para->edge_motion_use_always) > get_edge_speed(priv, hw, edge, &x_edge_speed, &y_edge_speed); > @@ -1847,19 +1907,19 @@ ComputeDeltas(SynapticsPrivate *priv, const struct > SynapticsHwState *hw, > } > > /* to create fluid edge motion, call back 'soon' > - * even in the absence of new hardware events */ > + * even in the absence of new hardware events > + * Note: This should be longer that the device report rate! > + */ > delay = MIN(delay, POLL_MS); > > - if (priv->count_packet_finger <= 3) /* min. 3 packets, see get_delta() */ > - goto skip; /* skip the lot */ > + if (priv->count_packet_finger < 1) /* min. 1 packet, see regress() */ > + goto out; /* skip the lot */ > > if (priv->moving_state == MS_TRACKSTICK) > get_delta_for_trackstick(priv, hw, &dx, &dy); > else if (moving_state == MS_TOUCHPAD_RELATIVE) > get_delta(priv, hw, edge, &dx, &dy); > > -skip: > - priv->count_packet_finger++; > out: > priv->prevFingers = hw->numFingers; > > @@ -2594,7 +2654,7 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState > *hw, CARD32 now, > priv->lastButtons = buttons; > > /* generate a history of the absolute positions */ > - if (inside_active_area) > + if (inside_active_area && actual) > store_history(priv, hw->x, hw->y, hw->millis); I sounds good but seems to belong somewhere else. _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
