From c902dcc8943a2bfcb6432d46303ace46def6fe86 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B8rgen=20Lind?= <jorgen.lind@nokia.com>
Date: Wed, 9 Feb 2011 15:16:14 +0100
Subject: Lighthouse: Wayland: Use EGLSurface

---
 src/plugins/platforms/wayland/qwaylanddisplay.cpp  |   4 +-
 src/plugins/platforms/wayland/qwaylanddisplay.h    |  11 +-
 .../platforms/wayland/qwaylanddrmsurface.cpp       | 245 +++++++--------------
 src/plugins/platforms/wayland/qwaylanddrmsurface.h |  71 +-----
 .../platforms/wayland/qwaylandeglwindow.cpp        | 115 ++++++++++
 src/plugins/platforms/wayland/qwaylandeglwindow.h  |  68 ++++++
 .../platforms/wayland/qwaylandglcontext.cpp        |  64 +++---
 src/plugins/platforms/wayland/qwaylandglcontext.h  |  17 +-
 src/plugins/platforms/wayland/qwaylandinclude.h    |  72 ++++++
 .../platforms/wayland/qwaylandintegration.cpp      |  14 +-
 src/plugins/platforms/wayland/qwaylandscreen.cpp   |  19 ++
 src/plugins/platforms/wayland/qwaylandscreen.h     |   3 +
 .../platforms/wayland/qwaylandshmsurface.cpp       |  23 +-
 .../platforms/wayland/qwaylandshmwindow.cpp        |  89 ++++++++
 src/plugins/platforms/wayland/qwaylandshmwindow.h  |  63 ++++++
 src/plugins/platforms/wayland/qwaylandwindow.cpp   |  35 +--
 src/plugins/platforms/wayland/qwaylandwindow.h     |  25 ++-
 src/plugins/platforms/wayland/wayland.pro          |  31 ++-
 18 files changed, 628 insertions(+), 341 deletions(-)
 create mode 100644 src/plugins/platforms/wayland/qwaylandeglwindow.cpp
 create mode 100644 src/plugins/platforms/wayland/qwaylandeglwindow.h
 create mode 100644 src/plugins/platforms/wayland/qwaylandinclude.h
 create mode 100644 src/plugins/platforms/wayland/qwaylandshmwindow.cpp
 create mode 100644 src/plugins/platforms/wayland/qwaylandshmwindow.h

diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
index 0747afd..ca23165 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
@@ -50,8 +50,6 @@
 #include <fcntl.h>
 #include <stdio.h>
 
-#include <wayland-egl.h>
-
 struct wl_surface *QWaylandDisplay::createSurface()
 {
     return wl_compositor_create_surface(mCompositor);
@@ -186,7 +184,7 @@ QWaylandDisplay::QWaylandDisplay(void)
 
     mNativeEglDisplay = wl_egl_display_create(mDisplay);
 
-    mEglDisplay = eglGetDisplay(mNativeEglDisplay);
+    mEglDisplay = eglGetDisplay((EGLNativeDisplayType)mNativeEglDisplay);
     if (mEglDisplay == NULL) {
         qWarning("EGL not available");
     } else {
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h
index 375a9c1..ca31756 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.h
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.h
@@ -44,13 +44,12 @@
 
 #include <QtCore/QObject>
 #include <QtCore/QRect>
+#include <QtCore/QDataStream>
+#include <QtCore/QTextStream>
+#include <QtCore/QMetaType>
+#include <QtGui>
 
-#include <wayland-client.h>
-
-#define MESA_EGL_NO_X11_HEADERS
-#define EGL_EGLEXT_PROTOTYPES
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
+#include "qwaylandinclude.h"
 
 class QWaylandInputDevice;
 class QSocketNotifier;
diff --git a/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp b/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp
index aaf4a5c..38bbc59 100644
--- a/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddrmsurface.cpp
@@ -38,183 +38,104 @@
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
+
 #include "qwaylanddrmsurface.h"
 
 #include "qwaylanddisplay.h"
 #include "qwaylandwindow.h"
 #include "qwaylandscreen.h"
 
-#include <QtCore/qdebug.h>
-#include <QtGui/private/qapplication_p.h>
-#include <QtOpenGL/private/qgl_p.h>
-#include <QtGui/private/qpaintengine_p.h>
+#include <QtOpenGL/QGLFramebufferObject>
+#include <QtOpenGL/QGLContext>
 
-#include <wayland-client.h>
-#include <wayland-egl.h>
+#include <QtOpenGL/private/qglengineshadermanager_p.h>
 
 QT_BEGIN_NAMESPACE
 
-/*
- * Shared DRM surface for GL based drawing
- */
-QWaylandDrmBuffer::QWaylandDrmBuffer(QWaylandDisplay *display,
-				     const QSize &size, QImage::Format format)
-    : mDisplay(display)
-    , mSize(size)
-{
-    struct wl_visual *visual;
-
-    switch (format) {
-    case QImage::Format_ARGB32:
-	visual = display->argbVisual();
-	break;
-    case QImage::Format_ARGB32_Premultiplied:
-	visual = display->argbPremultipliedVisual();
-	break;
-    default:
-	qDebug("unsupported buffer format %d requested\n", format);
-	visual = display->argbVisual();
-	break;
-    }
-
-    mPixmap = wl_egl_pixmap_create(display->nativeDisplay(),
-				   size.width(), size.height(),
-				   visual, 0);
-
-    mImage = eglCreateImageKHR(display->eglDisplay(),
-			       NULL, EGL_NATIVE_PIXMAP_KHR,
-			       (EGLClientBuffer) mPixmap, NULL);
 
-    glGenTextures(1, &mTexture);
-    qDebug() << "generating mTexture" << mTexture;
-    glBindTexture(GL_TEXTURE_2D, mTexture);
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
 
-    mBuffer = wl_egl_pixmap_create_buffer(display->nativeDisplay(), mPixmap);
-}
-
-QWaylandDrmBuffer::~QWaylandDrmBuffer(void)
+static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br)
 {
-    glDeleteTextures(1, &mTexture);
-    eglDestroyImageKHR(mDisplay->eglDisplay(), mImage);
-    wl_egl_pixmap_destroy(mPixmap);
-    wl_buffer_destroy(mBuffer);
-}
+    const GLenum target = GL_TEXTURE_2D;
+    QRectF src = br.isEmpty()
+        ? QRectF(QPointF(), texSize)
+        : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size());
 
