Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
QOpenGLFunctions in Docker (headless OpenGL)
We have a QT-based application and we would like to run it in Docker without
xvfband without showing GUI. We want to create a headless mode, but if possible, we want to avoid dependency on
Approach #1: First, we tried simply by setting the
QT_QPA_PLATFORMenvironment variable to
offscreen. Although this hides the GUI on my PC it fails to create
QOpenGLContext *context = new QOpenGLContext(); QOpenGLFunctions *gl = context->functions(); // Shows warning: "QOpenGLFunctions created with non-current context"
Approach #2: Then, we tried to initialize OpenGL context (without QT) according to the following two articles:
And it works! It works in Docker and on my machine. We are able to use
gl*functions without the display in Docker. Here are some details:
GL_VENDOR=Mesa/X.org GL_VERSION=3.3 (Compatibility Profile) Mesa 20.2.6 GL_RENDERER=llvmpipe (LLVM 11.0.0, 256 bits) GL_SHADING_LANGUAGE_VERSION=4.50
Approach #3: Therefore, we tried to use our working EGL context to create
QOpenGLContext *context = new QOpenGLContext; context->setNativeHandle(QVariant::fromValue(QEGLNativeContext(ourEglContext, ourEglDisplay))); QOpenGLFunctions *gl = context->functions(); // Shows warning: "QOpenGLFunctions created with non-current context"
But again, although it works fine on my PC I get the same warning in Docker.
Do you have any suggestions? Does it make sense that we create a custom platform similar to the
offscreen, or there is a simpler solution?
It's outside my normal zone but Im wondering
if approach 3 is just missing
Again, its not something i have much experience with but i used Qt to render
openGL mesh to images as a command line tool. Not exactly headless nor in docker
but no harm in mentioning it.
Hi, thank you for the suggestion. You mean something like this:
QOpenGLContext *context = new QOpenGLContext; context->setNativeHandle(QVariant::fromValue(QEGLNativeContext(eglCtx, eglDpy))); QOffscreenSurface *surface = new QOffscreenSurface(); surface->setFormat(context->format()); context->makeCurrent(surface); context->create(); QOpenGLFunctions *gl = context->functions(); // <-- Shows the same warning
But I am getting the same warning. Maybe I am missing something?
But can you check if makeCurrent returns true or false ?
lukicdarkoo last edited by
@mrjj Oh, it returns
false. I will need some time to figure out why it returns
@mrjj I was calling the
create. Here is the fixed version:
QGuiApplication a(argc, argv); QOpenGLContext context; context.create(); assert(context.isValid()); // <----- fails here QOffscreenSurface surface; surface.create(); assert(surface.isValid()); context.makeCurrent(&surface); QOpenGLFunctions *gl = context.functions(); qDebug() << "Version: " << QString::fromLatin1((const char *)gl->glGetString(GL_VERSION)); qDebug() << "Renderer: " << QString::fromLatin1((const char *)gl->glGetString(GL_RENDERER));
But it also fails to create the OpenGL context in Docker. With
xvfb-runand on my PC it works fine though.
Hi and welcome to devnet,
Did you try to use the eglfs backend ? Since the Nvdia documentation mentions egl as system to use so you do not need an X server running.