diff mbox

input: Introduce light-weight contact tracking

Message ID 4CD724BC.8020702@seas.upenn.edu (mailing list archive)
State New, archived
Headers show

Commit Message

Rafi Rubin Nov. 7, 2010, 10:14 p.m. UTC
None
diff mbox

Patch

different.

- efficient for the common case where contact ordering stays consistent
- arbitrary number of contacts
- motion estimation to improve tracking
- leveraging tracking for error filtering

Also for fun, I was playing with smoothing in this particular version of the code.

For now, I'm sending this just for review and discussion.

Rafi

---
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index 69169ef..d163b9b 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -19,10 +19,25 @@ 
  #include "usbhid/usbhid.h"
  #include <linux/module.h>
  #include <linux/slab.h>
+#include <linux/list.h>

  #include "hid-ids.h"

  #define NTRIG_DUPLICATE_USAGES	0x001
+/**
+ * list_rotate_left - rotate the list to the left
+ * @head: the head of the list
+ */
+static inline void list_rotate_right(struct list_head *head)
+{
+	struct list_head *last;
+
+	if (!list_empty(head)) {
+		last = head->prev;
+		list_move(last, head);
+	}
+}
+

  static unsigned int min_width;
  module_param(min_width, uint, 0644);
@@ -52,10 +67,45 @@  module_param(activation_height, uint, 0644);
  MODULE_PARM_DESC(activation_height, "Height threshold to immediately start "
  		 "processing touch events.");

+struct ntrig_slot {
+	__u16 id;
+	struct list_head list;
+};
+
+struct ntrig_contact {
+	__u16 x, y, w, h;
+	__s16 est_x_min, est_x_max, est_y_min, est_y_max;
+	__s16 dx, dy;
+	__s16 id;
+
+	/* An age factor for counting frames since a track was last seen.
+	 * This enables drop compensation and delayed termination. */
+	__u8 inactive;
+
+	struct ntrig_slot *slot;
+
+	struct list_head list;
+
+	/* List of tracks sorted by first seen order */
+	struct list_head active_tracks;
+};
+
+struct ntrig_frame {
+
+	/* Items that represent physical contacts which have been mapped
+	 * to contacts from previous frames. */
+	struct list_head tracked;
+
+	/* Contacts that have yet to be matched and might be ghosts. */
+	struct list_head pending;
+	struct list_head list;
+};
+
  struct ntrig_data {
  	/* Incoming raw values for a single contact */
  	__u16 x, y, w, h;
  	__u16 id;
+	int slots;

  	bool tipswitch;
  	bool confidence;
@@ -63,6 +113,8 @@  struct ntrig_data {

  	bool reading_mt;

+	__u8 max_contacts;
+
  	__u8 mt_footer[4];
  	__u8 mt_foot_count;

@@ -87,8 +139,24 @@  struct ntrig_data {
  	__u16 sensor_logical_height;
  	__u16 sensor_physical_width;
  	__u16 sensor_physical_height;
-};

+	__u16 r_y;
+	__u16 r_x;
+
+	/* Circular list of frames used to maintain state of contacts */
+	struct list_head frames;
+
+	/* Contacts representing the last input from lost tracks and
+	 * old contacts to be recycled */
+	struct list_head old_contacts;
+
+	struct list_head available_slots;
+	struct list_head active_tracks;
+
+	struct ntrig_frame *first_frame;
+	struct ntrig_slot *first_slot;
+	struct ntrig_contact *first_contact;
+};

  /*
   * This function converts the 4 byte raw firmware code into
@@ -439,6 +507,7 @@  static int ntrig_input_mapping(struct hid_device *hdev, 
struct hid_input *hi,
  	case HID_UP_GENDESK:
  		switch (usage->hid) {
  		case HID_GD_X:
+			nd->max_contacts++;
  			hid_map_usage(hi, usage, bit, max,
  					EV_ABS, ABS_MT_POSITION_X);