-void QWaylandDrmBuffer::bindToCurrentFbo()
-{
-    Q_ASSERT(QPlatformGLContext::currentContext());
-    glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0,
-                           GL_TEXTURE_2D, mTexture, 0);
-    QT_CHECK_GLERROR();
-}
+    if (target == GL_TEXTURE_2D) {
+        qreal width = texSize.width();
+        qreal height = texSize.height();
 
-QWaylandPaintDevice::QWaylandPaintDevice(QWaylandDisplay *display, QWindowSurface *windowSurface, QPlatformGLContext *context)
-    : QGLPaintDevice()
-    , mDisplay(display)
-    , mPlatformGLContext(context)
-    , mWindowSurface(windowSurface)
-    , mBufferList(1)
-    , mCurrentPaintBuffer(0)
-    , mDepthStencil(0)
-{
-    for (int i = 0; i < mBufferList.size(); i++) {
-        mBufferList[i] = 0;
+        src.setLeft(src.left() / width);
+        src.setRight(src.right() / width);
+        src.setTop(src.top() / height);
+        src.setBottom(src.bottom() / height);
     }
 
-    mPlatformGLContext->makeCurrent();
-    glGenFramebuffers(1, &m_thisFBO);
-    glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_thisFBO);
+    const GLfloat tx1 = src.left();
+    const GLfloat tx2 = src.right();
+    const GLfloat ty1 = src.top();
+    const GLfloat ty2 = src.bottom();
 
-    glGenRenderbuffers(1, &mDepthStencil);
-    glBindRenderbuffer(GL_RENDERBUFFER_EXT, mDepthStencil);
-    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
-                              GL_RENDERBUFFER_EXT, mDepthStencil);
-    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
-                              GL_RENDERBUFFER_EXT, mDepthStencil);
+    GLfloat texCoordArray[4*2] = {
+        tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1
+    };
 
-    if (windowSurface->size().isValid())
-        resize(windowSurface->size());
-}
+    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();
 
-QWaylandPaintDevice::~QWaylandPaintDevice()
-{
-    for(int i = 0; i < mBufferList.size(); i++) {
-        delete mBufferList[i];
-    }
-    glDeleteRenderbuffers(1,&mDepthStencil);
-    glDeleteFramebuffers(1,&m_thisFBO);
-}
+    glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexArray);
+    glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray);
 
-QSize QWaylandPaintDevice::size() const
-{
-    return mSize;
-}
-QGLContext *QWaylandPaintDevice::context() const
-{
-    return QGLContext::fromPlatformGLContext(mPlatformGLContext);
-}
-QPaintEngine *QWaylandPaintDevice::paintEngine() const
-{
-    return qt_qgl_paint_engine();
-}
+    glBindTexture(target, tex_id);
 
-void QWaylandPaintDevice::beginPaint()
-{
-    QGLPaintDevice::beginPaint();
-    currentDrmBuffer()->bindToCurrentFbo();
-}
+    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);
 
-bool QWaylandPaintDevice::isFlipped()const
-{
-    return true;
+    glBindTexture(target, 0);
 }
 
-void QWaylandPaintDevice::resize(const QSize &size)
+static void blitTexture(QGLContext *ctx, GLuint texture, const QSize &viewport, const QSize &texSize, const QRect &targetRect, const QRect &sourceRect)
 {
-    QImage::Format format = QPlatformScreen::platformScreenForWidget(mWindowSurface->window())->format();
-    mPlatformGLContext->makeCurrent();
-    mSize = size;
-    for (int i = 0; i < mBufferList.size(); i++) {
-        if (!mBufferList.at(i) || mBufferList.at(i)->size() != size) {
-            delete mBufferList[i];
-            mBufferList[i] = new QWaylandDrmBuffer(mDisplay, size, format);
-        }
-    }
+    glDisable(GL_DEPTH_TEST);
+    glDisable(GL_SCISSOR_TEST);
+    glDisable(GL_BLEND);
+    glViewport(0, 0, viewport.width(), viewport.height());
 
-    glBindRenderbuffer(GL_RENDERBUFFER_EXT,mDepthStencil);
-    glRenderbufferStorage(GL_RENDERBUFFER_EXT,
-                          GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());
+    QGLShaderProgram *blitProgram =
+        QGLEngineSharedShaders::shadersForContext(ctx)->blitProgram();
+    blitProgram->bind();
+    blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/);
 
