diff options
Diffstat (limited to 'src/plugins/platforms/wayland/gl_integration')
47 files changed, 1054 insertions, 753 deletions
diff --git a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri index d9b5fa9bff..20c3aa0bd9 100644 --- a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri +++ b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri @@ -3,12 +3,10 @@ contains(QT_CONFIG, opengl) { QT += opengl HEADERS += \ - $$PWD/qwaylandglintegration.h \ - $$PWD/qwaylandglwindowsurface.h + $$PWD/qwaylandglintegration.h SOURCES += \ - $$PWD/qwaylandglintegration.cpp \ - $$PWD/qwaylandglwindowsurface.cpp + $$PWD/qwaylandglintegration.cpp QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG) contains(QT_CONFIG, opengles2) { @@ -22,6 +20,9 @@ SOURCES += \ QT_WAYLAND_GL_INTEGRATION = xcomposite_egl CONFIG += xcomposite_egl } + } else:mac { + QT_WAYLAND_GL_INTEGRATION = readback_cgl + CONFIG += readback_cgl } else { isEqual(QT_WAYLAND_GL_CONFIG, readback) { QT_WAYLAND_GL_INTEGRATION = readback_glx @@ -48,6 +49,10 @@ readback_glx { include ($$PWD/readback_glx/readback_glx.pri) } +readback_cgl { + include ($$PWD/readback_cgl/readback_cgl.pri) +} + xcomposite_glx { include ($$PWD/xcomposite_glx/xcomposite_glx.pri) } diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h index 4b50b4bd68..4f688e41d8 100644 --- a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h @@ -44,7 +44,10 @@ class QWaylandWindow; class QWaylandDisplay; -class QWidget; +class QWindow; + +class QPlatformOpenGLContext; +class QSurfaceFormat; class QWaylandGLIntegration { @@ -54,7 +57,8 @@ public: virtual void initialize() = 0; - virtual QWaylandWindow *createEglWindow(QWidget *widget) = 0; + virtual QWaylandWindow *createEglWindow(QWindow *window) = 0; + virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *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 deleted file mode 100644 index fef07e6bf7..0000000000 --- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp +++ /dev/null @@ -1,184 +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 plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandglwindowsurface.h" - -#include "qwaylanddisplay.h" -#include "qwaylandwindow.h" -#include "qwaylandscreen.h" - -#include <QtOpenGL/QGLFramebufferObject> -#include <QtOpenGL/QGLContext> - -#include <QtOpenGL/private/qglengineshadermanager_p.h> - -QT_BEGIN_NAMESPACE - -static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br) -{ -#if !defined(QT_OPENGL_ES_2) - QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); -#endif - const GLenum target = GL_TEXTURE_2D; - QRectF src = br.isEmpty() - ? QRectF(QPointF(), texSize) - : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size()); - - if (target == GL_TEXTURE_2D) { - qreal width = texSize.width(); - qreal height = texSize.height(); - - src.setLeft(src.left() / width); - src.setRight(src.right() / width); - src.setTop(src.top() / height); - src.setBottom(src.bottom() / height); - } - - const GLfloat tx1 = src.left(); - const GLfloat tx2 = src.right(); - const GLfloat ty1 = src.top(); - const GLfloat ty2 = src.bottom(); - - GLfloat texCoordArray[4*2] = { - tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1 - }; - - GLfloat vertexArray[4*2]; - vertexArray[0] = rect.left(); vertexArray[1] = rect.top(); - vertexArray[2] = rect.right(); vertexArray[3] = rect.top(); - vertexArray[4] = rect.right(); vertexArray[5] = rect.bottom(); - vertexArray[6] = rect.left(); vertexArray[7] = rect.bottom(); - - glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexArray); - glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray); - - glBindTexture(target, tex_id); - - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - - glBindTexture(target, 0); -} - -static void blitTexture(QGLContext *ctx, GLuint texture, const QSize &viewport, const QSize &texSize, const QRect &targetRect, const QRect &sourceRect) -{ - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - glViewport(0, 0, viewport.width(), viewport.height()); - - QGLShaderProgram *blitProgram = - QGLEngineSharedShaders::shadersForContext(ctx)->blitProgram(); - blitProgram->bind(); - blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/); - - // The shader manager's blit program does not multiply the - // vertices by the pmv matrix, so we need to do the effect - // of the orthographic projection here ourselves. - QRectF r; - qreal w = viewport.width(); - qreal h = viewport.height(); - r.setLeft((targetRect.left() / w) * 2.0f - 1.0f); - if (targetRect.right() == (viewport.width() - 1)) - r.setRight(1.0f); - else - r.setRight((targetRect.right() / w) * 2.0f - 1.0f); - r.setBottom((targetRect.top() / h) * 2.0f - 1.0f); - if (targetRect.bottom() == (viewport.height() - 1)) - r.setTop(1.0f); - else - r.setTop((targetRect.bottom() / w) * 2.0f - 1.0f); - - drawTexture(r, texture, texSize, sourceRect); -} - -QWaylandGLWindowSurface::QWaylandGLWindowSurface(QWidget *window) - : QWindowSurface(window) - , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display()) - , mPaintDevice(0) -{ - -} - -QWaylandGLWindowSurface::~QWaylandGLWindowSurface() -{ - delete mPaintDevice; -} - -QPaintDevice *QWaylandGLWindowSurface::paintDevice() -{ - return mPaintDevice; -} - -void QWaylandGLWindowSurface::beginPaint(const QRegion &) -{ - window()->platformWindow()->glContext()->makeCurrent(); - glClearColor(0,0,0,0xff); - glClear(GL_COLOR_BUFFER_BIT); -} - -void QWaylandGLWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) -{ - Q_UNUSED(offset); - Q_UNUSED(region); - QWaylandWindow *ww = (QWaylandWindow *) widget->platformWindow(); - - if (mPaintDevice->isBound()) - mPaintDevice->release(); - - QRect rect(0,0,size().width(),size().height()); - QGLContext *ctx = QGLContext::fromPlatformGLContext(ww->glContext()); - blitTexture(ctx,mPaintDevice->texture(),size(),mPaintDevice->size(),rect,rect); - ww->glContext()->swapBuffers(); -} - -void QWaylandGLWindowSurface::resize(const QSize &size) -{ - QWindowSurface::resize(size); - window()->platformWindow()->glContext()->makeCurrent(); - delete mPaintDevice; - mPaintDevice = new QGLFramebufferObject(size,QGLFramebufferObject::CombinedDepthStencil); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp new file mode 100644 index 0000000000..5f7663ef55 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandreadbackcglcontext.h" + +#include "qwaylandshmbackingstore.h" +#include "qwaylandreadbackcglwindow.h" + +#include <QtGui/QOpenGLContext> +#include <QtCore/QDebug> + +#include <OpenGL/OpenGL.h> +#include <OpenGL/glext.h> +#include <OpenGL/glu.h> + +#include <QtPlatformSupport/private/cglconvenience_p.h> + +QWaylandReadbackCGLContext::QWaylandReadbackCGLContext(QPlatformOpenGLContext *share) + : QPlatformOpenGLContext() +{ + Q_UNUSED(share); + m_glContext = qcgl_createGlContext(); +} + +QSurfaceFormat QWaylandReadbackCGLContext::format() const +{ + return qcgl_surfaceFormat(); +} + +bool QWaylandReadbackCGLContext::makeCurrent(QPlatformSurface *surface) +{ + QWaylandReadbackCGLWindow *window = static_cast<QWaylandReadbackCGLWindow *>(surface); + CGLSetPBuffer(m_glContext, window->pixelBuffer(), 0, 0, 0); + CGLSetCurrentContext(m_glContext); + return true; +} + +void QWaylandReadbackCGLContext::doneCurrent() +{ + CGLSetCurrentContext(0); +} + +void QWaylandReadbackCGLContext::swapBuffers(QPlatformSurface *surface) +{ + Q_UNUSED(surface); + + if (QOpenGLContext::currentContext()->handle() != this) { + makeCurrent(surface); + } + CGLFlushDrawable(m_glContext); + + QWaylandReadbackCGLWindow *window = static_cast<QWaylandReadbackCGLWindow *>(surface); + QSize size = window->geometry().size(); + + uchar *dstBits = const_cast<uchar *>(window->buffer()); + glReadPixels(0,0, size.width(), size.height(), GL_BGRA,GL_UNSIGNED_BYTE, dstBits); + + window->damage(QRect(QPoint(0,0),size)); + + // ### Should sync here but this call deadlocks with the server. + //window->waitForFrameSync(); +} + +void (*QWaylandReadbackCGLContext::getProcAddress(const QByteArray &procName)) () +{ + return qcgl_getProcAddress(procName); +} + diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h index 00da6976b8..eb065c3f69 100644 --- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h @@ -39,31 +39,34 @@ ** ****************************************************************************/ -#ifndef QWAYLANDDRMSURFACE_H -#define QWAYLANDDRMSURFACE_H +#ifndef QWAYLANDREADBACKCGLCONTEXT_H +#define QWAYLANDREADBACKCGLCONTEXT_H -#include "qwaylanddisplay.h" +#include <QPlatformOpenGLContext> -#include <QtGui/private/qwindowsurface_p.h> +#include "qwaylandreadbackcglintegration.h" -class QGLFramebufferObject; +#include <OpenGL/OpenGL.h> -class QWaylandGLWindowSurface : public QWindowSurface +class QWaylandReadbackCGLWindow; +class QWaylandShmBuffer; + +class QWaylandReadbackCGLContext : public QPlatformOpenGLContext { public: - QWaylandGLWindowSurface(QWidget *window); - ~QWaylandGLWindowSurface(); + QWaylandReadbackCGLContext(QPlatformOpenGLContext *share); - void beginPaint(const QRegion &); + QSurfaceFormat format() const; - QPaintDevice *paintDevice(); - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); + void swapBuffers(QPlatformSurface *surface); + void (*getProcAddress(const QByteArray &procName)) (); - void resize(const QSize &size); + void geometryChanged(); private: - QWaylandDisplay *mDisplay; - QGLFramebufferObject *mPaintDevice; + CGLContextObj m_glContext; }; -#endif // QWAYLANDDRMSURFACE_H +#endif // QWAYLANDREADBACKCGLCONTEXT_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp new file mode 100644 index 0000000000..2878f9e292 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandreadbackcglintegration.h" +#include "qwaylandreadbackcglcontext.h" +#include "qwaylandreadbackcglwindow.h" + +#include <QtCore/QDebug> + +QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) +{ + return new QWaylandReadbackCGLIntegration(waylandDisplay); +} + +QWaylandReadbackCGLIntegration::QWaylandReadbackCGLIntegration(QWaylandDisplay * waylandDispaly) + : QWaylandGLIntegration() + , mWaylandDisplay(waylandDispaly) +{ + qDebug() << "Using Readback-CGL"; +} + +QWaylandReadbackCGLIntegration::~QWaylandReadbackCGLIntegration() +{ + +} + +void QWaylandReadbackCGLIntegration::initialize() +{ +} + +QWaylandWindow * QWaylandReadbackCGLIntegration::createEglWindow(QWindow *window) +{ + return new QWaylandReadbackCGLWindow(window,this); +} + +QPlatformOpenGLContext *QWaylandReadbackCGLIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandReadbackCGLContext(share); +} + +QWaylandDisplay * QWaylandReadbackCGLIntegration::waylandDisplay() const +{ + return mWaylandDisplay; +} diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h new file mode 100644 index 0000000000..34c8d00a7c --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDREADBACKGLXINTEGRATION_H +#define QWAYLANDREADBACKGLXINTEGRATION_H + +#include "gl_integration/qwaylandglintegration.h" + +#include <QtCore/QTextStream> +#include <QtCore/QDataStream> +#include <QtCore/QMetaType> +#include <QtCore/QVariant> +#include <QtGui/QWindow> + +#include <X11/Xlib.h> + +class QWaylandReadbackCGLIntegration : public QWaylandGLIntegration +{ +public: + QWaylandReadbackCGLIntegration(QWaylandDisplay * waylandDispaly); + ~QWaylandReadbackCGLIntegration(); + + void initialize(); + + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; + QWaylandDisplay *waylandDisplay() const; + +private: + QWaylandDisplay *mWaylandDisplay; +}; + +#endif // QWAYLANDREADBACKGLXINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp new file mode 100644 index 0000000000..9e7f8520c9 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandreadbackcglwindow.h" +#include "qwaylandshmbackingstore.h" + +#include <OpenGL/OpenGL.h> +#include <OpenGL/glext.h> + +QWaylandReadbackCGLWindow::QWaylandReadbackCGLWindow(QWindow *window, QWaylandReadbackCGLIntegration *cglIntegration) + : QWaylandShmWindow(window) + , m_CglIntegration(cglIntegration) + , mContext(0) + , m_buffer(0) + , m_pixelBuffer(0) +{ +} + +QWaylandWindow::WindowType QWaylandReadbackCGLWindow::windowType() const +{ + //yeah. this type needs a new name + return QWaylandWindow::Egl; +} + + +void QWaylandReadbackCGLWindow::setGeometry(const QRect &rect) +{ + QWaylandShmWindow::setGeometry(rect); + + if (m_buffer) { + delete m_buffer; + m_buffer = 0; + + CGLDestroyPBuffer(m_pixelBuffer); + m_pixelBuffer = 0; + } +} + +CGLPBufferObj QWaylandReadbackCGLWindow::pixelBuffer() +{ + if (!m_pixelBuffer) + createSurface(); + + return m_pixelBuffer; +} + +uchar *QWaylandReadbackCGLWindow::buffer() +{ + return m_buffer->image()->bits(); +} + +void QWaylandReadbackCGLWindow::createSurface() +{ + QSize size(geometry().size()); + if (size.isEmpty()) { + //QGLWidget wants a context for a window without geometry + size = QSize(1,1); + } + + waitForFrameSync(); + + CGLCreatePBuffer(size.width(), size.height(), GL_TEXTURE_RECTANGLE_ARB, GL_BGRA, 0, &m_pixelBuffer); + + delete m_buffer; + m_buffer = new QWaylandShmBuffer(m_CglIntegration->waylandDisplay(),size,QImage::Format_ARGB32); + attach(m_buffer); +} + diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h new file mode 100644 index 0000000000..0598cf9037 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDREADBACKGLXWINDOW_H +#define QWAYLANDREADBACKGLXWINDOW_H + +#include "qwaylandshmwindow.h" +#include "qwaylandreadbackcglintegration.h" +#include "qwaylandreadbackcglcontext.h" + +#include <OpenGL/OpenGL.h> + +class QWaylandReadbackCGLWindow : public QWaylandShmWindow +{ +public: + QWaylandReadbackCGLWindow(QWindow *window, QWaylandReadbackCGLIntegration *cglIntegration); + WindowType windowType() const; + + void setGeometry(const QRect &rect); + CGLPBufferObj pixelBuffer(); + uchar *buffer(); +private: + void createSurface(); + + QWaylandReadbackCGLIntegration *m_CglIntegration; + QWaylandReadbackCGLContext *mContext; + + QWaylandShmBuffer *m_buffer; + CGLPBufferObj m_pixelBuffer; +}; + +#endif // QWAYLANDREADBACKGLXWINDOW_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri b/src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri new file mode 100644 index 0000000000..91cb90a30c --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri @@ -0,0 +1,10 @@ +HEADERS += \ + $$PWD/qwaylandreadbackcglintegration.h \ + $$PWD/qwaylandreadbackcglwindow.h \ + $$PWD/qwaylandreadbackcglcontext.h + +SOURCES += \ + $$PWD/qwaylandreadbackcglintegration.cpp \ + $$PWD/qwaylandreadbackcglwindow.cpp \ + $$PWD/qwaylandreadbackcglcontext.cpp + diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp index f02a10a05b..c03e8a9444 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp @@ -41,14 +41,16 @@ #include "qwaylandreadbackeglcontext.h" -#include "../../../eglconvenience/qeglconvenience.h" +#include <QPlatformSupport/eglconvenience/qeglconvenience_p.h> + +#include <QtCore/QDebug> +#include <QtGui/QWindowContext> #include <QtOpenGL/QGLContext> #include <QtOpenGL/private/qglextensions_p.h> #include "qwaylandshmsurface.h" -#include <QtCore/QDebug> static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type) { @@ -77,7 +79,7 @@ QWaylandReadbackEglContext::QWaylandReadbackEglContext(QWaylandReadbackEglIntegr , mWindow(window) , mBuffer(0) , mPixmap(0) - , mConfig(q_configFromQPlatformWindowFormat(eglIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_PIXMAP_BIT)) + , mConfig(q_configFromQWindowFormat(eglIntegration->eglDisplay(),window->window()->requestedWindowFormat(),true,EGL_PIXMAP_BIT)) , mPixmapSurface(EGL_NO_SURFACE) { QVector<EGLint> eglContextAttrs; @@ -97,8 +99,6 @@ QWaylandReadbackEglContext::~QWaylandReadbackEglContext() void QWaylandReadbackEglContext::makeCurrent() { - QPlatformGLContext::makeCurrent(); - mWindow->waitForFrameSync(); eglMakeCurrent(mEglIntegration->eglDisplay(),mPixmapSurface,mPixmapSurface,mContext); @@ -106,7 +106,7 @@ void QWaylandReadbackEglContext::makeCurrent() void QWaylandReadbackEglContext::doneCurrent() { - QPlatformGLContext::doneCurrent(); + QPlatformOpenGLContext::doneCurrent(); eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT); } @@ -114,7 +114,7 @@ void QWaylandReadbackEglContext::swapBuffers() { eglSwapBuffers(mEglIntegration->eglDisplay(),mPixmapSurface); - if (QPlatformGLContext::currentContext() != this) { + if (QWindowContext::currentContext()->handle() != this) { makeCurrent(); } @@ -143,9 +143,9 @@ void * QWaylandReadbackEglContext::getProcAddress(const QString &procName) return (void *) eglGetProcAddress(procName.toLatin1().data()); } -QPlatformWindowFormat QWaylandReadbackEglContext::platformWindowFormat() const +QWindowFormat QWaylandReadbackEglContext::windowFormat() const { - return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig); + return q_windowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig); } void QWaylandReadbackEglContext::geometryChanged() diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h index f9ab3783dd..75755fbd1a 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h @@ -42,15 +42,14 @@ #ifndef QWAYLANDREADBACKEGLGLCONTEXT_H #define QWAYLANDREADBACKEGLGLCONTEXT_H -#include <QPlatformGLContext> -#include <QtGui/QWidget> +#include <QPlatformOpenGLContext> #include "qwaylandreadbackeglintegration.h" #include "qwaylandreadbackeglwindow.h" class QWaylandShmBuffer; -class QWaylandReadbackEglContext : public QPlatformGLContext +class QWaylandReadbackEglContext : public QPlatformOpenGLContext { public: QWaylandReadbackEglContext(QWaylandReadbackEglIntegration *eglIntegration, QWaylandReadbackEglWindow *window); @@ -61,7 +60,7 @@ public: void swapBuffers(); void* getProcAddress(const QString& procName); - virtual QPlatformWindowFormat platformWindowFormat() const; + virtual QWindowFormat windowFormat() const; void geometryChanged(); 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 6bbac603cf..39fa3d589c 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp @@ -81,9 +81,14 @@ void QWaylandReadbackEglIntegration::initialize() } } -QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWidget *widget) +QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWindow *window) { - return new QWaylandReadbackEglWindow(widget,this); + return new QWaylandReadbackEglWindow(window, this); +} + +QPlatformOpenGLContext *QWaylandReadbackEglWindow::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *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 ae1e8e5095..0d6aa55e4e 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h @@ -48,7 +48,8 @@ #include <QtCore/QDataStream> #include <QtCore/QMetaType> #include <QtCore/QVariant> -#include <QtGui/QWidget> +#include <QtCore/QEvent> +#include <QtGui/QCursor> #include <X11/Xlib.h> @@ -61,7 +62,8 @@ public: ~QWaylandReadbackEglIntegration(); void initialize(); - QWaylandWindow *createEglWindow(QWidget *widget); + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; QWaylandDisplay *waylandDisplay() const; Display *xDisplay() const; diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp index 868e32e030..f4bc6379d6 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp @@ -43,7 +43,7 @@ #include "qwaylandreadbackeglcontext.h" -QWaylandReadbackEglWindow::QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration) +QWaylandReadbackEglWindow::QWaylandReadbackEglWindow(QWindow *window, QWaylandReadbackEglIntegration *eglIntegration) : QWaylandShmWindow(window) , mEglIntegration(eglIntegration) , mContext(0) @@ -57,7 +57,7 @@ QWaylandWindow::WindowType QWaylandReadbackEglWindow::windowType() const return QWaylandWindow::Egl; } -QPlatformGLContext *QWaylandReadbackEglWindow::glContext() const +QPlatformOpenGLContext *QWaylandReadbackEglWindow::glContext() const { if (!mContext) { QWaylandReadbackEglWindow *that = const_cast<QWaylandReadbackEglWindow *>(this); diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h index 1433483923..0852a8ee66 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h @@ -50,11 +50,11 @@ class QWaylandReadbackEglContext; class QWaylandReadbackEglWindow : public QWaylandShmWindow { public: - QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration); + QWaylandReadbackEglWindow(QWindow *window, QWaylandReadbackEglIntegration *eglIntegration); WindowType windowType() const; - QPlatformGLContext *glContext() const; + QPlatformOpenGLContext *glContext() const; void setGeometry(const QRect &rect); diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri b/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri index 0d8e01b6bb..3325fe8ec9 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri @@ -1,14 +1,12 @@ - LIBS += -lX11 -lXext -lEGL +load(qpa/egl/convenience) HEADERS += \ $$PWD/qwaylandreadbackeglintegration.h \ $$PWD/qwaylandreadbackeglcontext.h \ $$PWD/qwaylandreadbackeglwindow.h \ - $$PWD/../../../eglconvenience/qeglconvenience.h SOURCES += \ $$PWD/qwaylandreadbackeglintegration.cpp \ $$PWD/qwaylandreadbackeglwindow.cpp \ $$PWD/qwaylandreadbackeglcontext.cpp \ - $$PWD/../../../eglconvenience/qeglconvenience.cpp 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 857c1db6e3..850e7bb0ac 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp @@ -41,9 +41,10 @@ #include "qwaylandreadbackglxcontext.h" -#include "qwaylandshmsurface.h" +#include "qwaylandshmbackingstore.h" #include "qwaylandreadbackglxwindow.h" +#include <QtGui/QOpenGLContext> #include <QtCore/QDebug> static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type) @@ -68,96 +69,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 QSurfaceFormat &format, + QPlatformOpenGLContext *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_surfaceFormatFromGLXFBConfig(display, config, m_context); +} + +QSurfaceFormat QWaylandReadbackGlxContext::format() const +{ + return m_format; } -void QWaylandReadbackGlxContext::makeCurrent() +bool QWaylandReadbackGlxContext::makeCurrent(QPlatformSurface *surface) { - QPlatformGLContext::makeCurrent(); + GLXPixmap glxPixmap = static_cast<QWaylandReadbackGlxWindow *>(surface)->glxPixmap(); - glXMakeCurrent(mGlxIntegration->xDisplay(),mGlxPixmap,mContext); + return glXMakeCurrent(m_display, glxPixmap, m_context); } void QWaylandReadbackGlxContext::doneCurrent() { - QPlatformGLContext::doneCurrent(); + glXMakeCurrent(m_display, 0, 0); } -void QWaylandReadbackGlxContext::swapBuffers() +void QWaylandReadbackGlxContext::swapBuffers(QPlatformSurface *surface) { - if (QPlatformGLContext::currentContext() != this) { - makeCurrent(); - } + // #### makeCurrent() directly on the platform context doesn't update QOpenGLContext::currentContext() + if (QOpenGLContext::currentContext()->handle() != this) + makeCurrent(surface); + + QWaylandReadbackGlxWindow *w = static_cast<QWaylandReadbackGlxWindow *>(surface); - QSize size = mWindow->geometry().size(); + QSize size = w->geometry().size(); - QImage img(size,QImage::Format_ARGB32); + 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 = w->buffer(); uchar *dstBits = const_cast<uchar *>(constDstBits); - memcpy(dstBits,constBits,(img.width()*4) * img.height()); + memcpy(dstBits, constBits, (img.width() * 4) * img.height()); + w->damage(QRect(QPoint(), size)); - mWindow->damage(QRegion(QRect(QPoint(0,0),size))); - mWindow->waitForFrameSync(); - + w->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..7b5eeece93 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h @@ -42,38 +42,35 @@ #ifndef QWAYLANDREADBACKGLXCONTEXT_H #define QWAYLANDREADBACKGLXCONTEXT_H -#include <QPlatformGLContext> +#include <QPlatformOpenGLContext> +#include <QSurfaceFormat> #include "qwaylandreadbackglxintegration.h" -#include "qglxconvenience.h" +#include <QtPlatformSupport/private/qglxconvenience_p.h> class QWaylandReadbackGlxWindow; class QWaylandShmBuffer; -class QWaylandReadbackGlxContext : public QPlatformGLContext +class QWaylandReadbackGlxContext : public QPlatformOpenGLContext { public: - QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window); + QWaylandReadbackGlxContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen); - void makeCurrent(); - void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString& procName); + QSurfaceFormat format() const; + + void swapBuffers(QPlatformSurface *surface); - QPlatformWindowFormat platformWindowFormat() const; + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); - void geometryChanged(); + void (*getProcAddress(const QByteArray &procName)) (); private: - QWaylandReadbackGlxIntegration *mGlxIntegration; - QWaylandReadbackGlxWindow *mWindow; - QWaylandShmBuffer *mBuffer; + GLXContext m_context; - Pixmap mPixmap; - GLXFBConfig mConfig; - GLXContext mContext; - GLXPixmap mGlxPixmap; + Display *m_display; + QSurfaceFormat 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 37a14a9f4c..752bb06a43 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp @@ -66,9 +66,14 @@ void QWaylandReadbackGlxIntegration::initialize() { } -QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWidget *widget) +QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWindow *window) { - return new QWaylandReadbackGlxWindow(widget,this); + return new QWaylandReadbackGlxWindow(window,this); +} + +QPlatformOpenGLContext *QWaylandReadbackGlxIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandReadbackGlxContext(glFormat, share, mDisplay, mScreen); } QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *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 d267d8dffe..ee50d74ebd 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h @@ -48,7 +48,7 @@ #include <QtCore/QDataStream> #include <QtCore/QMetaType> #include <QtCore/QVariant> -#include <QtGui/QWidget> +#include <QtGui/QWindow> #include <X11/Xlib.h> @@ -60,7 +60,8 @@ public: void initialize(); - QWaylandWindow *createEglWindow(QWidget *widget); + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *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 98198dfa06..35c3ca3154 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 "qwaylandshmbackingstore.h" -QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWidget *window, QWaylandReadbackGlxIntegration *glxIntegration) +QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration) : QWaylandShmWindow(window) - , mGlxIntegration(glxIntegration) - , mContext(0) + , m_glxIntegration(glxIntegration) + , m_buffer(0) + , m_pixmap(0) + , m_config(0) + , m_glxPixmap(0) + , m_window(window) { } @@ -54,20 +61,54 @@ 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(); + + return m_glxPixmap; +} - if (mContext) { - mContext->geometryChanged(); +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); + + if (!m_config) + m_config = qglx_findConfig(m_glxIntegration->xDisplay(), m_glxIntegration->screen(), m_window->format()); + + 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 d478961d53..c92646c80d 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h @@ -49,17 +49,25 @@ class QWaylandReadbackGlxWindow : public QWaylandShmWindow { public: - QWaylandReadbackGlxWindow(QWidget *window, QWaylandReadbackGlxIntegration *glxIntegration); + QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration); WindowType windowType() const; - QPlatformGLContext *glContext() 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; + QWindow *m_window; }; #endif // QWAYLANDREADBACKGLXWINDOW_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri b/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri index f8ea005937..746d594fa2 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri @@ -1,4 +1,3 @@ -include (../../../glxconvenience/glxconvenience.pri) HEADERS += \ $$PWD/qwaylandreadbackglxintegration.h \ $$PWD/qwaylandreadbackglxwindow.h \ diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp index d4deb01022..27f17a6153 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp @@ -44,11 +44,12 @@ #include "gl_integration/qwaylandglintegration.h" #include "qwaylandeglwindow.h" +#include "qwaylandglcontext.h" #include <QtCore/QDebug> QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay) - : mWaylandDisplay(waylandDisplay) + : m_waylandDisplay(waylandDisplay) { qDebug() << "Using Wayland-EGL"; } @@ -56,31 +57,41 @@ QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay QWaylandEglIntegration::~QWaylandEglIntegration() { - eglTerminate(mEglDisplay); + eglTerminate(m_eglDisplay); } void QWaylandEglIntegration::initialize() { + QByteArray eglPlatform = qgetenv("EGL_PLATFORM"); + if (eglPlatform.isEmpty()) { + setenv("EGL_PLATFORM","wayland",true); + } + EGLint major,minor; - mEglDisplay = eglGetDisplay(mWaylandDisplay); - if (mEglDisplay == NULL) { + m_eglDisplay = eglGetDisplay(m_waylandDisplay); + if (m_eglDisplay == NULL) { qWarning("EGL not available"); } else { - if (!eglInitialize(mEglDisplay, &major, &minor)) { + if (!eglInitialize(m_eglDisplay, &major, &minor)) { qWarning("failed to initialize EGL display"); return; } } } -QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWidget *window) +QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWindow *window) { return new QWaylandEglWindow(window); } +QPlatformOpenGLContext *QWaylandEglIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandGLContext(m_eglDisplay, glFormat, share); +} + EGLDisplay QWaylandEglIntegration::eglDisplay() const { - return mEglDisplay; + return m_eglDisplay; } QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h index ea8b0f725c..7a26c57658 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h @@ -47,7 +47,7 @@ #include "qwaylandeglinclude.h" class QWaylandWindow; -class QWidget; +class QWindow; class QWaylandEglIntegration : public QWaylandGLIntegration { @@ -57,14 +57,15 @@ public: void initialize(); - QWaylandWindow *createEglWindow(QWidget *window); + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; EGLDisplay eglDisplay() const; - struct wl_egl_display *nativeDisplay() const; + private: - struct wl_display *mWaylandDisplay; + struct wl_display *m_waylandDisplay; - EGLDisplay mEglDisplay; + EGLDisplay m_eglDisplay; }; #endif // QWAYLANDEGLINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp index cd8b5b3524..e0e1f772b9 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp @@ -44,19 +44,30 @@ #include "qwaylandscreen.h" #include "qwaylandglcontext.h" -QWaylandEglWindow::QWaylandEglWindow(QWidget *window) +#include <QtPlatformSupport/private/qeglconvenience_p.h> + +#include <QtGui/QWindow> +#include <QtGui/QWindowSystemInterface> + +QWaylandEglWindow::QWaylandEglWindow(QWindow *window) : QWaylandWindow(window) - , mGLContext(0) - , mWaylandEglWindow(0) + , m_waylandEglWindow(0) + , m_eglSurface(0) + , m_eglConfig(0) + , m_format(window->format()) { - mEglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration()); + m_eglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration()); + //super creates a new surface newSurfaceCreated(); } QWaylandEglWindow::~QWaylandEglWindow() { - delete mGLContext; + if (m_eglSurface) { + eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface); + m_eglSurface = 0; + } } QWaylandWindow::WindowType QWaylandEglWindow::windowType() const @@ -67,46 +78,48 @@ QWaylandWindow::WindowType QWaylandEglWindow::windowType() const void QWaylandEglWindow::setGeometry(const QRect &rect) { QWaylandWindow::setGeometry(rect); - if (mWaylandEglWindow) { - wl_egl_window_resize(mWaylandEglWindow,rect.width(),rect.height(),0,0); + if (m_waylandEglWindow){ + wl_egl_window_resize(m_waylandEglWindow, rect.width(), rect.height(), 0, 0); + QWindowSystemInterface::handleGeometryChange(window(), rect); } } -void QWaylandEglWindow::setParent(const QPlatformWindow *parent) +void QWaylandEglWindow::newSurfaceCreated() { - const QWaylandWindow *wParent = static_cast<const QWaylandWindow *>(parent); + if (m_waylandEglWindow) + wl_egl_window_destroy(m_waylandEglWindow); - mParentWindow = wParent; -} - -QPlatformGLContext * QWaylandEglWindow::glContext() const -{ - if (!mGLContext) { - QWaylandEglWindow *that = const_cast<QWaylandEglWindow *>(this); - that->mGLContext = new QWaylandGLContext(mEglIntegration->eglDisplay(),widget()->platformWindowFormat()); + wl_visual *visual = QWaylandScreen::waylandScreenFromWindow(window())->visual(); + QSize size = geometry().size(); + if (!size.isValid()) + size = QSize(0,0); - EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow)); - EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL); - that->mGLContext->setEglSurface(surface); + if (m_eglSurface) { + eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface); + m_eglSurface = 0; } - return mGLContext; + m_waylandEglWindow = wl_egl_window_create(mSurface, size.width(), size.height(), visual); } -void QWaylandEglWindow::newSurfaceCreated() +QSurfaceFormat QWaylandEglWindow::format() const { - if (mWaylandEglWindow) { - wl_egl_window_destroy(mWaylandEglWindow); - } - wl_visual *visual = QWaylandScreen::waylandScreenFromWidget(widget())->visual(); - QSize size = geometry().size(); - if (!size.isValid()) - size = QSize(0,0); + return m_format; +} - mWaylandEglWindow = wl_egl_window_create(mSurface,size.width(),size.height(),visual); - if (mGLContext) { - EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow)); - EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL); - mGLContext->setEglSurface(surface); +EGLSurface QWaylandEglWindow::eglSurface() const +{ + if (!m_waylandEglWindow) + return 0; + + if (!m_eglSurface) { + if (!m_eglConfig) + m_eglConfig = q_configFromGLFormat(m_eglIntegration->eglDisplay(), window()->format(), true); + + EGLNativeWindowType window = m_waylandEglWindow; + m_eglSurface = eglCreateWindowSurface(m_eglIntegration->eglDisplay(), m_eglConfig, window, 0); } + + return m_eglSurface; } + diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h index 6d2038824a..d435a511c4 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h @@ -51,20 +51,28 @@ class QWaylandGLContext; class QWaylandEglWindow : public QWaylandWindow { public: - QWaylandEglWindow(QWidget *window); + QWaylandEglWindow(QWindow *window); ~QWaylandEglWindow(); WindowType windowType() const; void setGeometry(const QRect &rect); - void setParent(const QPlatformWindow *parent); - QPlatformGLContext *glContext() const; + + EGLSurface eglSurface() const; + + QSurfaceFormat format() const; + protected: void newSurfaceCreated(); + private: - QWaylandEglIntegration *mEglIntegration; - QWaylandGLContext *mGLContext; - struct wl_egl_window *mWaylandEglWindow; + QWaylandEglIntegration *m_eglIntegration; + struct wl_egl_window *m_waylandEglWindow; + + const QWaylandWindow *m_parentWindow; + + mutable EGLSurface m_eglSurface; + mutable EGLConfig m_eglConfig; - const QWaylandWindow *mParentWindow; + QSurfaceFormat m_format; }; #endif // QWAYLANDEGLWINDOW_H diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp index 0f27501c71..aa61405eb6 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp @@ -43,26 +43,21 @@ #include "qwaylanddisplay.h" #include "qwaylandwindow.h" +#include "qwaylandeglwindow.h" -#include "../../../eglconvenience/qeglconvenience.h" +#include <QtPlatformSupport/private/qeglconvenience_p.h> -#include <QtGui/QPlatformGLContext> -#include <QtGui/QPlatformWindowFormat> +#include <QtGui/QPlatformOpenGLContext> +#include <QtGui/QSurfaceFormat> #include <QtCore/QMutex> -QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format) - : QPlatformGLContext() - , mEglDisplay(eglDisplay) - , mSurface(EGL_NO_SURFACE) - , mConfig(q_configFromQPlatformWindowFormat(mEglDisplay,format,true)) - , mFormat(qt_qPlatformWindowFormatFromConfig(mEglDisplay,mConfig)) +QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share) + : QPlatformOpenGLContext() + , m_eglDisplay(eglDisplay) + , m_config(q_configFromGLFormat(m_eglDisplay, format, true)) + , m_format(q_glFormatFromConfig(m_eglDisplay, m_config)) { - QPlatformGLContext *sharePlatformContext = 0; - sharePlatformContext = format.sharedGLContext(); - mFormat.setSharedContext(sharePlatformContext); - EGLContext shareEGLContext = EGL_NO_CONTEXT; - if (sharePlatformContext) - shareEGLContext = static_cast<const QWaylandGLContext*>(sharePlatformContext)->mContext; + EGLContext shareEGLContext = share ? static_cast<QWaylandGLContext *>(share)->eglContext() : EGL_NO_CONTEXT; eglBindAPI(EGL_OPENGL_ES_API); @@ -71,63 +66,38 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindo eglContextAttrs.append(2); eglContextAttrs.append(EGL_NONE); - mContext = eglCreateContext(mEglDisplay, mConfig, - shareEGLContext, eglContextAttrs.constData()); + m_context = eglCreateContext(m_eglDisplay, m_config, shareEGLContext, eglContextAttrs.constData()); } -QWaylandGLContext::QWaylandGLContext() - : QPlatformGLContext() - , mEglDisplay(0) - , mContext(EGL_NO_CONTEXT) - , mSurface(EGL_NO_SURFACE) - , mConfig(0) -{ } - QWaylandGLContext::~QWaylandGLContext() { - eglDestroyContext(mEglDisplay,mContext); + eglDestroyContext(m_eglDisplay, m_context); } -void QWaylandGLContext::makeCurrent() +bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) { - QPlatformGLContext::makeCurrent(); - if (mSurface == EGL_NO_SURFACE) { - qWarning("makeCurrent with EGL_NO_SURFACE"); - } - eglMakeCurrent(mEglDisplay, mSurface, mSurface, mContext); + EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface(); + return eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context); } void QWaylandGLContext::doneCurrent() { - QPlatformGLContext::doneCurrent(); - eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -} - -void QWaylandGLContext::swapBuffers() -{ - eglSwapBuffers(mEglDisplay,mSurface); + eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); } -void *QWaylandGLContext::getProcAddress(const QString &string) +void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) { - return (void *) eglGetProcAddress(string.toLatin1().data()); + EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface(); + eglSwapBuffers(m_eglDisplay, eglSurface); } -void QWaylandGLContext::setEglSurface(EGLSurface surface) +void (*QWaylandGLContext::getProcAddress(const QByteArray &procName)) () { - bool wasCurrent = false; - if (QPlatformGLContext::currentContext() == this) { - wasCurrent = true; - doneCurrent(); - } - mSurface = surface; - if (wasCurrent) { - makeCurrent(); - } + return eglGetProcAddress(procName.constData()); } EGLConfig QWaylandGLContext::eglConfig() const { - return mConfig; + return m_config; } diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h index 2c6feb498c..16d9fa4ada 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h @@ -44,36 +44,36 @@ #include "qwaylanddisplay.h" -#include <QtGui/QPlatformGLContext> +#include <QtGui/QPlatformOpenGLContext> #include "qwaylandeglinclude.h" class QWaylandWindow; class QWaylandGLWindowSurface; -class QWaylandGLContext : public QPlatformGLContext { +class QWaylandGLContext : public QPlatformOpenGLContext { public: - QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format); + QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share); ~QWaylandGLContext(); - void makeCurrent(); + + void swapBuffers(QPlatformSurface *surface); + + bool makeCurrent(QPlatformSurface *surface); void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString&); - QPlatformWindowFormat platformWindowFormat() const { return mFormat; } + void (*getProcAddress(const QByteArray &procName)) (); - void setEglSurface(EGLSurface surface); - EGLConfig eglConfig() const; -private: - EGLDisplay mEglDisplay; + QSurfaceFormat format() const { return m_format; } - EGLContext mContext; - EGLSurface mSurface; - EGLConfig mConfig; - QPlatformWindowFormat mFormat; + EGLConfig eglConfig() const; + EGLContext eglContext() const { return m_context; } - QWaylandGLContext(); +private: + EGLDisplay m_eglDisplay; + EGLContext m_context; + EGLConfig m_config; + QSurfaceFormat m_format; }; diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri index cd0701150f..8b4b163b03 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri @@ -1,5 +1,3 @@ -include (../../../eglconvenience/eglconvenience.pri) - LIBS += -lwayland-egl -lEGL INCLUDEPATH += $$PWD SOURCES += $$PWD/qwaylandeglintegration.cpp \ 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 999a411397..f2f9d1ceb6 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp @@ -42,128 +42,31 @@ #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 <QtPlatformSupport/private/qeglconvenience_p.h> -#include <X11/extensions/Xcomposite.h> - -QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window) - : QPlatformGLContext() - , mEglIntegration(glxIntegration) - , mWindow(window) - , mBuffer(0) - , mXWindow(0) - , mConfig(q_configFromQPlatformWindowFormat(glxIntegration->eglDisplay(),window->widget()->platformWindowFormat(),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() -{ - QPlatformGLContext::makeCurrent(); - - eglMakeCurrent(mEglIntegration->eglDisplay(),mEglWindowSurface,mEglWindowSurface,mContext); -} - -void QWaylandXCompositeEGLContext::doneCurrent() +QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display) + : QEGLPlatformContext(format, share, display) { - QPlatformGLContext::doneCurrent(); - eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT); } -void QWaylandXCompositeEGLContext::swapBuffers() +void QWaylandXCompositeEGLContext::swapBuffers(QPlatformSurface *surface) { - QSize size = mWindow->geometry().size(); + QEGLPlatformContext::swapBuffers(surface); - eglSwapBuffers(mEglIntegration->eglDisplay(),mEglWindowSurface); - mWindow->damage(QRect(QPoint(0,0),size)); - mWindow->waitForFrameSync(); -} + QWaylandXCompositeEGLWindow *w = + static_cast<QWaylandXCompositeEGLWindow *>(surface); -void * QWaylandXCompositeEGLContext::getProcAddress(const QString &procName) -{ - return (void *)eglGetProcAddress(qPrintable(procName)); -} + QSize size = w->geometry().size(); -QPlatformWindowFormat QWaylandXCompositeEGLContext::platformWindowFormat() const -{ - return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig); + w->damage(QRect(QPoint(), size)); + w->waitForFrameSync(); } -void QWaylandXCompositeEGLContext::sync_function(void *data) +EGLSurface QWaylandXCompositeEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) { - 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); - - mEglWindowSurface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mConfig,mXWindow,0); - if (mEglWindowSurface == EGL_NO_SURFACE) { - qFatal("Could not make eglsurface"); - } - - 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); - - mWaitingForSync = true; - wl_display_sync(mEglIntegration->waylandDisplay()->wl_display(),0); - mEglIntegration->waylandDisplay()->flushRequests(); - while (mWaitingForSync) { - mEglIntegration->waylandDisplay()->readEvents(); - } + return static_cast<QWaylandXCompositeEGLWindow *>(surface)->eglSurface(); } 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 9d9dd53e0b..8420f2be13 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h @@ -42,41 +42,23 @@ #ifndef QWAYLANDXCOMPOSITEEGLCONTEXT_H #define QWAYLANDXCOMPOSITEEGLCONTEXT_H -#include <QtGui/QPlatformGLContext> +#include <QtGui/QPlatformOpenGLContext> -#include <QtCore/QWaitCondition> - -#include "qwaylandbuffer.h" #include "qwaylandxcompositeeglintegration.h" +#include <QtPlatformSupport/private/qeglplatformcontext_p.h> + class QWaylandXCompositeEGLWindow; -class QWaylandXCompositeEGLContext : public QPlatformGLContext +class QWaylandXCompositeEGLContext : public QEGLPlatformContext { public: - QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window); - - void makeCurrent(); - void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString& procName); + QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display); - QPlatformWindowFormat platformWindowFormat() const; - - void geometryChanged(); + void swapBuffers(QPlatformSurface *surface); private: - QWaylandXCompositeEGLIntegration *mEglIntegration; - QWaylandXCompositeEGLWindow *mWindow; - QWaylandBuffer *mBuffer; - - Window mXWindow; - EGLConfig mConfig; - EGLContext mContext; - EGLSurface mEglWindowSurface; - - static void sync_function(void *data); - bool mWaitingForSync; + EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *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 53199e87b8..d7e37f8e70 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp @@ -70,9 +70,14 @@ void QWaylandXCompositeEGLIntegration::initialize() { } -QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWidget *widget) +QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWindow *window) { - return new QWaylandXCompositeEGLWindow(widget,this); + return new QWaylandXCompositeEGLWindow(window,this); +} + +QPlatformOpenGLContext *QWaylandXCompositeEGLIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandXCompositeEGLContext(glFormat, share, eglDisplay()); } Display * QWaylandXCompositeEGLIntegration::xDisplay() const 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 1e8055944f..74ea930e9a 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h @@ -49,7 +49,9 @@ #include <QtCore/QDataStream> #include <QtCore/QMetaType> #include <QtCore/QVariant> -#include <QtGui/QWidget> +#include <QtGui/QWindow> + +#include <QPlatformOpenGLContext> #include <QWaitCondition> @@ -66,7 +68,8 @@ public: void initialize(); - QWaylandWindow *createEglWindow(QWidget *widget); + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *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 1047cb8b0a..320113f58d 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp @@ -40,17 +40,29 @@ ****************************************************************************/ #include "qwaylandxcompositeeglwindow.h" +#include "qwaylandxcompositebuffer.h" + +#include <QtPlatformSupport/private/qeglconvenience_p.h> +#include <QtPlatformSupport/private/qxlibeglintegration_p.h> + +#include "wayland-xcomposite-client-protocol.h" + +#include <X11/extensions/Xcomposite.h> #include "qwaylandxcompositeeglintegration.h" #include "windowmanager_integration/qwaylandwindowmanagerintegration.h" #include <QtCore/QDebug> -QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWidget *window, QWaylandXCompositeEGLIntegration *glxIntegration) +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->format(), true)) + , m_surface(0) + , m_waitingForSync(false) { - } QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const @@ -59,23 +71,83 @@ QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const return QWaylandWindow::Egl; } -QPlatformGLContext * QWaylandXCompositeEGLWindow::glContext() const +void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect) { - if (!mContext) { - qDebug() << "creating glcontext;"; - QWaylandXCompositeEGLWindow *that = const_cast<QWaylandXCompositeEGLWindow *>(this); - that->mContext = new QWaylandXCompositeEGLContext(mGlxIntegration,that); + QWaylandWindow::setGeometry(rect); + + if (m_surface) { + eglDestroySurface(m_glxIntegration->eglDisplay(), m_surface); + m_surface = 0; } - return mContext; } -void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect) +EGLSurface QWaylandXCompositeEGLWindow::eglSurface() const { - QWaylandWindow::setGeometry(rect); + 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); + } - if (mContext) { - mContext->geometryChanged(); + 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; } void QWaylandXCompositeEGLWindow::requestActivateWindow() 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 ea4dd2d626..b2f8fbe6c4 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h @@ -43,24 +43,36 @@ #define QWAYLANDXCOMPOSITEEGLWINDOW_H #include "qwaylandwindow.h" +#include "qwaylandbuffer.h" + #include "qwaylandxcompositeeglintegration.h" #include "qwaylandxcompositeeglcontext.h" class QWaylandXCompositeEGLWindow : public QWaylandWindow { public: - QWaylandXCompositeEGLWindow(QWidget *window, QWaylandXCompositeEGLIntegration *glxIntegration); + QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration); WindowType windowType() const; - QPlatformGLContext *glContext() const; - void setGeometry(const QRect &rect); void requestActivateWindow(); + 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 c3533f9ce3..5f86bd9588 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,6 +1,4 @@ include (../xcomposite_share/xcomposite_share.pri) -include (../../../eglconvenience/eglconvenience.pri) -include (../../../eglconvenience/xlibeglintegration.pri) 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 3d49790f3a..75881a7fdd 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,56 @@ ** ****************************************************************************/ +#include <QtCore/QDebug> + #include "qwaylandxcompositeglxcontext.h" #include "qwaylandxcompositeglxwindow.h" -#include "qwaylandxcompositebuffer.h" -#include "wayland-xcomposite-client-protocol.h" -#include <QtCore/QDebug> +#include <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->widget()->platformWindowFormat())) - , mWaitingForSyncCallback(false) +QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen) + : m_display(display) { - XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig); - mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE); - - geometryChanged(); + qDebug("creating XComposite-GLX context"); + GLXContext shareContext = share ? static_cast<QWaylandXCompositeGLXContext *>(share)->m_context : 0; + GLXFBConfig config = qglx_findConfig(display, screen, format); + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config); + m_context = glXCreateContext(display, visualInfo, shareContext, true); + m_format = qglx_surfaceFormatFromGLXFBConfig(display, config, m_context); } -void QWaylandXCompositeGLXContext::makeCurrent() +bool QWaylandXCompositeGLXContext::makeCurrent(QPlatformSurface *surface) { - QPlatformGLContext::makeCurrent(); - glXMakeCurrent(mGlxIntegration->xDisplay(),mXWindow,mContext); + Window xWindow = static_cast<QWaylandXCompositeGLXWindow *>(surface)->xWindow(); + + return glXMakeCurrent(m_display, xWindow, m_context); } void QWaylandXCompositeGLXContext::doneCurrent() { - glXMakeCurrent(mGlxIntegration->xDisplay(),0,0); - QPlatformGLContext::doneCurrent(); + glXMakeCurrent(m_display, 0, 0); } -void QWaylandXCompositeGLXContext::swapBuffers() +void QWaylandXCompositeGLXContext::swapBuffers(QPlatformSurface *surface) { - QSize size = mWindow->geometry().size(); + QWaylandXCompositeGLXWindow *w = static_cast<QWaylandXCompositeGLXWindow *>(surface); - glXSwapBuffers(mGlxIntegration->xDisplay(),mXWindow); - mWindow->damage(QRect(QPoint(0,0),size)); - mWindow->waitForFrameSync(); -} + QSize size = w->geometry().size(); -void * QWaylandXCompositeGLXContext::getProcAddress(const QString &procName) -{ - return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data())); -} + glXSwapBuffers(m_display, w->xWindow()); -QPlatformWindowFormat QWaylandXCompositeGLXContext::platformWindowFormat() const -{ - return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext); + w->damage(QRect(QPoint(), size)); + w->waitForFrameSync(); } -void QWaylandXCompositeGLXContext::sync_function(void *data) +void (*QWaylandXCompositeGLXContext::getProcAddress(const QByteArray &procName)) () { - QWaylandXCompositeGLXContext *that = static_cast<QWaylandXCompositeGLXContext *>(data); - that->mWaitingForSyncCallback = false; + return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName.constData())); } -void QWaylandXCompositeGLXContext::waitForSync() +QSurfaceFormat QWaylandXCompositeGLXContext::format() const { - 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 m_format; } -void QWaylandXCompositeGLXContext::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(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(); -} 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 b6ee2bbc23..3364d88ec4 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h @@ -42,44 +42,33 @@ #ifndef QWAYLANDXCOMPOSITEGLXCONTEXT_H #define QWAYLANDXCOMPOSITEGLXCONTEXT_H -#include <QtGui/QPlatformGLContext> +#include <QtGui/QPlatformOpenGLContext> -#include <QtCore/QWaitCondition> - -#include "qwaylandbuffer.h" #include "qwaylandxcompositeglxintegration.h" - -#include "qglxconvenience.h" +#include <QtPlatformSupport/private/qglxconvenience_p.h> class QWaylandXCompositeGLXWindow; class QWaylandShmBuffer; -class QWaylandXCompositeGLXContext : public QPlatformGLContext +class QWaylandXCompositeGLXContext : public QPlatformOpenGLContext { public: - QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window); + QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen); - void makeCurrent(); - void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString& procName); + QSurfaceFormat format() const; - QPlatformWindowFormat platformWindowFormat() const; + void swapBuffers(QPlatformSurface *surface); - void geometryChanged(); + bool makeCurrent(QPlatformSurface *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; + QSurfaceFormat 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 e8dbea48c6..e1eb2e635a 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp @@ -52,12 +52,15 @@ QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDispl return new QWaylandXCompositeGLXIntegration(waylandDisplay); } -QWaylandXCompositeGLXIntegration::QWaylandXCompositeGLXIntegration(QWaylandDisplay * waylandDispaly) - : QWaylandGLIntegration() - , mWaylandDisplay(waylandDispaly) +QWaylandXCompositeGLXIntegration::QWaylandXCompositeGLXIntegration(QWaylandDisplay *waylandDisplay) + : mWaylandDisplay(waylandDisplay) + , mWaylandComposite(0) + , mDisplay(0) + , mScreen(0) + , mRootWindow(0) { qDebug() << "Using XComposite-GLX"; - wl_display_add_global_listener(waylandDispaly->wl_display(), QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal, + wl_display_add_global_listener(waylandDisplay->wl_display(), QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal, this); } @@ -70,9 +73,14 @@ void QWaylandXCompositeGLXIntegration::initialize() { } -QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWidget *widget) +QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWindow *window) { - return new QWaylandXCompositeGLXWindow(widget,this); + return new QWaylandXCompositeGLXWindow(window, this); +} + +QPlatformOpenGLContext *QWaylandXCompositeGLXIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandXCompositeGLXContext(glFormat, share, mDisplay, mScreen); } Display * QWaylandXCompositeGLXIntegration::xDisplay() const @@ -107,6 +115,7 @@ void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(wl_display *display { Q_UNUSED(version); if (strcmp(interface, "wl_xcomposite") == 0) { + qDebug("XComposite-GLX: got wl_xcomposite global"); QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data); integration->mWaylandComposite = wl_xcomposite_create(display,id,1); wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); @@ -119,6 +128,8 @@ void QWaylandXCompositeGLXIntegration::rootInformation(void *data, wl_xcomposite Q_UNUSED(xcomposite); QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data); + qDebug("XComposite-GLX: xcomposite listener callback"); + integration->mDisplay = XOpenDisplay(display_name); integration->mRootWindow = (Window) root_window; integration->mScreen = XDefaultScreen(integration->mDisplay); 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 17f2f6d4e4..b028067d8e 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h @@ -49,7 +49,7 @@ #include <QtCore/QDataStream> #include <QtCore/QMetaType> #include <QtCore/QVariant> -#include <QtGui/QWidget> +#include <QtGui/QWindow> #include <X11/Xlib.h> @@ -63,7 +63,8 @@ public: void initialize(); - QWaylandWindow *createEglWindow(QWidget *widget); + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *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 cd7ae1964c..abaf3b16a9 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> -QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWidget *window, QWaylandXCompositeGLXIntegration *glxIntegration) +#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->format())) + , 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 +void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect) { - if (!mContext) { - qDebug() << "creating glcontext;"; - QWaylandXCompositeGLXWindow *that = const_cast<QWaylandXCompositeGLXWindow *>(this); - that->mContext = new QWaylandXCompositeGLXContext(mGlxIntegration,that); + QWaylandWindow::setGeometry(rect); + + if (m_xWindow) { + delete m_buffer; + + XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow); + m_xWindow = 0; } - return mContext; } -void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect) +Window QWaylandXCompositeGLXWindow::xWindow() const { - QWaylandWindow::setGeometry(rect); + if (!m_xWindow) + const_cast<QWaylandXCompositeGLXWindow *>(this)->createSurface(); - if (mContext) { - mContext->geometryChanged(); + 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); } + + if (!m_glxIntegration->xDisplay()) { + qWarning("XCompositeGLXWindow: X display still null?!"); + return; + } + + 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 8808f2d482..acf6c8e63e 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,34 @@ #include "qwaylandxcompositeglxintegration.h" #include "qwaylandxcompositeglxcontext.h" +#include <QtCore/QWaitCondition> + +#include "qwaylandbuffer.h" + class QWaylandXCompositeGLXWindow : public QWaylandWindow { public: - QWaylandXCompositeGLXWindow(QWidget *window, QWaylandXCompositeGLXIntegration *glxIntegration); + QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration); WindowType windowType() const; - QPlatformGLContext *glContext() 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/gl_integration/xcomposite_glx/xcomposite_glx.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri index 43295e91e7..bbd6c12e42 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri @@ -1,5 +1,4 @@ include (../xcomposite_share/xcomposite_share.pri) -include (../../../glxconvenience/glxconvenience.pri) LIBS += -lXcomposite SOURCES += \ diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp index 7d309ef877..f4bacc3c1f 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp @@ -42,6 +42,7 @@ #include "qwaylandxcompositebuffer.h" #include "wayland-client.h" +#include "wayland-xcomposite-client-protocol.h" QWaylandXCompositeBuffer::QWaylandXCompositeBuffer(wl_xcomposite *xcomposite, uint32_t window, const QSize &size, wl_visual *visual) :mSize(size) diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h index cbd40ad381..02176d7850 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h @@ -43,8 +43,10 @@ #define QWAYLANDXCOMPOSITEBUFFER_H #include "qwaylandbuffer.h" +#include <stdint.h> -#include "wayland-xcomposite-client-protocol.h" +struct wl_xcomposite; +struct wl_visual; class QWaylandXCompositeBuffer : public QWaylandBuffer { |