diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/kernel/qplatformglcontext_qpa.cpp | 116 | ||||
-rw-r--r-- | src/gui/kernel/qplatformglcontext_qpa.h | 23 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_qpa.cpp | 12 |
3 files changed, 143 insertions, 8 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(); |