Qt5 OpenGL context question



  • Hi Qt

    I've succesfully managed to create several multithreaded QOpenGLContext's, and performed non-blocking calls to these contexts which showed the required results in the QWindow. Running my application on multiple platforms i encountered some differences and wanted to ask the experts :).

    Question 1: On windows i first have to create a QWindow, and show this. Then create the several QWindows/QOpenGLContext's and bind them (makeCurrent). If i don't create the first window without a context bound to it i only get one QOpenGLContext
    and the other's give the following error message: QWindowsEGLContext: eglError: 3005, this: 0x85766c67f0

    Question 2: All rendering goes fine i do however get a debug message on windows:
    QOpenGLContext::swapBuffers() called without corresponding makeCurrent()
    which to me is a bit strange since i'm performing my work in a dedicated thread, no need to makeCurrent (expensive call).

    The snippet, in a nutshell create x contexts/windows bind them an render stuff. After some time destory contexts/qwindows

    p.s all calls are made in the respectively contexts thread, no issues there.

    typedef std::unique_ptr<ximu::GlContext> CTX_TYPE;
    typedef std::unique_ptr<QWindow> WINDOW_TYPE;
    typedef std::tuple<CTX_TYPE,WINDOW_TYPE> DATA_TYPE;
    
    int main(int argc, char *argv[])
    {
        // Main Application
        QGuiApplication a(argc, argv);
    
        QWindow t; // <---- Question 1
        t.show();
    
        // Generate a some Contexts with QWindows
        std::vector<DATA_TYPE> data;
        for (size_t idx = 0; idx != 5; ++idx)
            data.push_back(
                     std::move(std::make_tuple(
                            CTX_TYPE(new ximu::GlContext()), 
                            WINDOW_TYPE(new QWindow)))
            );
    
        // Initialize
        for(auto& d : data)
        {
           std::get<0>(d)->create();
           std::get<1>(d)->setSurfaceType(QWindow::OpenGLSurface);
           std::get<1>(d)->show();
        }
    
        // Assume application runtime
        size_t numCalls = 1000;
        size_t calls = numCalls;
        std::thread closer( [&] {
            while(--calls  > 0)
            {
                std::this_thread::sleep_for(std::chrono::milliseconds(50));
                if (calls == (numCalls - 10))
                {
                    for(auto& d : data){
                        // attach Surface to Context
                        std::get<0>(d)->makeCurrent(std::get<1>(d).get());
                        // attach some renderer
                        std::get<0>(d)->add(std::shared_ptr<ximu::IGlRenderer>(new SmoothRenderer));
                   }
                }
            }
            // Destroy context, close window
            for(auto& d : data)
            {
              std::get<0>(d)->destroy();
              QMetaObject::invokeMethod(std::get<1>(d).get(), "close", Qt::QueuedConnection);
            }
             QMetaObject::invokeMethod(&t, "close", Qt::QueuedConnection);
        });
        auto retcode =  a.exec();
        closer.join();
        return retcode;
    }
    

    full source on Context and Application

    kind Regards Auke-Dirk


Log in to reply
 

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