Unsolved 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: 0x85766c67f0Question 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