diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2011-06-07 17:25:22 +0200 |
---|---|---|
committer | Samuel Rødal <samuel.rodal@nokia.com> | 2011-06-10 09:24:56 +0200 |
commit | 4a189c188ccd2fb5f8d1d5ddadf06cbd6bc0916f (patch) | |
tree | 99bff9f015e869b5521836ea5667590939b22a53 /src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp | |
parent | 4d10e64f2a78e32418a98e1c80c6579ae0779dfc (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_glx/qwaylandxcompositeglxwindow.cpp')
-rw-r--r-- | src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp | 91 |
1 files changed, 79 insertions, 12 deletions
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 6eec1d4eb8..41a14e3f66 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> +#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->glFormat())) + , 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 +QPlatformGLSurface *QWaylandXCompositeGLXWindow::createGLSurface() const { - if (!mContext) { - qDebug() << "creating glcontext;"; - QWaylandXCompositeGLXWindow *that = const_cast<QWaylandXCompositeGLXWindow *>(this); - that->mContext = new QWaylandXCompositeGLXContext(mGlxIntegration,that); - } - return mContext; + return new QWaylandXCompositeGLXSurface(const_cast<QWaylandXCompositeGLXWindow *>(this)); } void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect) { QWaylandWindow::setGeometry(rect); - if (mContext) { - mContext->geometryChanged(); + if (m_xWindow) { + delete m_buffer; + + XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow); + m_xWindow = 0; + } +} + +Window QWaylandXCompositeGLXWindow::xWindow() const +{ + if (!m_xWindow) + const_cast<QWaylandXCompositeGLXWindow *>(this)->createSurface(); + + 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); } + + 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; } + |