Skip to content

Commit e3ff84b

Browse files
committed
tslib.c: reduce memory usage
* Read the number of slots to allocate, if available * Use only 10 as fallback devices that *don't* use ABS_MT_SLOT, rarely support many slots * Read only up to 3 samples in one go, if available by tslib more is not realistic for almost all cases. 1 is used for the legacy API For my 5 slots test setup, this reduces memory consumption / moving overhead from 15*5=75 samples to 5*3=15.
1 parent 46f7aa1 commit e3ff84b

File tree

1 file changed

+54
-25
lines changed

1 file changed

+54
-25
lines changed

src/tslib.c

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@
6464
#include <errno.h>
6565
#endif
6666

67-
#define TOUCH_MAX_SLOTS 15
68-
#define TOUCH_SAMPLES_READ 5
67+
#define TOUCH_MAX_SLOTS 10 /* fallback if not found */
68+
#define TOUCH_SAMPLES_READ 3 /* up to, if available */
6969
#define MAXBUTTONS 11 /* > 10 */
7070

7171
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 23
@@ -79,6 +79,8 @@ struct ts_priv {
7979
struct ts_sample last;
8080
ValuatorMask *valuators;
8181
int8_t abs_x_only;
82+
uint16_t slots;
83+
uint32_t *touchids;
8284

8385
#ifdef TSLIB_VERSION_MT
8486
struct ts_sample_mt **samp_mt;
@@ -128,12 +130,11 @@ static void ReadHandleMTSample(InputInfoPtr local, int nr, int slot)
128130
struct ts_priv *priv = (struct ts_priv *) (local->private);
129131
int type;
130132
static unsigned int next_touchid;
131-
static unsigned int touchids[TOUCH_MAX_SLOTS] = {0};
132133
ValuatorMask *m = priv->valuators;
133134

134135
if (priv->last_mt[slot].pressure == 0 && priv->samp_mt[nr][slot].pressure > 0) {
135136
type = XI_TouchBegin;
136-
touchids[slot] = next_touchid++;
137+
priv->touchids[slot] = next_touchid++;
137138
} else if (priv->last_mt[slot].pressure > 0 && priv->samp_mt[nr][slot].pressure == 0) {
138139
type = XI_TouchEnd;
139140
} else if (priv->last_mt[slot].pressure > 0 && priv->samp_mt[nr][slot].pressure > 0) {
@@ -147,7 +148,7 @@ static void ReadHandleMTSample(InputInfoPtr local, int nr, int slot)
147148
valuator_mask_set_double(m, 1, priv->samp_mt[nr][slot].y);
148149
}
149150

150-
xf86PostTouchEvent(local->dev, touchids[slot], type, 0, m);
151+
xf86PostTouchEvent(local->dev, priv->touchids[slot], type, 0, m);
151152
}
152153

153154
static void ReadInputMT(InputInfoPtr local)
@@ -158,14 +159,14 @@ static void ReadInputMT(InputInfoPtr local)
158159

159160
while (1) {
160161
ret = ts_read_mt(priv->ts, priv->samp_mt,
161-
TOUCH_MAX_SLOTS, TOUCH_SAMPLES_READ);
162+
priv->slots, TOUCH_SAMPLES_READ);
162163
if (ret == -ENOSYS) /* tslib module_raw without MT support */
163164
ReadInputLegacy(local);
164165
else if (ret <= 0)
165166
return;
166167