-    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
+    // 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);
 
-    switch(status) {
-    case GL_NO_ERROR:
-    case GL_FRAMEBUFFER_COMPLETE_EXT:
-        qDebug() << "fbo ok";
-        break;
-    default:
-        qDebug() <<"QWaylandDrmBuffer error: "<< status;
-        break;
-    }
-    QT_CHECK_GLERROR();
-}
-
-QWaylandDrmBuffer *QWaylandPaintDevice::currentDrmBuffer() const
-{
-    return mBufferList[mCurrentPaintBuffer];
-}
-QWaylandDrmBuffer *QWaylandPaintDevice::currentDrmBufferAndSwap()
-{
-    QWaylandDrmBuffer *currentDrmBuffer = mBufferList[mCurrentPaintBuffer];
-    mCurrentPaintBuffer = (mCurrentPaintBuffer +1) % mBufferList.size();
-    return currentDrmBuffer;
+    drawTexture(r, texture, texSize, sourceRect);
 }
 
 QWaylandDrmWindowSurface::QWaylandDrmWindowSurface(QWidget *window)
     : QWindowSurface(window)
     , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
-    , mPaintDevice(new QWaylandPaintDevice(mDisplay, this,window->platformWindow()->glContext()))
+    , mPaintDevice(0)
 {
 
 }
@@ -224,41 +145,39 @@ QWaylandDrmWindowSurface::~QWaylandDrmWindowSurface()
     delete mPaintDevice;
 }
 
-void QWaylandDrmWindowSurface::beginPaint(const QRegion &)
+QPaintDevice *QWaylandDrmWindowSurface::paintDevice()
 {
-    window()->platformWindow()->glContext()->makeCurrent();
+    return mPaintDevice;
 }
 
