减少与X一起工作时的输入延迟

24

最近我看了一些关于输入延迟的文章:

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

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

我一直在努力改善我的小型文本编辑器的用户体验。我曾经使用SDL来池化输入并创建窗口,但决定将其删除并自己实现X。应用程序启动速度有所提高,但输入延迟没有太大改善。有没有特定的技术可以改善我的应用程序如何从X捕获鼠标和键盘数据?或者我应该放弃X并强制使用Wayland吗?

我考虑将我的XNextEvent()循环运行在一个单独的线程上,但这真的是唯一的解决方案吗?

#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();
      }
    }
  }
}

1
一个令人惊讶的反直觉的方法来减少延迟是在渲染循环中尽可能晚地处理输入。我们无法看到您的输入代码如何与您的渲染代码交互,因此很难确定这是否会对您有所帮助... - user4442671
2
请尝试使用select()。https://www.linuxquestions.org/questions/linux-software-2/xnextevent-non-blocking-equivalent-in-xlib-195337/ - sailfish009
1个回答

1
你也可以直接监听evdev输入驱动程序,但是这样你就需要通过自己的实现将事件传递到窗口。
XNextEvent()则会转换所有的数学计算(从原始事件到基于窗口的计算),计算当前焦点窗口以及其他许多事情。
我认为XNextEvent()是选择简单和易于实现的唯一选项。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接