167168
for (i = 0; i < ret; i++) {
168-
for (j = 0; j < TOUCH_MAX_SLOTS; j++) {
169+
for (j = 0; j < priv->slots; j++) {
169170
if (priv->samp_mt[i][j].valid != 1)
170171
continue;
171172

@@ -290,7 +291,7 @@ static int xf86TslibControlProc(DeviceIntPtr device, int what)
290291
}
291292

292293
if (InitTouchClassDeviceStruct(device,
293-
TOUCH_MAX_SLOTS,
294+
priv->slots,
294295
XIDirectTouch,
295296
2 /* axes */) == FALSE) {
296297
xf86IDrvMsg(pInfo, X_ERROR,
@@ -362,8 +363,7 @@ static int xf86TslibInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
362363
struct ts_priv *priv;
363364
char *s;
364365
int i;
365-
struct input_absinfo abs_x;
366-
struct input_absinfo abs_y;
366+
struct input_absinfo absinfo;
367367
#ifdef TSLIB_VERSION_MT
368368
struct ts_lib_version_data *ver = ts_libversion();
369369
#endif
@@ -409,6 +409,8 @@ static int xf86TslibInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
409409
}
410410
#endif
411411

412+
priv->slots = 0;
413+
412414
pInfo->fd = ts_fd(priv->ts);
413415

414416
/* process generic options */
@@ -419,28 +421,53 @@ static int xf86TslibInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
419421
if (!priv->valuators)
420422
return BadValue;
421423

424+
if (ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) {
425+
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT failed");
426+
return BadValue;
427+
}
428+
429+
if (absbit[BIT_WORD(ABS_MT_SLOT)] & BIT_MASK(ABS_MT_SLOT)) {
430+
if (ioctl(pInfo->fd, EVIOCGABS(ABS_X), &absinfo) < 0) {
431+
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOGABS failed");
432+
return BadValue;
433+
}
434+
priv->slots = absinfo.maximum;
435+
} else {
436+
priv->slots = TOUCH_MAX_SLOTS;
437+
}
438+
422439
#ifdef TSLIB_VERSION_MT
423-
priv->samp_mt = malloc(TOUCH_SAMPLES_READ * sizeof(struct ts_sample_mt *));
440+
priv->samp_mt = malloc(priv->slots * sizeof(struct ts_sample_mt *));
424441
if (!priv->samp_mt)
425442
return BadValue;
426443

427444
for (i = 0; i < TOUCH_SAMPLES_READ; i++) {
428-
priv->samp_mt[i] = calloc(TOUCH_MAX_SLOTS, sizeof(struct ts_sample_mt));
445+
priv->samp_mt[i] = calloc(priv->slots, sizeof(struct ts_sample_mt));
429446
if (!priv->samp_mt[i])
430447
return BadValue;
431448
}
432449

433-
priv->last_mt = calloc(TOUCH_MAX_SLOTS, sizeof(struct ts_sample_mt));
434-
if (!priv->last_mt)
450+
priv->last_mt = calloc(priv->slots, sizeof(struct ts_sample_mt));
451+
if (!priv->last_mt) {
452+
for (i = 0; i < TOUCH_SAMPLES_READ; i++)
453+
free(priv->samp_mt[i]);
454+
455+
free(priv->samp_mt);
435456
return BadValue;
457+
}
436458

437-
#endif /* TSLIB_VERSION_MT */
459+
priv->touchids = calloc(priv->slots, sizeof(uint32_t));
460+
if (!priv->touchids) {
461+
for (i = 0; i < TOUCH_SAMPLES_READ; i++)
462+
free(priv->samp_mt[i]);
438463

439-
if (ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0) {
440-
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT failed");
464+
free(priv->samp_mt);
465+
free(priv->last_mt);
441466
return BadValue;
442467
}
443468

469+
#endif /* TSLIB_VERSION_MT */
470+
444471
if (!(absbit[BIT_WORD(ABS_MT_POSITION_X)] & BIT_MASK(ABS_MT_POSITION_X)) ||
445472
!(absbit[BIT_WORD(ABS_MT_POSITION_Y)] & BIT_MASK(ABS_MT_POSITION_Y))) {
446473
if (!(absbit[BIT_WORD(ABS_X)] & BIT_MASK(ABS_X)) ||
@@ -455,27 +482,29 @@ static int xf86TslibInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
455482
}
456483

457484
if (priv->abs_x_only) {
458-
if (ioctl(pInfo->fd, EVIOCGABS(ABS_X), &abs_x) < 0) {
485+
if (ioctl(pInfo->fd, EVIOCGABS(ABS_X), &absinfo) < 0) {
459486
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOGABS failed");
460487
return BadValue;
461488
}
462-
if (ioctl(pInfo->fd, EVIOCGABS(ABS_Y), &abs_y) < 0) {
489+
priv->width = absinfo.maximum;
490+
491+
if (ioctl(pInfo->fd, EVIOCGABS(ABS_Y), &absinfo) < 0) {
463492
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOGABS failed");
464493
return BadValue;
465494
}
466-
priv->width = abs_x.maximum;
467-
priv->height = abs_y.maximum;
495+
priv->height = absinfo.maximum;
468496
} else {
469-
if (ioctl(pInfo->fd, EVIOCGABS(ABS_MT_POSITION_X), &abs_x) < 0) {
497+
if (ioctl(pInfo->fd, EVIOCGABS(ABS_MT_POSITION_X), &absinfo) < 0) {
470498
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOGABS failed");
471499
return BadValue;
472500
}
473-
if (ioctl(pInfo->fd, EVIOCGABS(ABS_MT_POSITION_Y), &abs_y) < 0) {
501+
priv->width = absinfo.maximum;
502+
503+
if (ioctl(pInfo->fd, EVIOCGABS(ABS_MT_POSITION_Y), &absinfo) < 0) {
474504
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOGABS failed");
475505
return BadValue;
476506
}
477-
priv->width = abs_x.maximum;
478-
priv->height = abs_y.maximum;
507+
priv->height = absinfo.maximum;
479508
}
480509

481510
/* Return the configured device */

0 commit comments

Comments
 (0)