在多台显示器上使用 GLX RHEL -- OpenGL、XLib 和多台显示器(带线程)

Posted

技术标签:

【中文标题】在多台显示器上使用 GLX RHEL -- OpenGL、XLib 和多台显示器(带线程)【英文标题】:Using GLX on Multiple Monitors RHEL -- OpenGL, XLib, and Multiple Monitors (with threads) 【发布时间】:2012-02-27 21:01:31 【问题描述】:

我面临的问题是我有一个基于 glx 的应用程序,它可以很好地在单个线程上呈现基本原语。我可以在两个屏幕之间移动 XWindow,并且我的渲染循环继续进行。但是,如果我的应用程序的任何部分都有线程,即使它没有进行任何 openGL 调用或触摸任何其他线程上的 XWindow,但当我将 XWindow 从一个屏幕移动到另一个屏幕时,我渲染的图形的主线程会丢失。

我做的第一个函数调用是 XInitThreads,所以我知道 X11 应该是线程安全的。正如我所说,这在一个线程上绘制基元时有效,但当我添加 1 个或多个线程时它不起作用。线程位于我无权访问源的库中。我只是被要求使用 X11 创建代码的窗口部分。

我应该寻找什么来解决这个问题?

另外请注意,我已经保证所有 glcalls 都发生在我从库中调用它们的线程上。


更新

[matt6809@hogganz400 SampleApp]$ cat /etc/X11/xorg.conf && echo "--------" && xrandr --verbose && echo "-------" && glxinfo && echo "-------" && xdpyinfo
# nvidia-settings: X configuration file generated by nvidia-settings
# nvidia-settings:  version 295.20  (buildmeister@swio-display-x86-rhel47-05.nvidia.com)  Mon Feb  6 22:13:16 PST 2012

# nvidia-xconfig: X configuration file generated by nvidia-xconfig
# nvidia-xconfig:  version 295.20  (buildmeister@swio-display-x86-rhel47-05.nvidia.com)  Mon Feb  6 22:13:40 PST 2012

Section "ServerLayout"
    Identifier     "Layout0"
    Screen      0  "Screen0" 0 0
    Screen      1  "Screen1" RightOf "Screen0"
    InputDevice    "Keyboard0" "CoreKeyboard"
    InputDevice    "Mouse0" "CorePointer"
    Option         "Xinerama" "1"
EndSection

Section "Files"
    FontPath        "/usr/share/fonts/default/Type1"
EndSection

Section "InputDevice"

    # generated from default
    Identifier     "Mouse0"
    Driver         "mouse"
    Option         "Protocol" "auto"
    Option         "Device" "/dev/input/mice"
    Option         "Emulate3Buttons" "no"
    Option         "ZAxisMapping" "4 5"
EndSection

Section "InputDevice"

    # generated from data in "/etc/sysconfig/keyboard"
    Identifier     "Keyboard0"
    Driver         "kbd"
    Option         "XkbLayout" "us"
    Option         "XkbModel" "pc105"
EndSection

Section "Monitor"
    Identifier     "Monitor0"
    VendorName     "Unknown"
    ModelName      "DELL P190S"
    HorizSync       30.0 - 81.0
    VertRefresh     56.0 - 76.0
    Option         "DPMS"
    EndSection

    Section "Monitor"
        Identifier     "Monitor1"
        VendorName     "Unknown"
 ModelName      "DELL P190S"
    HorizSync       30.0 - 81.0
    VertRefresh     56.0 - 76.0
    Option         "DPMS"
EndSection

Section "Monitor"
    Identifier     "Monitor1"
    VendorName     "Unknown"
    ModelName      "DELL 1908FP"
    HorizSync       31.0 - 83.0
    VertRefresh     56.0 - 76.0
EndSection

Section "Device"
    Identifier     "Device0"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    BoardName      "Quadro 4000"
    BusID          "PCI:15:0:0"
    Screen          0
EndSection

