QOpenGLContext: add a way to disable the thread affinity check

The problem of the check is that it makes Qt non compliant with OpenGL
thread affinity semantics. One is allowed to make a GL context
current on any thread, without the Qt-specific idea of moving
the QOpenGLContext to that thread first. Moreover, the move is
plain impossible if the user needs to handle the context
to 3rd party code which assumes the context to have GL semantics.

Add an application flag to disable that.

Change-Id: I55ca02ee62f8cc171a9a1bddef5331ad0949c061
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
bb10
Giuseppe D'Angelo 2016-04-08 12:38:00 +02:00
parent f40dbe0d0b
commit ea97a43175
3 changed files with 20 additions and 3 deletions

View File

@ -503,6 +503,7 @@ public:
AA_UseStyleSheetPropagationInWidgetStyles = 22, // ### Qt 6: remove me
AA_DontUseNativeDialogs = 23,
AA_SynthesizeMouseForUnhandledTabletEvents = 24,
AA_DontCheckOpenGLContextThreadAffinity = 25,
// Add new attributes before this line
AA_AttributeCount

View File

@ -234,6 +234,13 @@
set to true won't use the native dialogs provided by the platform.
This value has been added in Qt 5.7.
\value AA_DontCheckOpenGLContextThreadAffinity When making a context
current using QOpenGLContext, do not check that the
\l{QObject#Thread Affinity}{QObject thread affinity}
of the QOpenGLContext object is the same thread calling
\l{QOpenGLContext::makeCurrent}{makeCurrent()}. This value has been
added in Qt 5.8.
The following values are obsolete:
\value AA_ImmediateWidgetCreation This attribute is no longer fully

View File

@ -940,13 +940,20 @@ GLuint QOpenGLContext::defaultFramebufferObject() const
If \a surface is 0 this is equivalent to calling doneCurrent().
Do not call this function from a different thread than the one the
Avoid calling this function from a different thread than the one the
QOpenGLContext instance lives in. If you wish to use QOpenGLContext from a
different thread you should first call make sure it's not current in the
current thread, by calling doneCurrent() if necessary. Then call
moveToThread(otherThread) before using it in the other thread.
\sa functions(), doneCurrent()
By default Qt employs a check that enforces the above condition on the
thread affinity. It is still possible to disable this check by setting the
\c{Qt::AA_DontCheckOpenGLContextThreadAffinity} application attribute. Be
sure to understand the consequences of using QObjects from outside
the thread they live in, as explained in the
\l{QObject#Thread Affinity}{QObject thread affinity} documentation.
\sa functions(), doneCurrent(), Qt::AA_DontCheckOpenGLContextThreadAffinity
*/
bool QOpenGLContext::makeCurrent(QSurface *surface)
{
@ -954,8 +961,10 @@ bool QOpenGLContext::makeCurrent(QSurface *surface)
if (!isValid())
return false;
if (Q_UNLIKELY(thread() != QThread::currentThread()))
if (Q_UNLIKELY(!qApp->testAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity)
&& thread() != QThread::currentThread())) {
qFatal("Cannot make QOpenGLContext current in a different thread");
}
if (!surface) {
doneCurrent();