summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qopenglcontext.cpp275
-rw-r--r--src/gui/kernel/qopenglcontext.h63
-rw-r--r--src/gui/kernel/qopenglcontext_p.h3
3 files changed, 341 insertions, 0 deletions
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 645c13a2ea8..483baf0f099 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -54,11 +54,163 @@
#include <QtGui/QScreen>
#include <private/qopenglextensions_p.h>
+#include <private/qopenglversionfunctionsfactory_p.h>
#include <QDebug>
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 make sense if profiles are supported by this version.
+
+ \sa setProfile(), supportsProfiles()
+*/
+QSurfaceFormat::OpenGLContextProfile QOpenGLVersionProfile::profile() const
+{
+ return d->profile;
+}
+
+/*!
+ Sets the profile. Only make sense if profiles are supported by this version.
+
+ \sa profile(), supportsProfiles()
+*/
+void QOpenGLVersionProfile::setProfile(QSurfaceFormat::OpenGLContextProfile profile)
+{
+ d->profile = profile;
+}
+
+/*!
+ Returns 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 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 true if the version number is valid. Note that for a default constructed
+ QOpenGLVersionProfile object this function will return false.
+
+ \sa setVersion(), version()
+*/
+bool QOpenGLVersionProfile::isValid() const
+{
+ return d->majorVersion > 0 && d->minorVersion >= 0;
+}
+
class QGuiGLThreadContext
{
public:
@@ -367,6 +519,10 @@ void QOpenGLContext::destroy()
d->platformGLContext = 0;
delete d->functions;
d->functions = 0;
+ qDeleteAll(d->versionFunctions);
+ d->versionFunctions.clear();
+ qDeleteAll(d->versionFunctionsBackend);
+ d->versionFunctionsBackend.clear();
}
/*!
@@ -425,6 +581,97 @@ QOpenGLFunctions *QOpenGLContext::functions() const
}
/*!
+ \fn T *QOpenGLContext::versionFunctions() const
+
+ Returns a pointer to an object that provides access to all functions for
+ the version and profile of this context. Before using any of the functions
+ they must be initialized by calling QAbstractOpenGLFunctions::initializeOpenGLFunctions().
+
+ 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);
+ }
+ funcs->initializeOpenGLFunctions(context);
+ \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 a null pointer. 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 version of the current context. Before using any of the functions
+ they must be initialized by calling QAbstractOpenGLFunctions::initializeOpenGLFunctions().
+
+ Usually one would use the template version of this function to automatically
+ have the result cast to the correct type.
+
+ \sa T *QOpenGLContext::versionFunctions()
+*/
+QAbstractOpenGLFunctions *QOpenGLContext::versionFunctions(const QOpenGLVersionProfile &versionProfile) const
+{
+ 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 0;
+
+ // 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 0;
+
+ // Create object if suitable one not cached
+ QAbstractOpenGLFunctions* funcs = 0;
+ if (!d->versionFunctions.contains(vp)) {
+ funcs = QOpenGLVersionFunctionsFactory::create(vp);
+ if (funcs) {
+ funcs->setOwningContext(this);
+ d->versionFunctions.insert(vp, funcs);
+ }
+ } else {
+ funcs = d->versionFunctions.value(vp);
+ }
+
+ return funcs;
+}
+
+/*!
Returns the set of OpenGL extensions supported by this context.
The context or a sharing context must be current.
@@ -702,6 +949,34 @@ void QOpenGLContext::deleteQGLContext()
}
/*!
+ \internal
+*/
+QOpenGLVersionFunctionsBackend *QOpenGLContext::functionsBackend(const QOpenGLVersionStatus &v) const
+{
+ Q_D(const QOpenGLContext);
+ return d->versionFunctionsBackend.value(v, 0);
+}
+
+/*!
+ \internal
+*/
+void QOpenGLContext::insertFunctionsBackend(const QOpenGLVersionStatus &v,
+ QOpenGLVersionFunctionsBackend *backend)
+{
+ Q_D(QOpenGLContext);
+ d->versionFunctionsBackend.insert(v, backend);
+}
+
+/*!
+ \internal
+*/
+void QOpenGLContext::removeFunctionsBackend(const QOpenGLVersionStatus &v)
+{
+ Q_D(QOpenGLContext);
+ d->versionFunctionsBackend.remove(v);
+}
+
+/*!
\class QOpenGLContextGroup
\since 5.0
\brief The QOpenGLContextGroup class represents a group of contexts sharing
diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h
index e8d04d7446e..52b4a2da287 100644
--- a/src/gui/kernel/qopenglcontext.h
+++ b/src/gui/kernel/qopenglcontext.h
@@ -58,6 +58,10 @@
#endif
#include <QtGui/qopengl.h>
+#include <QtGui/qopenglversionfunctions.h>
+
+#include <QtCore/qhash.h>
+#include <QtCore/qpair.h>
QT_BEGIN_NAMESPACE
@@ -69,6 +73,50 @@ class QPlatformOpenGLContext;
class QScreen;
class QSurface;
+class QOpenGLVersionProfilePrivate;
+
+class Q_GUI_EXPORT QOpenGLVersionProfile
+{
+public:
+ QOpenGLVersionProfile();
+ explicit QOpenGLVersionProfile(const QSurfaceFormat &format);
+ QOpenGLVersionProfile(const QOpenGLVersionProfile &other);
+ ~QOpenGLVersionProfile();
+
+ QOpenGLVersionProfile &operator=(const QOpenGLVersionProfile &rhs);
+
+ QPair<int, int> version() const;
+ void setVersion(int majorVersion, int minorVersion);
+
+ QSurfaceFormat::OpenGLContextProfile profile() const;
+ void setProfile(QSurfaceFormat::OpenGLContextProfile profile);
+
+ bool hasProfiles() const;
+ bool isLegacyVersion() const;
+ bool isValid() const;
+
+private:
+ QOpenGLVersionProfilePrivate* d;
+};
+
+inline uint qHash(const QOpenGLVersionProfile &v, uint seed)
+{
+ return qHash(static_cast<int>(v.profile() * 1000)
+ + v.version().first * 100 + v.version().second * 10, seed);
+}
+
+inline bool operator==(const QOpenGLVersionProfile &lhs, const QOpenGLVersionProfile &rhs)
+{
+ if (lhs.profile() != rhs.profile())
+ return false;
+ return lhs.version() == rhs.version();
+}
+
+inline bool operator!=(const QOpenGLVersionProfile &lhs, const QOpenGLVersionProfile &rhs)
+{
+ return !operator==(lhs, rhs);
+}
+
class Q_GUI_EXPORT QOpenGLContextGroup : public QObject
{
Q_OBJECT
@@ -127,6 +175,15 @@ public:
QOpenGLFunctions *functions() const;
+ QAbstractOpenGLFunctions *versionFunctions(const QOpenGLVersionProfile &versionProfile = QOpenGLVersionProfile()) const;
+
+ template<class TYPE>
+ TYPE *versionFunctions() const
+ {
+ QOpenGLVersionProfile v = TYPE::versionProfile();
+ return static_cast<TYPE*>(versionFunctions(v));
+ }
+
QSet<QByteArray> extensions() const;
bool hasExtension(const QByteArray &extension) const;
@@ -147,11 +204,17 @@ private:
friend class QOpenGL2PaintEngineExPrivate;
friend class QSGDistanceFieldGlyphCache;
friend class QWidgetPrivate;
+ friend class QAbstractOpenGLFunctionsPrivate;
void *qGLContextHandle() const;
void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *));
void deleteQGLContext();
+ QOpenGLVersionFunctionsBackend* functionsBackend(const QOpenGLVersionStatus &v) const;
+ void insertFunctionsBackend(const QOpenGLVersionStatus &v,
+ QOpenGLVersionFunctionsBackend *backend);
+ void removeFunctionsBackend(const QOpenGLVersionStatus &v);
+
void destroy();
};
diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h
index ba5434e8acd..8a36df3e7ca 100644
--- a/src/gui/kernel/qopenglcontext_p.h
+++ b/src/gui/kernel/qopenglcontext_p.h
@@ -213,6 +213,9 @@ public:
//QWidgetPrivate::deleteTLSysExtra()
}
+ mutable QHash<QOpenGLVersionProfile, QAbstractOpenGLFunctions *> versionFunctions;
+ mutable QHash<QOpenGLVersionStatus, QOpenGLVersionFunctionsBackend *> versionFunctionsBackend;
+
void *qGLContextHandle;
void (*qGLContextDeleteFunction)(void *handle);