Merge remote branch 'gerrit/master' into refactor
[profile/ivi/qtwayland.git] / src / plugins / platforms / wayland / gl_integration / xcomposite_egl / qwaylandxcompositeeglwindow.cpp
index 1047cb8..320113f 100644 (file)
 ****************************************************************************/
 
 #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()