diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2011-06-07 17:25:22 +0200 |
---|---|---|
committer | Samuel Rødal <samuel.rodal@nokia.com> | 2011-06-10 09:24:56 +0200 |
commit | 4a189c188ccd2fb5f8d1d5ddadf06cbd6bc0916f (patch) | |
tree | 99bff9f015e869b5521836ea5667590939b22a53 /src/opengl | |
parent | 4d10e64f2a78e32418a98e1c80c6579ae0779dfc (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/opengl')
-rw-r--r-- | src/opengl/qgl.cpp | 8 | ||||
-rw-r--r-- | src/opengl/qgl.h | 10 | ||||
-rw-r--r-- | src/opengl/qgl_p.h | 4 | ||||
-rw-r--r-- | src/opengl/qgl_qpa.cpp | 123 |
4 files changed, 80 insertions, 65 deletions
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index dc07a6f77d..fdcfeb1864 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1711,7 +1711,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) vi = 0; #endif #if defined(Q_WS_QPA) - windowContext = 0; + guiGlContext = 0; #endif #if !defined(QT_NO_EGL) ownsEglContext = false; @@ -3330,7 +3330,7 @@ bool QGLContext::create(const QGLContext* shareContext) { Q_D(QGLContext); #ifdef Q_WS_QPA - if (!d->paintDevice && !d->windowContext) + if (!d->paintDevice && !d->guiGlContext) #else if (!d->paintDevice) #endif @@ -3420,8 +3420,8 @@ void QGLContext::setInitialized(bool on) const QGLContext* QGLContext::currentContext() { #ifdef Q_WS_QPA - if (const QWindowContext *threadContext = QWindowContext::currentContext()) { - return QGLContext::fromWindowContext(const_cast<QWindowContext *>(threadContext)); + if (const QGuiGLContext *threadContext = QGuiGLContext::currentContext()) { + return QGLContext::fromGuiGLContext(const_cast<QGuiGLContext *>(threadContext)); } return 0; #else diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 7e151184c8..7b0a237e83 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -49,7 +49,7 @@ #include <QtCore/qscopedpointer.h> #ifdef Q_WS_QPA -#include <QtGui/QWindowFormat> +#include <QtGui/QGuiGLFormat> #endif QT_BEGIN_HEADER @@ -283,8 +283,8 @@ public: static OpenGLVersionFlags openGLVersionFlags(); #if defined(Q_WS_QPA) - static QGLFormat fromWindowFormat(const QWindowFormat &format); - static QWindowFormat toWindowFormat(const QGLFormat &format); + static QGLFormat fromGuiGLFormat(const QGuiGLFormat &format); + static QGuiGLFormat toGuiGLFormat(const QGLFormat &format); #endif private: QGLFormatPrivate *d; @@ -397,7 +397,7 @@ public: static const QGLContext* currentContext(); #ifdef Q_WS_QPA - static QGLContext *fromWindowContext(QWindowContext *platformContext); + static QGLContext *fromGuiGLContext(QGuiGLContext *platformContext); #endif protected: virtual bool chooseContext(const QGLContext* shareContext = 0); @@ -429,7 +429,7 @@ protected: private: #ifdef Q_WS_QPA - QGLContext(QWindowContext *windowContext); + QGLContext(QGuiGLContext *windowContext); #endif QScopedPointer<QGLContextPrivate> d_ptr; diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index ec5edf3ba1..82b6e91c5d 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -69,7 +69,7 @@ #endif #if defined(Q_WS_QPA) -#include <QtGui/QWindowContext> +#include <QtGui/QGuiGLContext> #endif QT_BEGIN_NAMESPACE @@ -375,7 +375,7 @@ public: #endif #if defined(Q_WS_QPA) - QWindowContext *windowContext; + QGuiGLContext *guiGlContext; void setupSharing(); #elif defined(Q_WS_X11) || defined(Q_WS_MAC) diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 57c87d1238..cb3032bd59 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -47,7 +47,7 @@ #include <private/qapplication_p.h> #include <QtGui/QPlatformGLContext> #include <QtGui/QPlatformWindow> -#include <QtGui/QWindowContext> +#include <QtGui/QGuiGLFormat> #include "qgl.h" #include "qgl_p.h" @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE /*! Returns an OpenGL format for the window format specified by \a format. */ -QGLFormat QGLFormat::fromWindowFormat(const QWindowFormat &format) +QGLFormat QGLFormat::fromGuiGLFormat(const QGuiGLFormat &format) { QGLFormat retFormat; if (format.alphaBufferSize() >= 0) @@ -78,7 +78,7 @@ QGLFormat QGLFormat::fromWindowFormat(const QWindowFormat &format) retFormat.setStencil(true); retFormat.setStencilBufferSize(format.stencilBufferSize()); } - retFormat.setDoubleBuffer(format.swapBehavior() != QWindowFormat::SingleBuffer); + retFormat.setDoubleBuffer(format.swapBehavior() != QGuiGLFormat::SingleBuffer); retFormat.setStereo(format.stereo()); return retFormat; } @@ -86,9 +86,9 @@ QGLFormat QGLFormat::fromWindowFormat(const QWindowFormat &format) /*! Returns a window format for the OpenGL format specified by \a format. */ -QWindowFormat QGLFormat::toWindowFormat(const QGLFormat &format) +QGuiGLFormat QGLFormat::toGuiGLFormat(const QGLFormat &format) { - QWindowFormat retFormat; + QGuiGLFormat retFormat; if (format.alpha()) retFormat.setAlphaBufferSize(format.alphaBufferSize() == -1 ? 1 : format.alphaBufferSize()); if (format.blueBufferSize() >= 0) @@ -99,7 +99,7 @@ QWindowFormat QGLFormat::toWindowFormat(const QGLFormat &format) retFormat.setRedBufferSize(format.redBufferSize()); if (format.depth()) retFormat.setDepthBufferSize(format.depthBufferSize() == -1 ? 1 : format.depthBufferSize()); - retFormat.setSwapBehavior(format.doubleBuffer() ? QWindowFormat::DoubleBuffer : QWindowFormat::DefaultSwapBehavior); + retFormat.setSwapBehavior(format.doubleBuffer() ? QGuiGLFormat::DoubleBuffer : QGuiGLFormat::DefaultSwapBehavior); if (format.sampleBuffers()) retFormat.setSamples(format.samples() == -1 ? 4 : format.samples()); if (format.stencil()) @@ -110,11 +110,11 @@ QWindowFormat QGLFormat::toWindowFormat(const QGLFormat &format) void QGLContextPrivate::setupSharing() { Q_Q(QGLContext); - QWindowContext *sharedContext = windowContext->handle()->windowFormat().sharedContext(); + QGuiGLContext *sharedContext = guiGlContext->shareContext(); if (sharedContext) { - QGLContext *actualSharedContext = QGLContext::fromWindowContext(sharedContext); + QGLContext *actualSharedContext = QGLContext::fromGuiGLContext(sharedContext); sharing = true; - QGLContextGroup::addShare(q,actualSharedContext); + QGLContextGroup::addShare(q, actualSharedContext); } } @@ -137,25 +137,26 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) d->valid = false; }else { QWidget *widget = static_cast<QWidget *>(d->paintDevice); + QGLFormat glformat = format(); + QGuiGLFormat winFormat = QGLFormat::toGuiGLFormat(glformat); + if (widget->testAttribute(Qt::WA_TranslucentBackground)) + winFormat.setAlphaBufferSize(qMax(winFormat.alphaBufferSize(), 8)); + winFormat.setWindowSurface(false); + if (!widget->windowHandle()->handle()) { - QGLFormat glformat = format(); - QWindowFormat winFormat = QGLFormat::toWindowFormat(glformat); - if (shareContext) { - winFormat.setSharedContext(shareContext->d_func()->windowContext); - } widget->windowHandle()->setSurfaceType(QWindow::OpenGLSurface); - if (widget->testAttribute(Qt::WA_TranslucentBackground)) - winFormat.setAlphaBufferSize(qMax(winFormat.alphaBufferSize(), 8)); - winFormat.setWindowSurface(false); - widget->windowHandle()->setWindowFormat(winFormat); + widget->windowHandle()->setGLFormat(winFormat); widget->winId();//make window } - d->windowContext = widget->windowHandle()->glContext(); - Q_ASSERT(d->windowContext); - d->glFormat = QGLFormat::fromWindowFormat(d->windowContext->handle()->windowFormat()); - d->valid =(bool) d->windowContext; + + delete d->guiGlContext; + QGuiGLContext *shareGlContext = shareContext ? shareContext->d_func()->guiGlContext : 0; + d->guiGlContext = new QGuiGLContext(winFormat, shareGlContext); + + d->glFormat = QGLFormat::fromGuiGLFormat(d->guiGlContext->format()); + d->valid = d->guiGlContext->isValid(); if (d->valid) { - d->windowContext->setQGLContextHandle(this,qDeleteQGLContext); + d->guiGlContext->setQGLContextHandle(this,qDeleteQGLContext); } d->setupSharing(); } @@ -177,42 +178,55 @@ void QGLContext::reset() d->transpColor = QColor(); d->initDone = false; QGLContextGroup::removeShare(this); - if (d->windowContext) { - d->windowContext->setQGLContextHandle(0,0); + if (d->guiGlContext) { + d->guiGlContext->setQGLContextHandle(0,0); } } void QGLContext::makeCurrent() { Q_D(QGLContext); - d->windowContext->makeCurrent(); + if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) + return; + + QWidget *widget = static_cast<QWidget *>(d->paintDevice); + if (!widget->windowHandle()) + return; - if (!d->workaroundsCached) { - d->workaroundsCached = true; - const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); - if (renderer && strstr(renderer, "Mali")) { - d->workaround_brokenFBOReadBack = true; + if (d->guiGlContext->makeCurrent(widget->windowHandle()->glSurface())) { + if (!d->workaroundsCached) { + d->workaroundsCached = true; + const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); + if (renderer && strstr(renderer, "Mali")) { + d->workaround_brokenFBOReadBack = true; + } } } - } void QGLContext::doneCurrent() { Q_D(QGLContext); - d->windowContext->doneCurrent(); + d->guiGlContext->doneCurrent(); } void QGLContext::swapBuffers() const { Q_D(const QGLContext); - d->windowContext->swapBuffers(); + if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) + return; + + QWidget *widget = static_cast<QWidget *>(d->paintDevice); + if (!widget->windowHandle()) + return; + + d->guiGlContext->swapBuffers(widget->windowHandle()->glSurface()); } void *QGLContext::getProcAddress(const QString &procName) const { Q_D(const QGLContext); - return (void *)d->windowContext->getProcAddress(procName.toAscii()); + return (void *)d->guiGlContext->getProcAddress(procName.toAscii()); } void QGLWidget::setContext(QGLContext *context, @@ -271,30 +285,31 @@ class QGLTemporaryContextPrivate { public: QWindow *window; - QWindowContext *context; + QGuiGLContext *context; + + QGLContext *oldContext; }; QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) : d(new QGLTemporaryContextPrivate) { - d->context = const_cast<QWindowContext *>(QWindowContext::currentContext()); - if (d->context) - d->context->doneCurrent(); + d->oldContext = const_cast<QGLContext *>(QGLContext::currentContext()); d->window = new QWindow; d->window->setGeometry(QRect(0, 0, 3, 3)); d->window->setSurfaceType(QWindow::OpenGLSurface); d->window->create(); - d->window->glContext()->makeCurrent(); + d->context = new QGuiGLContext; + d->context->makeCurrent(d->window->glSurface()); } QGLTemporaryContext::~QGLTemporaryContext() { - if (d->context) - d->context->makeCurrent(); - else - d->window->glContext()->doneCurrent(); + if (d->oldContext) + d->oldContext->makeCurrent(); + + delete d->context; delete d->window; } @@ -361,28 +376,28 @@ void QGLWidget::setColormap(const QGLColormap & c) Q_UNUSED(c); } -QGLContext::QGLContext(QWindowContext *windowContext) +QGLContext::QGLContext(QGuiGLContext *context) : d_ptr(new QGLContextPrivate(this)) { Q_D(QGLContext); - d->init(0,QGLFormat::fromWindowFormat(windowContext->handle()->windowFormat())); - d->windowContext = windowContext; - d->windowContext->setQGLContextHandle(this,qDeleteQGLContext); - d->valid = true; + d->init(0,QGLFormat::fromGuiGLFormat(context->format())); + d->guiGlContext = context; + d->guiGlContext->setQGLContextHandle(this,qDeleteQGLContext); + d->valid = context->isValid(); d->setupSharing(); } /*! Returns a OpenGL context for the window context specified by \a windowContext */ -QGLContext *QGLContext::fromWindowContext(QWindowContext *windowContext) +QGLContext *QGLContext::fromGuiGLContext(QGuiGLContext *context) { - if (!windowContext) + if (!context) return 0; - if (windowContext->qGLContextHandle()) { - return reinterpret_cast<QGLContext *>(windowContext->qGLContextHandle()); + if (context->qGLContextHandle()) { + return reinterpret_cast<QGLContext *>(context->qGLContextHandle()); } - QGLContext *glContext = new QGLContext(windowContext); + QGLContext *glContext = new QGLContext(context); //Dont call create on context. This can cause the platformFormat to be set on the widget, which //will cause the platformWindow to be recreated. return glContext; |