c++ - reaper - Reduciendo la latencia de entrada cuando se trabaja con X
lexicon lambda latencia (1)
También puede escuchar directamente el controlador de entrada evdev, pero luego debe enviar el evento a la ventana mediante su propia implementación.
XNextEvent()
a su vez convierte todas las conversiones matemáticas (de eventos en bruto a ventanas), calcula la ventana en foco y muchas otras cosas.
Siento que XNextEvent()
es la única opción si XNextEvent()
por la simplicidad y la fácil implementación.
He estado leyendo algunos artículos sobre la latencia de entrada últimamente:
https://danluu.com/term-latency/
https://pavelfatin.com/typing-with-pleasure/
Y he estado tratando de mejorar la experiencia de usuario de mi pequeño editor de texto. Estaba usando SDL para agrupar las entradas y crear la ventana, pero decidí eliminarlo y hacer mi propia implementación de X. El inicio de la aplicación ha mejorado, pero la latencia de entrada no tanto. ¿Existe alguna técnica específica que se pueda hacer para mejorar la forma en que mi aplicación recoge los datos del mouse y el teclado de X? ¿O debería simplemente rendirme y forzar a Wayland?
He considerado ejecutar mi bucle XNextEvent () en un subproceso separado, pero ¿es realmente la única solución para esto?
#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();
}
}
}
}