From 6e28e8441b698c3397c2c78125c877f2e9867cb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 22 Aug 2011 10:49:28 +0200 Subject: Copy core GL functionality to QtGui with QGL -> QOpenGL naming. Change-Id: Ibc989afa4a30dd184d41d1a1cd89f97196e48855 Reviewed-on: http://codereview.qt.nokia.com/3710 Reviewed-by: Gunnar Sletta --- src/gui/kernel/kernel.pri | 10 +- src/gui/kernel/qguiglcontext_qpa.cpp | 500 ---------------------- src/gui/kernel/qguiglcontext_qpa.h | 132 ------ src/gui/kernel/qguiglcontext_qpa_p.h | 181 -------- src/gui/kernel/qopenglcontext.cpp | 531 ++++++++++++++++++++++++ src/gui/kernel/qopenglcontext.h | 145 +++++++ src/gui/kernel/qopenglcontext_p.h | 230 ++++++++++ src/gui/kernel/qplatformglcontext_qpa.cpp | 111 ----- src/gui/kernel/qplatformglcontext_qpa.h | 105 ----- src/gui/kernel/qplatformintegration_qpa.cpp | 4 +- src/gui/kernel/qplatformintegration_qpa.h | 4 +- src/gui/kernel/qplatformnativeinterface_qpa.cpp | 2 +- src/gui/kernel/qplatformnativeinterface_qpa.h | 4 +- src/gui/kernel/qplatformopenglcontext_qpa.cpp | 111 +++++ src/gui/kernel/qplatformopenglcontext_qpa.h | 105 +++++ src/gui/kernel/qplatformscreen_qpa.h | 2 +- src/gui/kernel/qplatformwindow_qpa.cpp | 4 +- src/gui/kernel/qplatformwindow_qpa.h | 2 +- src/gui/kernel/qsurfaceformat.cpp | 54 ++- src/gui/kernel/qsurfaceformat.h | 12 +- src/gui/kernel/qwindow.cpp | 4 +- 21 files changed, 1203 insertions(+), 1050 deletions(-) delete mode 100644 src/gui/kernel/qguiglcontext_qpa.cpp delete mode 100644 src/gui/kernel/qguiglcontext_qpa.h delete mode 100644 src/gui/kernel/qguiglcontext_qpa_p.h create mode 100644 src/gui/kernel/qopenglcontext.cpp create mode 100644 src/gui/kernel/qopenglcontext.h create mode 100644 src/gui/kernel/qopenglcontext_p.h delete mode 100644 src/gui/kernel/qplatformglcontext_qpa.cpp delete mode 100644 src/gui/kernel/qplatformglcontext_qpa.h create mode 100644 src/gui/kernel/qplatformopenglcontext_qpa.cpp create mode 100644 src/gui/kernel/qplatformopenglcontext_qpa.h (limited to 'src/gui/kernel') diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 44d039512f..b24d51c17d 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -49,9 +49,9 @@ qpa { kernel/qplatformintegrationfactory_qpa_p.h \ kernel/qplatformintegrationplugin_qpa.h \ kernel/qplatformwindow_qpa.h \ - kernel/qplatformglcontext_qpa.h \ - kernel/qguiglcontext_qpa.h \ - kernel/qguiglcontext_qpa_p.h \ + kernel/qplatformopenglcontext_qpa.h \ + kernel/qopenglcontext.h \ + kernel/qopenglcontext_p.h \ kernel/qplatformcursor_qpa.h \ kernel/qplatformclipboard_qpa.h \ kernel/qplatformnativeinterface_qpa.h \ @@ -73,8 +73,8 @@ qpa { kernel/qplatformintegrationfactory_qpa.cpp \ kernel/qplatformintegrationplugin_qpa.cpp \ kernel/qplatformwindow_qpa.cpp \ - kernel/qplatformglcontext_qpa.cpp \ - kernel/qguiglcontext_qpa.cpp \ + kernel/qplatformopenglcontext_qpa.cpp \ + kernel/qopenglcontext.cpp \ kernel/qplatformcursor_qpa.cpp \ kernel/qplatformclipboard_qpa.cpp \ kernel/qplatformnativeinterface_qpa.cpp \ diff --git a/src/gui/kernel/qguiglcontext_qpa.cpp b/src/gui/kernel/qguiglcontext_qpa.cpp deleted file mode 100644 index 71c830174e..0000000000 --- a/src/gui/kernel/qguiglcontext_qpa.cpp +++ /dev/null @@ -1,500 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qplatformglcontext_qpa.h" -#include "qguiglcontext_qpa.h" -#include "qguiglcontext_qpa_p.h" -#include "qwindow.h" - -#include -#include - -#include -#include - -#include - -class QGuiGLThreadContext -{ -public: - ~QGuiGLThreadContext() { - if (context) - context->doneCurrent(); - } - QGuiGLContext *context; -}; - -static QThreadStorage qwindow_context_storage; - -void QGuiGLContextPrivate::setCurrentContext(QGuiGLContext *context) -{ - QGuiGLThreadContext *threadContext = qwindow_context_storage.localData(); - if (!threadContext) { - if (!QThread::currentThread()) { - qWarning("No QTLS available. currentContext wont work"); - return; - } - threadContext = new QGuiGLThreadContext; - qwindow_context_storage.setLocalData(threadContext); - } - threadContext->context = context; -} - -/*! - Returns the last context which called makeCurrent. This function is thread aware. -*/ -QGuiGLContext* QGuiGLContext::currentContext() -{ - QGuiGLThreadContext *threadContext = qwindow_context_storage.localData(); - if(threadContext) { - return threadContext->context; - } - return 0; -} - -bool QGuiGLContext::areSharing(QGuiGLContext *first, QGuiGLContext *second) -{ - return first->shareGroup() == second->shareGroup(); -} - -QPlatformGLContext *QGuiGLContext::handle() const -{ - Q_D(const QGuiGLContext); - return d->platformGLContext; -} - -QPlatformGLContext *QGuiGLContext::shareHandle() const -{ - Q_D(const QGuiGLContext); - if (d->shareContext) - return d->shareContext->handle(); - return 0; -} - -/*! - Creates a new GL context instance, you need to call create() before it can be used. -*/ -QGuiGLContext::QGuiGLContext() - : QObject(*new QGuiGLContextPrivate()) -{ - Q_D(QGuiGLContext); - d->screen = QGuiApplication::primaryScreen(); -} - -/*! - Sets the format the GL context should be compatible with. You need to call create() before it takes effect. -*/ -void QGuiGLContext::setFormat(const QSurfaceFormat &format) -{ - Q_D(QGuiGLContext); - d->requestedFormat = format; -} - -/*! - Sets the context to share textures, shaders, and other GL resources with. You need to call create() before it takes effect. -*/ -void QGuiGLContext::setShareContext(QGuiGLContext *shareContext) -{ - Q_D(QGuiGLContext); - d->shareContext = shareContext; -} - -/*! - Sets the screen the GL context should be valid for. You need to call create() before it takes effect. -*/ -void QGuiGLContext::setScreen(QScreen *screen) -{ - Q_D(QGuiGLContext); - d->screen = screen; - if (!d->screen) - d->screen = QGuiApplication::primaryScreen(); -} - -/*! - Attempts to create the GL context with the desired parameters. - - Returns true if the native context was successfully created and is ready to be used. -*/ -bool QGuiGLContext::create() -{ - destroy(); - - Q_D(QGuiGLContext); - d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformGLContext(this); - d->platformGLContext->setContext(this); - d->shareGroup = d->shareContext ? d->shareContext->shareGroup() : new QGuiGLContextGroup; - d->shareGroup->d_func()->addContext(this); - return d->platformGLContext; -} - -void QGuiGLContext::destroy() -{ - Q_D(QGuiGLContext); - if (QGuiGLContext::currentContext() == this) - doneCurrent(); - if (d->shareGroup) - d->shareGroup->d_func()->removeContext(this); - d->shareGroup = 0; - delete d->platformGLContext; - d->platformGLContext = 0; -} - -/*! - If this is the current context for the thread, doneCurrent is called -*/ -QGuiGLContext::~QGuiGLContext() -{ - destroy(); -} - -/*! - Returns if this context is valid, i.e. has been successfully created. -*/ -bool QGuiGLContext::isValid() const -{ - Q_D(const QGuiGLContext); - return d->platformGLContext != 0; -} - -/*! - If surface is 0 this is equivalent to calling doneCurrent(). -*/ -bool QGuiGLContext::makeCurrent(QSurface *surface) -{ - Q_D(QGuiGLContext); - if (!d->platformGLContext) - return false; - - if (!surface) { - doneCurrent(); - return true; - } - - if (!surface->surfaceHandle()) - return false; - - if (d->platformGLContext->makeCurrent(surface->surfaceHandle())) { - QGuiGLContextPrivate::setCurrentContext(this); - d->surface = surface; - - d->shareGroup->d_func()->deletePendingResources(this); - - return true; - } - - return false; -} - -/*! - Convenience function for calling makeCurrent with a 0 surface. -*/ -void QGuiGLContext::doneCurrent() -{ - Q_D(QGuiGLContext); - if (!d->platformGLContext) - return; - - if (QGuiGLContext::currentContext() == this) - d->shareGroup->d_func()->deletePendingResources(this); - - d->platformGLContext->doneCurrent(); - QGuiGLContextPrivate::setCurrentContext(0); - - d->surface = 0; -} - -/*! - Returns the surface the context is current for. -*/ -QSurface *QGuiGLContext::surface() const -{ - Q_D(const QGuiGLContext); - return d->surface; -} - - -void QGuiGLContext::swapBuffers(QSurface *surface) -{ - Q_D(QGuiGLContext); - if (!d->platformGLContext) - return; - - if (!surface) { - qWarning() << "QGuiGLContext::swapBuffers() called with null argument"; - return; - } - - d->platformGLContext->swapBuffers(surface->surfaceHandle()); -} - -void (*QGuiGLContext::getProcAddress(const QByteArray &procName)) () -{ - Q_D(QGuiGLContext); - if (!d->platformGLContext) - return 0; - return d->platformGLContext->getProcAddress(procName); -} - -QSurfaceFormat QGuiGLContext::format() const -{ - Q_D(const QGuiGLContext); - if (!d->platformGLContext) - return d->requestedFormat; - return d->platformGLContext->format(); -} - -QGuiGLContextGroup *QGuiGLContext::shareGroup() const -{ - Q_D(const QGuiGLContext); - return d->shareGroup; -} - -QGuiGLContext *QGuiGLContext::shareContext() const -{ - Q_D(const QGuiGLContext); - return d->shareContext; -} - -QScreen *QGuiGLContext::screen() const -{ - Q_D(const QGuiGLContext); - return d->screen; -} - -/* - internal: Needs to have a pointer to qGLContext. But since this is in QtGui we cant - have any type information. -*/ -void *QGuiGLContext::qGLContextHandle() const -{ - Q_D(const QGuiGLContext); - return d->qGLContextHandle; -} - -void QGuiGLContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *)) -{ - Q_D(QGuiGLContext); - d->qGLContextHandle = handle; - d->qGLContextDeleteFunction = qGLContextDeleteFunction; -} - -void QGuiGLContext::deleteQGLContext() -{ - Q_D(QGuiGLContext); - if (d->qGLContextDeleteFunction && d->qGLContextHandle) { - d->qGLContextDeleteFunction(d->qGLContextHandle); - d->qGLContextDeleteFunction = 0; - d->qGLContextHandle = 0; - } -} - -QGuiGLContextGroup::QGuiGLContextGroup() - : QObject(*new QGuiGLContextGroupPrivate()) -{ -} - -QGuiGLContextGroup::~QGuiGLContextGroup() -{ - Q_D(QGuiGLContextGroup); - - QList::iterator it = d->m_sharedResources.begin(); - QList::iterator end = d->m_sharedResources.end(); - - while (it != end) { - (*it)->invalidateResource(); - (*it)->m_group = 0; - ++it; - } - - qDeleteAll(d->m_pendingDeletion.begin(), d->m_pendingDeletion.end()); -} - -QList QGuiGLContextGroup::shares() const -{ - Q_D(const QGuiGLContextGroup); - return d->m_shares; -} - -QGuiGLContextGroup *QGuiGLContextGroup::currentContextGroup() -{ - QGuiGLContext *current = QGuiGLContext::currentContext(); - return current ? current->shareGroup() : 0; -} - -void QGuiGLContextGroupPrivate::addContext(QGuiGLContext *ctx) -{ - QMutexLocker locker(&m_mutex); - m_refs.ref(); - m_shares << ctx; -} - -void QGuiGLContextGroupPrivate::removeContext(QGuiGLContext *ctx) -{ - Q_Q(QGuiGLContextGroup); - - QMutexLocker locker(&m_mutex); - m_shares.removeOne(ctx); - - if (ctx == m_context && !m_shares.isEmpty()) - m_context = m_shares.first(); - - if (!m_refs.deref()) - q->deleteLater(); -} - -void QGuiGLContextGroupPrivate::deletePendingResources(QGuiGLContext *ctx) -{ - QMutexLocker locker(&m_mutex); - - QList::iterator it = m_pendingDeletion.begin(); - QList::iterator end = m_pendingDeletion.end(); - while (it != end) { - (*it)->freeResource(ctx); - delete *it; - ++it; - } - m_pendingDeletion.clear(); -} - -QGLSharedResource::QGLSharedResource(QGuiGLContextGroup *group) - : m_group(group) -{ - QMutexLocker locker(&m_group->d_func()->m_mutex); - m_group->d_func()->m_sharedResources << this; -} - -QGLSharedResource::~QGLSharedResource() -{ -} - -// schedule the resource for deletion at an appropriate time -void QGLSharedResource::free() -{ - if (!m_group) { - delete this; - return; - } - - QMutexLocker locker(&m_group->d_func()->m_mutex); - m_group->d_func()->m_sharedResources.removeOne(this); - m_group->d_func()->m_pendingDeletion << this; - - // can we delete right away? - QGuiGLContext *current = QGuiGLContext::currentContext(); - if (current && current->shareGroup() == m_group) { - m_group->d_func()->deletePendingResources(current); - } -} - -QGLMultiGroupSharedResource::QGLMultiGroupSharedResource() - : active(0) -{ -#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG - qDebug("Creating context group resource object %p.", this); -#endif -} - -QGLMultiGroupSharedResource::~QGLMultiGroupSharedResource() -{ -#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG - qDebug("Deleting context group resource %p. Group size: %d.", this, m_groups.size()); -#endif - for (int i = 0; i < m_groups.size(); ++i) { - QGuiGLContext *context = m_groups.at(i)->shares().first(); - QGLSharedResource *resource = value(context); - if (resource) - resource->free(); - m_groups.at(i)->d_func()->m_resources.remove(this); - active.deref(); - } -#ifndef QT_NO_DEBUG - if (active != 0) { - qWarning("QtOpenGL: Resources are still available at program shutdown.\n" - " This is possibly caused by a leaked QGLWidget, \n" - " QGLFramebufferObject or QGLPixelBuffer."); - } -#endif -} - -void QGLMultiGroupSharedResource::insert(QGuiGLContext *context, QGLSharedResource *value) -{ -#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG - qDebug("Inserting context group resource %p for context %p, managed by %p.", value, context, this); -#endif - QGuiGLContextGroup *group = context->shareGroup(); - Q_ASSERT(!group->d_func()->m_resources.contains(this)); - group->d_func()->m_resources.insert(this, value); - m_groups.append(group); - active.ref(); -} - -QGLSharedResource *QGLMultiGroupSharedResource::value(QGuiGLContext *context) -{ - QGuiGLContextGroup *group = context->shareGroup(); - return group->d_func()->m_resources.value(this, 0); -} - -void QGLMultiGroupSharedResource::cleanup(QGuiGLContext *ctx) -{ - QGLSharedResource *resource = value(ctx); - - if (resource != 0) { - resource->free(); - - QGuiGLContextGroup *group = ctx->shareGroup(); - group->d_func()->m_resources.remove(this); - m_groups.removeOne(group); - active.deref(); - } -} - -void QGLMultiGroupSharedResource::cleanup(QGuiGLContext *ctx, QGLSharedResource *value) -{ -#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG - qDebug("Cleaning up context group resource %p, for context %p in thread %p.", this, ctx, QThread::currentThread()); -#endif - value->free(); - active.deref(); - - QGuiGLContextGroup *group = ctx->shareGroup(); - m_groups.removeOne(group); -} - diff --git a/src/gui/kernel/qguiglcontext_qpa.h b/src/gui/kernel/qguiglcontext_qpa.h deleted file mode 100644 index a234bd3cb6..0000000000 --- a/src/gui/kernel/qguiglcontext_qpa.h +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGUIGLCONTEXT_H -#define QGUIGLCONTEXT_H - -#include -#include - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QGuiGLContextPrivate; -class QGuiGLContextGroupPrivate; -class QPlatformGLContext; -class QSurface; - -class Q_GUI_EXPORT QGuiGLContextGroup : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QGuiGLContextGroup) -public: - ~QGuiGLContextGroup(); - - QList shares() const; - - static QGuiGLContextGroup *currentContextGroup(); - -private: - QGuiGLContextGroup(); - - friend class QGuiGLContext; - friend class QGLContextGroupResourceBase; - friend class QGLSharedResource; - friend class QGLMultiGroupSharedResource; -}; - -class Q_GUI_EXPORT QGuiGLContext : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QGuiGLContext); -public: - QGuiGLContext(); - ~QGuiGLContext(); - - void setFormat(const QSurfaceFormat &format); - void setShareContext(QGuiGLContext *shareContext); - void setScreen(QScreen *screen); - - bool create(); - bool isValid() const; - - QSurfaceFormat format() const; - QGuiGLContext *shareContext() const; - QGuiGLContextGroup *shareGroup() const; - QScreen *screen() const; - - bool makeCurrent(QSurface *surface); - void doneCurrent(); - - void swapBuffers(QSurface *surface); - void (*getProcAddress(const QByteArray &procName)) (); - - QSurface *surface() const; - - static QGuiGLContext *currentContext(); - static bool areSharing(QGuiGLContext *first, QGuiGLContext *second); - - QPlatformGLContext *handle() const; - QPlatformGLContext *shareHandle() const; - -private: - //hack to make it work with QGLContext::CurrentContext - friend class QGLContext; - friend class QGLContextResourceBase; - friend class QWidgetPrivate; - - void *qGLContextHandle() const; - void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *)); - void deleteQGLContext(); - - void destroy(); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QGUIGLCONTEXT_H diff --git a/src/gui/kernel/qguiglcontext_qpa_p.h b/src/gui/kernel/qguiglcontext_qpa_p.h deleted file mode 100644 index a9c8f5c75e..0000000000 --- a/src/gui/kernel/qguiglcontext_qpa_p.h +++ /dev/null @@ -1,181 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGUIGLCONTEXT_P_H -#define QGUIGLCONTEXT_P_H - -#include "qguiglcontext_qpa.h" -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QGuiGLContext; -class QGLMultiGroupSharedResource; - -class Q_GUI_EXPORT QGLSharedResource -{ -public: - QGLSharedResource(QGuiGLContextGroup *group); - virtual ~QGLSharedResource() = 0; - - QGuiGLContextGroup *group() const { return m_group; } - - // schedule the resource for deletion at an appropriate time - void free(); - -protected: - // the resource's share group no longer exists, invalidate the resource - virtual void invalidateResource() = 0; - - // a valid context in the group is current, free the resource - virtual void freeResource(QGuiGLContext *context) = 0; - -private: - QGuiGLContextGroup *m_group; - - friend class QGuiGLContextGroup; - friend class QGuiGLContextGroupPrivate; - - Q_DISABLE_COPY(QGLSharedResource); -}; - -class Q_GUI_EXPORT QGuiGLContextGroupPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QGuiGLContextGroup); -public: - QGuiGLContextGroupPrivate() - : m_context(0) - , m_mutex(QMutex::Recursive) - , m_refs(0) - { - } - - void addContext(QGuiGLContext *ctx); - void removeContext(QGuiGLContext *ctx); - - void deletePendingResources(QGuiGLContext *ctx); - - QGuiGLContext *m_context; - - QList m_shares; - QMutex m_mutex; - - QHash m_resources; - QAtomicInt m_refs; - - QList m_sharedResources; - QList m_pendingDeletion; - - void cleanupResources(QGuiGLContext *ctx); -}; - -class Q_GUI_EXPORT QGLMultiGroupSharedResource -{ -public: - QGLMultiGroupSharedResource(); - ~QGLMultiGroupSharedResource(); - - void insert(QGuiGLContext *context, QGLSharedResource *value); - void cleanup(QGuiGLContext *context); - void cleanup(QGuiGLContext *context, QGLSharedResource *value); - - QGLSharedResource *value(QGuiGLContext *context); - - template - T *value(QGuiGLContext *context) { - QGuiGLContextGroup *group = context->shareGroup(); - T *resource = static_cast(group->d_func()->m_resources.value(this, 0)); - if (!resource) { - resource = new T(context); - insert(context, resource); - } - return resource; - } - -private: - QAtomicInt active; - QList m_groups; -}; - -class Q_GUI_EXPORT QGuiGLContextPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QGuiGLContext); -public: - QGuiGLContextPrivate() - : qGLContextHandle(0) - , platformGLContext(0) - , shareContext(0) - , shareGroup(0) - , screen(0) - , surface(0) - { - } - - virtual ~QGuiGLContextPrivate() - { - //do not delete the QGLContext handle here as it is deleted in - //QWidgetPrivate::deleteTLSysExtra() - } - void *qGLContextHandle; - void (*qGLContextDeleteFunction)(void *handle); - - QSurfaceFormat requestedFormat; - QPlatformGLContext *platformGLContext; - QGuiGLContext *shareContext; - QGuiGLContextGroup *shareGroup; - QScreen *screen; - QSurface *surface; - - QHash m_resources; - - static void setCurrentContext(QGuiGLContext *context); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QGUIGLCONTEXT_P_H diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp new file mode 100644 index 0000000000..92a651ddf4 --- /dev/null +++ b/src/gui/kernel/qopenglcontext.cpp @@ -0,0 +1,531 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qplatformopenglcontext_qpa.h" +#include "qopenglcontext.h" +#include "qopenglcontext_p.h" +#include "qwindow.h" + +#include +#include + +#include +#include + +#include + +#include + +class QGuiGLThreadContext +{ +public: + ~QGuiGLThreadContext() { + if (context) + context->doneCurrent(); + } + QOpenGLContext *context; +}; + +static QThreadStorage qwindow_context_storage; + +void QOpenGLContextPrivate::setCurrentContext(QOpenGLContext *context) +{ + QGuiGLThreadContext *threadContext = qwindow_context_storage.localData(); + if (!threadContext) { + if (!QThread::currentThread()) { + qWarning("No QTLS available. currentContext wont work"); + return; + } + threadContext = new QGuiGLThreadContext; + qwindow_context_storage.setLocalData(threadContext); + } + threadContext->context = context; +} + +/*! + Returns the last context which called makeCurrent. This function is thread aware. +*/ +QOpenGLContext* QOpenGLContext::currentContext() +{ + QGuiGLThreadContext *threadContext = qwindow_context_storage.localData(); + if(threadContext) { + return threadContext->context; + } + return 0; +} + +bool QOpenGLContext::areSharing(QOpenGLContext *first, QOpenGLContext *second) +{ + return first->shareGroup() == second->shareGroup(); +} + +QPlatformOpenGLContext *QOpenGLContext::handle() const +{ + Q_D(const QOpenGLContext); + return d->platformGLContext; +} + +QPlatformOpenGLContext *QOpenGLContext::shareHandle() const +{ + Q_D(const QOpenGLContext); + if (d->shareContext) + return d->shareContext->handle(); + return 0; +} + +/*! + Creates a new GL context instance, you need to call create() before it can be used. +*/ +QOpenGLContext::QOpenGLContext(QObject *parent) + : QObject(*new QOpenGLContextPrivate(), parent) +{ + Q_D(QOpenGLContext); + d->screen = QGuiApplication::primaryScreen(); +} + +/*! + Sets the format the GL context should be compatible with. You need to call create() before it takes effect. +*/ +void QOpenGLContext::setFormat(const QSurfaceFormat &format) +{ + Q_D(QOpenGLContext); + d->requestedFormat = format; +} + +/*! + Sets the context to share textures, shaders, and other GL resources with. You need to call create() before it takes effect. +*/ +void QOpenGLContext::setShareContext(QOpenGLContext *shareContext) +{ + Q_D(QOpenGLContext); + d->shareContext = shareContext; +} + +/*! + Sets the screen the GL context should be valid for. You need to call create() before it takes effect. +*/ +void QOpenGLContext::setScreen(QScreen *screen) +{ + Q_D(QOpenGLContext); + d->screen = screen; + if (!d->screen) + d->screen = QGuiApplication::primaryScreen(); +} + +/*! + Attempts to create the GL context with the desired parameters. + + Returns true if the native context was successfully created and is ready to be used. +*/ +bool QOpenGLContext::create() +{ + destroy(); + + Q_D(QOpenGLContext); + d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this); + d->platformGLContext->setContext(this); + d->shareGroup = d->shareContext ? d->shareContext->shareGroup() : new QOpenGLContextGroup; + d->shareGroup->d_func()->addContext(this); + return d->platformGLContext; +} + +void QOpenGLContext::destroy() +{ + Q_D(QOpenGLContext); + if (QOpenGLContext::currentContext() == this) + doneCurrent(); + if (d->shareGroup) + d->shareGroup->d_func()->removeContext(this); + d->shareGroup = 0; + delete d->platformGLContext; + d->platformGLContext = 0; + delete d->functions; + d->functions = 0; +} + +/*! + If this is the current context for the thread, doneCurrent is called +*/ +QOpenGLContext::~QOpenGLContext() +{ + destroy(); +} + +/*! + Returns if this context is valid, i.e. has been successfully created. +*/ +bool QOpenGLContext::isValid() const +{ + Q_D(const QOpenGLContext); + return d->platformGLContext != 0; +} + +/*! + Get the QOpenGLFunctions instance for this context. + + The context or a sharing context must be current. +*/ + +QOpenGLFunctions *QOpenGLContext::functions() const +{ + Q_D(const QOpenGLContext); + if (!d->functions) + const_cast(d->functions) = new QOpenGLExtensions(QOpenGLContext::currentContext()); + return d->functions; +} + +/*! + If surface is 0 this is equivalent to calling doneCurrent(). +*/ +bool QOpenGLContext::makeCurrent(QSurface *surface) +{ + Q_D(QOpenGLContext); + if (!d->platformGLContext) + return false; + + if (!surface) { + doneCurrent(); + return true; + } + + if (!surface->surfaceHandle()) + return false; + + if (d->platformGLContext->makeCurrent(surface->surfaceHandle())) { + QOpenGLContextPrivate::setCurrentContext(this); + d->surface = surface; + + d->shareGroup->d_func()->deletePendingResources(this); + + return true; + } + + return false; +} + +/*! + Convenience function for calling makeCurrent with a 0 surface. +*/ +void QOpenGLContext::doneCurrent() +{ + Q_D(QOpenGLContext); + if (!d->platformGLContext) + return; + + if (QOpenGLContext::currentContext() == this) + d->shareGroup->d_func()->deletePendingResources(this); + + d->platformGLContext->doneCurrent(); + QOpenGLContextPrivate::setCurrentContext(0); + + d->surface = 0; +} + +/*! + Returns the surface the context is current for. +*/ +QSurface *QOpenGLContext::surface() const +{ + Q_D(const QOpenGLContext); + return d->surface; +} + + +void QOpenGLContext::swapBuffers(QSurface *surface) +{ + Q_D(QOpenGLContext); + if (!d->platformGLContext) + return; + + if (!surface) { + qWarning() << "QOpenGLContext::swapBuffers() called with null argument"; + return; + } + + d->platformGLContext->swapBuffers(surface->surfaceHandle()); +} + +void (*QOpenGLContext::getProcAddress(const QByteArray &procName)) () +{ + Q_D(QOpenGLContext); + if (!d->platformGLContext) + return 0; + return d->platformGLContext->getProcAddress(procName); +} + +QSurfaceFormat QOpenGLContext::format() const +{ + Q_D(const QOpenGLContext); + if (!d->platformGLContext) + return d->requestedFormat; + return d->platformGLContext->format(); +} + +QOpenGLContextGroup *QOpenGLContext::shareGroup() const +{ + Q_D(const QOpenGLContext); + return d->shareGroup; +} + +QOpenGLContext *QOpenGLContext::shareContext() const +{ + Q_D(const QOpenGLContext); + return d->shareContext; +} + +QScreen *QOpenGLContext::screen() const +{ + Q_D(const QOpenGLContext); + return d->screen; +} + +/* + internal: Needs to have a pointer to qGLContext. But since this is in QtGui we cant + have any type information. +*/ +void *QOpenGLContext::qGLContextHandle() const +{ + Q_D(const QOpenGLContext); + return d->qGLContextHandle; +} + +void QOpenGLContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *)) +{ + Q_D(QOpenGLContext); + d->qGLContextHandle = handle; + d->qGLContextDeleteFunction = qGLContextDeleteFunction; +} + +void QOpenGLContext::deleteQGLContext() +{ + Q_D(QOpenGLContext); + if (d->qGLContextDeleteFunction && d->qGLContextHandle) { + d->qGLContextDeleteFunction(d->qGLContextHandle); + d->qGLContextDeleteFunction = 0; + d->qGLContextHandle = 0; + } +} + +QOpenGLContextGroup::QOpenGLContextGroup() + : QObject(*new QOpenGLContextGroupPrivate()) +{ +} + +QOpenGLContextGroup::~QOpenGLContextGroup() +{ + Q_D(QOpenGLContextGroup); + + QList::iterator it = d->m_sharedResources.begin(); + QList::iterator end = d->m_sharedResources.end(); + + while (it != end) { + (*it)->invalidateResource(); + (*it)->m_group = 0; + ++it; + } + + qDeleteAll(d->m_pendingDeletion.begin(), d->m_pendingDeletion.end()); +} + +QList QOpenGLContextGroup::shares() const +{ + Q_D(const QOpenGLContextGroup); + return d->m_shares; +} + +QOpenGLContextGroup *QOpenGLContextGroup::currentContextGroup() +{ + QOpenGLContext *current = QOpenGLContext::currentContext(); + return current ? current->shareGroup() : 0; +} + +void QOpenGLContextGroupPrivate::addContext(QOpenGLContext *ctx) +{ + QMutexLocker locker(&m_mutex); + m_refs.ref(); + m_shares << ctx; +} + +void QOpenGLContextGroupPrivate::removeContext(QOpenGLContext *ctx) +{ + Q_Q(QOpenGLContextGroup); + + QMutexLocker locker(&m_mutex); + m_shares.removeOne(ctx); + + if (ctx == m_context && !m_shares.isEmpty()) + m_context = m_shares.first(); + + if (!m_refs.deref()) + q->deleteLater(); +} + +void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx) +{ + QMutexLocker locker(&m_mutex); + + QList pending = m_pendingDeletion; + m_pendingDeletion.clear(); + + QList::iterator it = pending.begin(); + QList::iterator end = pending.end(); + while (it != end) { + (*it)->freeResource(ctx); + delete *it; + ++it; + } +} + +QOpenGLSharedResource::QOpenGLSharedResource(QOpenGLContextGroup *group) + : m_group(group) +{ + QMutexLocker locker(&m_group->d_func()->m_mutex); + m_group->d_func()->m_sharedResources << this; +} + +QOpenGLSharedResource::~QOpenGLSharedResource() +{ +} + +// schedule the resource for deletion at an appropriate time +void QOpenGLSharedResource::free() +{ + if (!m_group) { + delete this; + return; + } + + QMutexLocker locker(&m_group->d_func()->m_mutex); + m_group->d_func()->m_sharedResources.removeOne(this); + m_group->d_func()->m_pendingDeletion << this; + + // can we delete right away? + QOpenGLContext *current = QOpenGLContext::currentContext(); + if (current && current->shareGroup() == m_group) { + m_group->d_func()->deletePendingResources(current); + } +} + +void QOpenGLSharedResourceGuard::freeResource(QOpenGLContext *context) +{ + if (m_id) { + QOpenGLFunctions functions(context); + m_func(&functions, m_id); + m_id = 0; + } +} + +QOpenGLMultiGroupSharedResource::QOpenGLMultiGroupSharedResource() + : active(0) +{ +#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG + qDebug("Creating context group resource object %p.", this); +#endif +} + +QOpenGLMultiGroupSharedResource::~QOpenGLMultiGroupSharedResource() +{ +#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG + qDebug("Deleting context group resource %p. Group size: %d.", this, m_groups.size()); +#endif + for (int i = 0; i < m_groups.size(); ++i) { + if (!m_groups.at(i)->shares().isEmpty()) { + QOpenGLContext *context = m_groups.at(i)->shares().first(); + QOpenGLSharedResource *resource = value(context); + if (resource) + resource->free(); + } + m_groups.at(i)->d_func()->m_resources.remove(this); + active.deref(); + } +#ifndef QT_NO_DEBUG + if (active != 0) { + qWarning("QtGui: Resources are still available at program shutdown.\n" + " This is possibly caused by a leaked QOpenGLWidget, \n" + " QOpenGLFramebufferObject or QOpenGLPixelBuffer."); + } +#endif +} + +void QOpenGLMultiGroupSharedResource::insert(QOpenGLContext *context, QOpenGLSharedResource *value) +{ +#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG + qDebug("Inserting context group resource %p for context %p, managed by %p.", value, context, this); +#endif + QOpenGLContextGroup *group = context->shareGroup(); + Q_ASSERT(!group->d_func()->m_resources.contains(this)); + group->d_func()->m_resources.insert(this, value); + m_groups.append(group); + active.ref(); +} + +QOpenGLSharedResource *QOpenGLMultiGroupSharedResource::value(QOpenGLContext *context) +{ + QOpenGLContextGroup *group = context->shareGroup(); + return group->d_func()->m_resources.value(this, 0); +} + +void QOpenGLMultiGroupSharedResource::cleanup(QOpenGLContext *ctx) +{ + QOpenGLSharedResource *resource = value(ctx); + + if (resource != 0) { + resource->free(); + + QOpenGLContextGroup *group = ctx->shareGroup(); + group->d_func()->m_resources.remove(this); + m_groups.removeOne(group); + active.deref(); + } +} + +void QOpenGLMultiGroupSharedResource::cleanup(QOpenGLContext *ctx, QOpenGLSharedResource *value) +{ +#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG + qDebug("Cleaning up context group resource %p, for context %p in thread %p.", this, ctx, QThread::currentThread()); +#endif + value->free(); + active.deref(); + + QOpenGLContextGroup *group = ctx->shareGroup(); + m_groups.removeOne(group); +} + diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h new file mode 100644 index 0000000000..cf334709ec --- /dev/null +++ b/src/gui/kernel/qopenglcontext.h @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QOPENGLCONTEXT_H +#define QOPENGLCONTEXT_H + +#include +#include + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QOpenGLContextPrivate; +class QOpenGLContextGroupPrivate; +class QOpenGLFunctions; +class QPlatformOpenGLContext; + +class QScreen; +class QSurface; + +class Q_GUI_EXPORT QOpenGLContextGroup : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QOpenGLContextGroup) +public: + ~QOpenGLContextGroup(); + + QList shares() const; + + static QOpenGLContextGroup *currentContextGroup(); + +private: + QOpenGLContextGroup(); + + friend class QOpenGLContext; + friend class QOpenGLContextGroupResourceBase; + friend class QOpenGLSharedResource; + friend class QOpenGLMultiGroupSharedResource; +}; + +class Q_GUI_EXPORT QOpenGLContext : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QOpenGLContext); +public: + QOpenGLContext(QObject *parent = 0); + ~QOpenGLContext(); + + void setFormat(const QSurfaceFormat &format); + void setShareContext(QOpenGLContext *shareContext); + void setScreen(QScreen *screen); + + bool create(); + bool isValid() const; + + QSurfaceFormat format() const; + QOpenGLContext *shareContext() const; + QOpenGLContextGroup *shareGroup() const; + QScreen *screen() const; + + bool makeCurrent(QSurface *surface); + void doneCurrent(); + + void swapBuffers(QSurface *surface); + void (*getProcAddress(const QByteArray &procName)) (); + + QSurface *surface() const; + + static QOpenGLContext *currentContext(); + static bool areSharing(QOpenGLContext *first, QOpenGLContext *second); + + QPlatformOpenGLContext *handle() const; + QPlatformOpenGLContext *shareHandle() const; + + QOpenGLFunctions *functions() const; + +private: + friend class QGLContext; + friend class QOpenGLContextResourceBase; + friend class QOpenGLPaintDevice; + friend class QOpenGLGlyphTexture; + friend class QOpenGLTextureGlyphCache; + friend class QOpenGLEngineShaderManager; + friend class QOpenGLFramebufferObject; + friend class QOpenGLFramebufferObjectPrivate; + friend class QOpenGL2PaintEngineEx; + friend class QOpenGL2PaintEngineExPrivate; + friend class QSGDistanceFieldGlyphCache; + friend class QWidgetPrivate; + + void *qGLContextHandle() const; + void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *)); + void deleteQGLContext(); + + void destroy(); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGUIGLCONTEXT_H diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h new file mode 100644 index 0000000000..61cfbf9563 --- /dev/null +++ b/src/gui/kernel/qopenglcontext_p.h @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGUIGLCONTEXT_P_H +#define QGUIGLCONTEXT_P_H + +#include "qopengl.h" +#include "qopenglcontext.h" +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QOpenGLFunctions; +class QOpenGLContext; +class QOpenGLMultiGroupSharedResource; + +class Q_GUI_EXPORT QOpenGLSharedResource +{ +public: + QOpenGLSharedResource(QOpenGLContextGroup *group); + virtual ~QOpenGLSharedResource() = 0; + + QOpenGLContextGroup *group() const { return m_group; } + + // schedule the resource for deletion at an appropriate time + void free(); + +protected: + // the resource's share group no longer exists, invalidate the resource + virtual void invalidateResource() = 0; + + // a valid context in the group is current, free the resource + virtual void freeResource(QOpenGLContext *context) = 0; + +private: + QOpenGLContextGroup *m_group; + + friend class QOpenGLContextGroup; + friend class QOpenGLContextGroupPrivate; + + Q_DISABLE_COPY(QOpenGLSharedResource); +}; + +class Q_GUI_EXPORT QOpenGLSharedResourceGuard : public QOpenGLSharedResource +{ +public: + typedef void (*FreeResourceFunc)(QOpenGLFunctions *functions, GLuint id); + QOpenGLSharedResourceGuard(QOpenGLContext *context, GLuint id, FreeResourceFunc func) + : QOpenGLSharedResource(context->shareGroup()) + , m_id(id) + , m_func(func) + { + } + + GLuint id() const { return m_id; } + +protected: + void invalidateResource() + { + m_id = 0; + } + + void freeResource(QOpenGLContext *context); + +private: + GLuint m_id; + FreeResourceFunc m_func; +}; + +class Q_GUI_EXPORT QOpenGLContextGroupPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QOpenGLContextGroup); +public: + QOpenGLContextGroupPrivate() + : m_context(0) + , m_mutex(QMutex::Recursive) + , m_refs(0) + { + } + + void addContext(QOpenGLContext *ctx); + void removeContext(QOpenGLContext *ctx); + + void deletePendingResources(QOpenGLContext *ctx); + + QOpenGLContext *m_context; + + QList m_shares; + QMutex m_mutex; + + QHash m_resources; + QAtomicInt m_refs; + + QList m_sharedResources; + QList m_pendingDeletion; + + void cleanupResources(QOpenGLContext *ctx); +}; + +class Q_GUI_EXPORT QOpenGLMultiGroupSharedResource +{ +public: + QOpenGLMultiGroupSharedResource(); + ~QOpenGLMultiGroupSharedResource(); + + void insert(QOpenGLContext *context, QOpenGLSharedResource *value); + void cleanup(QOpenGLContext *context); + void cleanup(QOpenGLContext *context, QOpenGLSharedResource *value); + + QOpenGLSharedResource *value(QOpenGLContext *context); + + template + T *value(QOpenGLContext *context) { + QOpenGLContextGroup *group = context->shareGroup(); + T *resource = static_cast(group->d_func()->m_resources.value(this, 0)); + if (!resource) { + resource = new T(context); + insert(context, resource); + } + return resource; + } + +private: + QAtomicInt active; + QList m_groups; +}; + +class QPaintEngineEx; +class QOpenGLFunctions; + +class Q_GUI_EXPORT QOpenGLContextPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QOpenGLContext); +public: + QOpenGLContextPrivate() + : qGLContextHandle(0) + , platformGLContext(0) + , shareContext(0) + , shareGroup(0) + , screen(0) + , surface(0) + , functions(0) + , current_fbo(0) + , default_fbo(0) + , workaround_brokenFBOReadBack(false) + , workaround_brokenTexSubImage(false) + , active_engine(0) + { + } + + virtual ~QOpenGLContextPrivate() + { + //do not delete the QOpenGLContext handle here as it is deleted in + //QWidgetPrivate::deleteTLSysExtra() + } + + void *qGLContextHandle; + void (*qGLContextDeleteFunction)(void *handle); + + QSurfaceFormat requestedFormat; + QPlatformOpenGLContext *platformGLContext; + QOpenGLContext *shareContext; + QOpenGLContextGroup *shareGroup; + QScreen *screen; + QSurface *surface; + QOpenGLFunctions *functions; + + GLuint current_fbo; + GLuint default_fbo; + + bool workaround_brokenFBOReadBack; + bool workaround_brokenTexSubImage; + + QPaintEngineEx *active_engine; + + QHash m_resources; + + static void setCurrentContext(QOpenGLContext *context); + + int maxTextureSize() const { return 1024; } +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGUIGLCONTEXT_P_H diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp deleted file mode 100644 index 5ce7db09e2..0000000000 --- a/src/gui/kernel/qplatformglcontext_qpa.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qplatformglcontext_qpa.h" - -/*! - \class QPlatformGLContext - \since 4.8 - \internal - \preliminary - \ingroup qpa - - \brief The QPlatformGLContext class provides an abstraction for native GL contexts. - - In QPA the way to support OpenGL or OpenVG or other technologies that requires a native GL - context is through the QPlatformGLContext wrapper. - - There is no factory function for QPlatformGLContexts, but rather only one accessor function. - The only place to retrieve a QPlatformGLContext from is through a QPlatformWindow. - - The context which is current for a specific thread can be collected by the currentContext() - function. This is how QPlatformGLContext also makes it possible to use the QtOpenGL module - withhout using QGLWidget. When using QGLContext::currentContext(), it will ask - QPlatformGLContext for the currentContext. Then a corresponding QGLContext will be returned, - which maps to the QPlatformGLContext. -*/ - -/*! \fn void QPlatformGLContext::swapBuffers() - Reimplement in subclass to native swap buffers calls - - The implementation must support being called in a thread different than the gui-thread. -*/ - -/*! \fn void *QPlatformGLContext::getProcAddress(const QString &procName) - Reimplement in subclass to native getProcAddr calls. - - Note: its convenient to use qPrintable(const QString &str) to get the const char * pointer -*/ - -/*! \fn QPlatformWindowFormat QPlatformGLContext::platformWindowFormat() const - QWidget has the function qplatformWindowFormat(). That function is for the application - programmer to request the format of the window and the context that he wants. - - Reimplement this function in a subclass to indicate what format the glContext actually has. -*/ - -struct QPlatformGLContextPrivate -{ - QGuiGLContext *context; -}; - -QPlatformGLContext::QPlatformGLContext() - : d_ptr(new QPlatformGLContextPrivate) -{ - Q_D(QPlatformGLContext); - d->context = 0; -} - -QPlatformGLContext::~QPlatformGLContext() -{ -} - -QGuiGLContext *QPlatformGLContext::context() const -{ - Q_D(const QPlatformGLContext); - return d->context; -} - -void QPlatformGLContext::setContext(QGuiGLContext *context) -{ - Q_D(QPlatformGLContext); - d->context = context; -} diff --git a/src/gui/kernel/qplatformglcontext_qpa.h b/src/gui/kernel/qplatformglcontext_qpa.h deleted file mode 100644 index 30d7186bd1..0000000000 --- a/src/gui/kernel/qplatformglcontext_qpa.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPLATFORMGLCONTEXT_H -#define QPLATFORMGLCONTEXT_H - -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class Q_GUI_EXPORT QPlatformSurface -{ -public: - virtual QSurfaceFormat format() const = 0; - - QSurface::SurfaceType surfaceType() const { return m_type; } - -private: - QPlatformSurface(QSurface::SurfaceType type) : m_type(type) {} - - QSurface::SurfaceType m_type; - - friend class QPlatformWindow; -}; - -class QPlatformGLContextPrivate; - -class Q_GUI_EXPORT QPlatformGLContext -{ - Q_DECLARE_PRIVATE(QPlatformGLContext) -public: - QPlatformGLContext(); - virtual ~QPlatformGLContext(); - - virtual QSurfaceFormat format() const = 0; - - virtual void swapBuffers(QPlatformSurface *surface) = 0; - - virtual bool makeCurrent(QPlatformSurface *surface) = 0; - virtual void doneCurrent() = 0; - - virtual void (*getProcAddress(const QByteArray &procName)) () = 0; - - QGuiGLContext *context() const; - -private: - friend class QGuiGLContext; - - QScopedPointer d_ptr; - - void setContext(QGuiGLContext *context); - - Q_DISABLE_COPY(QPlatformGLContext) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - - -#endif // QPLATFORMGLCONTEXT_H diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp index ccbf52bb1e..39341fa88f 100644 --- a/src/gui/kernel/qplatformintegration_qpa.cpp +++ b/src/gui/kernel/qplatformintegration_qpa.cpp @@ -192,10 +192,10 @@ QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::Pix return new QRasterPlatformPixmap(type); } -QPlatformGLContext *QPlatformIntegration::createPlatformGLContext(QGuiGLContext *context) const +QPlatformOpenGLContext *QPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { Q_UNUSED(context); - qWarning("This plugin does not support createPlatformGLContext!"); + qWarning("This plugin does not support createPlatformOpenGLContext!"); return 0; } diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h index 97811d45b5..d26fcfabb4 100644 --- a/src/gui/kernel/qplatformintegration_qpa.h +++ b/src/gui/kernel/qplatformintegration_qpa.h @@ -59,7 +59,7 @@ class QPlatformFontDatabase; class QPlatformClipboard; class QPlatformNativeInterface; class QPlatformDrag; -class QPlatformGLContext; +class QPlatformOpenGLContext; class QGuiGLFormat; class QAbstractEventDispatcher; class QPlatformInputContext; @@ -80,7 +80,7 @@ public: virtual QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; virtual QPlatformWindow *createPlatformWindow(QWindow *window) const = 0; virtual QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const = 0; - virtual QPlatformGLContext *createPlatformGLContext(QGuiGLContext *context) const; + virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; // Event dispatcher: virtual QAbstractEventDispatcher *guiThreadEventDispatcher() const = 0; diff --git a/src/gui/kernel/qplatformnativeinterface_qpa.cpp b/src/gui/kernel/qplatformnativeinterface_qpa.cpp index 18bef8a595..20d136e691 100644 --- a/src/gui/kernel/qplatformnativeinterface_qpa.cpp +++ b/src/gui/kernel/qplatformnativeinterface_qpa.cpp @@ -50,7 +50,7 @@ void *QPlatformNativeInterface::nativeResourceForWindow(const QByteArray &resour return 0; } -void *QPlatformNativeInterface::nativeResourceForContext(const QByteArray &resource, QGuiGLContext *context) +void *QPlatformNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) { Q_UNUSED(resource); Q_UNUSED(context); diff --git a/src/gui/kernel/qplatformnativeinterface_qpa.h b/src/gui/kernel/qplatformnativeinterface_qpa.h index 136191e2aa..6ea8104fa3 100644 --- a/src/gui/kernel/qplatformnativeinterface_qpa.h +++ b/src/gui/kernel/qplatformnativeinterface_qpa.h @@ -50,14 +50,14 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -class QGuiGLContext; +class QOpenGLContext; class QWindow; class QBackingStore; class Q_GUI_EXPORT QPlatformNativeInterface { public: - virtual void *nativeResourceForContext(const QByteArray &resource, QGuiGLContext *context); + virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context); virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); virtual void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *backingStore); }; diff --git a/src/gui/kernel/qplatformopenglcontext_qpa.cpp b/src/gui/kernel/qplatformopenglcontext_qpa.cpp new file mode 100644 index 0000000000..2957b4db4b --- /dev/null +++ b/src/gui/kernel/qplatformopenglcontext_qpa.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qplatformopenglcontext_qpa.h" + +/*! + \class QPlatformOpenGLContext + \since 4.8 + \internal + \preliminary + \ingroup qpa + + \brief The QPlatformOpenGLContext class provides an abstraction for native GL contexts. + + In QPA the way to support OpenGL or OpenVG or other technologies that requires a native GL + context is through the QPlatformOpenGLContext wrapper. + + There is no factory function for QPlatformOpenGLContexts, but rather only one accessor function. + The only place to retrieve a QPlatformOpenGLContext from is through a QPlatformWindow. + + The context which is current for a specific thread can be collected by the currentContext() + function. This is how QPlatformOpenGLContext also makes it possible to use the QtGui module + withhout using QOpenGLWidget. When using QOpenGLContext::currentContext(), it will ask + QPlatformOpenGLContext for the currentContext. Then a corresponding QOpenGLContext will be returned, + which maps to the QPlatformOpenGLContext. +*/ + +/*! \fn void QPlatformOpenGLContext::swapBuffers() + Reimplement in subclass to native swap buffers calls + + The implementation must support being called in a thread different than the gui-thread. +*/ + +/*! \fn void *QPlatformOpenGLContext::getProcAddress(const QString &procName) + Reimplement in subclass to native getProcAddr calls. + + Note: its convenient to use qPrintable(const QString &str) to get the const char * pointer +*/ + +/*! \fn QPlatformWindowFormat QPlatformOpenGLContext::platformWindowFormat() const + QWidget has the function qplatformWindowFormat(). That function is for the application + programmer to request the format of the window and the context that he wants. + + Reimplement this function in a subclass to indicate what format the glContext actually has. +*/ + +struct QPlatformOpenGLContextPrivate +{ + QOpenGLContext *context; +}; + +QPlatformOpenGLContext::QPlatformOpenGLContext() + : d_ptr(new QPlatformOpenGLContextPrivate) +{ + Q_D(QPlatformOpenGLContext); + d->context = 0; +} + +QPlatformOpenGLContext::~QPlatformOpenGLContext() +{ +} + +QOpenGLContext *QPlatformOpenGLContext::context() const +{ + Q_D(const QPlatformOpenGLContext); + return d->context; +} + +void QPlatformOpenGLContext::setContext(QOpenGLContext *context) +{ + Q_D(QPlatformOpenGLContext); + d->context = context; +} diff --git a/src/gui/kernel/qplatformopenglcontext_qpa.h b/src/gui/kernel/qplatformopenglcontext_qpa.h new file mode 100644 index 0000000000..902ccdec6d --- /dev/null +++ b/src/gui/kernel/qplatformopenglcontext_qpa.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPLATFORMGLCONTEXT_H +#define QPLATFORMGLCONTEXT_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class Q_GUI_EXPORT QPlatformSurface +{ +public: + virtual QSurfaceFormat format() const = 0; + + QSurface::SurfaceType surfaceType() const { return m_type; } + +private: + QPlatformSurface(QSurface::SurfaceType type) : m_type(type) {} + + QSurface::SurfaceType m_type; + + friend class QPlatformWindow; +}; + +class QPlatformOpenGLContextPrivate; + +class Q_GUI_EXPORT QPlatformOpenGLContext +{ + Q_DECLARE_PRIVATE(QPlatformOpenGLContext) +public: + QPlatformOpenGLContext(); + virtual ~QPlatformOpenGLContext(); + + virtual QSurfaceFormat format() const = 0; + + virtual void swapBuffers(QPlatformSurface *surface) = 0; + + virtual bool makeCurrent(QPlatformSurface *surface) = 0; + virtual void doneCurrent() = 0; + + virtual void (*getProcAddress(const QByteArray &procName)) () = 0; + + QOpenGLContext *context() const; + +private: + friend class QOpenGLContext; + + QScopedPointer d_ptr; + + void setContext(QOpenGLContext *context); + + Q_DISABLE_COPY(QPlatformOpenGLContext) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + + +#endif // QPLATFORMGLCONTEXT_H diff --git a/src/gui/kernel/qplatformscreen_qpa.h b/src/gui/kernel/qplatformscreen_qpa.h index 8d3dd4cc71..3851b1821a 100644 --- a/src/gui/kernel/qplatformscreen_qpa.h +++ b/src/gui/kernel/qplatformscreen_qpa.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) class QPlatformBackingStore; -class QPlatformGLContext; +class QPlatformOpenGLContext; class QPlatformScreenPrivate; class QPlatformWindow; class QScreen; diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index 766967eafa..0734fb7a26 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -260,7 +260,7 @@ bool QPlatformWindow::setMouseGrabEnabled(bool grab) However, it is not concerned with how Qt renders into the window it represents. Visible QWindows will always have a QPlatformWindow. However, it is not necessary for - all windows to have a QWindowSurface. This is the case for QGLWidget. And could be the case for + all windows to have a QWindowSurface. This is the case for QOpenGLWidget. And could be the case for windows where some 3.party renders into it. The platform specific window handle can be retrieved by the winId function. @@ -268,7 +268,7 @@ bool QPlatformWindow::setMouseGrabEnabled(bool grab) QPlatformWindow is also the way QPA defines how native child windows should be supported through the setParent function. - The only way to retrieve a QPlatformGLContext in QPA is by calling the glContext() function + The only way to retrieve a QPlatformOpenGLContext in QPA is by calling the glContext() function on QPlatformWindow. \sa QWindowSurface, QWindow diff --git a/src/gui/kernel/qplatformwindow_qpa.h b/src/gui/kernel/qplatformwindow_qpa.h index 680b24ac9b..ef2e07d774 100644 --- a/src/gui/kernel/qplatformwindow_qpa.h +++ b/src/gui/kernel/qplatformwindow_qpa.h @@ -47,7 +47,7 @@ #include #include #include -#include +#include QT_BEGIN_HEADER diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp index 063e68d29f..c53c510d8c 100644 --- a/src/gui/kernel/qsurfaceformat.cpp +++ b/src/gui/kernel/qsurfaceformat.cpp @@ -44,6 +44,14 @@ #include #include +#ifdef major +#undef major +#endif + +#ifdef minor +#undef minor +#endif + class QSurfaceFormatPrivate { public: @@ -59,6 +67,8 @@ public: , swapBehavior(QSurfaceFormat::DefaultSwapBehavior) , numSamples(-1) , profile(QSurfaceFormat::NoProfile) + , major(1) + , minor(1) { } @@ -73,7 +83,9 @@ public: stencilSize(other->stencilSize), swapBehavior(other->swapBehavior), numSamples(other->numSamples), - profile(other->profile) + profile(other->profile), + major(other->major), + minor(other->minor) { } @@ -88,6 +100,8 @@ public: QSurfaceFormat::SwapBehavior swapBehavior; int numSamples; QSurfaceFormat::OpenGLContextProfile profile; + int major; + int minor; }; QSurfaceFormat::QSurfaceFormat() : d(new QSurfaceFormatPrivate) @@ -351,6 +365,12 @@ void QSurfaceFormat::setAlphaBufferSize(int size) } } +/*! + Sets the desired OpenGL context profile. + + This setting is ignored if the requested OpenGL version is + less than 3.2. +*/ void QSurfaceFormat::setProfile(OpenGLContextProfile profile) { if (d->profile != profile) { @@ -364,6 +384,38 @@ QSurfaceFormat::OpenGLContextProfile QSurfaceFormat::profile() const return d->profile; } +/*! + Sets the desired major OpenGL version. +*/ +void QSurfaceFormat::setMajorVersion(int major) +{ + d->major = major; +} + +/*! + Returns the major OpenGL version. +*/ +int QSurfaceFormat::majorVersion() const +{ + return d->major; +} + +/*! + Sets the desired minor OpenGL version. +*/ +void QSurfaceFormat::setMinorVersion(int minor) +{ + d->minor = minor; +} + +/*! + Returns the minor OpenGL version. +*/ +int QSurfaceFormat::minorVersion() const +{ + return d->minor; +} + bool operator==(const QSurfaceFormat& a, const QSurfaceFormat& b) { return (a.d == b.d) || ((int) a.d->opts == (int) b.d->opts diff --git a/src/gui/kernel/qsurfaceformat.h b/src/gui/kernel/qsurfaceformat.h index 6e89aa667b..f305edbcc9 100644 --- a/src/gui/kernel/qsurfaceformat.h +++ b/src/gui/kernel/qsurfaceformat.h @@ -49,14 +49,16 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -class QGuiGLContext; +class QOpenGLContext; class QSurfaceFormatPrivate; class Q_GUI_EXPORT QSurfaceFormat { public: enum FormatOption { - StereoBuffers = 0x0001 + StereoBuffers = 0x0001, + DebugContext = 0x0002, + DeprecatedFunctions = 0x0004 }; Q_DECLARE_FLAGS(FormatOptions, FormatOption) @@ -105,6 +107,12 @@ public: void setProfile(OpenGLContextProfile profile); OpenGLContextProfile profile() const; + void setMajorVersion(int majorVersion); + int majorVersion() const; + + void setMinorVersion(int minorVersion); + int minorVersion() const; + bool stereo() const; void setStereo(bool enable); diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 6fbc249631..c6e479358d 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -43,8 +43,8 @@ #include "qplatformwindow_qpa.h" #include "qsurfaceformat.h" -#include "qplatformglcontext_qpa.h" -#include "qguiglcontext_qpa.h" +#include "qplatformopenglcontext_qpa.h" +#include "qopenglcontext.h" #include "qscreen.h" #include "qwindow_p.h" -- cgit v1.2.3