diff options
Diffstat (limited to 'src/gui/kernel/qopenglcontext.cpp')
-rw-r--r-- | src/gui/kernel/qopenglcontext.cpp | 134 |
1 files changed, 118 insertions, 16 deletions
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 406c784c5c..6b2bb092b1 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -63,6 +63,7 @@ #ifndef QT_OPENGL_ES_2 #include <QOpenGLFunctions_1_0> +#include <QOpenGLFunctions_3_2_Core> #endif QT_BEGIN_NAMESPACE @@ -242,6 +243,27 @@ QMutex QOpenGLContextPrivate::makeCurrentTrackerMutex; #endif /*! + \internal + + This function is used by the Qt WebEngine to set up context sharing + across multiple windows. Do not use it for any other purpose. + + Please maintain the binary compatibility of these functions. +*/ +void qt_gl_set_global_share_context(QOpenGLContext *context) +{ + global_share_context = context; +} + +/*! + \internal +*/ +QOpenGLContext *qt_gl_global_share_context() +{ + return global_share_context; +} + +/*! \class QOpenGLContext \inmodule QtGui \since 5.0 @@ -335,23 +357,14 @@ QOpenGLContext *QOpenGLContextPrivate::setCurrentContext(QOpenGLContext *context return previous; } -/*! - \internal - - This function is used by the Qt WebEngine to set up context sharing - across multiple windows. Do not use it for any other purpose. -*/ void QOpenGLContextPrivate::setGlobalShareContext(QOpenGLContext *context) { - global_share_context = context; + qt_gl_set_global_share_context(context); } -/*! - \internal -*/ QOpenGLContext *QOpenGLContextPrivate::globalShareContext() { - return global_share_context; + return qt_gl_global_share_context(); } int QOpenGLContextPrivate::maxTextureSize() @@ -370,9 +383,25 @@ int QOpenGLContextPrivate::maxTextureSize() GLint size; GLint next = 64; funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - QOpenGLFunctions_1_0 *gl1funcs = q->versionFunctions<QOpenGLFunctions_1_0>(); - gl1funcs->initializeOpenGLFunctions(); - gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); + + QOpenGLFunctions_1_0 *gl1funcs = 0; + QOpenGLFunctions_3_2_Core *gl3funcs = 0; + + if (q->format().profile() == QSurfaceFormat::CoreProfile) { + gl3funcs = q->versionFunctions<QOpenGLFunctions_3_2_Core>(); + gl3funcs->initializeOpenGLFunctions(); + } else { + gl1funcs = q->versionFunctions<QOpenGLFunctions_1_0>(); + gl1funcs->initializeOpenGLFunctions(); + } + + Q_ASSERT(gl1funcs || gl3funcs); + + if (gl1funcs) + gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); + else + gl3funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); + if (size == 0) { return max_texture_size; } @@ -383,7 +412,11 @@ int QOpenGLContextPrivate::maxTextureSize() if (next > max_texture_size) break; funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); + if (gl1funcs) + gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); + else + gl3funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); + } while (next > size); max_texture_size = size; @@ -456,6 +489,12 @@ QOpenGLContext::QOpenGLContext(QObject *parent) /*! Sets the \a format the OpenGL context should be compatible with. You need to call create() before it takes effect. + + When the format is not explicitly set via this function, the format returned + by QSurfaceFormat::defaultFormat() will be used. This means that when having + multiple contexts, individual calls to this function can be replaced by one + single call to QSurfaceFormat::setDefaultFormat() before creating the first + context. */ void QOpenGLContext::setFormat(const QSurfaceFormat &format) { @@ -486,6 +525,64 @@ void QOpenGLContext::setScreen(QScreen *screen) } /*! + Set the native handles for this context. When create() is called and a + native handle is set, configuration settings, like format(), are ignored + since this QOpenGLContext will wrap an already created native context + instead of creating a new one from scratch. + + On some platforms the native context handle is not sufficient and other + related handles (for example, for a window or display) have to be provided + in addition. Therefore \a handle is variant containing a platform-specific + value type. These classes can be found in the QtPlatformHeaders module. + + When create() is called with native handles set, the handles' ownership are + not taken, meaning that destroy() will not destroy the native context. + + \note Some frameworks track the current context and surfaces internally. + Making the adopted QOpenGLContext current via Qt will have no effect on such + other frameworks' internal state. Therefore a subsequent makeCurrent done + via the other framework may have no effect. It is therefore advisable to + make explicit calls to make no context and surface current to reset the + other frameworks' internal state after performing OpenGL operations via Qt. + + \note Using foreign contexts with Qt windows and Qt contexts with windows + and surfaces created by other frameworks may give unexpected results, + depending on the platform, due to potential mismatches in context and window + pixel formats. To make sure this does not happen, avoid making contexts and + surfaces from different frameworks current together. Instead, prefer + approaches based on context sharing where OpenGL resources like textures are + accessible both from Qt's and the foreign framework's contexts. + + \since 5.4 + \sa nativeHandle() +*/ +void QOpenGLContext::setNativeHandle(const QVariant &handle) +{ + Q_D(QOpenGLContext); + d->nativeHandle = handle; +} + +/*! + Returns the native handle for the context. + + This function provides access to the QOpenGLContext's underlying native + context. The returned variant contains a platform-specific value type. These + classes can be found in the module QtPlatformHeaders. + + On platforms where retrieving the native handle is not supported, or if + neither create() nor setNativeHandle() was called, a null variant is + returned. + + \since 5.4 + \sa setNativeHandle() + */ +QVariant QOpenGLContext::nativeHandle() const +{ + Q_D(const QOpenGLContext); + return d->nativeHandle; +} + +/*! Attempts to create the OpenGL context with the current configuration. The current configuration includes the format, the share context, and the @@ -502,11 +599,15 @@ void QOpenGLContext::setScreen(QScreen *screen) Returns \c true if the native context was successfully created and is ready to be used with makeCurrent(), swapBuffers(), etc. + \note If the context is already created, this function will first call + destroy(), and then create a new OpenGL context. + \sa makeCurrent(), destroy(), format() */ bool QOpenGLContext::create() { - destroy(); + if (isValid()) + destroy(); Q_D(QOpenGLContext); d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this); @@ -557,6 +658,7 @@ void QOpenGLContext::destroy() d->versionFunctionsBackend.clear(); delete d->textureFunctions; d->textureFunctions = 0; + d->nativeHandle = QVariant(); } /*! |