QGLPixelbuffer in threads is blocking



  • Hello,
    I am trying to use a QGLPixelbuffer in a multi threaded GL application (X11). My problem with this seems related to this discussion I have found on the web:
    http://stackoverflow.com/questions/8028108/qt-qglwidget-opengl-rendering-from-thread-blocks-on-swapbuffers
    Generally speaking, any GL context I create in another thread than the main thread will block at some time in an arbitrary GL command until any event is triggered. Usually, moving the mouse on top of the gui window works.
    I will post a very stripped down example. Here, in the main thread, I open an empty QWidget and show it, then I create another thread that opens a QGLPixelBuffer and then calls makeCurrent(), doneCurrent() repeatedly and writes dots to the console.
    Expected behaviour:
    console fills up with dots, because makeCurrent() and doneCurrent() do not block.
    Shown behaviour:
    Each call to makeCurrent() locks up (traced down to xcb_wait_event()) until the mouse is moved on top of the Gui Window, which generates events that cause makeCurrent() to unlock and continue.

    Of course calling makeCurrent/doneCurrent here repeatedly does not make much sense but is meant as a minimal example of the effect. In the actual application, it might also hang when creating a texture or drawing a vertex buffer or whatever, but only very seldom.

    If I instead use a glxPBuffer it seems to work as expected.

    I tried Qt4.7 and Qt4.8 on Suse 11.4 and debian testing on different machines with nvidia boards, drivers 295.20 and 290.xy.
    I do not know where the problem is or if I am doing something completely wrong here.
    Any suggestions welcome!

    [edit] I was wrong, it actually works on Debian Testing (wheezy)! It does not work on Suse 11.4 and 12.1, see my other post below.
    [edit2] In the code below, QGLPixelBuffer should be created in the Gui-Thread. This does not help with the problem.

    @#include <QApplication>
    #include <QtOpenGL/QGLPixelBuffer>
    #include <QThread>
    #include <X11/Xlib.h>
    #include <iostream>

    using namespace std;

    class MyThread : public QThread
    {
    public:
    MyThread(QObject *parent = 0) : QThread(parent) { run_=true; start(); };
    virtual ~MyThread() { run_=false; wait(); }
    virtual void run();
    protected:
    bool run_;
    };

    void MyThread::run() {
    QGLFormat format;
    QGLPixelBuffer buffer(5,5, format);

    while (run_) {
    buffer.makeCurrent();
    usleep(10);
    buffer.doneCurrent();
    cout << "." << flush;
    }
    }

    int main(int argc, char *argv[]) {
    QApplication::setAttribute(Qt::AA_X11InitThreads);
    // XInitThreads();
    QApplication app(argc, argv);

    QWidget widget;
    widget.show();
    MyThread thread;
    return app.exec();
    }
    @



  • Hi,
    I have a very similar problem. My setup differs in that I use a normal QGLWidget as base for my threaded renderer, but the hangs are very similar. (Mouse movement and various other kinds of events wake the renderer again.)
    I have found that adding sleeps to the QTimer event handler that triggers my rendering somewhat mitigates the problem, as a rule of thumb if the sleep was about the same length that the rendering itself is (20ms for me) the problem mostly disappears. Sadly I have no clue about why this helps. But since this "fix" highly depends on timing it may not work in a C++ application (I'm using qt from within python)
    Another difference is that i do the XInitThreads() myself since I started my project in qt 4.6 times, but thanks to you I now know that it doesn't matter.
    Since this problem has bugged my application for almost a year now, I'm seriously starting to consider a switch to windows. I tried threaded opengl there once and it simply worked out of the box...
    Regards,
    io-sys

    [edit] one last question, did you manage to embed the results of a glxpbuffer in some kind of QWidget and if yes how?



  • Hi,
    thanks for your reply! I think this is not a Qt bug but might be related to this xcb bug:
    https://bugs.freedesktop.org//attachment.cgi?id=32685
    I dont know if the fix for this is in all the distributions yet, but I tested above code now with Suse 11.4, Suse 12.1 (both blocking) and debian testing. Here I have to correct myself: With a fully updated debian testing the code works without blocking!

    My code using a glxPbuffer would open a new X connection for every buffer whereas the Qt implementation seems to reuse the same connection, triggering the problem with xcb.
    But maybe it is something completely different - I do not know.

    In my example code, the pbuffer should be created in the GUI thread, but that does not change the behaviour.

    To use the content of your glxpbuffer in a QWidget you could use glreadpixels to read the content to an image for example. If you use the glxpbuffer as an offscreen context only you could render to framebuffers and use the resulting textures in your widgets.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.