diff options
author | Jørgen Lind <jorgen.lind@nokia.com> | 2011-03-24 08:57:38 (GMT) |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2011-03-24 08:58:16 (GMT) |
commit | bbdc68b95bcec6e1a369df6b99df8ea499284d21 (patch) | |
tree | df86ab8fdb0b88043af3a068e9c239da5ae6dfff /src/plugins/platforms/wayland | |
parent | 8debf8fb8bc18dc4b125aa7ac1ee4980f5ac146c (diff) | |
download | Qt-bbdc68b95bcec6e1a369df6b99df8ea499284d21.zip Qt-bbdc68b95bcec6e1a369df6b99df8ea499284d21.tar.gz Qt-bbdc68b95bcec6e1a369df6b99df8ea499284d21.tar.bz2 |
Lighthouse: Wayland. Added glx backend for gl integration
Diffstat (limited to 'src/plugins/platforms/wayland')
12 files changed, 309 insertions, 10 deletions
diff --git a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri index ed2b021..10567cd 100644 --- a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri +++ b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri @@ -14,4 +14,6 @@ xpixmap_egl { include ($$PWD/xpixmap_egl/xpixmap_egl.pri) } - +xpixmap_glx { + include ($$PWD/xpixmap_glx/xpixmap_glx.pri) +} diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp index 8c83128..ebe4c7b 100644 --- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp +++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp @@ -54,6 +54,9 @@ 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) diff --git a/src/plugins/platforms/wayland/gl_integration/xpixmap_egl/qwaylandxpixmapwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xpixmap_egl/qwaylandxpixmapwindow.cpp index add30d8..35ce41a 100644 --- a/src/plugins/platforms/wayland/gl_integration/xpixmap_egl/qwaylandxpixmapwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xpixmap_egl/qwaylandxpixmapwindow.cpp @@ -24,10 +24,6 @@ QPlatformGLContext *QWaylandXPixmapWindow::glContext() const return mContext; } -void QWaylandXPixmapWindow::newSurfaceCreated() -{ -} - void QWaylandXPixmapWindow::setGeometry(const QRect &rect) { QPlatformWindow::setGeometry(rect); diff --git a/src/plugins/platforms/wayland/gl_integration/xpixmap_egl/qwaylandxpixmapwindow.h b/src/plugins/platforms/wayland/gl_integration/xpixmap_egl/qwaylandxpixmapwindow.h index 919e29d..1f10112 100644 --- a/src/plugins/platforms/wayland/gl_integration/xpixmap_egl/qwaylandxpixmapwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/xpixmap_egl/qwaylandxpixmapwindow.h @@ -16,8 +16,6 @@ public: QPlatformGLContext *glContext() const; void setGeometry(const QRect &rect); -protected: - void newSurfaceCreated(); private: QWaylandXPixmapEglIntegration *mEglIntegration; diff --git a/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxcontext.cpp new file mode 100644 index 0000000..c8b5fba --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxcontext.cpp @@ -0,0 +1,98 @@ +#include "qwaylandxpixmapglxcontext.h" + +#include "qwaylandshmsurface.h" +#include "qwaylandxpixmapglxwindow.h" + +#include <QtCore/QDebug> + +QWaylandXPixmapGLXContext::QWaylandXPixmapGLXContext(QWaylandXPixmapGLXIntegration *glxIntegration, QWaylandXPixmapGLXWindow *window) + : QPlatformGLContext() + , mGlxIntegration(glxIntegration) + , mWindow(window) + , mBuffer(0) + , mPixmap(0) + , mConfig(findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->widget()->platformWindowFormat())) + , mGlxPixmap(0) +{ + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig); + mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE); + + geometryChanged(); +} + +void QWaylandXPixmapGLXContext::makeCurrent() +{ + QPlatformGLContext::makeCurrent(); + + while(mWindow->waitingForFrameSync()) { + mGlxIntegration->waylandDisplay()->iterate(); + } + + glXMakeCurrent(mGlxIntegration->xDisplay(),mGlxPixmap,mContext); +} + +void QWaylandXPixmapGLXContext::doneCurrent() +{ + QPlatformGLContext::doneCurrent(); +} + +void QWaylandXPixmapGLXContext::swapBuffers() +{ + if (QPlatformGLContext::currentContext() != this) { + makeCurrent(); + } + + QSize size = mWindow->geometry().size(); + + QImage img(size,QImage::Format_ARGB32); + const uchar *constBits = img.bits(); + void *pixels = const_cast<uchar *>(constBits); + + glReadPixels(0,0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels); + + img = img.mirrored(); + constBits = img.bits(); + + const uchar *constDstBits = mBuffer->image()->bits(); + uchar *dstBits = const_cast<uchar *>(constDstBits); + memcpy(dstBits,constBits,(img.width()*4) * img.height()); + + + mWindow->damage(QRegion(QRect(QPoint(0,0),size))); + +} + +void * QWaylandXPixmapGLXContext::getProcAddress(const QString &procName) +{ + return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data())); +} + +QPlatformWindowFormat QWaylandXPixmapGLXContext::platformWindowFormat() const +{ + return platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext); +} + +void QWaylandXPixmapGLXContext::geometryChanged() +{ + while (mWindow->waitingForFrameSync()) + mGlxIntegration->waylandDisplay()->iterate(); + + QSize size(mWindow->geometry().size()); + delete mBuffer; + if (mPixmap) + XFreePixmap(mGlxIntegration->xDisplay(),mPixmap); + if (mGlxPixmap) + glXDestroyPixmap(mGlxIntegration->xDisplay(),mGlxPixmap); + + 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 :("; + } +} diff --git a/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxcontext.h b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxcontext.h new file mode 100644 index 0000000..c4c3796 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxcontext.h @@ -0,0 +1,38 @@ +#ifndef QWAYLANDXPIXMAPGLXCONTEXT_H +#define QWAYLANDXPIXMAPGLXCONTEXT_H + +#include <QPlatformGLContext> + +#include "qwaylandxpixmapglxintegration.h" + +#include "qglxconvenience.h" + +class QWaylandXPixmapGLXWindow; +class QWaylandShmBuffer; + +class QWaylandXPixmapGLXContext : public QPlatformGLContext +{ +public: + QWaylandXPixmapGLXContext(QWaylandXPixmapGLXIntegration *glxIntegration, QWaylandXPixmapGLXWindow *window); + + void makeCurrent(); + void doneCurrent(); + void swapBuffers(); + void* getProcAddress(const QString& procName); + + QPlatformWindowFormat platformWindowFormat() const; + + void geometryChanged(); + +private: + QWaylandXPixmapGLXIntegration *mGlxIntegration; + QWaylandXPixmapGLXWindow *mWindow; + QWaylandShmBuffer *mBuffer; + + Pixmap mPixmap; + GLXFBConfig mConfig; + GLXContext mContext; + GLXPixmap mGlxPixmap; +}; + +#endif // QWAYLANDXPIXMAPGLXCONTEXT_H diff --git a/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxintegration.cpp new file mode 100644 index 0000000..17593d7 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxintegration.cpp @@ -0,0 +1,53 @@ +#include "qwaylandxpixmapglxintegration.h" + +#include "qwaylandxpixmapglxwindow.h" + +QWaylandXPixmapGLXIntegration::QWaylandXPixmapGLXIntegration(QWaylandDisplay * waylandDispaly) + : QWaylandGLIntegration() + , mWaylandDisplay(waylandDispaly) +{ + char *display_name = getenv("DISPLAY"); + mDisplay = XOpenDisplay(display_name); + mScreen = XDefaultScreen(mDisplay); + mRootWindow = XDefaultRootWindow(mDisplay); + XSync(mDisplay, False); +} + +QWaylandXPixmapGLXIntegration::~QWaylandXPixmapGLXIntegration() +{ + XCloseDisplay(mDisplay); +} + +void QWaylandXPixmapGLXIntegration::initialize() +{ +} + +QWaylandWindow * QWaylandXPixmapGLXIntegration::createEglWindow(QWidget *widget) +{ + return new QWaylandXPixmapGLXWindow(widget,this); +} + +QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) +{ + return new QWaylandXPixmapGLXIntegration(waylandDisplay); +} + +Display * QWaylandXPixmapGLXIntegration::xDisplay() const +{ + return mDisplay; +} + +int QWaylandXPixmapGLXIntegration::screen() const +{ + return mScreen; +} + +Window QWaylandXPixmapGLXIntegration::rootWindow() const +{ + return mRootWindow; +} + +QWaylandDisplay * QWaylandXPixmapGLXIntegration::waylandDisplay() const +{ + return mWaylandDisplay; +} diff --git a/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxintegration.h b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxintegration.h new file mode 100644 index 0000000..c48abb4 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxintegration.h @@ -0,0 +1,39 @@ +#ifndef QWAYLANDXPIXMAPGLXINTEGRATION_H +#define QWAYLANDXPIXMAPGLXINTEGRATION_H + +#include "gl_integration/qwaylandglintegration.h" + +#include <QtCore/QTextStream> +#include <QtCore/QDataStream> +#include <QtCore/QMetaType> +#include <QtCore/QVariant> +#include <QtGui/QWidget> + +#include <X11/Xlib.h> + +class QWaylandXPixmapGLXIntegration : public QWaylandGLIntegration +{ +public: + QWaylandXPixmapGLXIntegration(QWaylandDisplay * waylandDispaly); + ~QWaylandXPixmapGLXIntegration(); + + void initialize(); + + QWaylandWindow *createEglWindow(QWidget *widget); + + QWaylandDisplay *waylandDisplay() const; + + Display *xDisplay() const; + int screen() const; + Window rootWindow() const; + +private: + QWaylandDisplay *mWaylandDisplay; + + Display *mDisplay; + int mScreen; + Window mRootWindow; + +}; + +#endif // QWAYLANDXPIXMAPGLXINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxwindow.cpp new file mode 100644 index 0000000..a191320 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxwindow.cpp @@ -0,0 +1,32 @@ +#include "qwaylandxpixmapglxwindow.h" + +QWaylandXPixmapGLXWindow::QWaylandXPixmapGLXWindow(QWidget *window, QWaylandXPixmapGLXIntegration *glxIntegration) + : QWaylandShmWindow(window) + , mGlxIntegration(glxIntegration) + , mContext(0) +{ +} + +QWaylandWindow::WindowType QWaylandXPixmapGLXWindow::windowType() const +{ + //yeah. this type needs a new name + return QWaylandWindow::Egl; +} + +QPlatformGLContext * QWaylandXPixmapGLXWindow::glContext() const +{ + if (!mContext) { + QWaylandXPixmapGLXWindow *that = const_cast<QWaylandXPixmapGLXWindow *>(this); + that->mContext = new QWaylandXPixmapGLXContext(mGlxIntegration,that); + } + return mContext; +} + +void QWaylandXPixmapGLXWindow::setGeometry(const QRect &rect) +{ + QWaylandShmWindow::setGeometry(rect); + + if (mContext) { + mContext->geometryChanged(); + } +} diff --git a/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxwindow.h b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxwindow.h new file mode 100644 index 0000000..6aba21c --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/qwaylandxpixmapglxwindow.h @@ -0,0 +1,24 @@ +#ifndef QWAYLANDXPIXMAPGLXWINDOW_H +#define QWAYLANDXPIXMAPGLXWINDOW_H + +#include "qwaylandshmwindow.h" +#include "qwaylandxpixmapglxintegration.h" +#include "qwaylandxpixmapglxcontext.h" + +class QWaylandXPixmapGLXWindow : public QWaylandShmWindow +{ +public: + QWaylandXPixmapGLXWindow(QWidget *window, QWaylandXPixmapGLXIntegration *glxIntegration); + WindowType windowType() const; + + QPlatformGLContext *glContext() const; + + void setGeometry(const QRect &rect); + +private: + QWaylandXPixmapGLXIntegration *mGlxIntegration; + QWaylandXPixmapGLXContext *mContext; + +}; + +#endif // QWAYLANDXPIXMAPGLXWINDOW_H diff --git a/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/xpixmap_glx.pri b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/xpixmap_glx.pri new file mode 100644 index 0000000..07654df --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xpixmap_glx/xpixmap_glx.pri @@ -0,0 +1,10 @@ +include (../../../glxconvenience/glxconvenience.pri) +HEADERS += \ + $$PWD/qwaylandxpixmapglxintegration.h \ + gl_integration/xpixmap_glx/qwaylandxpixmapglxwindow.h \ + gl_integration/xpixmap_glx/qwaylandxpixmapglxcontext.h + +SOURCES += \ + $$PWD/qwaylandxpixmapglxintegration.cpp \ + gl_integration/xpixmap_glx/qwaylandxpixmapglxwindow.cpp \ + gl_integration/xpixmap_glx/qwaylandxpixmapglxcontext.cpp diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro index f2d9d6b..45457fc 100644 --- a/src/plugins/platforms/wayland/wayland.pro +++ b/src/plugins/platforms/wayland/wayland.pro @@ -31,12 +31,18 @@ QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_WAYLAND INCLUDEPATH += $$PWD -contains(QT_CONFIG, opengles2) { +contains(QT_CONFIG, opengl) { DEFINES += QT_WAYLAND_GL_SUPPORT QT += opengl - CONFIG += wayland_egl -# CONFIG += xpixmap_egl + contains(QT_CONFIG, opengles2) { + CONFIG += wayland_egl + #CONFIG += xpixmap_egl + } else { + message("HELLO") + CONFIG += xpixmap_glx + } + include ($$PWD/gl_integration/gl_integration.pri) } |