Section "Device"
    Identifier     "Device1"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    BoardName      "Quadro 4000"
    BusID          "PCI:15:0:0"
    Screen          1
EndSection

Section "Screen"
    Identifier     "Screen0"
    Device         "Device0"
    Monitor        "Monitor0"
    DefaultDepth    24
    Option         "TwinView" "0"
    Option         "TwinViewXineramaInfoOrder" "DFP-0"
    Option         "metamodes" "DFP-0: nvidia-auto-select +0+0"
    SubSection     "Display"
        Depth       24
    EndSubSection
EndSection

Section "Screen"
    Identifier     "Screen1"
    Device         "Device1"
    Monitor        "Monitor1"
    DefaultDepth    24
    Option         "TwinView" "0"
    Option         "metamodes" "DFP-2: nvidia-auto-select +0+0"
    SubSection     "Display"
        Depth       24
    EndSubSection
EndSection

--------
Xlib:  extension "RANDR" missing on display ":0.0".
RandR extension missing
[matt6809@hogganz400 SampleApp]$ 

【问题讨论】:

【参考方案1】:

这只是一种预感,但可能是,OpenGL 上下文没有在线程之间干净地迁移。如果您完全控制 OpenGL 和窗口操作,您的问题并不清楚。

涉及 OpenGL 和多线程的常用方法是将所有 OpenGL 操作限制在一个特定线程中。

如果你不能确定这一点,你应该打电话

glXMakeContextCurrent(display, None, None, NULL); // GLX 1.3

glXMakeCurrent(display, None, NULL); // GLX 1.2 and earlier

在屈服于另一个线程之前完成 OpenGL 操作或完成 tasklet 以确保上下文与当前线程正确解除绑定。

在需要时相应地重新绑定上下文。

【讨论】:

我唯一可以简单地做到这一点的地方是在调用 swapbuffers 之后。我这样做无济于事。我确实可以控制设备的创建以及 glxMakeCurrent 和 glxSwapBuffers 函数。在我调用图书馆进行绘图之前,我会在绘图周围调用这些。此外,当调用 draw 时,我被承诺所有 gl 调用都是在您调用 draw 的线程上进行的。我的绘图调用在主线程上。 此外,当 XWindow 从一个屏幕拖到另一个屏幕时,所有 2 X (#CPUs) + 1 个线程都位于 pthread_cond_wait @MatthewHoggan:您的系统设置是什么(使用的 GPU、xorg.conf[.d] 输出的xrandr --verboseglxinfoxdpyinfo)? 我运行了指定的命令并将它们作为更新发布。让我知道我是否可以为您提供任何其他帮助。 @MatthewHoggan:由于您将命令与&& 链接在一起,因此失败的 xrandr 会阻止进一步执行。请改用简单的;。但我已经看到了一些东西:你已经启用了 Xinerama,这与 NVidia 的 TwinView 不兼容,后者带来了自己的 Xinerama 协议仿真。所以作为第一次测试,在服务器布局中切换Xinerama并再次测试。这也意味着只配置一个设备,现在配置两个,并使用 TwinView MetaModes。【参考方案2】:

我认为它必须是 GL 上下文。当您从一个屏幕移动到另一个屏幕时,您应该切换到具有该(新)显示的 GL 上下文。使用暴露事件来选择其他上下文。也就是说,创建两个上下文并使用 glxMakeCurrent(xdisplay,xwindow,xglcontext)。其中 xdisplay 是新的显示,而 xglcontext 将是另一个上下文)

【讨论】:

以上是关于在多台显示器上使用 GLX RHEL -- OpenGL、XLib 和多台显示器(带线程)的主要内容,如果未能解决你的问题,请参考以下文章

QXcbIntegration:无法创建平台 OpenGL 上下文,GLX 和 EGL 均未启用

glm glx 旋转不起作用

openGL glx.h 缺少表单 xcode 4 mac lion

无法在 RHEL 上打开显示

Ansible(二)如何在多台主机上批量执行任务

如何一台电脑接多台显示器,且只用一套鼠标键盘操作