diff options
Diffstat (limited to 'src/gui/kernel/qopenglcontext.cpp')
-rw-r--r-- | src/gui/kernel/qopenglcontext.cpp | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 645c13a2ea..483baf0f09 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 |