-QPaintDevice *QWaylandDrmWindowSurface::paintDevice()
+void QWaylandDrmWindowSurface::beginPaint(const QRegion &)
 {
-    return mPaintDevice;
+    window()->platformWindow()->glContext()->makeCurrent();
+    glClearColor(0,0,0,0xff);
+    glClear(GL_COLOR_BUFFER_BIT);
 }
 
 void QWaylandDrmWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
 {
     Q_UNUSED(offset);
+    Q_UNUSED(region);
     QWaylandWindow *ww = (QWaylandWindow *) widget->platformWindow();
 
-    glFlush();
-    ww->attach(mPaintDevice->currentDrmBufferAndSwap());
+    if (mPaintDevice->isBound())
+        mPaintDevice->release();
 
-    QVector<QRect> rects = region.rects();
-    for (int i = 0; i < rects.size(); i++) {
-        QRect r = rects.at(i);
-        wl_surface_damage(ww->surface(),
-                          r.x(), r.y(), r.width(), r.height());
-    }
+    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 QWaylandDrmWindowSurface::resize(const QSize &requestedSize)
+void QWaylandDrmWindowSurface::resize(const QSize &size)
 {
-    QWindowSurface::resize(requestedSize);
-    QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow();
-
-    ww->glContext()->makeCurrent();
-
-    mPaintDevice->resize(requestedSize);
-    ww->attach(mPaintDevice->currentDrmBuffer());
+    QWindowSurface::resize(size);
+    window()->platformWindow()->glContext()->makeCurrent();
+    delete mPaintDevice;
+    mPaintDevice = new QGLFramebufferObject(size,QGLFramebufferObject::CombinedDepthStencil,GL_TEXTURE_2D,GL_RGBA);
 }
 
 QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylanddrmsurface.h b/src/plugins/platforms/wayland/qwaylanddrmsurface.h
index f49263b..78418ee 100644
--- a/src/plugins/platforms/wayland/qwaylanddrmsurface.h
+++ b/src/plugins/platforms/wayland/qwaylanddrmsurface.h
@@ -43,76 +43,10 @@
 #define QWAYLANDDRMSURFACE_H
 
 #include "qwaylanddisplay.h"
-#include "qwaylandbuffer.h"
 
 #include <QtGui/private/qwindowsurface_p.h>
-#include <QtCore/QVarLengthArray>
-#include <QtOpenGL/private/qglpaintdevice_p.h>
 
-#define GL_GLEXT_PROTOTYPES
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#define QT_RESET_GLERROR()                                \
-{                                                         \
-    while (glGetError() != GL_NO_ERROR) {}                \
-}
-#define QT_CHECK_GLERROR()                                \
-{                                                         \
-    GLenum err = glGetError();                            \
-    if (err != GL_NO_ERROR) {                             \
-        qDebug("[%s line %d] GL Error: 0x%x",             \
-               __FILE__, __LINE__, (int)err);             \
-    }                                                     \
-}
-
-class QWaylandDrmBuffer : public QWaylandBuffer {
-public:
-    QWaylandDrmBuffer(QWaylandDisplay *display,
-                       const QSize &size, QImage::Format format);
-    ~QWaylandDrmBuffer();
-
-    void bindToCurrentFbo();
-    QSize size() const { return mSize; }
-
-private:
-    struct wl_egl_pixmap *mPixmap;
-    EGLImageKHR mImage;
-    QWaylandDisplay *mDisplay;
-    QSize mSize;
-    GLuint mTexture;
-
-};
-
-class QWaylandPaintDevice : public QGLPaintDevice
-{
-public:
-    QWaylandPaintDevice(QWaylandDisplay *display, QWindowSurface *windowSurface, QPlatformGLContext *context);
-    ~QWaylandPaintDevice();
-
-    QSize size() const;
-    QGLContext *context() const;
-    QPaintEngine *paintEngine() const;
-
-    void beginPaint();
-
-    bool isFlipped()const;
-
-    void resize(const QSize &size);
-
-    QWaylandDrmBuffer *currentDrmBuffer() const;
-    QWaylandDrmBuffer *currentDrmBufferAndSwap();
-
-private:
-    QWaylandDisplay *mDisplay;
-    QPlatformGLContext  *mPlatformGLContext;
-    QWindowSurface *mWindowSurface;
-    QVarLengthArray<QWaylandDrmBuffer *> mBufferList;
-    int mCurrentPaintBuffer;
-    GLuint mDepthStencil;
-    QSize mSize;
-
-};
+class QGLFramebufferObject;
 
 class QWaylandDrmWindowSurface : public QWindowSurface
 {
@@ -124,12 +58,13 @@ public:
 
     QPaintDevice *paintDevice();
     void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+
     void resize(const QSize &size);
 
 private:
 
     QWaylandDisplay *mDisplay;
-    QWaylandPaintDevice *mPaintDevice;
+    QGLFramebufferObject *mPaintDevice;
 };
 
 #endif // QWAYLANDDRMSURFACE_H
diff --git a/src/plugins/platforms/wayland/qwaylandeglwindow.cpp b/src/plugins/platforms/wayland/qwaylandeglwindow.cpp
new file mode 100644
index 0000000..6e5e5bb
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandeglwindow.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** 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 config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandeglwindow.h"
+
+#include "qwaylandscreen.h"
+#include "qwaylandglcontext.h"
+
+#include <wayland-egl.h>
+
+
+QWaylandEglWindow::QWaylandEglWindow(QWidget *window)
+    : QWaylandWindow(window)
+    , mGLContext(0)
+    , mWaylandEglWindow(0)
+{
+    //super creates a new surface
+    newSurfaceCreated();
+}
+
+QWaylandEglWindow::~QWaylandEglWindow()
+{
+    if (mGLContext)
+        delete mGLContext;
+}
+
+QWaylandWindow::WindowType QWaylandEglWindow::windowType() const
+{
+    return QWaylandWindow::Egl;
+}
+
+void QWaylandEglWindow::setGeometry(const QRect &rect)
+{
+    QWaylandWindow::setGeometry(rect);
+    if (mWaylandEglWindow) {
+        wl_egl_window_resize(mWaylandEglWindow,rect.width(),rect.height(),0,0);
+    }
+}
+
+void QWaylandEglWindow::setParent(const QPlatformWindow *parent)
+{
+    const QWaylandWindow *wParent = static_cast<const QWaylandWindow *>(parent);
+
+    mParentWindow = wParent;
+}
+
+QPlatformGLContext * QWaylandEglWindow::glContext() const
+{
+    if (!mGLContext) {
+        QWaylandEglWindow *that = const_cast<QWaylandEglWindow *>(this);
+        that->mGLContext = new QWaylandGLContext(that->mDisplay,widget()->platformWindowFormat());
+
+        EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow));
+        EGLSurface surface = eglCreateWindowSurface(mDisplay->eglDisplay(),mGLContext->eglConfig(),window,NULL);
+        that->mGLContext->setEglSurface(surface);
+    }
+
+    return mGLContext;
+}
+
+void QWaylandEglWindow::newSurfaceCreated()
+{
+    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);
+
+    mWaylandEglWindow = wl_egl_window_create(mSurface,size.width(),size.height(),visual);
+    if (mGLContext) {
+        EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow));
+        EGLSurface surface = eglCreateWindowSurface(mDisplay->eglDisplay(),mGLContext->eglConfig(),window,NULL);
+        mGLContext->setEglSurface(surface);
+    }
+}
diff --git a/src/plugins/platforms/wayland/qwaylandeglwindow.h b/src/plugins/platforms/wayland/qwaylandeglwindow.h
new file mode 100644
index 0000000..4b3bb5b
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandeglwindow.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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 config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDEGLWINDOW_H
+#define QWAYLANDEGLWINDOW_H
+
+#include "qwaylandwindow.h"
+
+class QWaylandGLContext;
+
+class QWaylandEglWindow : public QWaylandWindow
+{
+public:
+    QWaylandEglWindow(QWidget *window);
+    ~QWaylandEglWindow();
+    WindowType windowType() const;
+    void setGeometry(const QRect &rect);
+    void setParent(const QPlatformWindow *parent);
+    QPlatformGLContext *glContext() const;
+protected:
+    void newSurfaceCreated();
+private:
+    QWaylandGLContext *mGLContext;
+    struct wl_egl_window *mWaylandEglWindow;
+    EGLConfig mConfig;
+
+    const QWaylandWindow *mParentWindow;
+};
+
+#endif // QWAYLANDEGLWINDOW_H
diff --git a/src/plugins/platforms/wayland/qwaylandglcontext.cpp b/src/plugins/platforms/wayland/qwaylandglcontext.cpp
index 23631d9..3720567 100644
--- a/src/plugins/platforms/wayland/qwaylandglcontext.cpp
+++ b/src/plugins/platforms/wayland/qwaylandglcontext.cpp
@@ -45,25 +45,21 @@
 #include "qwaylandwindow.h"
 #include "qwaylanddrmsurface.h"
 
