diff options
77 files changed, 1426 insertions, 1038 deletions
diff --git a/examples/opengl/hellowindow/hellowindow.cpp b/examples/opengl/hellowindow/hellowindow.cpp index 32732f72b6..50cf8b0453 100644 --- a/examples/opengl/hellowindow/hellowindow.cpp +++ b/examples/opengl/hellowindow/hellowindow.cpp @@ -1,72 +1,82 @@ #include "hellowindow.h" -#include <QWindowContext> +#include <QGuiGLContext> #include <QTimer> #include <qmath.h> -HelloWindow::HelloWindow() - : colorIndex(0) +Renderer::Renderer() + : m_initialized(false) +{ + m_format.setDepthBufferSize(16); + m_format.setSamples(4); + + m_context = new QGuiGLContext(m_format); +} + +QGuiGLFormat Renderer::format() const +{ + return m_format; +} + +HelloWindow::HelloWindow(Renderer *renderer) + : m_colorIndex(0) + , m_renderer(renderer) { setSurfaceType(OpenGLSurface); setWindowTitle(QLatin1String("Hello Window")); - QWindowFormat format; - format.setDepthBufferSize(16); - format.setSamples(4); - - setWindowFormat(format); + setGLFormat(renderer->format()); setGeometry(QRect(10, 10, 640, 480)); create(); - initialize(); - QTimer *timer = new QTimer(this); timer->start(10); connect(timer, SIGNAL(timeout()), this, SLOT(render())); -} -void HelloWindow::mousePressEvent(QMouseEvent *) -{ updateColor(); } -void HelloWindow::resizeEvent(QResizeEvent *) +void HelloWindow::mousePressEvent(QMouseEvent *) { - glContext()->makeCurrent(); - - glViewport(0, 0, geometry().width(), geometry().height()); + updateColor(); } void HelloWindow::updateColor() { - float colors[][4] = + QColor colors[] = { - { 0.4, 1.0, 0.0, 0.0 }, - { 0.0, 0.4, 1.0, 0.0 } + QColor(100, 255, 0), + QColor(0, 100, 255) }; - glContext()->makeCurrent(); - - program.bind(); - program.setUniformValue(colorUniform, colors[colorIndex][0], colors[colorIndex][1], colors[colorIndex][2], colors[colorIndex][3]); - program.release(); + m_color = colors[m_colorIndex]; - colorIndex++; - if (colorIndex >= sizeof(colors) / sizeof(colors[0])) - colorIndex = 0; + m_colorIndex++; + if (m_colorIndex >= int(sizeof(colors) / sizeof(colors[0]))) + m_colorIndex = 0; } void HelloWindow::render() { - if (!glContext()) - return; + if (glSurface()) + m_renderer->render(glSurface(), m_color, geometry().size()); +} + +void Renderer::render(QPlatformGLSurface *surface, const QColor &color, const QSize &viewSize) +{ + m_context->makeCurrent(surface); + + if (!m_initialized) { + initialize(); + m_initialized = true; + } - glContext()->makeCurrent(); + glViewport(0, 0, viewSize.width(), viewSize.height()); glClearColor(0.1f, 0.1f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -84,18 +94,19 @@ void HelloWindow::render() program.bind(); program.setUniformValue(matrixUniform, modelview); + program.setUniformValue(colorUniform, color); paintQtLogo(); program.release(); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); - glContext()->swapBuffers(); + m_context->swapBuffers(surface); m_fAngle += 1.0f; } -void HelloWindow::paintQtLogo() +void Renderer::paintQtLogo() { program.enableAttributeArray(normalAttr); program.enableAttributeArray(vertexAttr); @@ -106,10 +117,8 @@ void HelloWindow::paintQtLogo() program.disableAttributeArray(vertexAttr); } -void HelloWindow::initialize() +void Renderer::initialize() { - glContext()->makeCurrent(); - glClearColor(0.1f, 0.1f, 0.2f, 1.0f); QGLShader *vshader = new QGLShader(QGLShader::Vertex, this); @@ -150,10 +159,9 @@ void HelloWindow::initialize() m_fAngle = 0; createGeometry(); - updateColor(); } -void HelloWindow::createGeometry() +void Renderer::createGeometry() { vertices.clear(); normals.clear(); @@ -204,7 +212,7 @@ void HelloWindow::createGeometry() vertices[i] *= 2.0f; } -void HelloWindow::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4) +void Renderer::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4) { vertices << QVector3D(x1, y1, -0.05f); vertices << QVector3D(x2, y2, -0.05f); @@ -245,7 +253,7 @@ void HelloWindow::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y normals << n; } -void HelloWindow::extrude(qreal x1, qreal y1, qreal x2, qreal y2) +void Renderer::extrude(qreal x1, qreal y1, qreal x2, qreal y2) { vertices << QVector3D(x1, y1, +0.05f); vertices << QVector3D(x2, y2, +0.05f); diff --git a/examples/opengl/hellowindow/hellowindow.h b/examples/opengl/hellowindow/hellowindow.h index f0b8ee8b45..274dc9ca17 100644 --- a/examples/opengl/hellowindow/hellowindow.h +++ b/examples/opengl/hellowindow/hellowindow.h @@ -5,22 +5,19 @@ #include <QTime> -class HelloWindow : public QWindow +class QGuiGLContext; + +class Renderer : public QObject { - Q_OBJECT public: - HelloWindow(); + Renderer(); -protected: - void mousePressEvent(QMouseEvent *); - void resizeEvent(QResizeEvent *); + QGuiGLFormat format() const; -private slots: - void render(); + void render(QPlatformGLSurface *surface, const QColor &color, const QSize &viewSize); private: void initialize(); - void updateColor(); qreal m_fAngle; bool m_showBubbles; @@ -36,5 +33,28 @@ private: int normalAttr; int matrixUniform; int colorUniform; - uint colorIndex; + + bool m_initialized; + QGuiGLFormat m_format; + QGuiGLContext *m_context; +}; + +class HelloWindow : public QWindow +{ + Q_OBJECT +public: + HelloWindow(Renderer *renderer); + +private slots: + void render(); + +protected: + void mousePressEvent(QMouseEvent *); + +private: + void updateColor(); + + int m_colorIndex; + QColor m_color; + Renderer *m_renderer; }; diff --git a/examples/opengl/hellowindow/main.cpp b/examples/opengl/hellowindow/main.cpp index 1b80dc7523..af5943adf4 100644 --- a/examples/opengl/hellowindow/main.cpp +++ b/examples/opengl/hellowindow/main.cpp @@ -6,8 +6,13 @@ int main(int argc, char **argv) { QGuiApplication app(argc, argv); - HelloWindow window; - window.setVisible(true); + Renderer renderer; + + HelloWindow windowA(&renderer); + windowA.setVisible(true); + + HelloWindow windowB(&renderer); + windowB.setVisible(true); return app.exec(); } diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 19a33d9637..e00db5e01a 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -334,7 +334,7 @@ Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata) QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags) : QObjectPrivate(), argc(aargc), argv(aargv), application_type(0), eventFilter(0), - in_exec(false), aboutToQuitEmitted(false) + in_exec(false), aboutToQuitEmitted(false), threadData_clean(false) { app_compile_version = flags & 0xffffff; #if defined(QT3_SUPPORT) @@ -362,7 +362,12 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint QCoreApplicationPrivate::~QCoreApplicationPrivate() { - if (threadData) { + cleanupThreadData(); +} + +void QCoreApplicationPrivate::cleanupThreadData() +{ + if (threadData && !threadData_clean) { #ifndef QT_NO_THREAD void *data = &threadData->tls; QThreadStorageData::finish((void **)data); @@ -381,6 +386,7 @@ QCoreApplicationPrivate::~QCoreApplicationPrivate() threadData->postEventList.clear(); threadData->postEventList.recursion = 0; threadData->quitNow = false; + threadData_clean = true; } } diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 804906e6da..22585a1ce9 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -110,6 +110,7 @@ public: int &argc; char **argv; void appendApplicationPathToLibraryPaths(void); + void cleanupThreadData(); #ifndef QT_NO_TRANSLATION QTranslatorList translators; @@ -120,6 +121,7 @@ public: bool in_exec; bool aboutToQuitEmitted; + bool threadData_clean; QString cachedApplicationDirPath; QString cachedApplicationFilePath; #if defined(Q_OS_SYMBIAN) 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; - } -} diff --git a/src/gui/painting/qwindowsurface_p.h b/src/gui/painting/qwindowsurface_p.h index 90a2762ec7..068df2e70f 100644 --- a/src/gui/painting/qwindowsurface_p.h +++ b/src/gui/painting/qwindowsurface_p.h @@ -53,7 +53,10 @@ // We mean it. // +#include <QtCore/qrect.h> + #include <QtGui/qwindow.h> +#include <QtGui/qregion.h> QT_BEGIN_NAMESPACE 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; diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h index 4d330a4294..01d931b662 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.h +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h @@ -1,26 +1,52 @@ #ifndef QCOCOAGLCONTEXT_H #define QCOCOAGLCONTEXT_H +#include <QtCore/QWeakPointer> #include <QtGui/QPlatformGLContext> -#include <QtGui/QWindowFormat> +#include <QtGui/QGuiGLContext> +#include <QtGui/QWindow> #include <Cocoa/Cocoa.h> QT_BEGIN_NAMESPACE +class QCocoaGLSurface : public QPlatformGLSurface +{ +public: + QCocoaGLSurface(const QGuiGLFormat &format, QWindow *window) + : QPlatformGLSurface(format) + , window(window) + { + } + + QWindow *window; +}; + class QCocoaGLContext : public QPlatformGLContext { public: - QCocoaGLContext(NSOpenGLView *glView); - void makeCurrent(); + QCocoaGLContext(const QGuiGLFormat &format, QPlatformGLContext *share); + + QGuiGLFormat format() const; + + void swapBuffers(const QPlatformGLSurface &surface); + + bool makeCurrent(const QPlatformGLSurface &surface); void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString& procName); - QWindowFormat windowFormat() const; + + void (*getProcAddress(const QByteArray &procName)) (); + + void update(); + static NSOpenGLPixelFormat *createNSOpenGLPixelFormat(); NSOpenGLContext *nsOpenGLContext() const; + private: - NSOpenGLView *m_glView; + void setActiveWindow(QWindow *window); + + NSOpenGLContext *m_context; + QGuiGLFormat m_format; + QWeakPointer<QWindow> m_currentWindow; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index 3a87537e64..f9cda1bb37 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -1,66 +1,88 @@ #include "qcocoaglcontext.h" +#include "qcocoawindow.h" #include <qdebug.h> #include <QtCore/private/qcore_mac_p.h> #import <Cocoa/Cocoa.h> -QCocoaGLContext::QCocoaGLContext(NSOpenGLView *glView) -:m_glView(glView) +QCocoaGLContext::QCocoaGLContext(const QGuiGLFormat &format, QPlatformGLContext *share) + : m_format(format) { + NSOpenGLPixelFormat *pixelFormat = createNSOpenGLPixelFormat(); + NSOpenGLContext *actualShare = share ? static_cast<QCocoaGLContext *>(share)->m_context : 0; + m_context = [NSOpenGLContext alloc]; + [m_context initWithFormat:pixelFormat shareContext:actualShare]; } -void QCocoaGLContext::makeCurrent() +// Match up with createNSOpenGLPixelFormat! +QGuiGLFormat QCocoaGLContext::format() const { - [[m_glView openGLContext] makeCurrentContext]; + return m_format; } -void QCocoaGLContext::doneCurrent() + +void QCocoaGLContext::swapBuffers(const QPlatformGLSurface &surface) { - [NSOpenGLContext clearCurrentContext]; + QWindow *window = static_cast<const QCocoaGLSurface &>(surface).window; + setActiveWindow(window); + + [m_context flushBuffer]; +} + +bool QCocoaGLContext::makeCurrent(const QPlatformGLSurface &surface) +{ + QWindow *window = static_cast<const QCocoaGLSurface &>(surface).window; + setActiveWindow(window); + + [m_context makeCurrentContext]; + return true; +} + +void QCocoaGLContext::setActiveWindow(QWindow *window) +{ + if (window == m_currentWindow.data()) + return; + + if (m_currentWindow) + static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0); + + Q_ASSERT(window->handle()); + + m_currentWindow = window; + + QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle()); + cocoaWindow->setCurrentContext(this); + + NSView *view = cocoaWindow->windowSurfaceView(); + [m_context setView:view]; } -void QCocoaGLContext::swapBuffers() +void QCocoaGLContext::doneCurrent() { - [[m_glView openGLContext] flushBuffer]; + if (m_currentWindow) + static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0); + + m_currentWindow.clear(); + + [NSOpenGLContext clearCurrentContext]; } -void* QCocoaGLContext::getProcAddress(const QString& procName) +void (*QCocoaGLContext::getProcAddress(const QByteArray &procName)) () { CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, false); CFBundleRef bundle = CFBundleCreate(kCFAllocatorDefault, url); - CFStringRef procNameCF = QCFString::toCFStringRef(procName); + CFStringRef procNameCF = QCFString::toCFStringRef(QString::fromAscii(procName.constData())); void *proc = CFBundleGetFunctionPointerForName(bundle, procNameCF); CFRelease(url); CFRelease(bundle); CFRelease(procNameCF); - return proc; + return (void (*) ())proc; } -// Match up with createNSOpenGLPixelFormat below! -QWindowFormat QCocoaGLContext::windowFormat() const +void QCocoaGLContext::update() { - QWindowFormat format; - format.setRedBufferSize(8); - format.setGreenBufferSize(8); - format.setBlueBufferSize(8); - format.setAlphaBufferSize(8); - -/* - format.setDepthBufferSize(24); - format.setAccumBufferSize(0); - format.setStencilBufferSize(8); - format.setSampleBuffers(false); - format.setSamples(1); - format.setDepth(true); - format.setRgba(true); - format.setAlpha(true); - format.setAccum(false); - format.setStencil(true); - format.setStereo(false); - format.setDirectRendering(false); -*/ - return format; + [m_context update]; } NSOpenGLPixelFormat *QCocoaGLContext::createNSOpenGLPixelFormat() @@ -78,6 +100,6 @@ NSOpenGLPixelFormat *QCocoaGLContext::createNSOpenGLPixelFormat() NSOpenGLContext *QCocoaGLContext::nsOpenGLContext() const { - return [m_glView openGLContext]; + return m_context; } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 3e705e7805..59008b4e3f 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -78,6 +78,7 @@ public: bool hasCapability(QPlatformIntegration::Capability cap) const; QPixmapData *createPixmapData(QPixmapData::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; + QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const; QWindowSurface *createWindowSurface(QWindow *widget, WId winId) const; QList<QPlatformScreen *> screens() const { return mScreens; } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 42ec268964..dfe225ff2e 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -113,6 +113,11 @@ QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWindow *window) const return new QCocoaWindow(window); } +QPlatformGLContext *QCocoaIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const +{ + return new QCocoaGLContext(glFormat, share); +} + QWindowSurface *QCocoaIntegration::createWindowSurface(QWindow *window, WId winId) const { return new QCocoaWindowSurface(window, winId); diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index 6b86108f75..87d0ec4a0c 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -41,19 +41,20 @@ #include "qcocoanativeinterface.h" #include "qcocoaglcontext.h" +#include "qcocoawindow.h" #include <qbytearray.h> #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 <qdebug.h> void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) { if (resourceString == "nsopenglcontext") { - QPlatformGLContext *platformContext = window->glContext()->handle(); - return static_cast<QCocoaGLContext *>(platformContext)->nsOpenGLContext(); + + static_cast<QCocoaWindow *>(window->handle())->currentContext()->nsOpenGLContext(); } return 0; } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index dcf755d009..9d7d37c2ee 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -65,17 +65,22 @@ public: WId winId() const; NSView *contentView() const; + NSView *windowSurfaceView() const; + void windowDidMove(); void windowDidResize(); - QPlatformGLContext *glContext() const; + QPlatformGLSurface *createGLSurface() const; + + void setCurrentContext(QCocoaGLContext *context); + QCocoaGLContext *currentContext() const; private: friend class QCocoaWindowSurface; NSWindow *m_nsWindow; QNSView *m_contentView; NSView *m_windowSurfaceView; - mutable QCocoaGLContext *m_glContext; + QCocoaGLContext *m_glContext; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index a5ad8c87ae..874790a128 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -84,6 +84,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) QCocoaWindow::~QCocoaWindow() { + } void QCocoaWindow::setGeometry(const QRect &rect) @@ -92,6 +93,9 @@ void QCocoaWindow::setGeometry(const QRect &rect) NSRect bounds = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()); [[m_nsWindow contentView]setFrameSize:bounds.size]; + + if (m_glContext) + m_glContext->update(); } void QCocoaWindow::setVisible(bool visible) @@ -131,18 +135,41 @@ NSView *QCocoaWindow::contentView() const return [m_nsWindow contentView]; } +NSView *QCocoaWindow::windowSurfaceView() const +{ + return m_windowSurfaceView; +} + +void QCocoaWindow::windowDidMove() +{ + if (m_glContext) + m_glContext->update(); +} + void QCocoaWindow::windowDidResize() { //jlind: XXX This isn't ideal. Eventdispatcher does not run when resizing... NSRect rect = [[m_nsWindow contentView]frame]; QRect geo(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height); QWindowSystemInterface::handleGeometryChange(window(),geo); + + if (m_glContext) + m_glContext->update(); } -QPlatformGLContext *QCocoaWindow::glContext() const +QPlatformGLSurface *QCocoaWindow::createGLSurface() const +{ + Q_ASSERT(window()->surfaceType() == QWindow::OpenGLSurface); + return new QCocoaGLSurface(window()->glFormat(), window()); +} + +void QCocoaWindow::setCurrentContext(QCocoaGLContext *context) +{ + m_glContext = context; +} + +QCocoaGLContext *QCocoaWindow::currentContext() const { - if (!m_glContext) { - m_glContext = new QCocoaGLContext(m_windowSurfaceView); - } return m_glContext; } + diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h index 1ea02ac016..5cd226a71d 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.h +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h @@ -53,7 +53,7 @@ - (void)windowDidResize:(NSNotification *)notification; - (void)windowWillClose:(NSNotification *)notification; //- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)defaultFrame; -//- (void)windowDidMove:(NSNotification *)notification; +- (void)windowDidMove:(NSNotification *)notification; //- (BOOL)windowShouldClose:(id)window; //- (void)windowDidDeminiaturize:(NSNotification *)notification; //- (void)windowDidBecomeMain:(NSNotification*)notification; @@ -74,6 +74,7 @@ - (id)initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow; - (void)windowDidResize:(NSNotification *)notification; +- (void)windowDidMove:(NSNotification *)notification; - (void)windowWillClose:(NSNotification *)notification; @end diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm index 54def7e592..6521db5cf7 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm @@ -64,6 +64,14 @@ } } +- (void)windowDidMove:(NSNotification *)notification +{ + Q_UNUSED(notification); + if (m_cocoaWindow) { + m_cocoaWindow->windowDidMove(); + } +} + - (void)windowWillClose:(NSNotification *)notification { Q_UNUSED(notification); diff --git a/src/plugins/platforms/eglconvenience/qeglconvenience.cpp b/src/plugins/platforms/eglconvenience/qeglconvenience.cpp index 333425632c..2f686d6f76 100644 --- a/src/plugins/platforms/eglconvenience/qeglconvenience.cpp +++ b/src/plugins/platforms/eglconvenience/qeglconvenience.cpp @@ -39,11 +39,13 @@ ** ****************************************************************************/ +#include <QByteArray> + #include "qeglconvenience.h" QT_BEGIN_NAMESPACE -QVector<EGLint> q_createConfigAttributesFromFormat(const QWindowFormat &format) +QVector<EGLint> q_createConfigAttributesFromFormat(const QGuiGLFormat &format) { int redSize = format.redBufferSize(); int greenSize = format.greenBufferSize(); @@ -68,7 +70,7 @@ QVector<EGLint> q_createConfigAttributesFromFormat(const QWindowFormat &format) // "AtLeast" for EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are // put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit, // we must set the red/green/blue sizes to zero. This has an unfortunate consequence that - // if the application sets the red/green/blue size to 5/6/5 on the QPlatformWindowFormat, + // if the application sets the red/green/blue size to 5/6/5 on the QGuiGLFormat, // they will probably get a 32-bit config, even when there's an RGB565 config available. // // Now normalize the values so -1 becomes 0 @@ -195,7 +197,7 @@ bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes) return false; } -EGLConfig q_configFromQWindowFormat(EGLDisplay display, const QWindowFormat &format, bool highestPixelFormat, int surfaceType) +EGLConfig q_configFromGLFormat(EGLDisplay display, const QGuiGLFormat &format, bool highestPixelFormat, int surfaceType) { EGLConfig cfg = 0; QVector<EGLint> configureAttributes = q_createConfigAttributesFromFormat(format); @@ -257,9 +259,9 @@ EGLConfig q_configFromQWindowFormat(EGLDisplay display, const QWindowFormat &for return 0; } -QWindowFormat q_windowFormatFromConfig(EGLDisplay display, const EGLConfig config) +QGuiGLFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config) { - QWindowFormat format; + QGuiGLFormat format; EGLint redSize = 0; EGLint greenSize = 0; EGLint blueSize = 0; diff --git a/src/plugins/platforms/eglconvenience/qeglconvenience.h b/src/plugins/platforms/eglconvenience/qeglconvenience.h index 978cab4925..302aba318f 100644 --- a/src/plugins/platforms/eglconvenience/qeglconvenience.h +++ b/src/plugins/platforms/eglconvenience/qeglconvenience.h @@ -43,16 +43,16 @@ #define QEGLCONVENIENCE_H -#include <QtGui/QWindowFormat> +#include <QtGui/QGuiGLFormat> #include <QtCore/QVector> #include <EGL/egl.h> QT_BEGIN_NAMESPACE -QVector<EGLint> q_createConfigAttributesFromFormat(const QWindowFormat &format); +QVector<EGLint> q_createConfigAttributesFromFormat(const QGuiGLFormat &format); bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes); -EGLConfig q_configFromQWindowFormat(EGLDisplay display, const QWindowFormat &format, bool highestPixelFormat = false, int surfaceType = EGL_WINDOW_BIT); -QWindowFormat q_windowFormatFromConfig(EGLDisplay display, const EGLConfig config); +EGLConfig q_configFromGLFormat(EGLDisplay display, const QGuiGLFormat &format, bool highestPixelFormat = false, int surfaceType = EGL_WINDOW_BIT); +QGuiGLFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config); bool q_hasEglExtension(EGLDisplay display,const char* extensionName); QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp index db3666bb3e..c96e8ed67a 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp @@ -48,51 +48,47 @@ #include <EGL/egl.h> -QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi) - : QPlatformGLContext() - , m_eglDisplay(display) +QEGLSurface::QEGLSurface(EGLSurface surface, const QGuiGLFormat &format) + : QPlatformGLSurface(format) , m_eglSurface(surface) +{ +} + +QEGLPlatformContext::QEGLPlatformContext(const QGuiGLFormat &format, QPlatformGLContext *share, EGLDisplay display, + EGLint eglClientVersion, EGLenum eglApi) + : m_eglDisplay(display) , m_eglApi(eglApi) + , m_format(format) { - if (m_eglSurface == EGL_NO_SURFACE) { - qWarning("Createing QEGLPlatformContext with no surface"); - } + EGLConfig config = q_configFromGLFormat(display, format, true); + m_format = q_glFormatFromConfig(display, config); + + EGLContext shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0; + + QVector<EGLint> contextAttrs; + contextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); + contextAttrs.append(eglClientVersion); + contextAttrs.append(EGL_NONE); eglBindAPI(m_eglApi); - m_eglContext = eglCreateContext(m_eglDisplay,config, 0,contextAttrs); + m_eglContext = eglCreateContext(m_eglDisplay, config, shareContext, contextAttrs.constData()); if (m_eglContext == EGL_NO_CONTEXT) { qWarning("Could not create the egl context\n"); eglTerminate(m_eglDisplay); qFatal("EGL error"); } - - m_windowFormat = q_windowFormatFromConfig(display,config); -} - -QEGLPlatformContext::~QEGLPlatformContext() -{ -#ifdef QEGL_EXTRA_DEBUG - qWarning("QEglContext::~QEglContext(): %p\n",this); -#endif - if (m_eglSurface != EGL_NO_SURFACE) { - doneCurrent(); - eglDestroySurface(m_eglDisplay, m_eglSurface); - m_eglSurface = EGL_NO_SURFACE; - } - - if (m_eglContext != EGL_NO_CONTEXT) { - eglDestroyContext(m_eglDisplay, m_eglContext); - m_eglContext = EGL_NO_CONTEXT; - } } -void QEGLPlatformContext::makeCurrent() +bool QEGLPlatformContext::makeCurrent(const QPlatformGLSurface &surface) { #ifdef QEGL_EXTRA_DEBUG qWarning("QEglContext::makeCurrent: %p\n",this); #endif eglBindAPI(m_eglApi); - bool ok = eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext); + + EGLSurface eglSurface = static_cast<const QEGLSurface &>(surface).eglSurface(); + + bool ok = eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext); if (!ok) qWarning("QEGLPlatformContext::makeCurrent: eglError: %d, this: %p \n", eglGetError(), this); #ifdef QEGL_EXTRA_DEBUG @@ -114,7 +110,20 @@ void QEGLPlatformContext::makeCurrent() } #endif + return ok; +} + +QEGLPlatformContext::~QEGLPlatformContext() +{ +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglContext::~QEglContext(): %p\n",this); +#endif + if (m_eglContext != EGL_NO_CONTEXT) { + eglDestroyContext(m_eglDisplay, m_eglContext); + m_eglContext = EGL_NO_CONTEXT; + } } + void QEGLPlatformContext::doneCurrent() { #ifdef QEGL_EXTRA_DEBUG @@ -125,28 +134,30 @@ void QEGLPlatformContext::doneCurrent() if (!ok) qWarning("QEGLPlatformContext::doneCurrent(): eglError: %d, this: %p \n", eglGetError(), this); } -void QEGLPlatformContext::swapBuffers() + +void QEGLPlatformContext::swapBuffers(const QPlatformGLSurface &surface) { #ifdef QEGL_EXTRA_DEBUG qWarning("QEglContext::swapBuffers:%p\n",this); #endif eglBindAPI(m_eglApi); - bool ok = eglSwapBuffers(m_eglDisplay, m_eglSurface); + bool ok = eglSwapBuffers(m_eglDisplay, static_cast<const QEGLSurface &>(surface).eglSurface()); if (!ok) qWarning("QEGLPlatformContext::swapBuffers(): eglError: %d, this: %p \n", eglGetError(), this); } -void* QEGLPlatformContext::getProcAddress(const QString& procName) + +void (*QEGLPlatformContext::getProcAddress(const QByteArray &procName)) () { #ifdef QEGL_EXTRA_DEBUG qWarning("QEglContext::getProcAddress%p\n",this); #endif eglBindAPI(m_eglApi); - return (void *)eglGetProcAddress(qPrintable(procName)); + return eglGetProcAddress(procName.constData()); } -QWindowFormat QEGLPlatformContext::windowFormat() const +QGuiGLFormat QEGLPlatformContext::format() const { - return m_windowFormat; + return m_format; } EGLContext QEGLPlatformContext::eglContext() const diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h index 531f553f3b..9877b77e4e 100644 --- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h +++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h @@ -39,33 +39,45 @@ ** ****************************************************************************/ -#ifndef QOPENKODEGLINTEGRATION_H -#define QOPENKODEGLINTEGRATION_H +#ifndef QEGLPLATFORMCONTEXT_H +#define QEGLPLATFORMCONTEXT_H #include <QtGui/QPlatformGLContext> #include <EGL/egl.h> +class QEGLSurface : public QPlatformGLSurface +{ +public: + QEGLSurface(EGLSurface surface, const QGuiGLFormat &format); + + virtual EGLSurface eglSurface() const { return m_eglSurface; } + +private: + EGLSurface m_eglSurface; +}; + class QEGLPlatformContext : public QPlatformGLContext { public: - QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi); + QEGLPlatformContext(const QGuiGLFormat &format, QPlatformGLContext *share, EGLDisplay display, + EGLint eglClientVersion = 2, EGLenum eglApi = EGL_OPENGL_ES_API); ~QEGLPlatformContext(); - void makeCurrent(); + bool makeCurrent(const QPlatformGLSurface &surface); void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString& procName); + void swapBuffers(const QPlatformGLSurface &surface); + void (*getProcAddress(const QByteArray &procName)) (); - QWindowFormat windowFormat() const; + QGuiGLFormat format() const; EGLContext eglContext() const; + private: EGLContext m_eglContext; EGLDisplay m_eglDisplay; - EGLSurface m_eglSurface; EGLenum m_eglApi; - QWindowFormat m_windowFormat; + QGuiGLFormat m_format; }; -#endif //QOPENKODEGLINTEGRATION_H +#endif //QEGLPLATFORMCONTEXT_H diff --git a/src/plugins/platforms/glxconvenience/qglxconvenience.cpp b/src/plugins/platforms/glxconvenience/qglxconvenience.cpp index ad7668136d..189ab397d2 100644 --- a/src/plugins/platforms/glxconvenience/qglxconvenience.cpp +++ b/src/plugins/platforms/glxconvenience/qglxconvenience.cpp @@ -70,7 +70,7 @@ enum { #undef FontChange #endif -QVector<int> qglx_buildSpec(const QWindowFormat &format, int drawableBit) +QVector<int> qglx_buildSpec(const QGuiGLFormat &format, int drawableBit) { QVector<int> spec(48); int i = 0; @@ -88,7 +88,7 @@ QVector<int> qglx_buildSpec(const QWindowFormat &format, int drawableBit) spec[i++] = GLX_ALPHA_SIZE; spec[i++] = format.alphaBufferSize(); } - spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = format.swapBehavior() != QWindowFormat::SingleBuffer ? True : False; + spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = format.swapBehavior() != QGuiGLFormat::SingleBuffer ? True : False; spec[i++] = GLX_STEREO; spec[i++] = format.stereo() ? True : False; @@ -111,11 +111,11 @@ QVector<int> qglx_buildSpec(const QWindowFormat &format, int drawableBit) return spec; } -GLXFBConfig qglx_findConfig(Display *display, int screen , const QWindowFormat &format, int drawableBit) +GLXFBConfig qglx_findConfig(Display *display, int screen , const QGuiGLFormat &format, int drawableBit) { bool reduced = true; GLXFBConfig chosenConfig = 0; - QWindowFormat reducedFormat = format; + QGuiGLFormat reducedFormat = format; while (!chosenConfig && reduced) { QVector<int> spec = qglx_buildSpec(reducedFormat, drawableBit); int confcount = 0; @@ -147,7 +147,7 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , const QWindowFormat & XFree(configs); } - reducedFormat = qglx_reduceWindowFormat(reducedFormat,&reduced); + reducedFormat = qglx_reduceGuiGLFormat(reducedFormat,&reduced); } if (!chosenConfig) @@ -156,16 +156,16 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , const QWindowFormat & return chosenConfig; } -XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QWindowFormat &format) +XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QGuiGLFormat &format) { GLXFBConfig config = qglx_findConfig(display,screen,format); XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display,config); return visualInfo; } -QWindowFormat qglx_platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext) +QGuiGLFormat qglx_guiGLFormatFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext) { - QWindowFormat format; + QGuiGLFormat format; int redSize = 0; int greenSize = 0; int blueSize = 0; @@ -203,9 +203,9 @@ QWindowFormat qglx_platformWindowFromGLXFBConfig(Display *display, GLXFBConfig c return format; } -QWindowFormat qglx_reduceWindowFormat(const QWindowFormat &format, bool *reduced) +QGuiGLFormat qglx_reduceGuiGLFormat(const QGuiGLFormat &format, bool *reduced) { - QWindowFormat retFormat = format; + QGuiGLFormat retFormat = format; *reduced = true; if (retFormat.samples() > 1) { diff --git a/src/plugins/platforms/glxconvenience/qglxconvenience.h b/src/plugins/platforms/glxconvenience/qglxconvenience.h index fe51214006..1a0510067b 100644 --- a/src/plugins/platforms/glxconvenience/qglxconvenience.h +++ b/src/plugins/platforms/glxconvenience/qglxconvenience.h @@ -42,15 +42,16 @@ #ifndef QGLXCONVENIENCE_H #define QGLXCONVENIENCE_H -#include <QWindowFormat> +#include <QGuiGLFormat> +#include <QVector> #include <X11/Xlib.h> #include <GL/glx.h> -XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QWindowFormat &format); -GLXFBConfig qglx_findConfig(Display *display, int screen, const QWindowFormat &format, int drawableBit = GLX_WINDOW_BIT); -QWindowFormat qglx_platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext context); -QVector<int> qglx_buildSpec(const QWindowFormat &format, int drawableBit = GLX_WINDOW_BIT); -QWindowFormat qglx_reduceWindowFormat(const QWindowFormat &format, bool *reduced); +XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QGuiGLFormat &format); +GLXFBConfig qglx_findConfig(Display *display, int screen, const QGuiGLFormat &format, int drawableBit = GLX_WINDOW_BIT); +QGuiGLFormat qglx_guiGLFormatFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext context); +QVector<int> qglx_buildSpec(const QGuiGLFormat &format, int drawableBit = GLX_WINDOW_BIT); +QGuiGLFormat qglx_reduceGuiGLFormat(const QGuiGLFormat &format, bool *reduced); #endif // QGLXCONVENIENCE_H diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h index 250fdccf41..2960d64eea 100644 --- a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h @@ -46,6 +46,9 @@ class QWaylandWindow; class QWaylandDisplay; class QWindow; +class QPlatformGLContext; +class QGuiGLFormat; + class QWaylandGLIntegration { public: @@ -55,6 +58,7 @@ public: virtual void initialize() = 0; virtual QWaylandWindow *createEglWindow(QWindow *window) = 0; + virtual QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const = 0; static QWaylandGLIntegration *createGLIntegration(QWaylandDisplay *waylandDisplay); }; diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp index 57da38ed3c..1d6e79e94c 100644 --- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp +++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp @@ -138,13 +138,14 @@ QWaylandGLWindowSurface::QWaylandGLWindowSurface(QWindow *window) : QWindowSurface(window) , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) , mPaintDevice(0) + , mContext(0) { - } QWaylandGLWindowSurface::~QWaylandGLWindowSurface() { delete mPaintDevice; + delete mContext; } QPaintDevice *QWaylandGLWindowSurface::paintDevice() @@ -152,31 +153,38 @@ QPaintDevice *QWaylandGLWindowSurface::paintDevice() return mPaintDevice; } +QGuiGLContext *QWaylandGLWindowSurface::context() const +{ + if (!mContext) + const_cast<QGuiGLContext *&>(mContext) = new QGuiGLContext(window()->glFormat()); + return mContext; +} + void QWaylandGLWindowSurface::beginPaint(const QRegion &) { - window()->handle()->glContext()->makeCurrent(); - glClearColor(0,0,0,0xff); + context()->makeCurrent(window()->glSurface()); + glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); } -void QWaylandGLWindowSurface::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +void QWaylandGLWindowSurface::flush(QWindow *, const QRegion ®ion, const QPoint &offset) { Q_UNUSED(offset); Q_UNUSED(region); - + if (mPaintDevice->isBound()) mPaintDevice->release(); QRect rect(0,0,size().width(),size().height()); - QGLContext *ctx = QGLContext::fromWindowContext(window->glContext()); + QGLContext *ctx = QGLContext::fromGuiGLContext(context()); blitTexture(ctx,mPaintDevice->texture(),size(),mPaintDevice->size(),rect,rect); - window->glContext()->swapBuffers(); + context()->swapBuffers(window()->glSurface()); } void QWaylandGLWindowSurface::resize(const QSize &size) { QWindowSurface::resize(size); - window()->glContext()->makeCurrent(); + context()->makeCurrent(window()->glSurface()); delete mPaintDevice; mPaintDevice = new QGLFramebufferObject(size); } diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h index 31c0fd2daa..3703869a60 100644 --- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h +++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h @@ -61,9 +61,12 @@ public: void resize(const QSize &size); + QGuiGLContext *context() const; + private: QWaylandDisplay *mDisplay; QGLFramebufferObject *mPaintDevice; + QGuiGLContext *mContext; }; #endif // QWAYLANDDRMSURFACE_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp index 50a1170f79..7fbe5cc725 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp @@ -83,7 +83,12 @@ void QWaylandReadbackEglIntegration::initialize() QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWindow *window) { - return new QWaylandReadbackEglWindow(window,this); + return new QWaylandReadbackEglWindow(window, this); +} + +QPlatformGLContext *QWaylandReadbackEglWindow::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const +{ + return new QWaylandReadbackEglContext(glFormat, share, this); } EGLDisplay QWaylandReadbackEglIntegration::eglDisplay() diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h index 649f96e9cc..8945cdab38 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h @@ -63,6 +63,7 @@ public: void initialize(); QWaylandWindow *createEglWindow(QWindow *window); + QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const; QWaylandDisplay *waylandDisplay() const; Display *xDisplay() const; diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp index 5750c948cd..54b7d322f8 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp @@ -44,8 +44,19 @@ #include "qwaylandshmsurface.h" #include "qwaylandreadbackglxwindow.h" +#include <QtGui/QGuiGLContext> #include <QtCore/QDebug> +QWaylandReadbackGlxSurface::QWaylandReadbackGlxSurface(QWaylandReadbackGlxWindow *window) + : m_window(window) +{ +} + +GLXPixmap QWaylandReadbackGlxSurface::glxPixmap() const +{ + return m_window->glxPixmap(); +} + static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type) { const int width = img.width(); @@ -68,94 +79,66 @@ static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type) } } -QWaylandReadbackGlxContext::QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window) - : QPlatformGLContext() - , mGlxIntegration(glxIntegration) - , mWindow(window) - , mBuffer(0) - , mPixmap(0) - , mConfig(qglx_findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->widget()->platformWindowFormat(),GLX_PIXMAP_BIT)) - , mGlxPixmap(0) +QWaylandReadbackGlxContext::QWaylandReadbackGlxContext(const QGuiGLFormat &format, + QPlatformGLContext *share, Display *display, int screen) + : m_display(display) { - XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig); - mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE); + GLXFBConfig config = qglx_findConfig(display, screen, format, GLX_PIXMAP_BIT); - geometryChanged(); + GLXContext shareContext = share ? static_cast<QWaylandReadbackGlxContext *>(share)->m_context : 0; + + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config); + m_context = glXCreateContext(display, visualInfo, shareContext, TRUE); + m_format = qglx_guiGLFormatFromGLXFBConfig(display, config, m_context); } -void QWaylandReadbackGlxContext::makeCurrent() +QGuiGLFormat QWaylandReadbackGlxContext::format() const { - glXMakeCurrent(mGlxIntegration->xDisplay(),mGlxPixmap,mContext); + return m_format; +} + +bool QWaylandReadbackGlxContext::makeCurrent(const QPlatformGLSurface &surface) +{ + GLXPixmap glxPixmap = static_cast<const QWaylandReadbackGlxSurface &>(surface).glxPixmap(); + + return glXMakeCurrent(m_display, glxPixmap, m_context); } void QWaylandReadbackGlxContext::doneCurrent() { - QPlatformGLContext::doneCurrent(); + glXMakeCurrent(m_display, 0, 0); } -void QWaylandReadbackGlxContext::swapBuffers() +void QWaylandReadbackGlxContext::swapBuffers(const QPlatformGLSurface &surface) { - if (QWindowContext::currentContext().handle() != this) { - makeCurrent(); - } + // #### makeCurrent() directly on the platform context doesn't update QGuiGLContext::currentContext() + if (QGuiGLContext::currentContext()->handle() != this) + makeCurrent(surface, surface); - QSize size = mWindow->geometry().size(); + const QWaylandReadbackGlxSurface &s = + static_cast<const QWaylandReadbackGlxSurface &>(surface); - QImage img(size,QImage::Format_ARGB32); + QSize size = s.window()->geometry().size(); + + QImage img(size, QImage::Format_ARGB32); const uchar *constBits = img.bits(); void *pixels = const_cast<uchar *>(constBits); - glReadPixels(0,0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels); + glReadPixels(0, 0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels); img = img.mirrored(); - qgl_byteSwapImage(img,GL_UNSIGNED_INT_8_8_8_8_REV); + qgl_byteSwapImage(img, GL_UNSIGNED_INT_8_8_8_8_REV); constBits = img.bits(); - const uchar *constDstBits = mBuffer->image()->bits(); + const uchar *constDstBits = s.window()->buffer(); uchar *dstBits = const_cast<uchar *>(constDstBits); - memcpy(dstBits,constBits,(img.width()*4) * img.height()); - - - mWindow->damage(QRegion(QRect(QPoint(0,0),size))); - mWindow->waitForFrameSync(); + memcpy(dstBits, constBits, (img.width() * 4) * img.height()); + s.window()->damage(QRect(QPoint(), size)); + s.window()->waitForFrameSync(); } -void * QWaylandReadbackGlxContext::getProcAddress(const QString &procName) +void (*QWaylandReadbackGlxContext::getProcAddress(const QByteArray &procName)) () { - return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data())); -} - -QPlatformWindowFormat QWaylandReadbackGlxContext::platformWindowFormat() const -{ - return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext); -} - -void QWaylandReadbackGlxContext::geometryChanged() -{ - QSize size(mWindow->geometry().size()); - if (size.isEmpty()) { - //QGLWidget wants a context for a window without geometry - size = QSize(1,1); - } - - mWindow->waitForFrameSync(); - - delete mBuffer; - //XFreePixmap deletes the glxPixmap as well - if (mPixmap) { - XFreePixmap(mGlxIntegration->xDisplay(),mPixmap); - } - - mBuffer = new QWaylandShmBuffer(mGlxIntegration->waylandDisplay(),size,QImage::Format_ARGB32); - mWindow->attach(mBuffer); - int depth = XDefaultDepth(mGlxIntegration->xDisplay(),mGlxIntegration->screen()); - mPixmap = XCreatePixmap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),size.width(),size.height(),depth); - XSync(mGlxIntegration->xDisplay(),False); - - mGlxPixmap = glXCreatePixmap(mGlxIntegration->xDisplay(),mConfig,mPixmap,0); - - if (!mGlxPixmap) { - qDebug() << "Could not make egl surface out of pixmap :("; - } + return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName.constData())); } diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h index 07e0f620de..27a7287b07 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h @@ -43,6 +43,7 @@ #define QWAYLANDREADBACKGLXCONTEXT_H #include <QPlatformGLContext> +#include <QGuiGLFormat> #include "qwaylandreadbackglxintegration.h" @@ -51,29 +52,37 @@ class QWaylandReadbackGlxWindow; class QWaylandShmBuffer; +class QWaylandReadbackGlxSurface : public QPlatformGLSurface +{ +public: + QWaylandReadbackGlxSurface(QWaylandReadbackGlxWindow *window); + + QWaylandReadbackGlxWindow *window() const { return m_window; } + GLXPixmap glxPixmap() const; + +private: + QWaylandReadbackGlxWindow *m_window; +}; + class QWaylandReadbackGlxContext : public QPlatformGLContext { public: - QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window); + QWaylandReadbackGlxContext(const QGuiGLFormat &format, QPlatformGLContext *share, Display *display, int screen); - void makeCurrent(); - void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString& procName); + QGuiGLFormat format() const; - QPlatformWindowFormat platformWindowFormat() const; + void swapBuffers(const QPlatformGLSurface &surface); - void geometryChanged(); + bool makeCurrent(const QPlatformGLSurface &surface); + void doneCurrent(); + + void (*getProcAddress(const QByteArray &procName)) (); private: - QWaylandReadbackGlxIntegration *mGlxIntegration; - QWaylandReadbackGlxWindow *mWindow; - QWaylandShmBuffer *mBuffer; - - Pixmap mPixmap; - GLXFBConfig mConfig; - GLXContext mContext; - GLXPixmap mGlxPixmap; + GLXContext m_context; + + Display *m_display; + QGuiGLFormat m_format; }; #endif // QWAYLANDREADBACKGLXCONTEXT_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp index e17e3f87a0..6fb2a178c8 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp @@ -71,6 +71,11 @@ QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWindow *window return new QWaylandReadbackGlxWindow(window,this); } +QPlatformGLContext *QWaylandReadbackGlxIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const +{ + return new QWaylandReadbackGlxContext(glFormat, share, mDisplay, mScreen); +} + QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) { return new QWaylandReadbackGlxIntegration(waylandDisplay); diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h index 3055169c0a..0b3d0cc2cc 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h @@ -61,6 +61,7 @@ public: void initialize(); QWaylandWindow *createEglWindow(QWindow *window); + QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const; QWaylandDisplay *waylandDisplay() const; diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp index b70ed43e69..f878bef0c4 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp @@ -39,12 +39,19 @@ ** ****************************************************************************/ +#include <QtDebug> + #include "qwaylandreadbackglxwindow.h" +#include "qwaylandshmsurface.h" + QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration) : QWaylandShmWindow(window) - , mGlxIntegration(glxIntegration) - , mContext(0) + , m_glxIntegration(glxIntegration) + , m_buffer(0) + , m_pixmap(0) + , m_config(qglx_findConfig(glxIntegration->xDisplay(), glxIntegration->screen(), window->glFormat())) + , m_glxPixmap(0) { } @@ -54,20 +61,51 @@ QWaylandWindow::WindowType QWaylandReadbackGlxWindow::windowType() const return QWaylandWindow::Egl; } -QPlatformGLContext * QWaylandReadbackGlxWindow::glContext() const +void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect) { - if (!mContext) { - QWaylandReadbackGlxWindow *that = const_cast<QWaylandReadbackGlxWindow *>(this); - that->mContext = new QWaylandReadbackGlxContext(mGlxIntegration,that); + QWaylandShmWindow::setGeometry(rect); + + if (m_pixmap) { + delete mBuffer; + //XFreePixmap deletes the glxPixmap as well + XFreePixmap(m_glxIntegration->xDisplay(), m_pixmap); + m_pixmap = 0; } - return mContext; } -void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect) +GLXPixmap QWaylandReadbackGlxWindow::glxPixmap() const { - QWaylandShmWindow::setGeometry(rect); + if (!m_pixmap) + const_cast<QWaylandReadbackGlxWindow *>(this)->createSurface(); - if (mContext) { - mContext->geometryChanged(); + return m_glxPixmap; +} + +uchar *QWaylandReadbackGlxWindow::buffer() +{ + return m_buffer->image()->bits(); +} + +void QWaylandReadbackGlxWindow::createSurface() +{ + QSize size(geometry().size()); + if (size.isEmpty()) { + //QGLWidget wants a context for a window without geometry + size = QSize(1,1); } + + waitForFrameSync(); + + m_buffer = new QWaylandShmBuffer(m_glxIntegration->waylandDisplay(), size, QImage::Format_ARGB32); + attach(m_buffer); + + int depth = XDefaultDepth(m_glxIntegration->xDisplay(), m_glxIntegration->screen()); + m_pixmap = XCreatePixmap(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(), size.width(), size.height(), depth); + XSync(m_glxIntegration->xDisplay(), False); + + m_glxPixmap = glXCreatePixmap(m_glxIntegration->xDisplay(), m_config, m_pixmap,0); + + if (!m_glxPixmap) + qDebug() << "Could not make glx surface out of pixmap :("; } + diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h index 3f20a0e2fc..60b22a4408 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h @@ -52,14 +52,23 @@ public: QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration); WindowType windowType() const; - QPlatformGLContext *glContext() const; + QPlatformGLSurface *createGLSurface() const; void setGeometry(const QRect &rect); + Pixmap glxPixmap() const; + + uchar *buffer(); + private: - QWaylandReadbackGlxIntegration *mGlxIntegration; - QWaylandReadbackGlxContext *mContext; + void createSurface(); + + QWaylandReadbackGlxIntegration *m_glxIntegration; + QWaylandShmBuffer *m_buffer; + Pixmap m_pixmap; + GLXFBConfig m_config; + GLXPixmap m_glxPixmap; }; #endif // QWAYLANDREADBACKGLXWINDOW_H diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp index e61ee69d37..08b6f76daf 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp @@ -42,127 +42,37 @@ #include "qwaylandxcompositeeglcontext.h" #include "qwaylandxcompositeeglwindow.h" -#include "qwaylandxcompositebuffer.h" -#include "wayland-xcomposite-client-protocol.h" #include <QtCore/QDebug> #include <QtGui/QRegion> #include "qeglconvenience.h" -#include "qxlibeglintegration.h" -#include <X11/extensions/Xcomposite.h> - -QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window) - : QPlatformGLContext() - , mEglIntegration(glxIntegration) - , mWindow(window) - , mBuffer(0) - , mXWindow(0) - , mConfig(q_configFromQWindowFormat(glxIntegration->eglDisplay(),window->window()->requestedWindowFormat(),true,EGL_WINDOW_BIT)) - , mWaitingForSync(false) -{ - QVector<EGLint> eglContextAttrs; - eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); eglContextAttrs.append(2); - eglContextAttrs.append(EGL_NONE); - - mContext = eglCreateContext(glxIntegration->eglDisplay(),mConfig,EGL_NO_CONTEXT,eglContextAttrs.constData()); - if (mContext == EGL_NO_CONTEXT) { - qFatal("failed to find context"); - } - - geometryChanged(); -} - -void QWaylandXCompositeEGLContext::makeCurrent() +QWaylandXCompositeEGLSurface::QWaylandXCompositeEGLSurface(QWaylandXCompositeEGLWindow *window) + : QEGLSurface(window->eglSurface(), window->window()->glFormat()) + , m_window(window) { - eglMakeCurrent(mEglIntegration->eglDisplay(),mEglWindowSurface,mEglWindowSurface,mContext); } -void QWaylandXCompositeEGLContext::doneCurrent() +EGLSurface QWaylandXCompositeEGLSurface::eglSurface() const { - QPlatformGLContext::doneCurrent(); - eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT); + return m_window->eglSurface(); } -void QWaylandXCompositeEGLContext::swapBuffers() +QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(const QGuiGLFormat &format, QPlatformGLContext *share, EGLDisplay display) + : QEGLPlatformContext(format, share, display) { - QSize size = mWindow->geometry().size(); - - eglSwapBuffers(mEglIntegration->eglDisplay(),mEglWindowSurface); - mWindow->damage(QRegion(QRect(QPoint(0,0),size))); - mWindow->waitForFrameSync(); -} - -void * QWaylandXCompositeEGLContext::getProcAddress(const QString &procName) -{ - return (void *)eglGetProcAddress(qPrintable(procName)); } -QWindowFormat QWaylandXCompositeEGLContext::windowFormat() const +void QWaylandXCompositeEGLContext::swapBuffers(const QPlatformGLSurface &surface) { - return q_windowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig); -} - -void QWaylandXCompositeEGLContext::sync_function(void *data) -{ - QWaylandXCompositeEGLContext *that = static_cast<QWaylandXCompositeEGLContext *>(data); - that->mWaitingForSync = false; -} - -void QWaylandXCompositeEGLContext::geometryChanged() -{ - QSize size(mWindow->geometry().size()); - if (size.isEmpty()) { - //QGLWidget wants a context for a window without geometry - size = QSize(1,1); - } - - delete mBuffer; - //XFreePixmap deletes the glxPixmap as well - if (mXWindow) { - XDestroyWindow(mEglIntegration->xDisplay(),mXWindow); - } - - VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(mEglIntegration->xDisplay(),mEglIntegration->eglDisplay(),mConfig); - - XVisualInfo visualInfoTemplate; - memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); - visualInfoTemplate.visualid = visualId; - - int matchingCount = 0; - XVisualInfo *visualInfo = XGetVisualInfo(mEglIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount); - - Colormap cmap = XCreateColormap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),visualInfo->visual,AllocNone); - - XSetWindowAttributes a; - a.colormap = cmap; - mXWindow = XCreateWindow(mEglIntegration->xDisplay(), mEglIntegration->rootWindow(),0, 0, size.width(), size.height(), - 0, visualInfo->depth, InputOutput, visualInfo->visual, - CWColormap, &a); - - XCompositeRedirectWindow(mEglIntegration->xDisplay(), mXWindow, CompositeRedirectManual); - XMapWindow(mEglIntegration->xDisplay(), mXWindow); + QEGLPlatformContext::swapBuffers(surface); - mEglWindowSurface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mConfig,mXWindow,0); - if (mEglWindowSurface == EGL_NO_SURFACE) { - qFatal("Could not make eglsurface"); - } + const QWaylandXCompositeEGLSurface &s = + static_cast<const QWaylandXCompositeEGLSurface &>(surface); - XSync(mEglIntegration->xDisplay(),False); - mBuffer = new QWaylandXCompositeBuffer(mEglIntegration->waylandXComposite(), - (uint32_t)mXWindow, - size, - mEglIntegration->waylandDisplay()->argbVisual()); - mWindow->attach(mBuffer); - wl_display_sync_callback(mEglIntegration->waylandDisplay()->wl_display(), - QWaylandXCompositeEGLContext::sync_function, - this); + QSize size = s.window()->geometry().size(); - mWaitingForSync = true; - wl_display_sync(mEglIntegration->waylandDisplay()->wl_display(),0); - mEglIntegration->waylandDisplay()->flushRequests(); - while (mWaitingForSync) { - mEglIntegration->waylandDisplay()->readEvents(); - } + s.window()->damage(QRect(QPoint(), size)); + s.window()->waitForFrameSync(); } diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h index 528faf07c5..bd7039f284 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h @@ -44,37 +44,29 @@ #include <QtGui/QPlatformGLContext> -#include "qwaylandbuffer.h" #include "qwaylandxcompositeeglintegration.h" +#include "qeglplatformcontext.h" + class QWaylandXCompositeEGLWindow; -class QWaylandXCompositeEGLContext : public QPlatformGLContext +class QWaylandXCompositeEGLSurface : public QEGLSurface { public: - QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window); - - void makeCurrent(); - void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString& procName); - - QWindowFormat windowFormat() const; - - void geometryChanged(); + QWaylandXCompositeEGLSurface(QWaylandXCompositeEGLWindow *window); + EGLSurface eglSurface() const; + QWaylandXCompositeEGLWindow *window() const { return m_window; } private: - QWaylandXCompositeEGLIntegration *mEglIntegration; - QWaylandXCompositeEGLWindow *mWindow; - QWaylandBuffer *mBuffer; + QWaylandXCompositeEGLWindow *m_window; +}; - Window mXWindow; - EGLConfig mConfig; - EGLContext mContext; - EGLSurface mEglWindowSurface; +class QWaylandXCompositeEGLContext : public QEGLPlatformContext +{ +public: + QWaylandXCompositeEGLContext(const QGuiGLFormat &format, QPlatformGLContext *share, EGLDisplay display); - static void sync_function(void *data); - bool mWaitingForSync; + void swapBuffers(const QPlatformGLSurface &surface); }; #endif // QWAYLANDXCOMPOSITEEGLCONTEXT_H diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp index 239ec8963d..90d5bea770 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp @@ -75,6 +75,11 @@ QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWindow *wind return new QWaylandXCompositeEGLWindow(window,this); } +QPlatformGLContext *QWaylandXCompositeEGLIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const +{ + return new QWaylandXCompositeEGLContext(glFormat, share, eglDisplay()); +} + Display * QWaylandXCompositeEGLIntegration::xDisplay() const { return mDisplay; diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h index 3252ce741e..ac302ef89f 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h @@ -51,6 +51,8 @@ #include <QtCore/QVariant> #include <QtGui/QWindow> +#include <QPlatformGLContext> + #include <QWaitCondition> #include <X11/Xlib.h> @@ -67,6 +69,7 @@ public: void initialize(); QWaylandWindow *createEglWindow(QWindow *window); + QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const; QWaylandDisplay *waylandDisplay() const; struct wl_xcomposite *waylandXComposite() const; diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp index e57203f772..5c6717eb0c 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp @@ -40,15 +40,27 @@ ****************************************************************************/ #include "qwaylandxcompositeeglwindow.h" +#include "qwaylandxcompositebuffer.h" + +#include "qeglconvenience.h" + +#include "wayland-xcomposite-client-protocol.h" +#include "qxlibeglintegration.h" + +#include <X11/extensions/Xcomposite.h> #include <QtCore/QDebug> QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration) : QWaylandWindow(window) - , mGlxIntegration(glxIntegration) - , mContext(0) + , m_glxIntegration(glxIntegration) + , m_context(0) + , m_buffer(0) + , m_xWindow(0) + , m_config(q_configFromGLFormat(glxIntegration->eglDisplay(), window->glFormat(), true)) + , m_surface(0) + , m_waitingForSync(false) { - } QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const @@ -57,21 +69,86 @@ QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const return QWaylandWindow::Egl; } -QPlatformGLContext * QWaylandXCompositeEGLWindow::glContext() const +QPlatformGLSurface *QWaylandXCompositeEGLWindow::createGLSurface() const { - if (!mContext) { - qDebug() << "creating glcontext;"; - QWaylandXCompositeEGLWindow *that = const_cast<QWaylandXCompositeEGLWindow *>(this); - that->mContext = new QWaylandXCompositeEGLContext(mGlxIntegration,that); - } - return mContext; + return new QWaylandXCompositeEGLSurface(const_cast<QWaylandXCompositeEGLWindow *>(this)); } void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect) { QWaylandWindow::setGeometry(rect); - if (mContext) { - mContext->geometryChanged(); + if (m_surface) { + eglDestroySurface(m_glxIntegration->eglDisplay(), m_surface); + m_surface = 0; + } +} + +EGLSurface QWaylandXCompositeEGLWindow::eglSurface() const +{ + if (!m_surface) + const_cast<QWaylandXCompositeEGLWindow *>(this)->createEglSurface(); + return m_surface; +} + +void QWaylandXCompositeEGLWindow::createEglSurface() +{ + QSize size(geometry().size()); + if (size.isEmpty()) { + // QGLWidget wants a context for a window without geometry + size = QSize(1,1); + } + + delete m_buffer; + //XFreePixmap deletes the glxPixmap as well + if (m_xWindow) { + XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow); } + + VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(m_glxIntegration->xDisplay(), m_glxIntegration->eglDisplay(), m_config); + + XVisualInfo visualInfoTemplate; + memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); + visualInfoTemplate.visualid = visualId; + + int matchingCount = 0; + XVisualInfo *visualInfo = XGetVisualInfo(m_glxIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount); + + Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(),m_glxIntegration->rootWindow(),visualInfo->visual,AllocNone); + + XSetWindowAttributes a; + a.colormap = cmap; + m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(), + 0, visualInfo->depth, InputOutput, visualInfo->visual, + CWColormap, &a); + + XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual); + XMapWindow(m_glxIntegration->xDisplay(), m_xWindow); + + m_surface = eglCreateWindowSurface(m_glxIntegration->eglDisplay(), m_config, m_xWindow,0); + if (m_surface == EGL_NO_SURFACE) { + qFatal("Could not make eglsurface"); + } + + XSync(m_glxIntegration->xDisplay(),False); + mBuffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(), + (uint32_t)m_xWindow, + size, + m_glxIntegration->waylandDisplay()->argbVisual()); + attach(m_buffer); + wl_display_sync_callback(m_glxIntegration->waylandDisplay()->wl_display(), + QWaylandXCompositeEGLWindow::sync_function, + this); + + m_waitingForSync = true; + wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display(),0); + m_glxIntegration->waylandDisplay()->flushRequests(); + while (m_waitingForSync) + m_glxIntegration->waylandDisplay()->readEvents(); +} + +void QWaylandXCompositeEGLWindow::sync_function(void *data) +{ + QWaylandXCompositeEGLWindow *that = static_cast<QWaylandXCompositeEGLWindow *>(data); + that->m_waitingForSync = false; } diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h index 6efe556fb5..16188ca3e0 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h @@ -43,6 +43,8 @@ #define QWAYLANDXCOMPOSITEEGLWINDOW_H #include "qwaylandwindow.h" +#include "qwaylandbuffer.h" + #include "qwaylandxcompositeeglintegration.h" #include "qwaylandxcompositeeglcontext.h" @@ -52,14 +54,26 @@ public: QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration); WindowType windowType() const; - QPlatformGLContext *glContext() const; + QPlatformGLSurface *createGLSurface() const; void setGeometry(const QRect &rect); + EGLSurface eglSurface() const; + private: - QWaylandXCompositeEGLIntegration *mGlxIntegration; - QWaylandXCompositeEGLContext *mContext; + void createEglSurface(); + + QWaylandXCompositeEGLIntegration *m_glxIntegration; + QWaylandXCompositeEGLContext *m_context; + QWaylandBuffer *m_buffer; + + Window m_xWindow; + EGLConfig m_config; + EGLSurface m_surface; + + bool m_waitingForSync; + static void sync_function(void *data); }; #endif // QWAYLANDXCOMPOSITEEGLWINDOW_H diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri index 7d2f8ad443..a61391b2d1 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri @@ -1,5 +1,6 @@ include (../xcomposite_share/xcomposite_share.pri) load(qpa/egl/convenience) +load(qpa/egl/context) load(qpa/egl/xlibintegration) LIBS += -lXcomposite -lEGL diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp index aa26971021..5d4cf7a567 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp @@ -39,114 +39,67 @@ ** ****************************************************************************/ +#include <QtCore/QDebug> + #include "qwaylandxcompositeglxcontext.h" #include "qwaylandxcompositeglxwindow.h" -#include "qwaylandxcompositebuffer.h" -#include "wayland-xcomposite-client-protocol.h" -#include <QtCore/QDebug> -#include <QtGui/QRegion> - -#include <X11/extensions/Xcomposite.h> - -QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window) - : QPlatformGLContext() - , mGlxIntegration(glxIntegration) - , mWindow(window) - , mBuffer(0) - , mXWindow(0) - , mConfig(qglx_findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->window()->requestedWindowFormat())) - , mWaitingForSyncCallback(false) -{ - XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig); - mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE); +#include <QRegion> - geometryChanged(); -} - -void QWaylandXCompositeGLXContext::makeCurrent() +QWaylandXCompositeGLXSurface::QWaylandXCompositeGLXSurface(QWaylandXCompositeGLXWindow *window) + : m_window(window) { - glXMakeCurrent(mGlxIntegration->xDisplay(),mXWindow,mContext); } -void QWaylandXCompositeGLXContext::doneCurrent() +Window QWaylandXCompositeGLXSurface::xWindow() const { - glXMakeCurrent(mGlxIntegration->xDisplay(),0,0); - QPlatformGLContext::doneCurrent(); + return m_window->xWindow(); } -void QWaylandXCompositeGLXContext::swapBuffers() +QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(const QGuiGLFormat &format, QPlatformGLContext *share, Display *display, int screen) + : m_display(display) { - QSize size = mWindow->geometry().size(); + GLXContext shareContext = share ? static_cast<QWaylandXCompositeGLXContext *>(share)->m_context : 0; - glXSwapBuffers(mGlxIntegration->xDisplay(),mXWindow); - mWindow->damage(QRegion(QRect(QPoint(0,0),size))); - mWindow->waitForFrameSync(); + GLXFBConfig config = qglx_findConfig(display, screen, format); + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config); + m_context = glXCreateContext(display, visualInfo, shareContext, true); + m_format = qglx_guiGLFormatFromGLXFBConfig(display, config, m_context); } -void * QWaylandXCompositeGLXContext::getProcAddress(const QString &procName) +bool QWaylandXCompositeGLXContext::makeCurrent(const QPlatformGLSurface &surface) { - return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data())); + Window xWindow = static_cast<const QWaylandXCompositeGLXSurface &>(surface).xWindow(); + + return glXMakeCurrent(m_display, xWindow, m_context); } -QWindowFormat QWaylandXCompositeGLXContext::windowFormat() const +void QWaylandXCompositeGLXContext::doneCurrent() { - return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext); + glXMakeCurrent(m_display, 0, 0); } -void QWaylandXCompositeGLXContext::sync_function(void *data) +void QWaylandXCompositeGLXContext::swapBuffers(const QPlatformGLSurface &surface) { - QWaylandXCompositeGLXContext *that = static_cast<QWaylandXCompositeGLXContext *>(data); - that->mWaitingForSyncCallback = false; + const QWaylandXCompositeGLXSurface &s = + static_cast<const QWaylandXCompositeGLXSurface &>(surface); + + QSize size = s.window()->geometry().size(); + + glXSwapBuffers(m_display, s.xWindow()); + + s.window()->damage(QRect(QPoint(), size)); + s.window()->waitForFrameSync(); } -void QWaylandXCompositeGLXContext::waitForSync() +void (*QWaylandXCompositeGLXContext::getProcAddress(const QByteArray &procName)) () { - wl_display_sync_callback(mGlxIntegration->waylandDisplay()->wl_display(), - QWaylandXCompositeGLXContext::sync_function, - this); - mWaitingForSyncCallback = true; - wl_display_sync(mGlxIntegration->waylandDisplay()->wl_display(),0); - mGlxIntegration->waylandDisplay()->flushRequests(); - while (mWaitingForSyncCallback) { - mGlxIntegration->waylandDisplay()->readEvents(); - } + return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName.constData())); } -void QWaylandXCompositeGLXContext::geometryChanged() +QGuiGLFormat QWaylandXCompositeGLXContext::format() const { - QSize size(mWindow->geometry().size()); - if (size.isEmpty()) { - //QGLWidget wants a context for a window without geometry - size = QSize(1,1); - } - - delete mBuffer; - //XFreePixmap deletes the glxPixmap as well - if (mXWindow) { - XDestroyWindow(mGlxIntegration->xDisplay(),mXWindow); - } - - XVisualInfo *visualInfo = glXGetVisualFromFBConfig(mGlxIntegration->xDisplay(),mConfig); - Colormap cmap = XCreateColormap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),visualInfo->visual,AllocNone); - - XSetWindowAttributes a; - a.background_pixel = WhitePixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen()); - a.border_pixel = BlackPixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen()); - a.colormap = cmap; - mXWindow = XCreateWindow(mGlxIntegration->xDisplay(), mGlxIntegration->rootWindow(),0, 0, size.width(), size.height(), - 0, visualInfo->depth, InputOutput, visualInfo->visual, - CWBackPixel|CWBorderPixel|CWColormap, &a); - - XCompositeRedirectWindow(mGlxIntegration->xDisplay(), mXWindow, CompositeRedirectManual); - XMapWindow(mGlxIntegration->xDisplay(), mXWindow); - - XSync(mGlxIntegration->xDisplay(),False); - mBuffer = new QWaylandXCompositeBuffer(mGlxIntegration->waylandXComposite(), - (uint32_t)mXWindow, - size, - mGlxIntegration->waylandDisplay()->argbVisual()); - mWindow->attach(mBuffer); - waitForSync(); + return m_format; } + diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h index 49ae73de40..e0de801a5e 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h @@ -44,42 +44,44 @@ #include <QtGui/QPlatformGLContext> -#include <QtCore/QWaitCondition> - -#include "qwaylandbuffer.h" #include "qwaylandxcompositeglxintegration.h" - #include "qglxconvenience.h" class QWaylandXCompositeGLXWindow; class QWaylandShmBuffer; +class QWaylandXCompositeGLXSurface : public QPlatformGLSurface +{ +public: + QWaylandXCompositeGLXSurface(QWaylandXCompositeGLXWindow *window); + + QWaylandXCompositeGLXWindow *window() const { return m_window; } + Window xWindow() const; + +private: + QWaylandXCompositeGLXWindow *m_window; +}; + + class QWaylandXCompositeGLXContext : public QPlatformGLContext { public: - QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window); + QWaylandXCompositeGLXContext(const QGuiGLFormat &format, QPlatformGLContext *share, Display *display, int screen); - void makeCurrent(); - void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString& procName); + QGuiGLFormat format() const; - QWindowFormat windowFormat() const; + void swapBuffers(const QPlatformGLSurface &surface); - void geometryChanged(); + bool makeCurrent(const QPlatformGLSurface &surface); + void doneCurrent(); -private: - QWaylandXCompositeGLXIntegration *mGlxIntegration; - QWaylandXCompositeGLXWindow *mWindow; - QWaylandBuffer *mBuffer; + void (*getProcAddress(const QByteArray &procName)) (); - Window mXWindow; - GLXFBConfig mConfig; - GLXContext mContext; +private: + GLXContext m_context; - static void sync_function(void *data); - void waitForSync(); - bool mWaitingForSyncCallback; + Display *m_display; + QGuiGLFormat m_format; }; #endif // QWAYLANDXCOMPOSITEGLXCONTEXT_H diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp index e5f4feb436..a80a595768 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp @@ -72,7 +72,12 @@ void QWaylandXCompositeGLXIntegration::initialize() QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWindow *window) { - return new QWaylandXCompositeGLXWindow(window,this); + return new QWaylandXCompositeGLXWindow(window, this); +} + +QPlatformGLContext *QWaylandXCompositeGLXIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const +{ + return new QWaylandXCompositeGLXContext(glFormat, share, mDisplay, mScreen); } Display * QWaylandXCompositeGLXIntegration::xDisplay() const diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h index f934a9a4d2..c347b110c6 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h @@ -64,6 +64,7 @@ public: void initialize(); QWaylandWindow *createEglWindow(QWindow *window); + QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const; QWaylandDisplay *waylandDisplay() const; struct wl_xcomposite *waylandXComposite() const; diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp index 6eec1d4eb8..41a14e3f66 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp @@ -40,15 +40,24 @@ ****************************************************************************/ #include "qwaylandxcompositeglxwindow.h" +#include "qwaylandxcompositebuffer.h" #include <QtCore/QDebug> +#include "wayland-xcomposite-client-protocol.h" +#include <QtGui/QRegion> + +#include <X11/extensions/Xcomposite.h> + + QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration) : QWaylandWindow(window) - , mGlxIntegration(glxIntegration) - , mContext(0) + , m_glxIntegration(glxIntegration) + , m_xWindow(0) + , m_config(qglx_findConfig(glxIntegration->xDisplay(), glxIntegration->screen(), window->glFormat())) + , m_buffer(0) + , m_waitingForSync(false) { - } QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const @@ -57,21 +66,79 @@ QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const return QWaylandWindow::Egl; } -QPlatformGLContext * QWaylandXCompositeGLXWindow::glContext() const +QPlatformGLSurface *QWaylandXCompositeGLXWindow::createGLSurface() const { - if (!mContext) { - qDebug() << "creating glcontext;"; - QWaylandXCompositeGLXWindow *that = const_cast<QWaylandXCompositeGLXWindow *>(this); - that->mContext = new QWaylandXCompositeGLXContext(mGlxIntegration,that); - } - return mContext; + return new QWaylandXCompositeGLXSurface(const_cast<QWaylandXCompositeGLXWindow *>(this)); } void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect) { QWaylandWindow::setGeometry(rect); - if (mContext) { - mContext->geometryChanged(); + if (m_xWindow) { + delete m_buffer; + + XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow); + m_xWindow = 0; + } +} + +Window QWaylandXCompositeGLXWindow::xWindow() const +{ + if (!m_xWindow) + const_cast<QWaylandXCompositeGLXWindow *>(this)->createSurface(); + + return m_xWindow; +} + +void QWaylandXCompositeGLXWindow::waitForSync() +{ + wl_display_sync_callback(m_glxIntegration->waylandDisplay()->wl_display(), + QWaylandXCompositeGLXWindow::sync_function, + this); + m_waitingForSync= true; + wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display(), 0); + m_glxIntegration->waylandDisplay()->flushRequests(); + while (m_waitingForSync) + m_glxIntegration->waylandDisplay()->readEvents(); +} + + +void QWaylandXCompositeGLXWindow::createSurface() +{ + QSize size(geometry().size()); + if (size.isEmpty()) { + //QGLWidget wants a context for a window without geometry + size = QSize(1,1); } + + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(m_glxIntegration->xDisplay(), m_config); + Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(), + visualInfo->visual, AllocNone); + + XSetWindowAttributes a; + a.background_pixel = WhitePixel(m_glxIntegration->xDisplay(), m_glxIntegration->screen()); + a.border_pixel = BlackPixel(m_glxIntegration->xDisplay(), m_glxIntegration->screen()); + a.colormap = cmap; + m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(), + 0, visualInfo->depth, InputOutput, visualInfo->visual, + CWBackPixel|CWBorderPixel|CWColormap, &a); + + XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual); + XMapWindow(m_glxIntegration->xDisplay(), m_xWindow); + + XSync(m_glxIntegration->xDisplay(), False); + m_buffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(), + (uint32_t)m_xWindow, + size, + m_glxIntegration->waylandDisplay()->argbVisual()); + attach(m_buffer); + waitForSync(); +} + +void QWaylandXCompositeGLXWindow::sync_function(void *data) +{ + QWaylandXCompositeGLXWindow *that = static_cast<QWaylandXCompositeGLXWindow *>(data); + that->m_waitingForSync = false; } + diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h index 3305c12fa7..7a19c7175a 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h @@ -46,20 +46,36 @@ #include "qwaylandxcompositeglxintegration.h" #include "qwaylandxcompositeglxcontext.h" +#include <QtCore/QWaitCondition> + +#include "qwaylandbuffer.h" + class QWaylandXCompositeGLXWindow : public QWaylandWindow { public: QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration); WindowType windowType() const; - QPlatformGLContext *glContext() const; + QPlatformGLSurface *createGLSurface() const; void setGeometry(const QRect &rect); + Window xWindow() const; + private: - QWaylandXCompositeGLXIntegration *mGlxIntegration; - QWaylandXCompositeGLXContext *mContext; + void createSurface(); + + QWaylandXCompositeGLXIntegration *m_glxIntegration; + + Window m_xWindow; + GLXFBConfig m_config; + + QWaylandBuffer *m_buffer; + + void waitForSync(); + bool m_waitingForSync; + static void sync_function(void *data); }; #endif // QWAYLANDXCOMPOSITEGLXWINDOW_H diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 9aa512b38d..226bfd44d5 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -51,7 +51,7 @@ #include <QtGui/QWindowSystemInterface> #include <QtGui/QPlatformCursor> -#include <QtGui/QWindowFormat> +#include <QtGui/QGuiGLFormat> #include <QtGui/private/qpixmap_raster_p.h> #ifdef QT_WAYLAND_GL_SUPPORT @@ -108,6 +108,14 @@ QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) cons return new QWaylandShmWindow(window); } +QPlatformGLContext *QWaylandIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const +{ +#ifdef QT_WAYLAND_GL_SUPPORT + return mDisplay->eglIntegration()->createPlatformGLContext(glFormat, share); +#endif + return 0; +} + QWindowSurface *QWaylandIntegration::createWindowSurface(QWindow *window, WId winId) const { Q_UNUSED(winId); diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h index 1ca468cca4..2e05faf677 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.h +++ b/src/plugins/platforms/wayland/qwaylandintegration.h @@ -57,6 +57,7 @@ public: bool hasCapability(QPlatformIntegration::Capability cap) const; QPixmapData *createPixmapData(QPixmapData::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; + QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const; QWindowSurface *createWindowSurface(QWindow *window, WId winId) const; QList<QPlatformScreen *> screens() const; diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp index 087139e0b3..bd1e61fa4c 100644 --- a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp @@ -63,9 +63,9 @@ QWaylandWindow::WindowType QWaylandShmWindow::windowType() const return QWaylandWindow::Shm; } -QPlatformGLContext * QWaylandShmWindow::glContext() const +QPlatformGLSurface * QWaylandShmWindow::glSurface() const { - qWarning("Trying to retrieve a glContext from a Raster window surface!"); + qWarning("Raster window does not have a GL drawable"); return 0; } diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.h b/src/plugins/platforms/wayland/qwaylandshmwindow.h index e964e0d933..db26c5c928 100644 --- a/src/plugins/platforms/wayland/qwaylandshmwindow.h +++ b/src/plugins/platforms/wayland/qwaylandshmwindow.h @@ -52,7 +52,7 @@ public: ~QWaylandShmWindow(); WindowType windowType() const; - QPlatformGLContext *glContext() const; + QPlatformGLSurface *glSurface() const; }; #endif // QWAYLANDSHMWINDOW_H diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index 24d5d69ac7..67791080d5 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -50,7 +50,7 @@ #include <X11/Xutil.h> #include <GL/glx.h> -#include <QtGui/QWindowContext> +#include <QtGui/QGuiGLContext> #include "qglxintegration.h" #include "qglxconvenience.h" @@ -59,60 +59,61 @@ #include <dlfcn.h> #endif -QGLXContext::QGLXContext(Window window, QXcbScreen *screen, const QWindowFormat &format) +QGLXSurface::QGLXSurface(GLXDrawable drawable, const QGuiGLFormat &format) + : QPlatformGLSurface(format) + , glxDrawable(drawable) +{ +} + +QGLXContext::QGLXContext(QXcbScreen *screen, const QGuiGLFormat &format, QPlatformGLContext *share) : QPlatformGLContext() , m_screen(screen) - , m_drawable((Drawable)window) , m_context(0) { Q_XCB_NOOP(m_screen->connection()); - const QWindowContext *shareContext = format.sharedContext(); GLXContext shareGlxContext = 0; - if (shareContext) - shareGlxContext = static_cast<const QGLXContext*>(shareContext->handle())->glxContext(); + if (share) + shareGlxContext = static_cast<const QGLXContext*>(share)->glxContext(); GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen),screen->screenNumber(),format); m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, shareGlxContext, TRUE); - m_windowFormat = qglx_platformWindowFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); + m_format = qglx_guiGLFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); Q_XCB_NOOP(m_screen->connection()); } -QGLXContext::QGLXContext(QXcbScreen *screen, Drawable drawable, GLXContext context) - : QPlatformGLContext(), m_screen(screen), m_drawable(drawable), m_context(context) -{ - -} - QGLXContext::~QGLXContext() { Q_XCB_NOOP(m_screen->connection()); - if (m_context) - glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context); + glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context); Q_XCB_NOOP(m_screen->connection()); } -void QGLXContext::makeCurrent() +bool QGLXContext::makeCurrent(const QPlatformGLSurface &surface) { Q_XCB_NOOP(m_screen->connection()); - glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), m_drawable, m_context); + + GLXDrawable glxSurface = static_cast<const QGLXSurface &>(surface).glxDrawable; + + bool result = glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), glxSurface, m_context); + Q_XCB_NOOP(m_screen->connection()); + return result; } void QGLXContext::doneCurrent() { - Q_XCB_NOOP(m_screen->connection()); glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0); - Q_XCB_NOOP(m_screen->connection()); } -void QGLXContext::swapBuffers() +void QGLXContext::swapBuffers(const QPlatformGLSurface &drawable) { Q_XCB_NOOP(m_screen->connection()); - glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), m_drawable); + GLXDrawable glxDrawable = static_cast<const QGLXSurface &>(drawable).glxDrawable; + glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), glxDrawable); Q_XCB_NOOP(m_screen->connection()); } -void* QGLXContext::getProcAddress(const QString& procName) +void (*QGLXContext::getProcAddress(const QByteArray &procName)) () { Q_XCB_NOOP(m_screen->connection()); typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *); @@ -143,10 +144,10 @@ void* QGLXContext::getProcAddress(const QString& procName) } if (!glXGetProcAddressARB) return 0; - return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.toLatin1().data())); + return (void (*)())glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.constData())); } -QWindowFormat QGLXContext::windowFormat() const +QGuiGLFormat QGLXContext::format() const { - return m_windowFormat; + return m_format; } diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h index 1760521d47..ae95e23b81 100644 --- a/src/plugins/platforms/xcb/qglxintegration.h +++ b/src/plugins/platforms/xcb/qglxintegration.h @@ -45,34 +45,38 @@ #include "qxcbwindow.h" #include <QtGui/QPlatformGLContext> -#include <QtGui/QWindowFormat> +#include <QtGui/QGuiGLFormat> #include <QtCore/QMutex> #include <GL/glx.h> +class QGLXSurface : public QPlatformGLSurface +{ +public: + QGLXSurface(GLXDrawable drawable, const QGuiGLFormat &format); + GLXDrawable glxDrawable; +}; + class QGLXContext : public QPlatformGLContext { public: - QGLXContext(Window window, QXcbScreen *xd, const QWindowFormat &format); + QGLXContext(QXcbScreen *xd, const QGuiGLFormat &format, QPlatformGLContext *share); ~QGLXContext(); - virtual void makeCurrent(); - virtual void doneCurrent(); - virtual void swapBuffers(); - virtual void* getProcAddress(const QString& procName); + bool makeCurrent(const QPlatformGLSurface &surface); + void doneCurrent(); + void swapBuffers(const QPlatformGLSurface &surface); + void (*getProcAddress(const QByteArray &procName)) (); - GLXContext glxContext() const { return m_context; } + QGuiGLFormat format() const; - QWindowFormat windowFormat() const; + GLXContext glxContext() const { return m_context; } private: QXcbScreen *m_screen; - Drawable m_drawable; GLXContext m_context; - QWindowFormat m_windowFormat; - - QGLXContext (QXcbScreen *screen, Drawable drawable, GLXContext context); + QGuiGLFormat m_format; }; #endif diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index aa11ba5cb0..bd1924def9 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -63,6 +63,12 @@ #include <EGL/egl.h> #endif +#if defined(XCB_USE_GLX) +#include "qglxintegration.h" +#elif defined(XCB_USE_EGL) +#include "../eglconvenience/qeglplatformcontext.h" +#endif + QXcbIntegration::QXcbIntegration() : m_connection(new QXcbConnection), m_printerSupport(new QGenericUnixPrinterSupport) { @@ -97,6 +103,17 @@ QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const return new QXcbWindow(window); } +QPlatformGLContext *QXcbIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const +{ +#if defined(XCB_USE_GLX) + return new QGLXContext(static_cast<QXcbScreen *>(m_screens.at(0)), glFormat, share); +#elif defined(XCB_USE_EGL) + return new QEGLPlatformContext(glFormat, share, m_connection->egl_display()); +#elif defined(XCB_USE_DRI2) + return new QDri2Context(glFormat, share); +#endif +} + QWindowSurface *QXcbIntegration::createWindowSurface(QWindow *window, WId winId) const { Q_UNUSED(winId); diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index 1c1ca24094..d931e2a787 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -58,6 +58,7 @@ public: bool hasCapability(Capability cap) const; QPixmapData *createPixmapData(QPixmapData::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; + QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const; QWindowSurface *createWindowSurface(QWindow *window, WId winId) const; QList<QPlatformScreen *> screens() const; diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 43f93d07bc..bf8ca2a584 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -48,7 +48,7 @@ #include <QtCore/QDebug> -#include <QtGui/qwindowcontext_qpa.h> +#include <QtGui/qguiglcontext_qpa.h> #if defined(XCB_USE_EGL) #include "../eglconvenience/qeglplatformcontext.h" @@ -163,6 +163,7 @@ void *QXcbNativeInterface::graphicsDeviceForWindow(QWindow *window) void * QXcbNativeInterface::eglContextForWindow(QWindow *window) { +#if 0 Q_ASSERT(window); QPlatformGLContext *platformContext = window->glContext()->handle(); if (!platformContext) { @@ -179,4 +180,7 @@ void * QXcbNativeInterface::eglContextForWindow(QWindow *window) #else return 0; #endif +#else + return 0; +#endif } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index de48c83cd1..22a476b690 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -95,7 +95,6 @@ static inline bool isTransient(const QWindow *w) QXcbWindow::QXcbWindow(QWindow *window) : QPlatformWindow(window) , m_window(0) - , m_context(0) , m_syncCounter(0) , m_mapped(false) , m_netWmUserTimeWindow(XCB_NONE) @@ -157,14 +156,14 @@ void QXcbWindow::create() #if defined(XCB_USE_GLX) || defined(XCB_USE_EGL) if ((window()->surfaceType() == QWindow::OpenGLSurface && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) - || window()->requestedWindowFormat().hasAlpha()) + || window()->glFormat().hasAlpha()) { #if defined(XCB_USE_GLX) - XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), window()->requestedWindowFormat()); + XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), window()->glFormat()); #elif defined(XCB_USE_EGL) EGLDisplay eglDisplay = connection()->egl_display(); - EGLConfig eglConfig = q_configFromQWindowFormat(eglDisplay,window()->requestedWindowFormat(),true); + EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, window()->glFormat(), true); VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig); XVisualInfo visualInfoTemplate; @@ -283,7 +282,6 @@ QXcbWindow::~QXcbWindow() void QXcbWindow::destroy() { - delete m_context; if (m_syncCounter && m_screen->syncRequestSupported()) Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter)); if (m_window) { @@ -936,33 +934,27 @@ void QXcbWindow::requestActivateWindow() connection()->sync(); } -QPlatformGLContext *QXcbWindow::glContext() const +QPlatformGLSurface *QXcbWindow::createGLSurface() const { if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) { - printf("no opengl\n"); + qWarning() << "QXcb::createGLSurface() called without OpenGL support"; return 0; } - if (!m_context) { + + QGuiGLFormat format = window()->glFormat(); + #if defined(XCB_USE_GLX) - QXcbWindow *that = const_cast<QXcbWindow *>(this); - that->m_context = new QGLXContext(m_window, m_screen, window()->requestedWindowFormat()); + return new QGLXSurface(m_window, format); #elif defined(XCB_USE_EGL) - EGLDisplay display = connection()->egl_display(); - EGLConfig config = q_configFromQWindowFormat(display,window()->requestedWindowFormat(),true); - QVector<EGLint> eglContextAttrs; - eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); - eglContextAttrs.append(2); - eglContextAttrs.append(EGL_NONE); - - EGLSurface eglSurface = eglCreateWindowSurface(display,config,(EGLNativeWindowType)m_window,0); - QXcbWindow *that = const_cast<QXcbWindow *>(this); - that->m_context = new QEGLPlatformContext(display, config, eglContextAttrs.data(), eglSurface, EGL_OPENGL_ES_API); -#elif defined(XCB_USE_DRI2) - QXcbWindow *that = const_cast<QXcbWindow *>(this); - that->m_context = new QDri2Context(that); + EGLDisplay display = connection()->egl_display(); + EGLConfig config = q_configFromGLFormat(display, format, true); + + EGLSurface eglSurface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)m_window, 0); + + return new QEGLSurface(eglSurface, window()->glFormat()); +#else + return 0; #endif - } - return m_context; } void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event) diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index f6869c7937..f50a611b4e 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -43,7 +43,7 @@ #define QXCBWINDOW_H #include <QtGui/QPlatformWindow> -#include <QtGui/QWindowFormat> +#include <QtGui/QGuiGLFormat> #include <QtGui/QImage> #include <xcb/xcb.h> @@ -72,9 +72,9 @@ public: void lower(); void propagateSizeHints(); - void requestActivateWindow(); + QPlatformGLSurface *createGLSurface() const; - QPlatformGLContext *glContext() const; + void requestActivateWindow(); bool setKeyboardGrabEnabled(bool grab); bool setMouseGrabEnabled(bool grab); @@ -127,7 +127,6 @@ private: QXcbScreen *m_screen; xcb_window_t m_window; - QPlatformGLContext *m_context; uint m_depth; QImage::Format m_format; diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 47007726a8..2be5e5f52d 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -58,7 +58,6 @@ #ifdef Q_WS_QPA //should this go somewhere else? #include <QtGui/qwindow.h> -#include <QtGui/qwindowformat_qpa.h> #endif #ifdef QT_INCLUDE_COMPAT diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 66a1a4ce35..3363ad7454 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -48,6 +48,7 @@ #include "private/qapplication_p.h" #include "QtWidgets/qdesktopwidget.h" #include "QtGui/qplatformwindow_qpa.h" +#include "QtGui/qguiglformat_qpa.h" #include "QtGui/qplatformglcontext_qpa.h" #include "QtGui/private/qwindow_p.h" @@ -107,9 +108,9 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO win->setGeometry(q->geometry()); if (q->testAttribute(Qt::WA_TranslucentBackground)) { - QWindowFormat format = win->requestedWindowFormat(); + QGuiGLFormat format; format.setAlphaBufferSize(8); - win->setWindowFormat(format); + win->setGLFormat(format); } if (QWidget *nativeParent = q->nativeParentWidget()) { |