summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wayland/gl_integration/xcomposite_egl
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-06-07 17:25:22 +0200
committerSamuel Rødal <samuel.rodal@nokia.com>2011-06-10 09:24:56 +0200
commit4a189c188ccd2fb5f8d1d5ddadf06cbd6bc0916f (patch)
tree99bff9f015e869b5521836ea5667590939b22a53 /src/plugins/platforms/wayland/gl_integration/xcomposite_egl
parent4d10e64f2a78e32418a98e1c80c6579ae0779dfc (diff)
QWindowContext / QWindowFormat refactor.
To enable having a single GL context used for multiple drawables we need to de-couple the context class a bit more from the window class in the plugin API. Now contexts are created stand-alone based on a GL format and a share context, and when calling makeCurrent() a desired surface is specified. This maps well to GLX, EGL, Cocoa, AGL, and WGL, which all support this use case. QWindowContext is renamed to QGuiGLContext, and QWindowFormat is renamed to QGuiGLFormat. We have the ability to introduce a pbuffer or similar other offscreen GL drawable abstraction in the future.
Diffstat (limited to 'src/plugins/platforms/wayland/gl_integration/xcomposite_egl')
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp118
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h34
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp5
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h3
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp101
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h20
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri1
7 files changed, 142 insertions, 140 deletions
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
index e61ee69d37..08b6f76daf 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
@@ -42,127 +42,37 @@
#include "qwaylandxcompositeeglcontext.h"
#include "qwaylandxcompositeeglwindow.h"
-#include "qwaylandxcompositebuffer.h"
-#include "wayland-xcomposite-client-protocol.h"
#include <QtCore/QDebug>
#include <QtGui/QRegion>
#include "qeglconvenience.h"
-#include "qxlibeglintegration.h"
-#include <X11/extensions/Xcomposite.h>
-
-QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window)
- : QPlatformGLContext()
- , mEglIntegration(glxIntegration)
- , mWindow(window)
- , mBuffer(0)
- , mXWindow(0)
- , mConfig(q_configFromQWindowFormat(glxIntegration->eglDisplay(),window->window()->requestedWindowFormat(),true,EGL_WINDOW_BIT))
- , mWaitingForSync(false)
-{
- QVector<EGLint> eglContextAttrs;
- eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); eglContextAttrs.append(2);
- eglContextAttrs.append(EGL_NONE);
-
- mContext = eglCreateContext(glxIntegration->eglDisplay(),mConfig,EGL_NO_CONTEXT,eglContextAttrs.constData());
- if (mContext == EGL_NO_CONTEXT) {
- qFatal("failed to find context");
- }
-
- geometryChanged();
-}
-
-void QWaylandXCompositeEGLContext::makeCurrent()
+QWaylandXCompositeEGLSurface::QWaylandXCompositeEGLSurface(QWaylandXCompositeEGLWindow *window)
+ : QEGLSurface(window->eglSurface(), window->window()->glFormat())
+ , m_window(window)
{
- eglMakeCurrent(mEglIntegration->eglDisplay(),mEglWindowSurface,mEglWindowSurface,mContext);
}
-void QWaylandXCompositeEGLContext::doneCurrent()
+EGLSurface QWaylandXCompositeEGLSurface::eglSurface() const
{
- QPlatformGLContext::doneCurrent();
- eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
+ return m_window->eglSurface();
}
-void QWaylandXCompositeEGLContext::swapBuffers()
+QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(const QGuiGLFormat &format, QPlatformGLContext *share, EGLDisplay display)
+ : QEGLPlatformContext(format, share, display)
{
- QSize size = mWindow->geometry().size();
-
- eglSwapBuffers(mEglIntegration->eglDisplay(),mEglWindowSurface);
- mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
- mWindow->waitForFrameSync();
-}
-
-void * QWaylandXCompositeEGLContext::getProcAddress(const QString &procName)
-{
- return (void *)eglGetProcAddress(qPrintable(procName));
}
-QWindowFormat QWaylandXCompositeEGLContext::windowFormat() const
+void QWaylandXCompositeEGLContext::swapBuffers(const QPlatformGLSurface &surface)
{
- return q_windowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
-}
-
-void QWaylandXCompositeEGLContext::sync_function(void *data)
-{
- QWaylandXCompositeEGLContext *that = static_cast<QWaylandXCompositeEGLContext *>(data);
- that->mWaitingForSync = false;
-}
-
-void QWaylandXCompositeEGLContext::geometryChanged()
-{
- QSize size(mWindow->geometry().size());
- if (size.isEmpty()) {
- //QGLWidget wants a context for a window without geometry
- size = QSize(1,1);
- }
-
- delete mBuffer;
- //XFreePixmap deletes the glxPixmap as well
- if (mXWindow) {
- XDestroyWindow(mEglIntegration->xDisplay(),mXWindow);
- }
-
- VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(mEglIntegration->xDisplay(),mEglIntegration->eglDisplay(),mConfig);
-
- XVisualInfo visualInfoTemplate;
- memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
- visualInfoTemplate.visualid = visualId;
-
- int matchingCount = 0;
- XVisualInfo *visualInfo = XGetVisualInfo(mEglIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
-
- Colormap cmap = XCreateColormap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),visualInfo->visual,AllocNone);
-
- XSetWindowAttributes a;
- a.colormap = cmap;
- mXWindow = XCreateWindow(mEglIntegration->xDisplay(), mEglIntegration->rootWindow(),0, 0, size.width(), size.height(),
- 0, visualInfo->depth, InputOutput, visualInfo->visual,
- CWColormap, &a);
-
- XCompositeRedirectWindow(mEglIntegration->xDisplay(), mXWindow, CompositeRedirectManual);
- XMapWindow(mEglIntegration->xDisplay(), mXWindow);
+ QEGLPlatformContext::swapBuffers(surface);
- mEglWindowSurface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mConfig,mXWindow,0);
- if (mEglWindowSurface == EGL_NO_SURFACE) {
- qFatal("Could not make eglsurface");
- }
+ const QWaylandXCompositeEGLSurface &s =
+ static_cast<const QWaylandXCompositeEGLSurface &>(surface);
- XSync(mEglIntegration->xDisplay(),False);
- mBuffer = new QWaylandXCompositeBuffer(mEglIntegration->waylandXComposite(),
- (uint32_t)mXWindow,
- size,
- mEglIntegration->waylandDisplay()->argbVisual());
- mWindow->attach(mBuffer);
- wl_display_sync_callback(mEglIntegration->waylandDisplay()->wl_display(),
- QWaylandXCompositeEGLContext::sync_function,
- this);
+ QSize size = s.window()->geometry().size();
- mWaitingForSync = true;
- wl_display_sync(mEglIntegration->waylandDisplay()->wl_display(),0);
- mEglIntegration->waylandDisplay()->flushRequests();
- while (mWaitingForSync) {
- mEglIntegration->waylandDisplay()->readEvents();
- }
+ s.window()->damage(QRect(QPoint(), size));
+ s.window()->waitForFrameSync();
}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
index 528faf07c5..bd7039f284 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
@@ -44,37 +44,29 @@
#include <QtGui/QPlatformGLContext>
-#include "qwaylandbuffer.h"
#include "qwaylandxcompositeeglintegration.h"
+#include "qeglplatformcontext.h"
+
class QWaylandXCompositeEGLWindow;
-class QWaylandXCompositeEGLContext : public QPlatformGLContext
+class QWaylandXCompositeEGLSurface : public QEGLSurface
{
public:
- QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window);
-
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
-
- QWindowFormat windowFormat() const;
-
- void geometryChanged();
+ QWaylandXCompositeEGLSurface(QWaylandXCompositeEGLWindow *window);
+ EGLSurface eglSurface() const;
+ QWaylandXCompositeEGLWindow *window() const { return m_window; }
private:
- QWaylandXCompositeEGLIntegration *mEglIntegration;
- QWaylandXCompositeEGLWindow *mWindow;
- QWaylandBuffer *mBuffer;
+ QWaylandXCompositeEGLWindow *m_window;
+};
- Window mXWindow;
- EGLConfig mConfig;
- EGLContext mContext;
- EGLSurface mEglWindowSurface;
+class QWaylandXCompositeEGLContext : public QEGLPlatformContext
+{
+public:
+ QWaylandXCompositeEGLContext(const QGuiGLFormat &format, QPlatformGLContext *share, EGLDisplay display);
- static void sync_function(void *data);
- bool mWaitingForSync;
+ void swapBuffers(const QPlatformGLSurface &surface);
};
#endif // QWAYLANDXCOMPOSITEEGLCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
index 239ec8963d..90d5bea770 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
@@ -75,6 +75,11 @@ QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWindow *wind
return new QWaylandXCompositeEGLWindow(window,this);
}
+QPlatformGLContext *QWaylandXCompositeEGLIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const
+{
+ return new QWaylandXCompositeEGLContext(glFormat, share, eglDisplay());
+}
+
Display * QWaylandXCompositeEGLIntegration::xDisplay() const
{
return mDisplay;
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
index 3252ce741e..ac302ef89f 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
@@ -51,6 +51,8 @@
#include <QtCore/QVariant>
#include <QtGui/QWindow>
+#include <QPlatformGLContext>
+
#include <QWaitCondition>
#include <X11/Xlib.h>
@@ -67,6 +69,7 @@ public:
void initialize();
QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
struct wl_xcomposite *waylandXComposite() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
index e57203f772..5c6717eb0c 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
@@ -40,15 +40,27 @@
****************************************************************************/
#include "qwaylandxcompositeeglwindow.h"
+#include "qwaylandxcompositebuffer.h"
+
+#include "qeglconvenience.h"
+
+#include "wayland-xcomposite-client-protocol.h"
+#include "qxlibeglintegration.h"
+
+#include <X11/extensions/Xcomposite.h>
#include <QtCore/QDebug>
QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration)
: QWaylandWindow(window)
- , mGlxIntegration(glxIntegration)
- , mContext(0)
+ , m_glxIntegration(glxIntegration)
+ , m_context(0)
+ , m_buffer(0)
+ , m_xWindow(0)
+ , m_config(q_configFromGLFormat(glxIntegration->eglDisplay(), window->glFormat(), true))
+ , m_surface(0)
+ , m_waitingForSync(false)
{
-
}
QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const
@@ -57,21 +69,86 @@ QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const
return QWaylandWindow::Egl;
}
-QPlatformGLContext * QWaylandXCompositeEGLWindow::glContext() const
+QPlatformGLSurface *QWaylandXCompositeEGLWindow::createGLSurface() const
{
- if (!mContext) {
- qDebug() << "creating glcontext;";
- QWaylandXCompositeEGLWindow *that = const_cast<QWaylandXCompositeEGLWindow *>(this);
- that->mContext = new QWaylandXCompositeEGLContext(mGlxIntegration,that);
- }
- return mContext;
+ return new QWaylandXCompositeEGLSurface(const_cast<QWaylandXCompositeEGLWindow *>(this));
}
void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect)
{
QWaylandWindow::setGeometry(rect);
- if (mContext) {
- mContext->geometryChanged();
+ if (m_surface) {
+ eglDestroySurface(m_glxIntegration->eglDisplay(), m_surface);
+ m_surface = 0;
+ }
+}
+
+EGLSurface QWaylandXCompositeEGLWindow::eglSurface() const
+{
+ if (!m_surface)
+ const_cast<QWaylandXCompositeEGLWindow *>(this)->createEglSurface();
+ return m_surface;
+}
+
+void QWaylandXCompositeEGLWindow::createEglSurface()
+{
+ QSize size(geometry().size());
+ if (size.isEmpty()) {
+ // QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
+ }
+
+ delete m_buffer;
+ //XFreePixmap deletes the glxPixmap as well
+ if (m_xWindow) {
+ XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow);
}
+
+ VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(m_glxIntegration->xDisplay(), m_glxIntegration->eglDisplay(), m_config);
+
+ XVisualInfo visualInfoTemplate;
+ memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
+ visualInfoTemplate.visualid = visualId;
+
+ int matchingCount = 0;
+ XVisualInfo *visualInfo = XGetVisualInfo(m_glxIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
+
+ Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(),m_glxIntegration->rootWindow(),visualInfo->visual,AllocNone);
+
+ XSetWindowAttributes a;
+ a.colormap = cmap;
+ m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(),
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWColormap, &a);
+
+ XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual);
+ XMapWindow(m_glxIntegration->xDisplay(), m_xWindow);
+
+ m_surface = eglCreateWindowSurface(m_glxIntegration->eglDisplay(), m_config, m_xWindow,0);
+ if (m_surface == EGL_NO_SURFACE) {
+ qFatal("Could not make eglsurface");
+ }
+
+ XSync(m_glxIntegration->xDisplay(),False);
+ mBuffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(),
+ (uint32_t)m_xWindow,
+ size,
+ m_glxIntegration->waylandDisplay()->argbVisual());
+ attach(m_buffer);
+ wl_display_sync_callback(m_glxIntegration->waylandDisplay()->wl_display(),
+ QWaylandXCompositeEGLWindow::sync_function,
+ this);
+
+ m_waitingForSync = true;
+ wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display(),0);
+ m_glxIntegration->waylandDisplay()->flushRequests();
+ while (m_waitingForSync)
+ m_glxIntegration->waylandDisplay()->readEvents();
+}
+
+void QWaylandXCompositeEGLWindow::sync_function(void *data)
+{
+ QWaylandXCompositeEGLWindow *that = static_cast<QWaylandXCompositeEGLWindow *>(data);
+ that->m_waitingForSync = false;
}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
index 6efe556fb5..16188ca3e0 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
@@ -43,6 +43,8 @@
#define QWAYLANDXCOMPOSITEEGLWINDOW_H
#include "qwaylandwindow.h"
+#include "qwaylandbuffer.h"
+
#include "qwaylandxcompositeeglintegration.h"
#include "qwaylandxcompositeeglcontext.h"
@@ -52,14 +54,26 @@ public:
QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration);
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
+ QPlatformGLSurface *createGLSurface() const;
void setGeometry(const QRect &rect);
+ EGLSurface eglSurface() const;
+
private:
- QWaylandXCompositeEGLIntegration *mGlxIntegration;
- QWaylandXCompositeEGLContext *mContext;
+ void createEglSurface();
+
+ QWaylandXCompositeEGLIntegration *m_glxIntegration;
+ QWaylandXCompositeEGLContext *m_context;
+ QWaylandBuffer *m_buffer;
+
+ Window m_xWindow;
+ EGLConfig m_config;
+ EGLSurface m_surface;
+
+ bool m_waitingForSync;
+ static void sync_function(void *data);
};
#endif // QWAYLANDXCOMPOSITEEGLWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
index 7d2f8ad443..a61391b2d1 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
@@ -1,5 +1,6 @@
include (../xcomposite_share/xcomposite_share.pri)
load(qpa/egl/convenience)
+load(qpa/egl/context)
load(qpa/egl/xlibintegration)
LIBS += -lXcomposite -lEGL