【问题标题】:Multithreaded X11 application and OpenGL多线程 X11 应用程序和 OpenGL
【发布时间】:2011-06-19 12:56:27
【问题描述】:

我正在尝试使用 libx11 创建一个多线程 opengl 应用程序 - 每个窗口有一个单独的线程和一个管理器线程。

我在管理线程中有一个事件循环:

while(true)
  while(XQLength(mPlatformData->display)){
    XNextEvent(mPlatformData->display, &event);
    std::cout << "event" << std::endl;
  }
}

对于单线程应用程序来说,这是一个很棒的事件循环,但是在这种多线程设置中会发生奇怪的事情。

当我创建一个窗口时,我需要禁用事件队列,否则 GLXMakeCurrent 将挂起 - 我的整个线程停止,并且什么也不做。

我在网上找不到太多关于多线程 X11 应用程序的信息,我应该以不同的方式处理我的事件吗?

【问题讨论】:

  • 我猜 X11 和 OpenGL 是线程不安全的。
  • 如果我使用一个上下文/线程,GL 是线程安全的。而且根据 X11 文档,如果我先调用 XInitThreads() 应该是安全的,我做什么。

标签: multithreading opengl thread-safety x11


【解决方案1】:

众所周知,Xlib 有几个无法修复的运行时问题,这些问题体现在并发访问的情况下。我猜你正好遇到了其中之一。

这是最初创建 Xcb 的原因之一:修复 Xlib 的问题。 GLX 是针对 Xlib 指定的,因此当涉及到 OpenGL 时,这可能看起来像是一个阻碍。然而,Xcb 周围有一个 Xlib,人们可以安全地使用它来与 GLX 接口,并且仍然在程序的其余部分使用 Xcb:http://xcb.freedesktop.org/opengl/

我看到了两种可能的解决方案:

  1. XNextEvent 周围放置一个XLockDisplay/Mutex,GLX 会分别调用;你不必锁定普通的OpenGL,只需glX...前缀的函数。

  2. 使用 Xcb 获得运行时正确的行为,并按照我上面链接的指南使其与 OpenGL/GLX 一起使用。

【讨论】:

  • 我实现了第一个解决方案作为快速修复,但我希望有更好的解决方案,我会尝试第二个。
【解决方案2】:

正如 eile 所说,您应该检查您是否使用了 XInitThreads。

当我使用后台线程来绘制动画的窗口时,我能够从中获得一些不错的结果。如果你坚持绘制代码似乎没有真正的问题。

如果您需要更多,并且因为您使用的是低级 libX11,最好只打开多个 X11 连接并在每个顶层窗口使用一个连接。 10 年前,我在开发 BeOS 跨平台工具包时这样做了,当时一切都处于更糟糕的状态,然后就是现在。

您甚至可以将它用于事件处理和顶层的子窗口。但这需要一些非常棘手的 XEvent 掩码代码。

【讨论】:

  • 我正在使用 XInitThreads,但这还不够。而且我不能使用多个 Display 连接,因为我不能在它们之间共享 GLXContext。
【解决方案3】:

您在渲染线程中做什么?在任何情况下,如果您在不同的线程之间共享一个 Display* 连接,您必须调用 XInitThreads。

我在每个线程一个显示连接方面取得了很好的经验。使用 XSelectInput 获取主线程上的事件。窗口 ID 可在不同的 Display* 连接之间共享。

【讨论】:

  • 为 OP 发言:OP 了解 XInitThreads,请参阅他对问题的评论。打开一个额外的Display* 连接是处理这个问题的一种方法。不幸的是,它消耗了一种稀有的资源:连接。不幸的是,当前形式的 X11 服务器一次只支持相当少量的连接(客户端)(介于 256 到 1024 之间);所以如果每个进程的线程都打开一个自己的显示连接,你很快就会用完连接槽。
  • 多个显示连接不能共享 GLXContexts - 或者我无法让它们工作。
  • @Dutow:只有当涉及的上下文是间接渲染上下文时,您才能在不同连接之间共享 GLXContexts,即直接 = false 调用opengl.org/sdk/docs/man/xhtml/glXCreateContext.xml
  • 我们在均衡器分布 (eqAsync) 中有一个示例,它在第二个线程中为每个 GPU 打开一个显示连接和一个额外的共享上下文以上传 GL 纹理。 Afaik 这是使用 glX - 因此我的问题是你在第二个线程中做什么。代码在这里:github.com/Eyescale/Equalizer/tree/master/examples/eqAsync
猜你喜欢
  • 1970-01-01
  • 2015-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多