path: root/src/opengl/qgl.cpp
diff options
authorSamuel Rødal <>2012-11-26 12:57:09 +0100
committerThe Qt Project <>2012-11-30 18:28:04 +0100
commit6385a182f0f93820c96cf274e50a56492491ee10 (patch)
tree5772f4c8570e620448e3ab7473c9e2df5af4005a /src/opengl/qgl.cpp
parent3ee48926e6584b4afeda1fc406d19d7b1a8d6f20 (diff)
Added explicit threading API to QtOpenGL.
Since QtOpenGL/QGLContext is implemented in terms of QtGui/QOpenGLContext which has stricter requirements about how it's supposed to be used, we need to apply these requirements to QGLContext as well. This change adds QGLContext::moveToThread(QThread *) and documents it as a necessity for making a context current on another thread. Also introduces QGLPixelbuffer::context() to access the QGLContext of a pixelbuffer, and made QGLWidget::context() return a non-const QGLContext, since there's no good reason why it shouldn't, and it leads to less const_cast clutter. We could have introduced a backdoor in QOpenGLContext instead, making it loosen its requirements, but that would have made it harder / impossible to fully support threaded OpenGL in all the platforms. Task-number: QTBUG-22560 Change-Id: Ibb6f65f342e7c963e80cc42ab5664c5f1cab30b0 Reviewed-by: Friedemann Kleint <> Reviewed-by: Gunnar Sletta <>
Diffstat (limited to 'src/opengl/qgl.cpp')
1 files changed, 34 insertions, 11 deletions
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index c94c8f550e..583ecb69a8 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -3127,6 +3127,19 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
+ Moves the QGLContext to the given \a thread.
+ Enables calling swapBuffers() and makeCurrent() on the context in
+ the given thread.
+void QGLContext::moveToThread(QThread *thread)
+ Q_D(QGLContext);
+ if (d->guiGlContext)
+ d->guiGlContext->moveToThread(thread);
\fn bool QGLContext::chooseContext(const QGLContext* shareContext = 0)
This semi-internal function is called by create(). It creates a
@@ -3195,16 +3208,18 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
In some very rare cases the underlying call may fail. If this
occurs an error message is output to stderr.
+ If you call this from a thread other than the main UI thread,
+ make sure you've first pushed the context to the relevant thread
+ from the UI thread using moveToThread().
\fn void QGLContext::swapBuffers() const
- Swaps the screen contents with an off-screen buffer. Only works if
- the context is in double buffer mode.
- \sa QGLFormat::setDoubleBuffer()
+ Call this to finish a frame of OpenGL rendering, and make sure to
+ call makeCurrent() again before you begin a new frame.
@@ -3362,13 +3377,18 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
1. Call doneCurrent() in the main thread when the rendering is
- 2. Notify the swapping thread that it can grab the context.
+ 2. Call QGLContext::moveToThread(swapThread) to transfer ownership
+ of the context to the swapping thread.
- 3. Make the rendering context current in the swapping thread with
+ 3. Notify the swapping thread that it can grab the context.
+ 4. Make the rendering context current in the swapping thread with
makeCurrent() and then call swapBuffers().
- 4. Call doneCurrent() in the swapping thread and notify the main
- thread that swapping is done.
+ 5. Call doneCurrent() in the swapping thread.
+ 6. Call QGLContext::moveToThread(qApp->thread()) and notify the
+ main thread that swapping is done.
Doing this will free up the main thread so that it can continue
with, for example, handling UI events or network requests. Even if
@@ -3400,7 +3420,10 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
QGLWidgets can only be created in the main GUI thread. This means
a call to doneCurrent() is necessary to release the GL context
from the main thread, before the widget can be drawn into by
- another thread. Also, the main GUI thread will dispatch resize and
+ another thread. You then need to call QGLContext::moveToThread()
+ to transfer ownership of the context to the thread in which you
+ want to make it current.
+ Also, the main GUI thread will dispatch resize and
paint events to a QGLWidget when the widget is resized, or parts
of it becomes exposed or needs redrawing. It is therefore
necessary to handle those events because the default
@@ -3749,7 +3772,7 @@ void QGLWidget::setFormat(const QGLFormat &format)
- \fn const QGLContext *QGLWidget::context() const
+ \fn QGLContext *QGLWidget::context() const
Returns the context of this widget.
@@ -4483,7 +4506,7 @@ QGLFormat QGLWidget::format() const
return d->glcx->format();
-const QGLContext *QGLWidget::context() const
+QGLContext *QGLWidget::context() const
Q_D(const QGLWidget);
return d->glcx;