diff options
author | Jørgen Lind <jorgen.lind@nokia.com> | 2010-11-18 12:03:59 (GMT) |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2010-11-22 13:14:08 (GMT) |
commit | 292f6a9ba1b5da049e4898525974c6f0575ccd65 (patch) | |
tree | b44bdf07f56298d7206a180a41690c2de3371fc6 /src | |
parent | a1acef227647b3043998f9ccf364ead5c29b882d (diff) | |
download | Qt-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.cpp | 116 | ||||
-rw-r--r-- | src/gui/kernel/qplatformglcontext_qpa.h | 23 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_qpa.cpp | 12 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 24 | ||||
-rw-r--r-- | src/opengl/qgl.h | 8 | ||||
-rw-r--r-- | src/opengl/qgl_qpa.cpp | 22 | ||||
-rw-r--r-- | src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp | 6 | ||||
-rw-r--r-- | src/plugins/platforms/eglconvenience/qeglplatformcontext.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/testlite/qglxintegration.cpp | 12 | ||||
-rw-r--r-- | src/plugins/platforms/testlite/qglxintegration.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/testlite/qtestlitewindow.cpp | 2 |
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; |