+#include "../eglconvenience/qeglconvenience.h"
+
 #include <QtGui/QPlatformGLContext>
 #include <QtGui/QPlatformWindowFormat>
 
-#include <unistd.h>
-#include <fcntl.h>
-
 Q_GLOBAL_STATIC(QMutex,qt_defaultSharedContextMutex)
 
-EGLint QWaylandGLContext::contextAttibutes[] = {
-    EGL_CONTEXT_CLIENT_VERSION, 2,
-    EGL_NONE
-};
-
 QWaylandGLContext::QWaylandGLContext(QWaylandDisplay *wd, const QPlatformWindowFormat &format)
     : QPlatformGLContext()
-    , mFormat(format)
     , mDisplay(wd)
+    , mSurface(EGL_NO_SURFACE)
+    , mConfig(q_configFromQPlatformWindowFormat(mDisplay->eglDisplay(),format,true))
+    , mFormat(qt_qPlatformWindowFormatFromConfig(mDisplay->eglDisplay(),mConfig))
 {
-    QPlatformGLContext *sharePlatformContext;
+    QPlatformGLContext *sharePlatformContext = 0;
     if (format.useDefaultSharedContext()) {
         if (!QPlatformGLContext::defaultSharedContext()) {
             if (qt_defaultSharedContextMutex()->tryLock()){
@@ -84,26 +80,22 @@ QWaylandGLContext::QWaylandGLContext(QWaylandDisplay *wd, const QPlatformWindowF
         shareEGLContext = static_cast<const QWaylandGLContext*>(sharePlatformContext)->mContext;
 
     eglBindAPI(EGL_OPENGL_ES_API);
-    mContext = eglCreateContext(mDisplay->eglDisplay(), NULL,
-                                shareEGLContext, contextAttibutes);
-
-    mFormat.setAccum(false);
-    mFormat.setAlphaBufferSize(8);
-    mFormat.setRedBufferSize(8);
-    mFormat.setGreenBufferSize(8);
-    mFormat.setBlueBufferSize(8);
-    mFormat.setDepth(false);
-//    mFormat.setDepthBufferSize(8);
-    mFormat.setStencil(false);
-//    mFormat.setStencilBufferSize(24);
-//    mFormat.setSampleBuffers(false);
 
+    QVector<EGLint> eglContextAttrs;
+    eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
+    eglContextAttrs.append(2);
+    eglContextAttrs.append(EGL_NONE);
+
+    mContext = eglCreateContext(mDisplay->eglDisplay(), mConfig,
+                                shareEGLContext, eglContextAttrs.constData());
 }
 
 QWaylandGLContext::QWaylandGLContext()
     : QPlatformGLContext()
     , mDisplay(0)
     , mContext(EGL_NO_CONTEXT)
+    , mSurface(EGL_NO_SURFACE)
+    , mConfig(0)
 { }
 
 QWaylandGLContext::~QWaylandGLContext()
@@ -114,7 +106,10 @@ QWaylandGLContext::~QWaylandGLContext()
 void QWaylandGLContext::makeCurrent()
 {
     QPlatformGLContext::makeCurrent();
-    eglMakeCurrent(mDisplay->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, mContext);
+    if (mSurface == EGL_NO_SURFACE) {
+        qWarning("makeCurrent with EGL_NO_SURFACE");
+    }
+    eglMakeCurrent(mDisplay->eglDisplay(), mSurface, mSurface, mContext);
 }
 
 void QWaylandGLContext::doneCurrent()
@@ -125,6 +120,7 @@ void QWaylandGLContext::doneCurrent()
 
 void QWaylandGLContext::swapBuffers()
 {
+    eglSwapBuffers(mDisplay->eglDisplay(),mSurface);
 }
 
 void *QWaylandGLContext::getProcAddress(const QString &string)
@@ -134,10 +130,26 @@ void *QWaylandGLContext::getProcAddress(const QString &string)
 
 void QWaylandGLContext::createDefaultSharedContex(QWaylandDisplay *display)
 {
+    QVector<EGLint> eglContextAttrs;
+    eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
+    eglContextAttrs.append(2);
+    eglContextAttrs.append(EGL_NONE);
+
     QWaylandGLContext *defaultSharedContext = new QWaylandGLContext;
     defaultSharedContext->mDisplay = display;
-    defaultSharedContext->mContext = eglCreateContext(mDisplay->eglDisplay(), NULL,
-                                                      EGL_NO_CONTEXT, contextAttibutes);
+    defaultSharedContext->mContext = eglCreateContext(mDisplay->eglDisplay(),mConfig,
+                                                      EGL_NO_CONTEXT, eglContextAttrs.constData());
     QPlatformGLContext::setDefaultSharedContext(defaultSharedContext);
 }
 
+void QWaylandGLContext::setEglSurface(EGLSurface surface)
+{
+    doneCurrent();
+    mSurface = surface;
+}
+
+EGLConfig QWaylandGLContext::eglConfig() const
+{
+    return mConfig;
+}
+
diff --git a/src/plugins/platforms/wayland/qwaylandglcontext.h b/src/plugins/platforms/wayland/qwaylandglcontext.h
index d9ba323..dd319fd 100644
--- a/src/plugins/platforms/wayland/qwaylandglcontext.h
+++ b/src/plugins/platforms/wayland/qwaylandglcontext.h
@@ -42,17 +42,14 @@
 #ifndef QWAYLANDGLCONTEXT_H
 #define QWAYLANDGLCONTEXT_H
 
+#include "qwaylanddisplay.h"
+
 #include <QtGui/QPlatformGLContext>
 
-#include <QtCore/QMutex>
-class QWaylandDisplay;
 class QWaylandWindow;
 class QWaylandDrmWindowSurface;
 
-#define MESA_EGL_NO_X11_HEADERS
-#define EGL_EGLEXT_PROTOTYPES
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
+#include "qwaylandinclude.h"
 
 class QWaylandGLContext : public QPlatformGLContext {
 public:
@@ -62,14 +59,18 @@ public:
     void doneCurrent();
     void swapBuffers();
     void* getProcAddress(const QString&);
+
     QPlatformWindowFormat platformWindowFormat() const { return mFormat; }
 
+    void setEglSurface(EGLSurface surface);
+    EGLConfig eglConfig() const;
 private:
-    QPlatformWindowFormat mFormat;
     QWaylandDisplay *mDisplay;
 
-    static EGLint contextAttibutes[];
     EGLContext mContext;
+    EGLSurface mSurface;
+    EGLConfig mConfig;
+    QPlatformWindowFormat mFormat;
 
     void createDefaultSharedContex(QWaylandDisplay *display);
     QWaylandGLContext();
diff --git a/src/plugins/platforms/wayland/qwaylandinclude.h b/src/plugins/platforms/wayland/qwaylandinclude.h
new file mode 100644
index 0000000..d1f7e39
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandinclude.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** 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 config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDINCLUDE_H
+#define QWAYLANDINCLUDE_H
+
+#include <wayland-client.h>
+
+#include <wayland-egl.h>
+
+#define GL_GLEXT_PROTOTYPES
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+//#define MESA_EGL_NO_X11_HEADERS
+#define EGL_EGLEXT_PROTOTYPES
+ #include <EGL/egl.h>
+ #include <EGL/eglext.h>
+
+#undef FocusOut
+#undef FocusIn
+#undef KeyPress
+#undef KeyRelease
+#undef None
+#undef RevertToParent
+#undef GrayScale
+#undef CursorShape
+
+#ifdef FontChange
+#undef FontChange
+#endif
+
+
+#endif // QWAYLANDINCLUDE_H
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
index 02bc680..9483a47 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.cpp
+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp
@@ -44,7 +44,8 @@
 #include "qwaylanddisplay.h"
 #include "qwaylandshmsurface.h"
 #include "qwaylanddrmsurface.h"
-#include "qwaylandwindow.h"
+#include "qwaylandshmwindow.h"
+#include "qwaylandeglwindow.h"
 
 #include "qfontconfigdatabase.h"
 
@@ -80,16 +81,21 @@ QPixmapData *QWaylandIntegration::createPixmapData(QPixmapData::PixelType type)
 QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWidget *widget, WId winId) const
 {
     Q_UNUSED(winId);
-    return new QWaylandWindow(widget);
+    bool useOpenGL = mUseOpenGL || (widget->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL);
+    if (useOpenGL)
+        return new QWaylandEglWindow(widget);
+
+    return new QWaylandShmWindow(widget);
 }
 
 QWindowSurface *QWaylandIntegration::createWindowSurface(QWidget *widget, WId winId) const
 {
     Q_UNUSED(winId);
     Q_UNUSED(winId);
-
-    if (mUseOpenGL)
+    bool useOpenGL = mUseOpenGL || (widget->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL);
+    if (useOpenGL)
         return new QWaylandDrmWindowSurface(widget);
+
     return new QWaylandShmWindowSurface(widget);
 }
 
diff --git a/src/plugins/platforms/wayland/qwaylandscreen.cpp b/src/plugins/platforms/wayland/qwaylandscreen.cpp
index aa1083f..35e2532 100644
--- a/src/plugins/platforms/wayland/qwaylandscreen.cpp
+++ b/src/plugins/platforms/wayland/qwaylandscreen.cpp
@@ -85,3 +85,22 @@ QWaylandScreen * QWaylandScreen::waylandScreenFromWidget(QWidget *widget)
     QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWidget(widget);
     return static_cast<QWaylandScreen *>(platformScreen);
 }
+
+wl_visual * QWaylandScreen::visual() const
+{
+    struct wl_visual *visual;
+
+    switch (format()) {
+    case QImage::Format_ARGB32:
+        visual = mWaylandDisplay->argbVisual();
+        break;
+    case QImage::Format_ARGB32_Premultiplied:
+        visual = mWaylandDisplay->argbPremultipliedVisual();
+        break;
+    default:
+        qDebug("unsupported buffer format %d requested\n", format());
+        visual = mWaylandDisplay->argbVisual();
+        break;
+    }
+    return visual;
+}
diff --git a/src/plugins/platforms/wayland/qwaylandscreen.h b/src/plugins/platforms/wayland/qwaylandscreen.h
index 368859f..7784646 100644
--- a/src/plugins/platforms/wayland/qwaylandscreen.h
+++ b/src/plugins/platforms/wayland/qwaylandscreen.h
@@ -46,6 +46,7 @@
 
 class QWaylandDisplay;
 class QWaylandCursor;
+struct wl_visual;
 
 class QWaylandScreen : public QPlatformScreen
 {
@@ -59,6 +60,8 @@ public:
     int depth() const;
     QImage::Format format() const;
 
+    wl_visual *visual() const;
+
     static QWaylandScreen *waylandScreenFromWidget(QWidget *widget);
 
 private:
diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
index 83bb993..9bcae26 100644
--- a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
+++ b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
@@ -44,7 +44,7 @@
 #include <QtGui/private/qapplication_p.h>
 
 #include "qwaylanddisplay.h"
-#include "qwaylandwindow.h"
+#include "qwaylandshmwindow.h"
 #include "qwaylandscreen.h"
 
 #include <wayland-client.h>
@@ -111,23 +111,22 @@ void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion &region, con
 {
     Q_UNUSED(widget);
     Q_UNUSED(offset);
-    QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow();
-    QVector<QRect> rects = region.rects();
-    const QRect *r;
-    int i;
+    QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
+    Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
 
-    for (i = 0; i < rects.size(); i++) {
-	r = &rects.at(i);
-	wl_surface_damage(ww->surface(),
-			  r->x(), r->y(), r->width(), r->height());
+    QVector<QRect> rects = region.rects();
+    for (int i = 0; i < rects.size(); i++) {
+        waylandWindow->damage(rects.at(i));
     }
 }
 
 void QWaylandShmWindowSurface::resize(const QSize &size)
 {
-    QWaylandWindow *ww = (QWaylandWindow *) window()->platformWindow();
+    QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
+    Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
+
     QWindowSurface::resize(size);
-    QImage::Format format = QApplicationPrivate::platformIntegration()->screens().first()->format();
+    QImage::Format format = QPlatformScreen::platformScreenForWidget(window())->format();
 
     if (mBuffer != NULL && mBuffer->size() == size)
 	return;
@@ -137,7 +136,7 @@ void QWaylandShmWindowSurface::resize(const QSize &size)
 
     mBuffer = new QWaylandShmBuffer(mDisplay, size, format);
 
-    ww->attach(mBuffer);
+    waylandWindow->attach(mBuffer);
 }
 
 QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
new file mode 100644
index 0000000..cafd2d0
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** 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 config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandshmwindow.h"
+
+#include "qwaylandbuffer.h"
+
+QWaylandShmWindow::QWaylandShmWindow(QWidget *widget)
+    : QWaylandWindow(widget)
+    , mBuffer(0)
+{
+    newSurfaceCreated();
+}
+
+QWaylandShmWindow::~QWaylandShmWindow()
+{
+
+}
+
+QWaylandWindow::WindowType QWaylandShmWindow::windowType() const
+{
+    return QWaylandWindow::Shm;
+}
+
+QPlatformGLContext * QWaylandShmWindow::glContext() const
+{
+    qWarning("Trying to retrieve a glContext from a Raster window surface!");
+    return 0;
+}
+
+void QWaylandShmWindow::attach(QWaylandBuffer *buffer)
+{
+    mBuffer = buffer;
+    if (mSurface) {
+        wl_surface_attach(mSurface, buffer->buffer(),0,0);
+    }
+}
+
+
+void QWaylandShmWindow::damage(const QRect &rect)
+{
+    wl_surface_damage(mSurface,
+                      rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+void QWaylandShmWindow::newSurfaceCreated()
+{
+    if (mBuffer) {
+        wl_surface_attach(mSurface,mBuffer->buffer(),0,0);
+    }
+}
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.h b/src/plugins/platforms/wayland/qwaylandshmwindow.h
new file mode 100644
index 0000000..14a29d2
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** 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 config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDSHMWINDOW_H
+#define QWAYLANDSHMWINDOW_H
+
+#include "qwaylandwindow.h"
+
+class QWaylandShmWindow : public QWaylandWindow
+{
+public:
+    QWaylandShmWindow(QWidget *widget);
+    ~QWaylandShmWindow();
+
+    WindowType windowType() const;
+    QPlatformGLContext *glContext() const;
+    void attach(QWaylandBuffer *buffer);
+    void damage(const QRect &rect);
+protected:
+    void newSurfaceCreated();
+private:
+    QWaylandBuffer *mBuffer;
+};
+
+#endif // QWAYLANDSHMWINDOW_H
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
index a28bdfe..934bbff 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -43,10 +43,6 @@
 
 #include "qwaylanddisplay.h"
 #include "qwaylandscreen.h"
-#include "qwaylandglcontext.h"
-#include "qwaylandbuffer.h"
-
-#include "qwaylanddrmsurface.h"
 
 #include <QtGui/QWidget>
 #include <QtGui/QWindowSystemInterface>
@@ -56,8 +52,6 @@
 QWaylandWindow::QWaylandWindow(QWidget *window)
     : QPlatformWindow(window)
     , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
-    , mGLContext(0)
-    , mBuffer(0)
 {
     static WId id = 1;
     mWindowId = id++;
@@ -67,8 +61,6 @@ QWaylandWindow::QWaylandWindow(QWidget *window)
 
 QWaylandWindow::~QWaylandWindow()
 {
-    if (mGLContext)
-        delete mGLContext;
 }
 
 WId QWaylandWindow::winId() const
@@ -78,13 +70,17 @@ WId QWaylandWindow::winId() const
 
 void QWaylandWindow::setParent(const QPlatformWindow *parent)
 {
-    QWaylandWindow *wParent = (QWaylandWindow *)parent;
-
-    mParentWindow = wParent;
+    Q_UNUSED(parent);
+    qWarning("Trying to add a raster window as a sub-window");
 }
 
 void QWaylandWindow::setVisible(bool visible)
 {
+    if (!mSurface) {
+        mSurface = mDisplay->createSurface();
+        newSurfaceCreated();
+    }
+
     if (visible) {
         wl_surface_set_user_data(mSurface, this);
         wl_surface_map_toplevel(mSurface);
@@ -94,13 +90,6 @@ void QWaylandWindow::setVisible(bool visible)
     }
 }
 
-void QWaylandWindow::attach(QWaylandBuffer *buffer)
-{
-    if (mSurface) {
-        wl_surface_attach(mSurface, buffer->buffer(),0,0);
-    }
-}
-
 void QWaylandWindow::configure(uint32_t time, uint32_t edges,
                                int32_t x, int32_t y,
                                int32_t width, int32_t height)
@@ -111,13 +100,3 @@ void QWaylandWindow::configure(uint32_t time, uint32_t edges,
 
     QWindowSystemInterface::handleGeometryChange(widget(), geometry);
 }
-
-QPlatformGLContext *QWaylandWindow::glContext() const
-{
-    if (!mGLContext) {
-        QWaylandWindow *that = const_cast<QWaylandWindow *>(this);
-        that->mGLContext = new QWaylandGLContext(mDisplay, widget()->platformWindowFormat());
-    }
-
-    return mGLContext;
-}
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h
index 8b047d7..3b51ee7 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.h
+++ b/src/plugins/platforms/wayland/qwaylandwindow.h
@@ -45,35 +45,38 @@
 #include <QtGui/QPlatformWindow>
 
 #include <stdint.h>
+#include "qwaylanddisplay.h"
 
 class QWaylandDisplay;
 class QWaylandBuffer;
+struct wl_egl_window;
 
 class QWaylandWindow : public QPlatformWindow
 {
 public:
+    enum WindowType {
+        Shm,
+        Egl
+    };
+
     QWaylandWindow(QWidget *window);
     ~QWaylandWindow();
-    struct wl_surface *surface() { return mSurface; }
 
+    virtual WindowType windowType() const = 0;
+    WId winId() const;
     void setVisible(bool visible);
+    void setParent(const QPlatformWindow *parent);
+
     void configure(uint32_t time, uint32_t edges,
                    int32_t x, int32_t y, int32_t width, int32_t height);
-    WId winId() const;
-    void setParent(const QPlatformWindow *parent);
-    QPlatformGLContext *glContext() const;
-    void attach(QWaylandBuffer *buffer);
-    QWaylandBuffer *getBuffer(void) { return mBuffer; }
-    QWaylandWindow *getParentWindow(void) { return mParentWindow; }
 
-private:
+protected:
     struct wl_surface *mSurface;
+    virtual void newSurfaceCreated() = 0;
     QWaylandDisplay *mDisplay;
-    QPlatformGLContext *mGLContext;
     WId mWindowId;
 
-    QWaylandBuffer *mBuffer;
-    QWaylandWindow *mParentWindow;
+
 };
 
 
diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro
index 803a8e9..7e8a1fa 100644
--- a/src/plugins/platforms/wayland/wayland.pro
+++ b/src/plugins/platforms/wayland/wayland.pro
@@ -9,20 +9,27 @@ SOURCES =   main.cpp \
             qwaylanddrmsurface.cpp \
             qwaylandinputdevice.cpp \
             qwaylandglcontext.cpp \
-    qwaylandcursor.cpp \
-    qwaylanddisplay.cpp \
-    qwaylandwindow.cpp \
-    qwaylandscreen.cpp
+            qwaylandcursor.cpp \
+            qwaylanddisplay.cpp \
+            qwaylandwindow.cpp \
+            qwaylandscreen.cpp \
+            ../eglconvenience/qeglconvenience.cpp \
+            qwaylandeglwindow.cpp \
+            qwaylandshmwindow.cpp
 
 HEADERS =   qwaylandintegration.h \
-    qwaylandcursor.h \
-    qwaylanddisplay.h \
-    qwaylandwindow.h \
-    qwaylandscreen.h \
-    qwaylandglcontext.h \
-    qwaylandshmsurface.h \
-    qwaylanddrmsurface.h \
-    qwaylandbuffer.h
+            qwaylandcursor.h \
+            qwaylanddisplay.h \
+            qwaylandwindow.h \
+            qwaylandscreen.h \
+            qwaylandglcontext.h \
+            qwaylandshmsurface.h \
+            qwaylanddrmsurface.h \
+            qwaylandbuffer.h \
+            ../eglconvenience/qeglconvenience.h \
+            qwaylandinclude.h \
+            qwaylandeglwindow.h \
+            qwaylandshmwindow.h
 
 contains(QT_CONFIG, opengl) {
     QT += opengl
-- 
cgit v0.12