summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qopenglcontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qopenglcontext.cpp')
-rw-r--r--src/gui/kernel/qopenglcontext.cpp134
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();
}
/*!