summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-06-07 17:25:22 +0200
committerSamuel Rødal <samuel.rodal@nokia.com>2011-06-10 09:24:56 +0200
commit4a189c188ccd2fb5f8d1d5ddadf06cbd6bc0916f (patch)
tree99bff9f015e869b5521836ea5667590939b22a53 /src/gui/kernel
parent4d10e64f2a78e32418a98e1c80c6579ae0779dfc (diff)
QWindowContext / QWindowFormat refactor.
To enable having a single GL context used for multiple drawables we need to de-couple the context class a bit more from the window class in the plugin API. Now contexts are created stand-alone based on a GL format and a share context, and when calling makeCurrent() a desired surface is specified. This maps well to GLX, EGL, Cocoa, AGL, and WGL, which all support this use case. QWindowContext is renamed to QGuiGLContext, and QWindowFormat is renamed to QGuiGLFormat. We have the ability to introduce a pbuffer or similar other offscreen GL drawable abstraction in the future.
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/kernel.pri8
-rw-r--r--src/gui/kernel/qguiapplication.cpp8
-rw-r--r--src/gui/kernel/qguiglcontext_qpa.cpp247
-rw-r--r--src/gui/kernel/qguiglcontext_qpa.h (renamed from src/gui/kernel/qwindowcontext_qpa.h)38
-rw-r--r--src/gui/kernel/qguiglformat_qpa.cpp (renamed from src/gui/kernel/qwindowformat_qpa.cpp)128
-rw-r--r--src/gui/kernel/qguiglformat_qpa.h (renamed from src/gui/kernel/qwindowformat_qpa.h)55
-rw-r--r--src/gui/kernel/qplatformglcontext_qpa.h37
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.cpp7
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.h2
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.cpp4
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.h4
-rw-r--r--src/gui/kernel/qwindow.cpp32
-rw-r--r--src/gui/kernel/qwindow.h15
-rw-r--r--src/gui/kernel/qwindow_p.h6
-rw-r--r--src/gui/kernel/qwindowcontext_qpa.cpp201
15 files changed, 430 insertions, 362 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index f166e4ffeb..1d708e85b2 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -48,11 +48,11 @@ qpa {
kernel/qplatformintegrationplugin_qpa.h \
kernel/qplatformwindow_qpa.h \
kernel/qplatformglcontext_qpa.h \
- kernel/qwindowcontext_qpa.h \
+ kernel/qguiglcontext_qpa.h \
kernel/qplatformcursor_qpa.h \
kernel/qplatformclipboard_qpa.h \
kernel/qplatformnativeinterface_qpa.h \
- kernel/qwindowformat_qpa.h \
+ kernel/qguiglformat_qpa.h \
kernel/qguiapplication.h \
kernel/qguiapplication_p.h \
kernel/qwindow_p.h \
@@ -71,12 +71,12 @@ qpa {
kernel/qplatformintegrationplugin_qpa.cpp \
kernel/qplatformwindow_qpa.cpp \
kernel/qplatformglcontext_qpa.cpp \
- kernel/qwindowcontext_qpa.cpp \
+ kernel/qguiglcontext_qpa.cpp \
kernel/qplatformcursor_qpa.cpp \
kernel/qplatformclipboard_qpa.cpp \
kernel/qplatformnativeinterface_qpa.cpp \
kernel/qsessionmanager_qpa.cpp \
- kernel/qwindowformat_qpa.cpp \
+ kernel/qguiglformat_qpa.cpp \
kernel/qguiapplication.cpp \
kernel/qwindow.cpp
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 81124473bd..4e53973568 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -328,9 +328,6 @@ void QGuiApplicationPrivate::init()
QGuiApplicationPrivate::~QGuiApplicationPrivate()
{
- delete platform_integration;
- platform_integration = 0;
-
is_app_closing = true;
is_app_running = false;
@@ -341,6 +338,11 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate()
#endif
layout_direction = Qt::LeftToRight;
+
+ cleanupThreadData();
+
+ delete platform_integration;
+ platform_integration = 0;
}
#if 0
diff --git a/src/gui/kernel/qguiglcontext_qpa.cpp b/src/gui/kernel/qguiglcontext_qpa.cpp
new file mode 100644
index 0000000000..4b30b41ab8
--- /dev/null
+++ b/src/gui/kernel/qguiglcontext_qpa.cpp
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** 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 "qwindow.h"
+
+#include <QtCore/QThreadStorage>
+#include <QtCore/QThread>
+
+#include <QtGui/private/qguiapplication_p.h>
+
+#include <QDebug>
+
+class QGuiGLThreadContext
+{
+public:
+ ~QGuiGLThreadContext() {
+ if (context)
+ context->doneCurrent();
+ }
+ QGuiGLContext *context;
+};
+
+static QThreadStorage<QGuiGLThreadContext *> qwindow_context_storage;
+
+class QGuiGLContextPrivate
+{
+public:
+ QGuiGLContextPrivate()
+ : qGLContextHandle(0)
+ , platformGLContext(0)
+ , shareContext(0)
+ {
+ }
+
+ virtual ~QGuiGLContextPrivate()
+ {
+ //do not delete the QGLContext handle here as it is deleted in
+ //QWidgetPrivate::deleteTLSysExtra()
+ }
+ void *qGLContextHandle;
+ void (*qGLContextDeleteFunction)(void *handle);
+ QPlatformGLContext *platformGLContext;
+ QGuiGLContext *shareContext;
+
+ static void setCurrentContext(QGuiGLContext *context);
+};
+
+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;
+}
+
+QPlatformGLContext *QGuiGLContext::handle() const
+{
+ Q_D(const QGuiGLContext);
+ return d->platformGLContext;
+}
+
+/*!
+ Creates a new GL context with the given format and shared context.
+*/
+QGuiGLContext::QGuiGLContext(const QGuiGLFormat &format, QGuiGLContext *shareContext)
+ : d_ptr(new QGuiGLContextPrivate())
+{
+ Q_D(QGuiGLContext);
+ QPlatformGLContext *share = shareContext ? shareContext->handle() : 0;
+ d->shareContext = shareContext;
+ d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformGLContext(format, share);
+}
+
+/*!
+ If this is the current context for the thread, doneCurrent is called
+*/
+QGuiGLContext::~QGuiGLContext()
+{
+ Q_D(QGuiGLContext);
+ if (QGuiGLContext::currentContext() == this)
+ doneCurrent();
+ delete d->platformGLContext;
+}
+
+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(QPlatformGLSurface *surface)
+{
+ Q_D(QGuiGLContext);
+ if (!d->platformGLContext)
+ return false;
+
+ if (!surface) {
+ doneCurrent();
+ return true;
+ }
+
+ if (d->platformGLContext->makeCurrent(*surface)) {
+ QGuiGLContextPrivate::setCurrentContext(this);
+ return true;
+ }
+
+ return false;
+}
+
+/*!
+ Convenience function for calling makeCurrent with a 0 surface.
+*/
+void QGuiGLContext::doneCurrent()
+{
+ Q_D(QGuiGLContext);
+ if (!d->platformGLContext)
+ return;
+
+ d->platformGLContext->doneCurrent();
+ QGuiGLContextPrivate::setCurrentContext(0);
+}
+
+void QGuiGLContext::swapBuffers(QPlatformGLSurface *surface)
+{
+ Q_D(QGuiGLContext);
+ if (!d->platformGLContext)
+ return;
+
+ if (!surface) {
+ qWarning() << "QGuiGLContext::swapBuffers() called with null argument";
+ return;
+ }
+
+ d->platformGLContext->swapBuffers(*surface);
+}
+
+void (*QGuiGLContext::getProcAddress(const QByteArray &procName)) ()
+{
+ Q_D(QGuiGLContext);
+ if (!d->platformGLContext)
+ return 0;
+ return d->platformGLContext->getProcAddress(procName);
+}
+
+QGuiGLFormat QGuiGLContext::format() const
+{
+ Q_D(const QGuiGLContext);
+ if (!d->platformGLContext)
+ return QGuiGLFormat();
+ return d->platformGLContext->format();
+}
+
+QGuiGLContext *QGuiGLContext::shareContext() const
+{
+ Q_D(const QGuiGLContext);
+ if (!d->platformGLContext)
+ return 0;
+ return d->shareContext;
+}
+
+/*
+ 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;
+ }
+}
diff --git a/src/gui/kernel/qwindowcontext_qpa.h b/src/gui/kernel/qguiglcontext_qpa.h
index 08ba815a17..4b597dde67 100644
--- a/src/gui/kernel/qwindowcontext_qpa.h
+++ b/src/gui/kernel/qguiglcontext_qpa.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QWINDOWCONTEXT_H
-#define QWINDOWCONTEXT_H
+#ifndef QGUIGLCONTEXT_H
+#define QGUIGLCONTEXT_H
#include <QtCore/qnamespace.h>
@@ -50,41 +50,49 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-class QWindowContextPrivate;
+class QGuiGLContextPrivate;
class QPlatformGLContext;
+class QPlatformGLSurface;
-class Q_GUI_EXPORT QWindowContext
+class Q_GUI_EXPORT QGuiGLContext
{
-Q_DECLARE_PRIVATE(QWindowContext);
+Q_DECLARE_PRIVATE(QGuiGLContext);
public:
- ~QWindowContext();
+ QGuiGLContext(const QGuiGLFormat &format = QGuiGLFormat(), QGuiGLContext *shareContext = 0);
+ ~QGuiGLContext();
- void makeCurrent();
+ bool isValid() const;
+
+ bool makeCurrent(QPlatformGLSurface *surface);
void doneCurrent();
- void swapBuffers();
+
+ void swapBuffers(QPlatformGLSurface *surface);
void (*getProcAddress(const QByteArray &procName)) ();
- static QWindowContext *currentContext();
+ QGuiGLFormat format() const;
+
+ QGuiGLContext *shareContext() const;
+
+ static QGuiGLContext *currentContext();
QPlatformGLContext *handle() const;
private:
- QWindowContext(QWindow *window);
-
- QScopedPointer<QWindowContextPrivate> d_ptr;
+ QScopedPointer<QGuiGLContextPrivate> d_ptr;
//hack to make it work with QGLContext::CurrentContext
friend class QGLContext;
friend class QWidgetPrivate;
- friend class QWindow;
+
void *qGLContextHandle() const;
void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *));
void deleteQGLContext();
- Q_DISABLE_COPY(QWindowContext);
+
+ Q_DISABLE_COPY(QGuiGLContext);
};
QT_END_NAMESPACE
QT_END_HEADER
-#endif // QWINDOWCONTEXT_H
+#endif // QGUIGLCONTEXT_H
diff --git a/src/gui/kernel/qwindowformat_qpa.cpp b/src/gui/kernel/qguiglformat_qpa.cpp
index 03ccba7b07..65bd6a4ac2 100644
--- a/src/gui/kernel/qwindowformat_qpa.cpp
+++ b/src/gui/kernel/qguiglformat_qpa.cpp
@@ -39,31 +39,29 @@
**
****************************************************************************/
-#include "qwindowformat_qpa.h"
-
-#include "qplatformglcontext_qpa.h"
+#include "qguiglformat_qpa.h"
+#include <QtCore/qatomic.h>
#include <QtCore/QDebug>
-class QWindowFormatPrivate
+class QGuiGLFormatPrivate
{
public:
- QWindowFormatPrivate()
+ QGuiGLFormatPrivate()
: ref(1)
- , opts(QWindowFormat::DoubleBuffer | QWindowFormat::WindowSurface)
+ , opts(QGuiGLFormat::DoubleBuffer | QGuiGLFormat::WindowSurface)
, redBufferSize(-1)
, greenBufferSize(-1)
, blueBufferSize(-1)
, alphaBufferSize(-1)
, depthSize(-1)
, stencilSize(-1)
- , swapBehavior(QWindowFormat::DefaultSwapBehavior)
+ , swapBehavior(QGuiGLFormat::DefaultSwapBehavior)
, numSamples(-1)
- , sharedContext(0)
{
}
- QWindowFormatPrivate(const QWindowFormatPrivate *other)
+ QGuiGLFormatPrivate(const QGuiGLFormatPrivate *other)
: ref(1),
opts(other->opts),
redBufferSize(other->redBufferSize),
@@ -73,41 +71,40 @@ public:
depthSize(other->depthSize),
stencilSize(other->stencilSize),
swapBehavior(other->swapBehavior),
- numSamples(other->numSamples),
- sharedContext(other->sharedContext)
+ numSamples(other->numSamples)
{
}
+
QAtomicInt ref;
- QWindowFormat::FormatOptions opts;
+ QGuiGLFormat::FormatOptions opts;
int redBufferSize;
int greenBufferSize;
int blueBufferSize;
int alphaBufferSize;
int depthSize;
int stencilSize;
- QWindowFormat::SwapBehavior swapBehavior;
+ QGuiGLFormat::SwapBehavior swapBehavior;
int numSamples;
- QWindowContext *sharedContext;
};
-QWindowFormat::QWindowFormat()
+QGuiGLFormat::QGuiGLFormat()
{
- d = new QWindowFormatPrivate;
+ d = new QGuiGLFormatPrivate;
}
-QWindowFormat::QWindowFormat(QWindowFormat::FormatOptions options)
+QGuiGLFormat::QGuiGLFormat(QGuiGLFormat::FormatOptions options)
{
- d = new QWindowFormatPrivate;
+ d = new QGuiGLFormatPrivate;
d->opts = options;
}
/*!
\internal
*/
-void QWindowFormat::detach()
+void QGuiGLFormat::detach()
{
if (d->ref != 1) {
- QWindowFormatPrivate *newd = new QWindowFormatPrivate(d);
+ QGuiGLFormatPrivate *newd = new QGuiGLFormatPrivate(d);
if (!d->ref.deref())
delete d;
d = newd;
@@ -118,7 +115,7 @@ void QWindowFormat::detach()
Constructs a copy of \a other.
*/
-QWindowFormat::QWindowFormat(const QWindowFormat &other)
+QGuiGLFormat::QGuiGLFormat(const QGuiGLFormat &other)
{
d = other.d;
d->ref.ref();
@@ -128,7 +125,7 @@ QWindowFormat::QWindowFormat(const QWindowFormat &other)
Assigns \a other to this object.
*/
-QWindowFormat &QWindowFormat::operator=(const QWindowFormat &other)
+QGuiGLFormat &QGuiGLFormat::operator=(const QGuiGLFormat &other)
{
if (d != other.d) {
other.d->ref.ref();
@@ -140,16 +137,16 @@ QWindowFormat &QWindowFormat::operator=(const QWindowFormat &other)
}
/*!
- Destroys the QWindowFormat.
+ Destroys the QGuiGLFormat.
*/
-QWindowFormat::~QWindowFormat()
+QGuiGLFormat::~QGuiGLFormat()
{
if (!d->ref.deref())
delete d;
}
/*!
- \fn bool QWindowFormat::stereo() const
+ \fn bool QGuiGLFormat::stereo() const
Returns true if stereo buffering is enabled; otherwise returns
false. Stereo buffering is disabled by default.
@@ -169,12 +166,12 @@ QWindowFormat::~QWindowFormat()
\sa stereo()
*/
-void QWindowFormat::setStereo(bool enable)
+void QGuiGLFormat::setStereo(bool enable)
{
if (enable) {
- d->opts |= QWindowFormat::StereoBuffers;
+ d->opts |= QGuiGLFormat::StereoBuffers;
} else {
- d->opts &= ~QWindowFormat::StereoBuffers;
+ d->opts &= ~QGuiGLFormat::StereoBuffers;
}
}
@@ -185,7 +182,7 @@ void QWindowFormat::setStereo(bool enable)
\sa setSampleBuffers(), sampleBuffers(), setSamples()
*/
-int QWindowFormat::samples() const
+int QGuiGLFormat::samples() const
{
return d->numSamples;
}
@@ -197,26 +194,15 @@ int QWindowFormat::samples() const
\sa setSampleBuffers(), sampleBuffers(), samples()
*/
-void QWindowFormat::setSamples(int numSamples)
+void QGuiGLFormat::setSamples(int numSamples)
{
detach();
d->numSamples = numSamples;
}
-
-void QWindowFormat::setSharedContext(QWindowContext *context)
-{
- d->sharedContext = context;
-}
-
-QWindowContext *QWindowFormat::sharedContext() const
-{
- return d->sharedContext;
-}
-
/*!
- \fn bool QWindowFormat::hasWindowSurface() const
+ \fn bool QGuiGLFormat::hasWindowSurface() const
Returns true if the corresponding widget has an instance of QWindowSurface.
@@ -227,12 +213,12 @@ QWindowContext *QWindowFormat::sharedContext() const
\sa setOverlay()
*/
-void QWindowFormat::setWindowSurface(bool enable)
+void QGuiGLFormat::setWindowSurface(bool enable)
{
if (enable) {
- d->opts |= QWindowFormat::WindowSurface;
+ d->opts |= QGuiGLFormat::WindowSurface;
} else {
- d->opts &= ~QWindowFormat::WindowSurface;
+ d->opts &= ~QGuiGLFormat::WindowSurface;
}
}
@@ -242,7 +228,7 @@ void QWindowFormat::setWindowSurface(bool enable)
\sa testOption()
*/
-void QWindowFormat::setOption(QWindowFormat::FormatOptions opt)
+void QGuiGLFormat::setOption(QGuiGLFormat::FormatOptions opt)
{
detach();
d->opts |= opt;
@@ -254,7 +240,7 @@ void QWindowFormat::setOption(QWindowFormat::FormatOptions opt)
\sa setOption()
*/
-bool QWindowFormat::testOption(QWindowFormat::FormatOptions opt) const
+bool QGuiGLFormat::testOption(QGuiGLFormat::FormatOptions opt) const
{
return d->opts & opt;
}
@@ -264,7 +250,7 @@ bool QWindowFormat::testOption(QWindowFormat::FormatOptions opt) const
\sa depthBufferSize(), setDepth(), depth()
*/
-void QWindowFormat::setDepthBufferSize(int size)
+void QGuiGLFormat::setDepthBufferSize(int size)
{
detach();
d->depthSize = size;
@@ -275,22 +261,22 @@ void QWindowFormat::setDepthBufferSize(int size)
\sa depth(), setDepth(), setDepthBufferSize()
*/
-int QWindowFormat::depthBufferSize() const
+int QGuiGLFormat::depthBufferSize() const
{
return d->depthSize;
}
-void QWindowFormat::setSwapBehavior(SwapBehavior behavior)
+void QGuiGLFormat::setSwapBehavior(SwapBehavior behavior)
{
d->swapBehavior = behavior;
}
-QWindowFormat::SwapBehavior QWindowFormat::swapBehavior() const
+QGuiGLFormat::SwapBehavior QGuiGLFormat::swapBehavior() const
{
return d->swapBehavior;
}
-bool QWindowFormat::hasAlpha() const
+bool QGuiGLFormat::hasAlpha() const
{
return d->alphaBufferSize > 0;
}
@@ -300,7 +286,7 @@ bool QWindowFormat::hasAlpha() const
\sa stencilBufferSize(), setStencil(), stencil()
*/
-void QWindowFormat::setStencilBufferSize(int size)
+void QGuiGLFormat::setStencilBufferSize(int size)
{
detach();
d->stencilSize = size;
@@ -311,52 +297,52 @@ void QWindowFormat::setStencilBufferSize(int size)
\sa stencil(), setStencil(), setStencilBufferSize()
*/
-int QWindowFormat::stencilBufferSize() const
+int QGuiGLFormat::stencilBufferSize() const
{
return d->stencilSize;
}
-int QWindowFormat::redBufferSize() const
+int QGuiGLFormat::redBufferSize() const
{
return d->redBufferSize;
}
-int QWindowFormat::greenBufferSize() const
+int QGuiGLFormat::greenBufferSize() const
{
return d->greenBufferSize;
}
-int QWindowFormat::blueBufferSize() const
+int QGuiGLFormat::blueBufferSize() const
{
return d->blueBufferSize;
}
-int QWindowFormat::alphaBufferSize() const
+int QGuiGLFormat::alphaBufferSize() const
{
return d->alphaBufferSize;
}
-void QWindowFormat::setRedBufferSize(int size)
+void QGuiGLFormat::setRedBufferSize(int size)
{
d->redBufferSize = size;
}
-void QWindowFormat::setGreenBufferSize(int size)
+void QGuiGLFormat::setGreenBufferSize(int size)
{
d->greenBufferSize = size;
}
-void QWindowFormat::setBlueBufferSize(int size)
+void QGuiGLFormat::setBlueBufferSize(int size)
{
d->blueBufferSize = size;
}
-void QWindowFormat::setAlphaBufferSize(int size)
+void QGuiGLFormat::setAlphaBufferSize(int size)
{
d->alphaBufferSize = size;
}
-bool operator==(const QWindowFormat& a, const QWindowFormat& b)
+bool operator==(const QGuiGLFormat& a, const QGuiGLFormat& b)
{
return (a.d == b.d) || ((int) a.d->opts == (int) b.d->opts
&& a.d->stencilSize == b.d->stencilSize
@@ -366,29 +352,28 @@ bool operator==(const QWindowFormat& a, const QWindowFormat& b)
&& a.d->alphaBufferSize == b.d->alphaBufferSize
&& a.d->depthSize == b.d->depthSize
&& a.d->numSamples == b.d->numSamples
- && a.d->swapBehavior == b.d->swapBehavior
- && a.d->sharedContext == b.d->sharedContext);
+ && a.d->swapBehavior == b.d->swapBehavior);
}
/*!
- Returns false if all the options of the two QWindowFormat objects
+ Returns false if all the options of the two QGuiGLFormat objects
\a a and \a b are equal; otherwise returns true.
- \relates QWindowFormat
+ \relates QGuiGLFormat
*/
-bool operator!=(const QWindowFormat& a, const QWindowFormat& b)
+bool operator!=(const QGuiGLFormat& a, const QGuiGLFormat& b)
{
return !(a == b);
}
#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug dbg, const QWindowFormat &f)
+QDebug operator<<(QDebug dbg, const QGuiGLFormat &f)
{
- const QWindowFormatPrivate * const d = f.d;
+ const QGuiGLFormatPrivate * const d = f.d;
- dbg.nospace() << "QWindowFormat("
+ dbg.nospace() << "QGuiGLFormat("
<< "options " << d->opts
<< ", depthBufferSize " << d->depthSize
<< ", redBufferSize " << d->redBufferSize
@@ -398,7 +383,6 @@ QDebug operator<<(QDebug dbg, const QWindowFormat &f)
<< ", stencilBufferSize " << d->stencilSize
<< ", samples " << d->numSamples
<< ", swapBehavior " << d->swapBehavior
- << ", sharedContext " << d->sharedContext
<< ')';
return dbg.space();
diff --git a/src/gui/kernel/qwindowformat_qpa.h b/src/gui/kernel/qguiglformat_qpa.h
index e3214cceca..a14a8256b6 100644
--- a/src/gui/kernel/qwindowformat_qpa.h
+++ b/src/gui/kernel/qguiglformat_qpa.h
@@ -38,10 +38,10 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef QPLATFORMWINDOWFORMAT_QPA_H
-#define QPLATFORMWINDOWFORMAT_QPA_H
+#ifndef QGUIGLFORMAT_QPA_H
+#define QGUIGLFORMAT_QPA_H
-#include <QtGui/QPlatformWindow>
+#include <qglobal.h>
QT_BEGIN_HEADER
@@ -49,10 +49,10 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-class QWindowContext;
-class QWindowFormatPrivate;
+class QGuiGLContext;
+class QGuiGLFormatPrivate;
-class Q_GUI_EXPORT QWindowFormat
+class Q_GUI_EXPORT QGuiGLFormat
{
public:
enum FormatOption {
@@ -74,11 +74,11 @@ public:
CompatibilityProfile
};
- QWindowFormat();
- QWindowFormat(FormatOptions options);
- QWindowFormat(const QWindowFormat &other);
- QWindowFormat &operator=(const QWindowFormat &other);
- ~QWindowFormat();
+ QGuiGLFormat();
+ QGuiGLFormat(FormatOptions options);
+ QGuiGLFormat(const QGuiGLFormat &other);
+ QGuiGLFormat &operator=(const QGuiGLFormat &other);
+ ~QGuiGLFormat();
void setDepthBufferSize(int size);
int depthBufferSize() const;
@@ -106,50 +106,47 @@ public:
void setProfile(OpenGLContextProfile profile);
OpenGLContextProfile profile() const;
- void setSharedContext(QWindowContext *context);
- QWindowContext *sharedContext() const;
-
bool stereo() const;
void setStereo(bool enable);
bool windowSurface() const;
void setWindowSurface(bool enable);
- void setOption(QWindowFormat::FormatOptions opt);
- bool testOption(QWindowFormat::FormatOptions opt) const;
+ void setOption(QGuiGLFormat::FormatOptions opt);
+ bool testOption(QGuiGLFormat::FormatOptions opt) const;
private:
- QWindowFormatPrivate *d;
+ QGuiGLFormatPrivate *d;
void detach();
- friend Q_GUI_EXPORT bool operator==(const QWindowFormat&, const QWindowFormat&);
- friend Q_GUI_EXPORT bool operator!=(const QWindowFormat&, const QWindowFormat&);
+ friend Q_GUI_EXPORT bool operator==(const QGuiGLFormat&, const QGuiGLFormat&);
+ friend Q_GUI_EXPORT bool operator!=(const QGuiGLFormat&, const QGuiGLFormat&);
#ifndef QT_NO_DEBUG_STREAM
- friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QWindowFormat &);
+ friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QGuiGLFormat &);
#endif
};
-Q_GUI_EXPORT bool operator==(const QWindowFormat&, const QWindowFormat&);
-Q_GUI_EXPORT bool operator!=(const QWindowFormat&, const QWindowFormat&);
+Q_GUI_EXPORT bool operator==(const QGuiGLFormat&, const QGuiGLFormat&);
+Q_GUI_EXPORT bool operator!=(const QGuiGLFormat&, const QGuiGLFormat&);
#ifndef QT_NO_DEBUG_STREAM
-Q_GUI_EXPORT QDebug operator<<(QDebug, const QWindowFormat &);
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QGuiGLFormat &);
#endif
-Q_DECLARE_OPERATORS_FOR_FLAGS(QWindowFormat::FormatOptions)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGuiGLFormat::FormatOptions)
-inline bool QWindowFormat::stereo() const
+inline bool QGuiGLFormat::stereo() const
{
- return testOption(QWindowFormat::StereoBuffers);
+ return testOption(QGuiGLFormat::StereoBuffers);
}
-inline bool QWindowFormat::windowSurface() const
+inline bool QGuiGLFormat::windowSurface() const
{
- return testOption(QWindowFormat::WindowSurface);
+ return testOption(QGuiGLFormat::WindowSurface);
}
QT_END_NAMESPACE
QT_END_HEADER
-#endif //QPLATFORMWINDOWFORMAT_QPA_H
+#endif //QGUIGLFORMAT_QPA_H
diff --git a/src/gui/kernel/qplatformglcontext_qpa.h b/src/gui/kernel/qplatformglcontext_qpa.h
index 21c4766097..51c63d3fa1 100644
--- a/src/gui/kernel/qplatformglcontext_qpa.h
+++ b/src/gui/kernel/qplatformglcontext_qpa.h
@@ -43,7 +43,7 @@
#define QPLATFORM_GL_CONTEXT_H
#include <QtCore/qnamespace.h>
-#include <QtGui/qwindowformat_qpa.h>
+#include <QtGui/qguiglformat_qpa.h>
QT_BEGIN_HEADER
@@ -51,17 +51,44 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
+class Q_GUI_EXPORT QPlatformGLSurface
+{
+public:
+ QPlatformGLSurface(const QGuiGLFormat &format = QGuiGLFormat())
+ : m_format(format)
+ {
+ }
+
+ virtual ~QPlatformGLSurface() {}
+
+ QGuiGLFormat format() const
+ {
+ return m_format;
+ }
+
+protected:
+ void setFormat(const QGuiGLFormat &format)
+ {
+ m_format = format;
+ }
+
+private:
+ QGuiGLFormat m_format;
+};
+
class Q_GUI_EXPORT QPlatformGLContext
{
public:
virtual ~QPlatformGLContext() {}
- virtual void makeCurrent() = 0;
+ virtual QGuiGLFormat format() const = 0;
+
+ virtual void swapBuffers(const QPlatformGLSurface &surface) = 0;
+
+ virtual bool makeCurrent(const QPlatformGLSurface &surface) = 0;
virtual void doneCurrent() = 0;
- virtual void swapBuffers() = 0;
- virtual void *getProcAddress(const QString& procName) = 0;
- virtual QWindowFormat windowFormat() const = 0;
+ virtual void (*getProcAddress(const QByteArray &procName)) () = 0;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp
index 19bac35736..d3944ab1fe 100644
--- a/src/gui/kernel/qplatformintegration_qpa.cpp
+++ b/src/gui/kernel/qplatformintegration_qpa.cpp
@@ -172,6 +172,13 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
\sa createPlatformWindow(QWindow *window, WId winId = 0) const
*/
+
+QPlatformGLContext *QPlatformIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const
+{
+ qWarning("This plugin does not support createPlatformGLContext!");
+ return 0;
+}
+
/*!
\fn void QPlatformIntegration::moveToScreen(QWindow *window, int screen)
diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h
index 053605b8ac..1a46a479e6 100644
--- a/src/gui/kernel/qplatformintegration_qpa.h
+++ b/src/gui/kernel/qplatformintegration_qpa.h
@@ -61,6 +61,7 @@ class QPlatformClipboard;
class QPlatformNativeInterface;
class QPlatformPrinterSupport;
class QPlatformDrag;
+class QPlatformGLContext;
class Q_GUI_EXPORT QPlatformIntegration
{
@@ -78,6 +79,7 @@ public:
virtual QPixmapData *createPixmapData(QPixmapData::PixelType type) const = 0;
virtual QPlatformWindow *createPlatformWindow(QWindow *window) const = 0;
virtual QWindowSurface *createWindowSurface(QWindow *window, WId winId) const = 0;
+ virtual QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const;
// Window System functions
virtual QList<QPlatformScreen *> screens() const = 0;
diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp
index fcf375fdad..cba5529df4 100644
--- a/src/gui/kernel/qplatformwindow_qpa.cpp
+++ b/src/gui/kernel/qplatformwindow_qpa.cpp
@@ -205,9 +205,9 @@ void QPlatformWindow::requestActivateWindow()
}
/*!
- Reimplement to return the glContext associated with the window.
+ Reimplement to create a GL surface for the window.
*/
-QPlatformGLContext *QPlatformWindow::glContext() const
+QPlatformGLSurface *QPlatformWindow::createGLSurface() const
{
return 0;
}
diff --git a/src/gui/kernel/qplatformwindow_qpa.h b/src/gui/kernel/qplatformwindow_qpa.h
index 7991e5e21c..72f63ebcef 100644
--- a/src/gui/kernel/qplatformwindow_qpa.h
+++ b/src/gui/kernel/qplatformwindow_qpa.h
@@ -56,7 +56,7 @@ QT_MODULE(Gui)
class QPlatformWindowPrivate;
class QWindow;
-class QPlatformGLContext;
+class QPlatformGLSurface;
class Q_GUI_EXPORT QPlatformWindow
{
@@ -87,7 +87,7 @@ public:
virtual void setOpacity(qreal level);
virtual void requestActivateWindow();
- virtual QPlatformGLContext *glContext() const;
+ virtual QPlatformGLSurface *createGLSurface() const;
virtual bool setKeyboardGrabEnabled(bool grab);
virtual bool setMouseGrabEnabled(bool grab);
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 3d227f49ca..97e74c5652 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -42,9 +42,9 @@
#include "qwindow.h"
#include "qplatformwindow_qpa.h"
-#include "qwindowformat_qpa.h"
+#include "qguiglformat_qpa.h"
#include "qplatformglcontext_qpa.h"
-#include "qwindowcontext_qpa.h"
+#include "qguiglcontext_qpa.h"
#include "qwindow_p.h"
#include "qguiapplication_p.h"
@@ -177,21 +177,26 @@ void QWindow::setWindowModality(Qt::WindowModality windowModality)
d->modality = windowModality;
}
-void QWindow::setWindowFormat(const QWindowFormat &format)
+void QWindow::setGLFormat(const QGuiGLFormat &format)
{
Q_D(QWindow);
d->requestedFormat = format;
}
-QWindowFormat QWindow::requestedWindowFormat() const
+QGuiGLFormat QWindow::glFormat() const
{
Q_D(const QWindow);
+ if (d->glSurface)
+ return d->glSurface->format();
return d->requestedFormat;
}
-QWindowFormat QWindow::actualWindowFormat() const
+QPlatformGLSurface *QWindow::glSurface() const
{
- return glContext()->handle()->windowFormat();
+ Q_D(const QWindow);
+ if (d->platformWindow && !d->glSurface)
+ const_cast<QPlatformGLSurface *&>(d->glSurface) = d->platformWindow->createGLSurface();
+ return d->glSurface;
}
void QWindow::setSurfaceType(SurfaceType type)
@@ -397,23 +402,12 @@ void QWindow::setWindowIcon(const QImage &icon) const
qDebug() << "unimplemented:" << __FILE__ << __LINE__;
}
-QWindowContext * QWindow::glContext() const
-{
- Q_D(const QWindow);
- if (d->platformWindow && !d->glContext)
- const_cast<QWindowPrivate *>(d)->glContext = new QWindowContext(const_cast<QWindow *>(this));
- return d->glContext;
-}
-
void QWindow::destroy()
{
Q_D(QWindow);
- if (d->glContext) {
- d->glContext->deleteQGLContext();
- }
- delete d->glContext;
- d->glContext = 0;
+ delete d->glSurface;
delete d->platformWindow;
+ d->glSurface = 0;
d->platformWindow = 0;
}
diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h
index d1c48484ab..4356153683 100644
--- a/src/gui/kernel/qwindow.h
+++ b/src/gui/kernel/qwindow.h
@@ -44,7 +44,9 @@
#include <QtCore/QObject>
#include <QtCore/QEvent>
-#include <QtGui/qwindowformat_qpa.h>
+
+#include <QtGui/qguiglformat_qpa.h>
+#include <QtGui/qwindowdefs.h>
QT_BEGIN_HEADER
@@ -64,8 +66,8 @@ class QMouseEvent;
class QWheelEvent;
#endif
+class QPlatformGLSurface;
class QPlatformWindow;
-class QWindowContext;
class QWindowSurface;
class Q_GUI_EXPORT QWindow : public QObject
@@ -100,9 +102,10 @@ public:
Qt::WindowModality windowModality() const;
void setWindowModality(Qt::WindowModality windowModality);
- void setWindowFormat(const QWindowFormat &format);
- QWindowFormat requestedWindowFormat() const;
- QWindowFormat actualWindowFormat() const;
+ void setGLFormat(const QGuiGLFormat &format);
+ QGuiGLFormat glFormat() const;
+
+ QPlatformGLSurface *glSurface() const;
void setSurfaceType(SurfaceType type);
SurfaceType surfaceType() const;
@@ -137,8 +140,6 @@ public:
void setWindowIcon(const QImage &icon) const;
- QWindowContext *glContext() const;
-
void destroy();
QPlatformWindow *handle() const;
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 5c971da6ba..2f33629ccf 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -64,7 +64,7 @@ public:
, parentWindow(0)
, platformWindow(0)
, visible(false)
- , glContext(0)
+ , glSurface(0)
, surface(0)
, windowState(Qt::WindowNoState)
, maximumSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX)
@@ -83,10 +83,10 @@ public:
QWindow *parentWindow;
QPlatformWindow *platformWindow;
bool visible;
- QWindowFormat requestedFormat;
+ QGuiGLFormat requestedFormat;
QString windowTitle;
QRect geometry;
- QWindowContext *glContext;
+ QPlatformGLSurface *glSurface;
QWindowSurface *surface;
Qt::WindowState windowState;
diff --git a/src/gui/kernel/qwindowcontext_qpa.cpp b/src/gui/kernel/qwindowcontext_qpa.cpp
deleted file mode 100644
index f121e846b2..0000000000
--- a/src/gui/kernel/qwindowcontext_qpa.cpp
+++ /dev/null
@@ -1,201 +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 "qwindowcontext_qpa.h"
-#include "qwindow.h"
-
-#include <QtCore/QThreadStorage>
-#include <QtCore/QThread>
-
-#include <QDebug>
-
-class QWindowThreadContext
-{
-public:
- ~QWindowThreadContext() {
- if (context)
- context->doneCurrent();
- }
- QWindowContext *context;
-};
-
-static QThreadStorage<QWindowThreadContext *> qwindow_context_storage;
-
-class QWindowContextPrivate
-{
-public:
- QWindowContextPrivate()
- :qGLContextHandle(0)
- {
- }
-
- virtual ~QWindowContextPrivate()
- {
- //do not delete the QGLContext handle here as it is deleted in
- //QWidgetPrivate::deleteTLSysExtra()
- }
- void *qGLContextHandle;
- void (*qGLContextDeleteFunction)(void *handle);
- QPlatformGLContext *platformGLContext;
- static QWindowContext *staticSharedContext;
-
- static void setCurrentContext(QWindowContext *context);
-};
-
-QWindowContext *QWindowContextPrivate::staticSharedContext = 0;
-
-void QWindowContextPrivate::setCurrentContext(QWindowContext *context)
-{
- QWindowThreadContext *threadContext = qwindow_context_storage.localData();
- if (!threadContext) {
- if (!QThread::currentThread()) {
- qWarning("No QTLS available. currentContext wont work");
- return;
- }
- threadContext = new QWindowThreadContext;
- qwindow_context_storage.setLocalData(threadContext);
- }
- threadContext->context = context;
-}
-
-/*!
- Returns the last context which called makeCurrent. This function is thread aware.
-*/
-QWindowContext* QWindowContext::currentContext()
-{
- QWindowThreadContext *threadContext = qwindow_context_storage.localData();
- if(threadContext) {
- return threadContext->context;
- }
- return 0;
-}
-
-QPlatformGLContext *QWindowContext::handle() const
-{
- Q_D(const QWindowContext);
- return d->platformGLContext;
-}
-
-/*!
- All subclasses needs to specify the platformWindow. It can be a null window.
-*/
-QWindowContext::QWindowContext(QWindow *window)
- :d_ptr(new QWindowContextPrivate())
-{
- Q_D(QWindowContext);
- Q_ASSERT(window);
- if (!window->handle())
- window->create();
- d->platformGLContext = window->handle()->glContext();
-}
-
-/*!
- If this is the current context for the thread, doneCurrent is called
-*/
-QWindowContext::~QWindowContext()
-{
- if (QWindowContext::currentContext() == this) {
- doneCurrent();
- }
-
-}
-
-/*!
- Reimplement in subclass to do makeCurrent on native GL context
-*/
-void QWindowContext::makeCurrent()
-{
- Q_D(QWindowContext);
- QWindowContextPrivate::setCurrentContext(this);
- d->platformGLContext->makeCurrent();
-}
-
-/*!
- Reimplement in subclass to release current context.
- Typically this is calling makeCurrent with 0 "surface"
-*/
-void QWindowContext::doneCurrent()
-{
- Q_D(QWindowContext);
- d->platformGLContext->doneCurrent();
- QWindowContextPrivate::setCurrentContext(0);
-}
-
-void QWindowContext::swapBuffers()
-{
- Q_D(QWindowContext);
- d->platformGLContext->swapBuffers();
-}
-
-void (*QWindowContext::getProcAddress(const QByteArray &procName)) ()
-{
- Q_D(QWindowContext);
- void *result = d->platformGLContext->getProcAddress(QString::fromAscii(procName.constData()));
- return (void (*)())result;
-}
-
-/*
- internal: Needs to have a pointer to qGLContext. But since this is in QtGui we cant
- have any type information.
-*/
-void *QWindowContext::qGLContextHandle() const
-{
- Q_D(const QWindowContext);
- return d->qGLContextHandle;
-}
-
-void QWindowContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *))
-{
- Q_D(QWindowContext);
- d->qGLContextHandle = handle;
- d->qGLContextDeleteFunction = qGLContextDeleteFunction;
-}
-
-void QWindowContext::deleteQGLContext()
-{
- Q_D(QWindowContext);
- if (d->qGLContextDeleteFunction && d->qGLContextHandle) {
- d->qGLContextDeleteFunction(d->qGLContextHandle);
- d->qGLContextDeleteFunction = 0;
- d->qGLContextHandle = 0;
- }
-}