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.cpp675
1 files changed, 147 insertions, 528 deletions
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 124b39f2a9..dd41318f72 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <qpa/qplatformopenglcontext.h>
#include <qpa/qplatformintegration.h>
@@ -54,171 +18,11 @@
#include <qpa/qplatformnativeinterface.h>
#include <private/qopenglextensions_p.h>
-#include <private/qopenglversionfunctionsfactory_p.h>
-
-#include <private/qopengltexturehelper_p.h>
#include <QDebug>
-#ifndef QT_OPENGL_ES_2
-#include <QOpenGLFunctions_1_0>
-#include <QOpenGLFunctions_3_2_Core>
-#endif
-
QT_BEGIN_NAMESPACE
-class QOpenGLVersionProfilePrivate
-{
-public:
- QOpenGLVersionProfilePrivate()
- : majorVersion(0),
- minorVersion(0),
- profile(QSurfaceFormat::NoProfile)
- {}
-
- int majorVersion;
- int minorVersion;
- QSurfaceFormat::OpenGLContextProfile profile;
-};
-
-
-/*!
- \class QOpenGLVersionProfile
- \inmodule QtGui
- \since 5.1
- \brief The QOpenGLVersionProfile class represents the version and if applicable
- the profile of an OpenGL context.
-
- An object of this class can be passed to QOpenGLContext::versionFunctions() to
- request a functions object for a specific version and profile of OpenGL.
-
- It also contains some helper functions to check if a version supports profiles
- or is a legacy version.
-*/
-
-/*!
- Creates a default invalid QOpenGLVersionProfile object.
-*/
-QOpenGLVersionProfile::QOpenGLVersionProfile()
- : d(new QOpenGLVersionProfilePrivate)
-{
-}
-
-/*!
- Creates a QOpenGLVersionProfile object initialised with the version and profile
- from \a format.
-*/
-QOpenGLVersionProfile::QOpenGLVersionProfile(const QSurfaceFormat &format)
- : d(new QOpenGLVersionProfilePrivate)
-{
- d->majorVersion = format.majorVersion();
- d->minorVersion = format.minorVersion();
- d->profile = format.profile();
-}
-
-/*!
- Constructs a copy of \a other.
-*/
-QOpenGLVersionProfile::QOpenGLVersionProfile(const QOpenGLVersionProfile &other)
- : d(new QOpenGLVersionProfilePrivate)
-{
- *d = *(other.d);
-}
-
-/*!
- Destroys the QOpenGLVersionProfile object.
-*/
-QOpenGLVersionProfile::~QOpenGLVersionProfile()
-{
- delete d;
-}
-
-/*!
- Assigns the version and profile of \a rhs to this QOpenGLVersionProfile object.
-*/
-QOpenGLVersionProfile &QOpenGLVersionProfile::operator=(const QOpenGLVersionProfile &rhs)
-{
- if (this == &rhs)
- return *this;
- *d = *(rhs.d);
- return *this;
-}
-
-/*!
- Returns a QPair<int,int> where the components represent the major and minor OpenGL
- version numbers respectively.
-
- \sa setVersion()
-*/
-QPair<int, int> QOpenGLVersionProfile::version() const
-{
- return qMakePair( d->majorVersion, d->minorVersion);
-}
-
-/*!
- Sets the major and minor version numbers to \a majorVersion and \a minorVersion respectively.
-
- \sa version()
-*/
-void QOpenGLVersionProfile::setVersion(int majorVersion, int minorVersion)
-{
- d->majorVersion = majorVersion;
- d->minorVersion = minorVersion;
-}
-
-/*!
- Returns the OpenGL profile. Only makes sense if profiles are supported by this version.
-
- \sa setProfile()
-*/
-QSurfaceFormat::OpenGLContextProfile QOpenGLVersionProfile::profile() const
-{
- return d->profile;
-}
-
-/*!
- Sets the OpenGL profile \a profile. Only makes sense if profiles are supported by
- this version.
-
- \sa profile()
-*/
-void QOpenGLVersionProfile::setProfile(QSurfaceFormat::OpenGLContextProfile profile)
-{
- d->profile = profile;
-}
-
-/*!
- Returns \c true if profiles are supported by the OpenGL version returned by version(). Only
- OpenGL versions >= 3.2 support profiles.
-
- \sa profile(), version()
-*/
-bool QOpenGLVersionProfile::hasProfiles() const
-{
- return ( d->majorVersion > 3
- || (d->majorVersion == 3 && d->minorVersion > 1));
-}
-
-/*!
- Returns \c true is the OpenGL version returned by version() contains deprecated functions
- and does not support profiles i.e. if the OpenGL version is <= 3.1.
-*/
-bool QOpenGLVersionProfile::isLegacyVersion() const
-{
- return (d->majorVersion < 3 || (d->majorVersion == 3 && d->minorVersion == 0));
-}
-
-/*!
- Returns \c true if the version number is valid. Note that for a default constructed
- QOpenGLVersionProfile object this function will return \c false.
-
- \sa setVersion(), version()
-*/
-bool QOpenGLVersionProfile::isValid() const
-{
- return d->majorVersion > 0 && d->minorVersion >= 0;
-}
-
class QGuiGLThreadContext
{
public:
@@ -238,7 +42,7 @@ static QOpenGLContext *global_share_context = nullptr;
#ifndef QT_NO_DEBUG
QHash<QOpenGLContext *, bool> QOpenGLContextPrivate::makeCurrentTracker;
-QMutex QOpenGLContextPrivate::makeCurrentTrackerMutex;
+Q_CONSTINIT QMutex QOpenGLContextPrivate::makeCurrentTrackerMutex;
#endif
/*!
@@ -265,6 +69,7 @@ QOpenGLContext *qt_gl_global_share_context()
/*!
\class QOpenGLContext
+ \ingroup painting-3D
\inmodule QtGui
\since 5.0
\brief The QOpenGLContext class represents a native OpenGL context, enabling
@@ -333,6 +138,22 @@ QOpenGLContext *qt_gl_global_share_context()
application is portable between different platforms. However, if you use
QOpenGLFunctions::glBindFramebuffer(), this is done automatically for you.
+ \warning WebAssembly
+
+ We recommend that only one QOpenGLContext is made current with a QSurface,
+ for the entire lifetime of the QSurface. Should more than once context be used,
+ it is important to understand that multiple QOpenGLContext instances may be
+ backed by the same native context underneath with the WebAssembly platform.
+ Therefore, calling makeCurrent() with the same QSurface on two QOpenGLContext
+ objects may not switch to a different native context in the second call. As
+ a result, any OpenGL state changes done after the second makeCurrent() may
+ alter the state of the first QOpenGLContext as well, as they are all backed
+ by the same native context.
+
+ \note This means that when targeting WebAssembly with existing OpenGL-based
+ Qt code, some porting may be required to cater to these limitations.
+
+
\sa QOpenGLFunctions, QOpenGLBuffer, QOpenGLShaderProgram, QOpenGLFramebufferObject
*/
@@ -349,6 +170,9 @@ QOpenGLContext *QOpenGLContextPrivate::setCurrentContext(QOpenGLContext *context
qWarning("No QTLS available. currentContext won't work");
return nullptr;
}
+ if (!context)
+ return nullptr;
+
threadContext = new QGuiGLThreadContext;
qwindow_context_storage()->setLocalData(threadContext);
}
@@ -366,7 +190,7 @@ int QOpenGLContextPrivate::maxTextureSize()
QOpenGLFunctions *funcs = q->functions();
funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
-#ifndef QT_OPENGL_ES
+#if !QT_CONFIG(opengles2)
if (!q->isOpenGLES()) {
GLenum proxy = GL_PROXY_TEXTURE_2D;
@@ -374,20 +198,8 @@ int QOpenGLContextPrivate::maxTextureSize()
GLint next = 64;
funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- QOpenGLFunctions_1_0 *gl1funcs = nullptr;
- QOpenGLFunctions_3_2_Core *gl3funcs = nullptr;
-
- if (q->format().profile() == QSurfaceFormat::CoreProfile)
- gl3funcs = q->versionFunctions<QOpenGLFunctions_3_2_Core>();
- else
- gl1funcs = q->versionFunctions<QOpenGLFunctions_1_0>();
-
- Q_ASSERT(gl1funcs || gl3funcs);
-
- if (gl1funcs)
- gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
- else
- gl3funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
+ QOpenGLExtraFunctions *extraFuncs = q->extraFunctions();
+ extraFuncs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
if (size == 0) {
return max_texture_size;
@@ -399,16 +211,12 @@ int QOpenGLContextPrivate::maxTextureSize()
if (next > max_texture_size)
break;
funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- if (gl1funcs)
- gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
- else
- gl3funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
-
+ extraFuncs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
} while (next > size);
max_texture_size = size;
}
-#endif // QT_OPENGL_ES
+#endif // QT_CONFIG(opengles2)
return max_texture_size;
}
@@ -523,63 +331,17 @@ void QOpenGLContextPrivate::_q_screenDestroyed(QObject *object)
}
/*!
- 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, QOpenGLContext does not
- take ownership of the handles, so destroying the QOpenGLContext does 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;
-}
+ \fn template <typename QNativeInterface> QNativeInterface *QOpenGLContext::nativeInterface() const
-/*!
- Returns the native handle for the context.
+ Returns a native interface of the given type 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.
+ This function provides access to platform specific functionality
+ of QOpenGLContext, as defined in the QNativeInterface namespace:
- On platforms where retrieving the native handle is not supported, or if
- neither create() nor setNativeHandle() was called, a null variant is
- returned.
+ \annotatedlist native-interfaces-qopenglcontext
- \since 5.4
- \sa setNativeHandle()
+ If the requested interface is not available a \nullptr is returned.
*/
-QVariant QOpenGLContext::nativeHandle() const
-{
- Q_D(const QOpenGLContext);
- return d->nativeHandle;
-}
/*!
Attempts to create the OpenGL context with the current configuration.
@@ -609,18 +371,33 @@ bool QOpenGLContext::create()
if (d->platformGLContext)
destroy();
- d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this);
- if (!d->platformGLContext)
+ auto *platformContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this);
+ if (!platformContext)
return false;
- d->platformGLContext->setContext(this);
- d->platformGLContext->initialize();
- if (!d->platformGLContext->isSharing())
- d->shareContext = nullptr;
- d->shareGroup = d->shareContext ? d->shareContext->shareGroup() : new QOpenGLContextGroup;
- d->shareGroup->d_func()->addContext(this);
+
+ d->adopt(platformContext);
+
return isValid();
}
+QOpenGLContextPrivate::~QOpenGLContextPrivate()
+{
+}
+
+void QOpenGLContextPrivate::adopt(QPlatformOpenGLContext *context)
+{
+ Q_Q(QOpenGLContext);
+
+ platformGLContext = context;
+ platformGLContext->setContext(q);
+ platformGLContext->initialize();
+
+ if (!platformGLContext->isSharing())
+ shareContext = nullptr;
+ shareGroup = shareContext ? shareContext->shareGroup() : new QOpenGLContextGroup;
+ shareGroup->d_func()->addContext(q);
+}
+
/*!
\internal
@@ -641,33 +418,48 @@ bool QOpenGLContext::create()
*/
void QOpenGLContext::destroy()
{
- deleteQGLContext();
Q_D(QOpenGLContext);
+
+ // Notify that the native context and the QPlatformOpenGLContext are going
+ // to go away.
if (d->platformGLContext)
emit aboutToBeDestroyed();
+
+ // Invoke callbacks for helpers and invalidate.
+ if (d->textureFunctionsDestroyCallback) {
+ d->textureFunctionsDestroyCallback();
+ d->textureFunctionsDestroyCallback = nullptr;
+ }
+ d->textureFunctions = nullptr;
+
+ delete d->versionFunctions;
+ d->versionFunctions = nullptr;
+
+ if (d->vaoHelperDestroyCallback) {
+ Q_ASSERT(d->vaoHelper);
+ d->vaoHelperDestroyCallback(d->vaoHelper);
+ d->vaoHelperDestroyCallback = nullptr;
+ }
+ d->vaoHelper = nullptr;
+
+ // Tear down function wrappers.
+ delete d->versionFunctions;
+ d->versionFunctions = nullptr;
+
+ delete d->functions;
+ d->functions = nullptr;
+
+ // Clean up and destroy the native context machinery.
if (QOpenGLContext::currentContext() == this)
doneCurrent();
+
if (d->shareGroup)
d->shareGroup->d_func()->removeContext(this);
+
d->shareGroup = nullptr;
+
delete d->platformGLContext;
d->platformGLContext = nullptr;
- delete d->functions;
- d->functions = nullptr;
-
- for (QAbstractOpenGLFunctions *func : qAsConst(d->externalVersionFunctions)) {
- QAbstractOpenGLFunctionsPrivate *func_d = QAbstractOpenGLFunctionsPrivate::get(func);
- func_d->owningContext = nullptr;
- func_d->initialized = false;
- }
- d->externalVersionFunctions.clear();
- qDeleteAll(d->versionFunctions);
- d->versionFunctions.clear();
-
- delete d->textureFunctions;
- d->textureFunctions = nullptr;
-
- d->nativeHandle = QVariant();
}
/*!
@@ -679,6 +471,11 @@ void QOpenGLContext::destroy()
If you wish to make the context current in order to do clean-up, make sure
to only connect to the signal using a direct connection.
+
+ \note In Qt for Python, this signal will not be received when emitted
+ from the destructor of QOpenGLWidget or QOpenGLWindow due to the Python
+ instance already being destroyed. We recommend doing cleanups
+ in QWidget::hideEvent() instead.
*/
/*!
@@ -707,6 +504,14 @@ QOpenGLContext::~QOpenGLContext()
OpenGL context by calling create(), call makeCurrent() again and then
reinitialize all OpenGL resources.
+ On some platforms context loss situations is not something that can
+ avoided. On others however, they may need to be opted-in to. This can be
+ done by enabling \l{QSurfaceFormat::ResetNotification}{ResetNotification} in
+ the QSurfaceFormat. This will lead to setting
+ \c{RESET_NOTIFICATION_STRATEGY_EXT} to \c{LOSE_CONTEXT_ON_RESET_EXT} in the
+ underlying native OpenGL context. QOpenGLContext will then monitor the
+ status via \c{glGetGraphicsResetStatusEXT()} in every makeCurrent().
+
\sa create()
*/
bool QOpenGLContext::isValid() const
@@ -757,115 +562,6 @@ QOpenGLExtraFunctions *QOpenGLContext::extraFunctions() const
}
/*!
- \fn T *QOpenGLContext::versionFunctions() const
-
- \overload versionFunctions()
-
- Returns a pointer to an object that provides access to all functions for
- the version and profile of this context. There is no need to call
- QAbstractOpenGLFunctions::initializeOpenGLFunctions() as long as this context
- is current. It is also possible to call this function when the context is not
- current, but in that case it is the caller's responsibility to ensure proper
- initialization by calling QAbstractOpenGLFunctions::initializeOpenGLFunctions()
- afterwards.
-
- Usually one would use the template version of this function to automatically
- have the result cast to the correct type.
-
- \code
- QOpenGLFunctions_3_3_Core* funcs = 0;
- funcs = context->versionFunctions<QOpenGLFunctions_3_3_Core>();
- if (!funcs) {
- qWarning() << "Could not obtain required OpenGL context version";
- exit(1);
- }
- \endcode
-
- It is possible to request a functions object for a different version and profile
- than that for which the context was created. To do this either use the template
- version of this function specifying the desired functions object type as the
- template parameter or by passing in a QOpenGLVersionProfile object as an argument
- to the non-template function.
-
- Note that requests for function objects of other versions or profiles can fail and
- in doing so will return \nullptr. Situations in which creation of the functions
- object can fail are if the request cannot be satisfied due to asking for functions
- that are not in the version or profile of this context. For example:
-
- \list
- \li Requesting a 3.3 core profile functions object would succeed.
- \li Requesting a 3.3 compatibility profile functions object would fail. We would fail
- to resolve the deprecated functions.
- \li Requesting a 4.3 core profile functions object would fail. We would fail to resolve
- the new core functions introduced in versions 4.0-4.3.
- \li Requesting a 3.1 functions object would succeed. There is nothing in 3.1 that is not
- also in 3.3 core.
- \endlist
-
- Note that if creating a functions object via this method that the QOpenGLContext
- retains ownership of the object. This is to allow the object to be cached and shared.
-*/
-
-/*!
- Returns a pointer to an object that provides access to all functions for the
- \a versionProfile of this context. There is no need to call
- QAbstractOpenGLFunctions::initializeOpenGLFunctions() as long as this context
- is current. It is also possible to call this function when the context is not
- current, but in that case it is the caller's responsibility to ensure proper
- initialization by calling QAbstractOpenGLFunctions::initializeOpenGLFunctions()
- afterwards.
-
- Usually one would use the template version of this function to automatically
- have the result cast to the correct type.
-*/
-QAbstractOpenGLFunctions *QOpenGLContext::versionFunctions(const QOpenGLVersionProfile &versionProfile) const
-{
-#ifndef QT_OPENGL_ES_2
- if (isOpenGLES()) {
- qWarning("versionFunctions: Not supported on OpenGL ES");
- return nullptr;
- }
-#endif // QT_OPENGL_ES_2
-
- Q_D(const QOpenGLContext);
- const QSurfaceFormat f = format();
-
- // Ensure we have a valid version and profile. Default to context's if none specified
- QOpenGLVersionProfile vp = versionProfile;
- if (!vp.isValid())
- vp = QOpenGLVersionProfile(f);
-
- // Check that context is compatible with requested version
- const QPair<int, int> v = qMakePair(f.majorVersion(), f.minorVersion());
- if (v < vp.version())
- return nullptr;
-
- // If this context only offers core profile functions then we can't create
- // function objects for legacy or compatibility profile requests
- if (((vp.hasProfiles() && vp.profile() != QSurfaceFormat::CoreProfile) || vp.isLegacyVersion())
- && f.profile() == QSurfaceFormat::CoreProfile)
- return nullptr;
-
- // Create object if suitable one not cached
- QAbstractOpenGLFunctions* funcs = nullptr;
- auto it = d->versionFunctions.constFind(vp);
- if (it == d->versionFunctions.constEnd()) {
- funcs = QOpenGLVersionFunctionsFactory::create(vp);
- if (funcs) {
- funcs->setOwningContext(this);
- d->versionFunctions.insert(vp, funcs);
- }
- } else {
- funcs = it.value();
- }
-
- if (funcs && QOpenGLContext::currentContext() == this)
- funcs->initializeOpenGLFunctions();
-
- return funcs;
-}
-
-/*!
Returns the set of OpenGL extensions supported by this context.
The context or a sharing context must be current.
@@ -941,7 +637,7 @@ GLuint QOpenGLContext::defaultFramebufferObject() const
The latter may happen if the surface is not exposed, or the graphics
hardware is not available due to e.g. the application being suspended.
- If \a surface is 0 this is equivalent to calling doneCurrent().
+ If \a surface is \nullptr this is equivalent to calling doneCurrent().
Avoid calling this function from a different thread than the one the
QOpenGLContext instance lives in. If you wish to use QOpenGLContext from a
@@ -1023,7 +719,8 @@ bool QOpenGLContext::makeCurrent(QSurface *surface)
|| qstrcmp(rendererString, "GC800 core") == 0
|| qstrcmp(rendererString, "GC1000 core") == 0
|| strstr(rendererString, "GC2000") != nullptr
- || qstrcmp(rendererString, "Immersion.16") == 0;
+ || qstrcmp(rendererString, "Immersion.16") == 0
+ || qstrncmp(rendererString, "Apple Mx", 7) == 0;
}
needsWorkaroundSet = true;
}
@@ -1093,12 +790,6 @@ void QOpenGLContext::swapBuffers(QSurface *surface)
return;
}
- if (surface->surfaceClass() == QSurface::Window
- && !qt_window_private(static_cast<QWindow *>(surface))->receivedExpose)
- {
- qWarning("QOpenGLContext::swapBuffers() called with non-exposed window, behavior is undefined");
- }
-
QPlatformSurface *surfaceHandle = surface->surfaceHandle();
if (!surfaceHandle)
return;
@@ -1192,71 +883,6 @@ QScreen *QOpenGLContext::screen() const
}
/*!
- internal: Needs to have a pointer to qGLContext. But since this is in Qt GUI we can't
- have any type information.
-
- \internal
-*/
-void *QOpenGLContext::qGLContextHandle() const
-{
- Q_D(const QOpenGLContext);
- return d->qGLContextHandle;
-}
-
-/*!
- internal: If the delete function is specified QOpenGLContext "owns"
- the passed context handle and will use the delete function to destroy it.
-
- \internal
-*/
-void QOpenGLContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *))
-{
- Q_D(QOpenGLContext);
- d->qGLContextHandle = handle;
- d->qGLContextDeleteFunction = qGLContextDeleteFunction;
-}
-
-/*!
- \internal
-*/
-void QOpenGLContext::deleteQGLContext()
-{
- Q_D(QOpenGLContext);
- if (d->qGLContextDeleteFunction && d->qGLContextHandle) {
- d->qGLContextDeleteFunction(d->qGLContextHandle);
- d->qGLContextDeleteFunction = nullptr;
- d->qGLContextHandle = nullptr;
- }
-}
-
-/*!
- Returns the platform-specific handle for the OpenGL implementation that
- is currently in use. (for example, a HMODULE on Windows)
-
- On platforms that do not use dynamic GL switching, the return value
- is \nullptr.
-
- The library might be GL-only, meaning that windowing system interface
- functions (for example EGL) may live in another, separate library.
-
- \note This function requires that the QGuiApplication instance is already created.
-
- \sa openGLModuleType()
-
- \since 5.3
- */
-void *QOpenGLContext::openGLModuleHandle()
-{
-#ifdef QT_OPENGL_DYNAMIC
- QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface();
- Q_ASSERT(ni);
- return ni->nativeResourceForIntegration(QByteArrayLiteral("glhandle"));
-#else
- return nullptr;
-#endif
-}
-
-/*!
\enum QOpenGLContext::OpenGLModuleType
This enum defines the type of the underlying OpenGL implementation.
@@ -1287,7 +913,7 @@ QOpenGLContext::OpenGLModuleType QOpenGLContext::openGLModuleType()
#if defined(QT_OPENGL_DYNAMIC)
Q_ASSERT(qGuiApp);
return QGuiApplicationPrivate::instance()->platformIntegration()->openGLModuleType();
-#elif defined(QT_OPENGL_ES_2)
+#elif QT_CONFIG(opengles2)
return LibGLES;
#else
return LibGL;
@@ -1352,33 +978,6 @@ QOpenGLContext *QOpenGLContext::globalShareContext()
/*!
\internal
*/
-QOpenGLVersionFunctionsStorage *QOpenGLContext::functionsBackendStorage() const
-{
- Q_D(const QOpenGLContext);
- return &d->versionFunctionsStorage;
-}
-
-/*!
- \internal
- */
-void QOpenGLContext::insertExternalFunctions(QAbstractOpenGLFunctions *f)
-{
- Q_D(QOpenGLContext);
- d->externalVersionFunctions.insert(f);
-}
-
-/*!
- \internal
- */
-void QOpenGLContext::removeExternalFunctions(QAbstractOpenGLFunctions *f)
-{
- Q_D(QOpenGLContext);
- d->externalVersionFunctions.remove(f);
-}
-
-/*!
- \internal
-*/
QOpenGLTextureHelper* QOpenGLContext::textureFunctions() const
{
Q_D(const QOpenGLContext);
@@ -1388,10 +987,11 @@ QOpenGLTextureHelper* QOpenGLContext::textureFunctions() const
/*!
\internal
*/
-void QOpenGLContext::setTextureFunctions(QOpenGLTextureHelper* textureFuncs)
+void QOpenGLContext::setTextureFunctions(QOpenGLTextureHelper* textureFuncs, std::function<void()> destroyCallback)
{
Q_D(QOpenGLContext);
d->textureFunctions = textureFuncs;
+ d->textureFunctionsDestroyCallback = destroyCallback;
}
/*!
@@ -1441,6 +1041,9 @@ QOpenGLContextGroup *QOpenGLContextGroup::currentContextGroup()
return current ? current->shareGroup() : nullptr;
}
+QOpenGLContextGroupPrivate::~QOpenGLContextGroupPrivate()
+ = default;
+
void QOpenGLContextGroupPrivate::addContext(QOpenGLContext *ctx)
{
const auto locker = qt_scoped_lock(m_mutex);
@@ -1582,6 +1185,10 @@ void QOpenGLSharedResource::free()
\inmodule QtGui
*/
+
+QOpenGLSharedResourceGuard::~QOpenGLSharedResourceGuard()
+ = default;
+
void QOpenGLSharedResourceGuard::freeResource(QOpenGLContext *context)
{
if (m_id) {
@@ -1654,14 +1261,14 @@ void QOpenGLMultiGroupSharedResource::insert(QOpenGLContext *context, QOpenGLSha
QOpenGLSharedResource *QOpenGLMultiGroupSharedResource::value(QOpenGLContext *context)
{
QOpenGLContextGroup *group = context->shareGroup();
- return group->d_func()->m_resources.value(this, 0);
+ return group->d_func()->m_resources.value(this, nullptr);
}
QList<QOpenGLSharedResource *> QOpenGLMultiGroupSharedResource::resources() const
{
QList<QOpenGLSharedResource *> result;
for (QList<QOpenGLContextGroup *>::const_iterator it = m_groups.constBegin(); it != m_groups.constEnd(); ++it) {
- QOpenGLSharedResource *resource = (*it)->d_func()->m_resources.value(const_cast<QOpenGLMultiGroupSharedResource *>(this), 0);
+ QOpenGLSharedResource *resource = (*it)->d_func()->m_resources.value(const_cast<QOpenGLMultiGroupSharedResource *>(this), nullptr);
if (resource)
result << resource;
}
@@ -1681,22 +1288,10 @@ void QOpenGLMultiGroupSharedResource::cleanup(QOpenGLContextGroup *group, QOpenG
m_groups.removeOne(group);
}
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug debug, const QOpenGLVersionProfile &vp)
-{
- QDebugStateSaver saver(debug);
- debug.nospace();
- debug << "QOpenGLVersionProfile(";
- if (vp.isValid()) {
- debug << vp.version().first << '.' << vp.version().second
- << ", profile=" << vp.profile();
- } else {
- debug << "invalid";
- }
- debug << ')';
- return debug;
-}
+QOpenGLContextVersionFunctionHelper::~QOpenGLContextVersionFunctionHelper()
+ = default;
+#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QOpenGLContext *ctx)
{
QDebugStateSaver saver(debug);
@@ -1706,8 +1301,7 @@ QDebug operator<<(QDebug debug, const QOpenGLContext *ctx)
if (ctx) {
debug << static_cast<const void *>(ctx);
if (ctx->isValid()) {
- debug << ", nativeHandle=" << ctx->nativeHandle()
- << ", format=" << ctx->format();
+ debug << ", format=" << ctx->format();
if (const QSurface *sf = ctx->surface())
debug << ", surface=" << sf;
if (const QScreen *s = ctx->screen())
@@ -1736,6 +1330,31 @@ QDebug operator<<(QDebug debug, const QOpenGLContextGroup *cg)
}
#endif // QT_NO_DEBUG_STREAM
-#include "moc_qopenglcontext.cpp"
+using namespace QNativeInterface;
+
+void *QOpenGLContext::resolveInterface(const char *name, int revision) const
+{
+ Q_UNUSED(name); Q_UNUSED(revision);
+
+ auto *platformContext = handle();
+ Q_UNUSED(platformContext);
+
+#if defined(Q_OS_MACOS)
+ QT_NATIVE_INTERFACE_RETURN_IF(QCocoaGLContext, platformContext);
+#endif
+#if defined(Q_OS_WIN)
+ QT_NATIVE_INTERFACE_RETURN_IF(QWGLContext, platformContext);
+#endif
+#if QT_CONFIG(xcb_glx_plugin)
+ QT_NATIVE_INTERFACE_RETURN_IF(QGLXContext, platformContext);
+#endif
+#if QT_CONFIG(egl)
+ QT_NATIVE_INTERFACE_RETURN_IF(QEGLContext, platformContext);
+#endif
+
+ return nullptr;
+}
QT_END_NAMESPACE
+
+#include "moc_qopenglcontext.cpp"