#include WarningEmitter* warningEmitter; void EngineThread::glDebugMessageLogged(QOpenGLDebugMessage message) { emit warningEmitter->onWarning(message.message()); } EngineThread::EngineThread(QSurfaceFormat* format, QOffscreenSurface* surface) : format(format) , surface(surface) { start(); } void EngineThread::run() { sleep(1); context = new QOpenGLContext(); context->setFormat(*format); if (!context->create()) { emit warningEmitter->onWarning("OpenGL context creating failure."); return; } if (!context->makeCurrent(surface)) { emit warningEmitter->onWarning("OpenGL context making current failure."); return; } if (!context->hasExtension("GL_KHR_debug")) { emit warningEmitter->onWarning("GL_KHR_debug is not available: OpenGL debug logger is disabled."); return; } f = context->extraFunctions(); f->initializeOpenGLFunctions(); logger = new QOpenGLDebugLogger(); logger->initialize(); connect(logger, SIGNAL(messageLogged(QOpenGLDebugMessage)), this, SLOT(glDebugMessageLogged(QOpenGLDebugMessage)), Qt::ConnectionType::DirectConnection); logger->startLogging(QOpenGLDebugLogger::LoggingMode::SynchronousLogging); emit warningEmitter->onWarning("OpenGL has inited! Let's do an OpenGL error, which DOESN'T cause a GUI deadlock."); f->glDrawArrays(GL_QUADS, 0, 3); // this doesn't cause a deadlock emit warningEmitter->onWarning("Let's do another OpenGL error, which DOESN'T cause a GUI deadlock."); f->glLinkProgram(1); // this doesn't cause a deadlock emit warningEmitter->onWarning("Now let's do an OpenGL error, which causes a GUI deadlock."); f->glTexStorage2D(GL_TEXTURE_2D, 0, GL_BGRA, 64, 64); // this causes a deadlock emit warningEmitter->onWarning("The message I can not see due to the GUI deadlock."); } void MainWindow::onWarningSlot(QString message) { qDebug() << "Warning: " << message; QMessageBox::warning(nullptr, "Warning", message); } MainWindow::MainWindow() { connect(warningEmitter, SIGNAL(onWarning(QString)), this, SLOT(onWarningSlot(QString)), Qt::BlockingQueuedConnection); auto format = new QSurfaceFormat(); format->setAlphaBufferSize(8); format->setRedBufferSize(8); format->setGreenBufferSize(8); format->setBlueBufferSize(8); format->setDepthBufferSize(24); format->setStencilBufferSize(8); format->setSwapInterval(1); format->setStereo(false); format->setSamples(1); format->setRenderableType(QSurfaceFormat::RenderableType::OpenGL); format->setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); format->setSwapBehavior(QSurfaceFormat::SwapBehavior::SingleBuffer); format->setMajorVersion(3); format->setMinorVersion(1); format->setOptions(QSurfaceFormat::FormatOption::DebugContext); auto surface = new QOffscreenSurface(); surface->setFormat(*format); surface->create(); EngineThread* engine = new EngineThread(format, surface); } void main(int argc, char** argv) { warningEmitter = new WarningEmitter(); QApplication app(argc, argv); MainWindow mainWindow; mainWindow.show(); app.exec(); }