如何在Wayland中使用glutSwapBuffers进行同步?

The*_*Vee 7 c++ linux opengl freeglut wayland

我注意到我的动画遭受了看起来像遗漏的vblank的伪影。没有可见的撕裂,但有时框架停顿了一秒钟,然后明显跳动。我决定测量两次缓冲区交换之间的时间:

void draw_cb() {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glutSwapBuffers();
  static auto last = std::chrono::high_resolution_clock::now();
  auto now = std::chrono::high_resolution_clock::now();
  std::cout
    << std::chrono::duration_cast<std::chrono::microseconds>(now - last).count()/1000.
    << '\n';
  last = now;
}
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,即使在这种完全不需要的程序中,我也看到时间相差高达1.5毫秒。帧之间测得的时间在16.6毫秒附近,但在较高端则始终如一:

在此处输入图片说明

如果我usleep在绘制回调中添加了几毫秒(显然不超过16毫秒),则没有任何变化,这确认不是导致延迟响应而是等待vsync的绘制命令。为什么然后我看不到非常接近16.666毫秒的值?我还能采取什么其他措施使动画流畅?我确定我的计算机足够快。

这是我设置的相关部分freeglut

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
    glutDisplayFunc(draw_cb);
    glutIdleFunc(glutPostRedisplay);
Run Code Online (Sandbox Code Playgroud)

我还尝试将draw回调放入glutIdleFunc,没有区别。

环境是Wayland上的Linux + Gnome 3集成图形。平均负载远低于1。仔细观察,glxgears表现出相似的行为,默认设置下5秒钟内达到约291帧。

更新资料

在评论员的大力帮助下,我现在可以说这是由于编写者造成的。在没有Wayland中间层的X上运行,我得到了更加清晰和居中的分布:

因此,问题仅针对Wayland(或者Wayland上的Gnome3)。但是,问题仍然没有改变:如何在此设置中以最小的变化获得平滑的动画?如果某种程度上不合适,我可以放开freeglut,但是我希望同样简单的事情也能解决,如果可能的话,我希望保留一个经过修饰的托管窗口。我更新了标题。