Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reducing input latency when working with X

Tags:

I've been reading a few articles about input latency lately:

https://danluu.com/term-latency/

https://pavelfatin.com/typing-with-pleasure/

And I've been trying to improve the user experience of my small text editor. I was using SDL to pool input and create the window, but decided to remove it and do my own X implementation. Application startup has improved, but input latency not so much. Is there any specific technique that can be done to improve how my application picks up mouse and keyboard data from X? Or should I just give up and force Wayland?

I've considered running my XNextEvent() loop on a separate thread, but is that really the only solution for this?

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <math.h> #include <time.h> #include <sys/time.h> #include <X11/Xlib.h> #include <X11/XKBlib.h> #include <GL/glx.h> #include <GL/glext.h> #include <GL/glu.h>  Display *dpy; Window root, win; GLint att[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None}; XVisualInfo *vi; Colormap cmap; XSetWindowAttributes swa; XWindowAttributes wa; XEvent xev; Mask mask;  float TimeCounter, LastFrameTimeCounter, DT, prevTime = 0.0, FPS; struct timeval tv, tv0; int Frame = 1, FramesPerFPS;  void CreateWindow() {   if ((dpy = XOpenDisplay(NULL)) == NULL) {     printf("\n\tcannot connect to x server\n\n");     exit(0);   }    root = DefaultRootWindow(dpy);    if ((vi = glXChooseVisual(dpy, 0, att)) == NULL) {     printf("\n\tno matching visual\n\n");     exit(0);   }    if ((cmap = XCreateColormap(dpy, root, vi->visual, AllocNone)) == 0) {     printf("\n\tcannot create colormap\n\n");     exit(0);   }    swa.event_mask = KeyPressMask;   swa.colormap = cmap;   win = XCreateWindow(dpy, root, 0, 0, 1024, 768, 0, vi->depth, InputOutput,                       vi->visual, CWColormap | CWEventMask, &swa);   XStoreName(dpy, win, "ed");   XMapWindow(dpy, win); }  void Close() {   XDestroyWindow(dpy, win);   XCloseDisplay(dpy);   exit(0); }  int main(int argc, char *argv[]) {   CreateWindow();    while (true) {     mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask;     while (XCheckWindowEvent(dpy, win, mask, &xev) ||            XCheckTypedWindowEvent(dpy, win, ClientMessage, &xev)) {       char *key_string =           XKeysymToString(XkbKeycodeToKeysym(dpy, xev.xkey.keycode, 0, 0));        if (strncmp(key_string, "Escape", 5) == 0) {         Close();       }     }   } } 
like image 215
vinnylinux Avatar asked Apr 27 '18 15:04

vinnylinux


People also ask

How do you reduce input latency?

First, try limiting the frame rate to just under your display's refresh rate. Attempt a higher frame rate. Second, try pushing the game to a much higher frame rate—double the monitor's refresh rate or more. This should lead to a small but noticeable improvement in input lag.

Should low input lag be on or off?

A lower input lag is advantageous because it leads to a snappier feeling when you interact with the display using your mouse or other controller. Monitors will process the image in various ways before outputting it – some models do this more extensively than others.


1 Answers

You can also directly listen the evdev input driver, but then you have to deliver the event to the window by your own implementation.

XNextEvent() in turn converts all the mathematical conversions (from raw events to window based), calculates window in focus and many other things.

I feel XNextEvent() is the only option if you go for simplicity and easy implementation.

like image 62
hkishn Avatar answered Jan 11 '23 11:01

hkishn