summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@nokia.com>2010-11-18 12:03:59 (GMT)
committerJørgen Lind <jorgen.lind@nokia.com>2010-11-22 13:14:08 (GMT)
commit292f6a9ba1b5da049e4898525974c6f0575ccd65 (patch)
treeb44bdf07f56298d7206a180a41690c2de3371fc6 /src
parenta1acef227647b3043998f9ccf364ead5c29b882d (diff)
downloadQt-292f6a9ba1b5da049e4898525974c6f0575ccd65.zip
Qt-292f6a9ba1b5da049e4898525974c6f0575ccd65.tar.gz
Qt-292f6a9ba1b5da049e4898525974c6f0575ccd65.tar.bz2
Lighthouse: move the currentContext functionality to QPlatformGLContext
This means the threading functionality has been delegated down to QPlatformGLContext. However, it is still possible to use QGLContext::currentContext to retrieve the QGLContext. This so that QGLFunctions, QGLShaderProgram etc can be used without a QGLWidget. Reviewed-by: paul
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/qplatformglcontext_qpa.cpp116
-rw-r--r--src/gui/kernel/qplatformglcontext_qpa.h23
-rw-r--r--src/gui/kernel/qwidget_qpa.cpp12
-rw-r--r--src/opengl/qgl.cpp24
-rw-r--r--src/opengl/qgl.h8
-rw-r--r--src/opengl/qgl_qpa.cpp22
-rw-r--r--src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp6
-rw-r--r--src/plugins/platforms/eglconvenience/qeglplatformcontext.h2
-rw-r--r--src/plugins/platforms/testlite/qglxintegration.cpp12
-rw-r--r--src/plugins/platforms/testlite/qglxintegration.h4
-rw-r--r--src/plugins/platforms/testlite/qtestlitewindow.cpp2
11 files changed, 205 insertions, 26 deletions
diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp
index 36db2b0..5ed1d3d 100644
--- a/src/gui/kernel/qplatformglcontext_qpa.cpp
+++ b/src/gui/kernel/qplatformglcontext_qpa.cpp
@@ -41,17 +41,123 @@
#include "qplatformglcontext_qpa.h"
+#include <QtCore/QThreadStorage>
+#include <QtCore/QThread>
+
+#include <QDebug>
+
+class QPlatformGLThreadContext
+{
+public:
+ ~QPlatformGLThreadContext() {
+ if (context)
+ context->doneCurrent();
+ }
+ QPlatformGLContext *context;
+};
+
+static QThreadStorage<QPlatformGLThreadContext *> qplatformgl_context_storage;
+
+class QPlatformGLContextPrivate
+{
+public:
+ QPlatformGLContextPrivate(QPlatformWindow *platformWindow)
+ :qGLContextHandle(0),platformWindow(platformWindow)
+ {
+ }
+
+ virtual ~QPlatformGLContextPrivate()
+ {
+ //do not delete the QGLContext handle here as it is deleted in
+ //QWidgetPrivate::deleteTLSysExtra()
+ }
+ void *qGLContextHandle;
+ void (*qGLContextDeleteFunction)(void *handle);
+ QPlatformWindow *platformWindow;
+ static QPlatformGLContext *staticSharedContext;
+
+ static void setCurrentContext(QPlatformGLContext *context);
+};
+
+QPlatformGLContext *QPlatformGLContextPrivate::staticSharedContext = 0;
+
+void QPlatformGLContextPrivate::setCurrentContext(QPlatformGLContext *context)
+{
+ QPlatformGLThreadContext *threadContext = qplatformgl_context_storage.localData();
+ if (!threadContext) {
+ if (!QThread::currentThread()) {
+ qWarning("No QTLS available. currentContext wont work");
+ return;
+ }
+ threadContext = new QPlatformGLThreadContext;
+ qplatformgl_context_storage.setLocalData(threadContext);
+ }
+ threadContext->context = context;
+}
+
+QPlatformWindow *QPlatformGLContext::platformWindow() const
+{
+ Q_D(const QPlatformGLContext);
+ return d->platformWindow;
+}
+
+const QPlatformGLContext* QPlatformGLContext::currentContext()
+{
+ QPlatformGLThreadContext *threadContext = qplatformgl_context_storage.localData();
+ if(threadContext) {
+ return threadContext->context;
+ }
+ return 0;
+}
+
+QPlatformGLContext::QPlatformGLContext(QPlatformWindow *platformWindow)
+ :d_ptr(new QPlatformGLContextPrivate(platformWindow))
+{
+}
+
QPlatformGLContext::~QPlatformGLContext()
-{ }
+{
+ if (QPlatformGLContext::currentContext() == this) {
+ doneCurrent();
+ }
-static QPlatformGLContext *staticSharedContext = 0;
+}
void QPlatformGLContext::setDefaultSharedContext(QPlatformGLContext *sharedContext)
{
- staticSharedContext = sharedContext;
+ QPlatformGLContextPrivate::staticSharedContext = sharedContext;
+}
+
+const QPlatformGLContext *QPlatformGLContext::defaultSharedContext()
+{
+ return QPlatformGLContextPrivate::staticSharedContext;
+}
+
+void QPlatformGLContext::makeCurrent()
+{
+ QPlatformGLContextPrivate::setCurrentContext(this);
+}
+
+void QPlatformGLContext::doneCurrent()
+{
+ QPlatformGLContextPrivate::setCurrentContext(0);
+}
+
+void *QPlatformGLContext::qGLContextHandle() const
+{
+ Q_D(const QPlatformGLContext);
+ return d->qGLContextHandle;
+}
+
+void QPlatformGLContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *))
+{
+ Q_D(QPlatformGLContext);
+ d->qGLContextHandle = handle;
+ d->qGLContextDeleteFunction = qGLContextDeleteFunction;
}
-QPlatformGLContext *QPlatformGLContext::defaultSharedContext()
+void QPlatformGLContext::deleteQGLContext()
{
- return staticSharedContext;
+ Q_D(QPlatformGLContext);
+ d->qGLContextDeleteFunction(d->qGLContextHandle);
}
diff --git a/src/gui/kernel/qplatformglcontext_qpa.h b/src/gui/kernel/qplatformglcontext_qpa.h
index ed41723..3e10c2b 100644
--- a/src/gui/kernel/qplatformglcontext_qpa.h
+++ b/src/gui/kernel/qplatformglcontext_qpa.h
@@ -51,24 +51,41 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
+class QPlatformGLContextPrivate;
+
class Q_OPENGL_EXPORT QPlatformGLContext
{
+Q_DECLARE_PRIVATE(QPlatformGLContext);
+
public:
+ explicit QPlatformGLContext(QPlatformWindow *platformWindow);
virtual ~QPlatformGLContext();
- virtual void makeCurrent() = 0;
- virtual void doneCurrent() = 0;
+ virtual void makeCurrent();
+ virtual void doneCurrent();
virtual void swapBuffers() = 0;
virtual void* getProcAddress(const QString& procName) = 0;
virtual QPlatformWindowFormat platformWindowFormat() const = 0;
- static QPlatformGLContext *defaultSharedContext();
+ QPlatformWindow *platformWindow() const;
+
+ const static QPlatformGLContext *currentContext();
+ const static QPlatformGLContext *defaultSharedContext();
protected:
static void setDefaultSharedContext(QPlatformGLContext *sharedContext);
+ QScopedPointer<QPlatformGLContextPrivate> d_ptr;
+private:
+ //hack to make it work with QGLContext::CurrentContext
+ friend class QGLContext;
+ friend class QWidgetPrivate;
+ void *qGLContextHandle() const;
+ void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *));
+ void deleteQGLContext();
+ Q_DISABLE_COPY(QPlatformGLContext);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp
index acb2615..aa6b3f8 100644
--- a/src/gui/kernel/qwidget_qpa.cpp
+++ b/src/gui/kernel/qwidget_qpa.cpp
@@ -48,6 +48,7 @@
#include "QtGui/private/qapplication_p.h"
#include "QtGui/qdesktopwidget.h"
#include "QtGui/qplatformwindow_qpa.h"
+#include "QtGui/qplatformglcontext_qpa.h"
#include <QtGui/QPlatformCursor>
@@ -99,6 +100,8 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
if (!surface && platformWindow && q->platformWindowFormat().hasWindowSurface()) {
surface = QApplicationPrivate::platformIntegration()->createWindowSurface(q,platformWindow->winId());
+ } else {
+ q->setAttribute(Qt::WA_PaintOnScreen,true);
}
data.window_flags = q->platformWindow()->setWindowFlags(data.window_flags);
@@ -784,6 +787,15 @@ void QWidgetPrivate::createTLSysExtra()
void QWidgetPrivate::deleteTLSysExtra()
{
if (extra && extra->topextra) {
+ if (extra->topextra->platformWindowFormat.windowApi() == QPlatformWindowFormat::OpenGL) {
+ //the toplevel might have a context with a "qglcontext assosiated with it. We need to
+ //delete the qglcontext before we delete the qplatformglcontext.
+ if (extra->topextra->platformWindow) {
+ if (QPlatformGLContext *context = extra->topextra->platformWindow->glContext()) {
+ context->deleteQGLContext();
+ }
+ }
+ }
delete extra->topextra->platformWindow;
extra->topextra->platformWindow = 0;
extra->topextra->backingStore.destroy();
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index cf45239..65d3bbe 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -79,6 +79,10 @@
#include <private/qglwindowsurface_qws_p.h>
#endif
+#ifdef Q_WS_QPA
+#include <QtGui/QPlatformGLContext>
+#endif
+
#include <qglpixelbuffer.h>
#include <qglframebufferobject.h>
@@ -117,7 +121,9 @@ struct QGLThreadContext {
QGLContext *context;
};
+#ifndef Q_WS_QPA
static QThreadStorage<QGLThreadContext *> qgl_context_storage;
+#endif
Q_GLOBAL_STATIC(QGLFormat, qgl_default_format)
@@ -3381,14 +3387,31 @@ void QGLContext::setInitialized(bool on)
const QGLContext* QGLContext::currentContext()
{
+#ifdef Q_WS_QPA
+ if (const QPlatformGLContext *threadContext = QPlatformGLContext::currentContext()) {
+ if (threadContext->qGLContextHandle()) {
+ return (const QGLContext *)threadContext->qGLContextHandle();
+ } else {
+ QWidget *widget = threadContext->platformWindow()->widget();
+ QGLContext *context = new QGLContext(QGLFormat::fromPlatformWindowFormat(threadContext->platformWindowFormat()),widget);
+ context->create(); //don't know how to pass in the sharecontext. (doesn't really matter though)
+ return context;
+ }
+ }
+ return 0;
+#else
QGLThreadContext *threadContext = qgl_context_storage.localData();
if (threadContext)
return threadContext->context;
return 0;
+#endif //Q_WS_QPA
}
void QGLContextPrivate::setCurrentContext(QGLContext *context)
{
+#ifdef Q_WS_QPA
+ Q_UNUSED(context);
+#else
QGLThreadContext *threadContext = qgl_context_storage.localData();
if (!threadContext) {
if (!QThread::currentThread()) {
@@ -3401,6 +3424,7 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
}
threadContext->context = context;
QGLContext::currentCtx = context; // XXX: backwards-compat, not thread-safe
+#endif
}
/*!
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index 4f10e5c..1f864a3 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -48,6 +48,10 @@
#include <QtCore/qmap.h>
#include <QtCore/qscopedpointer.h>
+#ifdef Q_WS_QPA
+#include <QtGui/QPlatformWindowFormat>
+#endif
+
QT_BEGIN_HEADER
#if defined(Q_WS_WIN)
@@ -270,6 +274,10 @@ public:
static OpenGLVersionFlags openGLVersionFlags();
+#if defined(Q_WS_QPA)
+ static QGLFormat fromPlatformWindowFormat(const QPlatformWindowFormat &format);
+ static QPlatformWindowFormat toPlatformWindowFormat(const QGLFormat &format);
+#endif
private:
QGLFormatPrivate *d;
diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp
index 1197013..28bea83 100644
--- a/src/opengl/qgl_qpa.cpp
+++ b/src/opengl/qgl_qpa.cpp
@@ -52,7 +52,7 @@
QT_BEGIN_NAMESPACE
-static QGLFormat qt_platformwindowformat_to_glformat(const QPlatformWindowFormat &format)
+QGLFormat QGLFormat::fromPlatformWindowFormat(const QPlatformWindowFormat &format)
{
QGLFormat retFormat;
retFormat.setAccum(format.accum());
@@ -83,7 +83,7 @@ static QGLFormat qt_platformwindowformat_to_glformat(const QPlatformWindowFormat
return retFormat;
}
-static QPlatformWindowFormat qt_glformat_to_platformwindowformat(const QGLFormat &format)
+QPlatformWindowFormat QGLFormat::toPlatformWindowFormat(const QGLFormat &format)
{
QPlatformWindowFormat retFormat;
retFormat.setAccum(format.accum());
@@ -120,6 +120,12 @@ bool QGLFormat::hasOpenGL()
return QApplicationPrivate::platformIntegration()->hasOpenGL();
}
+void qDeleteQGLContext(void *handle)
+{
+ QGLContext *context = static_cast<QGLContext *>(handle);
+ delete context;
+}
+
bool QGLContext::chooseContext(const QGLContext* shareContext)
{
Q_D(QGLContext);
@@ -129,7 +135,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
QWidget *widget = static_cast<QWidget *>(d->paintDevice);
if (!widget->platformWindow()){
QGLFormat glformat = format();
- QPlatformWindowFormat winFormat = qt_glformat_to_platformwindowformat(glformat);
+ QPlatformWindowFormat winFormat = QGLFormat::toPlatformWindowFormat(glformat);
if (shareContext) {
winFormat.setSharedContext(shareContext->d_func()->platformContext);
}
@@ -140,8 +146,11 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
}
d->platformContext = widget->platformWindow()->glContext();
Q_ASSERT(d->platformContext);
- d->glFormat = qt_platformwindowformat_to_glformat(d->platformContext->platformWindowFormat());
+ d->glFormat = QGLFormat::fromPlatformWindowFormat(d->platformContext->platformWindowFormat());
d->valid =(bool) d->platformContext;
+ if (d->valid) {
+ d->platformContext->setQGLContextHandle(this,qDeleteQGLContext);
+ }
}
return d->valid;
@@ -254,13 +263,13 @@ class QGLTemporaryContextPrivate
{
public:
QWidget *widget;
- QGLContext *context;
+ QPlatformGLContext *context;
};
QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
: d(new QGLTemporaryContextPrivate)
{
- d->context = const_cast<QGLContext *>(QGLContext::currentContext());
+ d->context = const_cast<QPlatformGLContext *>(QPlatformGLContext::currentContext());
if (d->context)
d->context->doneCurrent();
d->widget = new QWidget;
@@ -269,7 +278,6 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
format.setWindowApi(QPlatformWindowFormat::OpenGL);
d->widget->winId();
-
d->widget->platformWindow()->glContext()->makeCurrent();
}
diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
index ae3b539..a169c35 100644
--- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
+++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
@@ -48,8 +48,8 @@
#include <EGL/egl.h>
-QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi)
- : QPlatformGLContext()
+QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi, QPlatformWindow *platformWindow)
+ : QPlatformGLContext(platformWindow)
, m_eglDisplay(display)
, m_eglSurface(surface)
, m_eglApi(eglApi)
@@ -88,6 +88,7 @@ QEGLPlatformContext::~QEGLPlatformContext()
void QEGLPlatformContext::makeCurrent()
{
+ QPlatformGLContext::makeCurrent();
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglContext::makeCurrent: %p\n",this);
#endif
@@ -117,6 +118,7 @@ void QEGLPlatformContext::makeCurrent()
}
void QEGLPlatformContext::doneCurrent()
{
+ QPlatformGLContext::doneCurrent();
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglContext::doneCurrent:%p\n",this);
#endif
diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
index ae1a891..2c38aca 100644
--- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
+++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
@@ -48,7 +48,7 @@
class QEGLPlatformContext : public QPlatformGLContext
{
public:
- QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi);
+ QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi, QPlatformWindow *platformWindow);
~QEGLPlatformContext();
void makeCurrent();
diff --git a/src/plugins/platforms/testlite/qglxintegration.cpp b/src/plugins/platforms/testlite/qglxintegration.cpp
index e262d5b..c35db9b 100644
--- a/src/plugins/platforms/testlite/qglxintegration.cpp
+++ b/src/plugins/platforms/testlite/qglxintegration.cpp
@@ -235,14 +235,14 @@ QPlatformWindowFormat QGLXGLContext::reducePlatformWindowFormat(const QPlatformW
return retFormat;
}
-QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindowFormat &format)
- : QPlatformGLContext()
+QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *platformWindow, const QPlatformWindowFormat &format)
+ : QPlatformGLContext(platformWindow)
, m_xd(xd)
, m_drawable((Drawable)window)
, m_context(0)
{
- QPlatformGLContext *sharePlatformContext;
+ const QPlatformGLContext *sharePlatformContext;
if (format.useDefaultSharedContext()) {
if (!QPlatformGLContext::defaultSharedContext()) {
if (m_defaultSharedContextMutex.tryLock()){
@@ -259,7 +259,7 @@ QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindow
}
GLXContext shareGlxContext = 0;
if (sharePlatformContext)
- shareGlxContext = static_cast<QGLXGLContext*>(sharePlatformContext)->glxContext();
+ shareGlxContext = static_cast<const QGLXGLContext*>(sharePlatformContext)->glxContext();
GLXFBConfig config = findConfig(xd,format);
m_context = glXCreateNewContext(xd->display,config,GLX_RGBA_TYPE,shareGlxContext,TRUE);
@@ -271,7 +271,7 @@ QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindow
}
QGLXGLContext::QGLXGLContext(MyDisplay *display, Drawable drawable, GLXContext context)
- : QPlatformGLContext(), m_xd(display), m_drawable(drawable), m_context(context)
+ : QPlatformGLContext(0), m_xd(display), m_drawable(drawable), m_context(context)
{
}
@@ -313,6 +313,7 @@ void QGLXGLContext::createDefaultSharedContex(MyDisplay *xd)
void QGLXGLContext::makeCurrent()
{
+ QPlatformGLContext::makeCurrent();
#ifdef MYX11_DEBUG
qDebug("QGLXGLContext::makeCurrent(window=0x%x, ctx=0x%x)", m_drawable, m_context);
#endif
@@ -321,6 +322,7 @@ void QGLXGLContext::makeCurrent()
void QGLXGLContext::doneCurrent()
{
+ QPlatformGLContext::doneCurrent();
glXMakeCurrent(m_xd->display, 0, 0);
}
diff --git a/src/plugins/platforms/testlite/qglxintegration.h b/src/plugins/platforms/testlite/qglxintegration.h
index 479be4b..432dec5 100644
--- a/src/plugins/platforms/testlite/qglxintegration.h
+++ b/src/plugins/platforms/testlite/qglxintegration.h
@@ -58,7 +58,7 @@ class MyDisplay;
class QGLXGLContext : public QPlatformGLContext
{
public:
- QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindowFormat &format);
+ QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *platformWindow, const QPlatformWindowFormat &format);
~QGLXGLContext();
virtual void makeCurrent();
@@ -66,7 +66,7 @@ public:
virtual void swapBuffers();
virtual void* getProcAddress(const QString& procName);
- GLXContext glxContext() {return m_context;}
+ GLXContext glxContext() const {return m_context;}
QPlatformWindowFormat platformWindowFormat() const;
diff --git a/src/plugins/platforms/testlite/qtestlitewindow.cpp b/src/plugins/platforms/testlite/qtestlitewindow.cpp
index 9f3c435..0a6e1ff 100644
--- a/src/plugins/platforms/testlite/qtestlitewindow.cpp
+++ b/src/plugins/platforms/testlite/qtestlitewindow.cpp
@@ -1021,7 +1021,7 @@ QPlatformGLContext *QTestLiteWindow::glContext() const
if (!mGLContext) {
QTestLiteWindow *that = const_cast<QTestLiteWindow *>(this);
#ifndef QT_NO_OPENGL
- that->mGLContext = new QGLXGLContext(x_window, xd, widget()->platformWindowFormat());
+ that->mGLContext = new QGLXGLContext(x_window, xd, that,widget()->platformWindowFormat());
#endif
}
return mGLContext;