diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2011-06-23 15:37:37 +0200 |
---|---|---|
committer | Samuel Rødal <samuel.rodal@nokia.com> | 2011-06-23 15:40:42 +0200 |
commit | 8ab2f3d9bdf1119cc13567c9dd2c74879c0b0ee4 (patch) | |
tree | e3e0ef844725d8b9d79626b98a60cd94a20ebcda /src | |
parent | 90ac74c771b55dd6f8a9700e28278be446d8dd0d (diff) |
Get declarative and wayland EGL backend working for Qt compositor.
Diffstat (limited to 'src')
14 files changed, 149 insertions, 107 deletions
diff --git a/src/gui/kernel/qguiglcontext_qpa.h b/src/gui/kernel/qguiglcontext_qpa.h index 65e9fb4c3f..9e62905b68 100644 --- a/src/gui/kernel/qguiglcontext_qpa.h +++ b/src/gui/kernel/qguiglcontext_qpa.h @@ -45,6 +45,8 @@ #include <QtCore/qnamespace.h> #include <QtCore/QScopedPointer> +#include <QSurfaceFormat> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -54,7 +56,6 @@ QT_MODULE(Gui) class QGuiGLContextPrivate; class QPlatformGLContext; class QSurface; -class QSurfaceFormat; class Q_GUI_EXPORT QGuiGLContext { diff --git a/src/gui/kernel/qplatformnativeinterface_qpa.cpp b/src/gui/kernel/qplatformnativeinterface_qpa.cpp index ded917e398..82d6a97a47 100644 --- a/src/gui/kernel/qplatformnativeinterface_qpa.cpp +++ b/src/gui/kernel/qplatformnativeinterface_qpa.cpp @@ -50,4 +50,11 @@ void *QPlatformNativeInterface::nativeResourceForWindow(const QByteArray &resour return 0; } +void *QPlatformNativeInterface::nativeResourceForContext(const QByteArray &resource, QGuiGLContext *context) +{ + Q_UNUSED(resource); + Q_UNUSED(context); + return 0; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformnativeinterface_qpa.h b/src/gui/kernel/qplatformnativeinterface_qpa.h index 8e370fb2a5..edc1a9d96e 100644 --- a/src/gui/kernel/qplatformnativeinterface_qpa.h +++ b/src/gui/kernel/qplatformnativeinterface_qpa.h @@ -50,11 +50,13 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) +class QGuiGLContext; class QWindow; class Q_GUI_EXPORT QPlatformNativeInterface { public: + virtual void *nativeResourceForContext(const QByteArray &resource, QGuiGLContext *context); virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); }; diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index c9908ad01f..28c56a969a 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -394,7 +394,9 @@ public: #ifdef Q_WS_QPA static QGLContext *fromGuiGLContext(QGuiGLContext *platformContext); + QGuiGLContext *contextHandle() const; #endif + protected: virtual bool chooseContext(const QGLContext* shareContext = 0); diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 7a4fb2c1a7..cfd651e39d 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -386,6 +386,12 @@ QGLContext::QGLContext(QGuiGLContext *context) d->setupSharing(); } +QGuiGLContext *QGLContext::contextHandle() const +{ + Q_D(const QGLContext); + return d->guiGlContext; +} + /*! Returns a OpenGL context for the window context specified by \a windowContext */ diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp index d5c2f62e44..ab154017ec 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp @@ -44,11 +44,12 @@ #include "gl_integration/qwaylandglintegration.h" #include "qwaylandeglwindow.h" +#include "qwaylandglcontext.h" #include <QtCore/QDebug> QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay) - : mWaylandDisplay(waylandDisplay) + : m_waylandDisplay(waylandDisplay) { qDebug() << "Using Wayland-EGL"; } @@ -56,17 +57,17 @@ QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay QWaylandEglIntegration::~QWaylandEglIntegration() { - eglTerminate(mEglDisplay); + eglTerminate(m_eglDisplay); } void QWaylandEglIntegration::initialize() { EGLint major,minor; - mEglDisplay = eglGetDisplay(mWaylandDisplay); - if (mEglDisplay == NULL) { + m_eglDisplay = eglGetDisplay(m_waylandDisplay); + if (m_eglDisplay == NULL) { qWarning("EGL not available"); } else { - if (!eglInitialize(mEglDisplay, &major, &minor)) { + if (!eglInitialize(m_eglDisplay, &major, &minor)) { qWarning("failed to initialize EGL display"); return; } @@ -78,9 +79,14 @@ QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWindow *window) return new QWaylandEglWindow(window); } +QPlatformGLContext *QWaylandEglIntegration::createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *share) const +{ + return new QWaylandGLContext(m_eglDisplay, glFormat, share); +} + EGLDisplay QWaylandEglIntegration::eglDisplay() const { - return mEglDisplay; + return m_eglDisplay; } QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h index bc20b2cdb3..5e39e39fe8 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h @@ -58,13 +58,14 @@ public: void initialize(); QWaylandWindow *createEglWindow(QWindow *window); + QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *share) const; EGLDisplay eglDisplay() const; - struct wl_egl_display *nativeDisplay() const; + private: - struct wl_display *mWaylandDisplay; + struct wl_display *m_waylandDisplay; - EGLDisplay mEglDisplay; + EGLDisplay m_eglDisplay; }; #endif // QWAYLANDEGLINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp index 4a085ae0bd..245097ef6c 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp @@ -44,21 +44,29 @@ #include "qwaylandscreen.h" #include "qwaylandglcontext.h" +#include <QtPlatformSupport/private/qeglconvenience_p.h> + #include <QtGui/QWindow> QWaylandEglWindow::QWaylandEglWindow(QWindow *window) : QWaylandWindow(window) - , mGLContext(0) - , mWaylandEglWindow(0) + , m_waylandEglWindow(0) + , m_eglSurface(0) + , m_eglConfig(0) + , m_format(window->format()) { - mEglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration()); + m_eglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration()); + //super creates a new surface newSurfaceCreated(); } QWaylandEglWindow::~QWaylandEglWindow() { - delete mGLContext; + if (m_eglSurface) { + eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface); + m_eglSurface = 0; + } } QWaylandWindow::WindowType QWaylandEglWindow::windowType() const @@ -69,46 +77,46 @@ QWaylandWindow::WindowType QWaylandEglWindow::windowType() const void QWaylandEglWindow::setGeometry(const QRect &rect) { QWaylandWindow::setGeometry(rect); - if (mWaylandEglWindow) { - wl_egl_window_resize(mWaylandEglWindow,rect.width(),rect.height(),0,0); - } + if (m_waylandEglWindow) + wl_egl_window_resize(m_waylandEglWindow, rect.width(), rect.height(), 0, 0); } -void QWaylandEglWindow::setParent(const QPlatformWindow *parent) +void QWaylandEglWindow::newSurfaceCreated() { - const QWaylandWindow *wParent = static_cast<const QWaylandWindow *>(parent); - - mParentWindow = wParent; -} + if (m_waylandEglWindow) + wl_egl_window_destroy(m_waylandEglWindow); -QPlatformGLContext * QWaylandEglWindow::glContext() const -{ - if (!mGLContext) { - QWaylandEglWindow *that = const_cast<QWaylandEglWindow *>(this); - that->mGLContext = new QWaylandGLContext(mEglIntegration->eglDisplay(),this->window()->requestedWindowFormat()); + wl_visual *visual = QWaylandScreen::waylandScreenFromWindow(window())->visual(); + QSize size = geometry().size(); + if (!size.isValid()) + size = QSize(0,0); - EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow)); - EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL); - that->mGLContext->setEglSurface(surface); + if (m_eglSurface) { + eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface); + m_eglSurface = 0; } - return mGLContext; + m_waylandEglWindow = wl_egl_window_create(mSurface, size.width(), size.height(), visual); } -void QWaylandEglWindow::newSurfaceCreated() +QSurfaceFormat QWaylandEglWindow::format() const { - if (mWaylandEglWindow) { - wl_egl_window_destroy(mWaylandEglWindow); - } - wl_visual *visual = QWaylandScreen::waylandScreenFromWindow(window())->visual(); - QSize size = geometry().size(); - if (!size.isValid()) - size = QSize(0,0); + return m_format; +} + +EGLSurface QWaylandEglWindow::eglSurface() const +{ + if (!m_waylandEglWindow) + return 0; - mWaylandEglWindow = wl_egl_window_create(mSurface,size.width(),size.height(),visual); - if (mGLContext) { - EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow)); - EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL); - mGLContext->setEglSurface(surface); + if (!m_eglSurface) { + if (!m_eglConfig) + m_eglConfig = q_configFromGLFormat(m_eglIntegration->eglDisplay(), window()->format(), true); + + EGLNativeWindowType window = m_waylandEglWindow; + m_eglSurface = eglCreateWindowSurface(m_eglIntegration->eglDisplay(), m_eglConfig, window, 0); } + + return m_eglSurface; } + diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h index 343c50729b..d435a511c4 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h @@ -55,16 +55,24 @@ public: ~QWaylandEglWindow(); WindowType windowType() const; void setGeometry(const QRect &rect); - void setParent(const QPlatformWindow *parent); - QPlatformGLContext *glContext() const; + + EGLSurface eglSurface() const; + + QSurfaceFormat format() const; + protected: void newSurfaceCreated(); + private: - QWaylandEglIntegration *mEglIntegration; - QWaylandGLContext *mGLContext; - struct wl_egl_window *mWaylandEglWindow; + QWaylandEglIntegration *m_eglIntegration; + struct wl_egl_window *m_waylandEglWindow; + + const QWaylandWindow *m_parentWindow; + + mutable EGLSurface m_eglSurface; + mutable EGLConfig m_eglConfig; - const QWaylandWindow *mParentWindow; + QSurfaceFormat m_format; }; #endif // QWAYLANDEGLWINDOW_H diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp index 0cff704ab1..d3ece7c7a9 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp @@ -43,21 +43,21 @@ #include "qwaylanddisplay.h" #include "qwaylandwindow.h" +#include "qwaylandeglwindow.h" -#include "../../../eglconvenience/qeglconvenience.h" +#include <QtPlatformSupport/private/qeglconvenience_p.h> #include <QtGui/QPlatformGLContext> -#include <QtGui/QWindowFormat> +#include <QtGui/QSurfaceFormat> #include <QtCore/QMutex> -QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QWindowFormat &format) +QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformGLContext *share) : QPlatformGLContext() - , mEglDisplay(eglDisplay) - , mSurface(EGL_NO_SURFACE) - , mConfig(q_configFromQWindowFormat(mEglDisplay,format,true)) - , mFormat(q_windowFormatFromConfig(mEglDisplay,mConfig)) + , m_eglDisplay(eglDisplay) + , m_config(q_configFromGLFormat(m_eglDisplay, format, true)) + , m_format(q_glFormatFromConfig(m_eglDisplay, m_config)) { - EGLContext shareEGLContext = EGL_NO_CONTEXT; + EGLContext shareEGLContext = share ? static_cast<QWaylandGLContext *>(share)->eglContext() : EGL_NO_CONTEXT; eglBindAPI(EGL_OPENGL_ES_API); @@ -66,55 +66,38 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QWindowFormat eglContextAttrs.append(2); eglContextAttrs.append(EGL_NONE); - mContext = eglCreateContext(mEglDisplay, mConfig, - shareEGLContext, eglContextAttrs.constData()); + m_context = eglCreateContext(m_eglDisplay, m_config, shareEGLContext, eglContextAttrs.constData()); } -QWaylandGLContext::QWaylandGLContext() - : QPlatformGLContext() - , mEglDisplay(0) - , mContext(EGL_NO_CONTEXT) - , mSurface(EGL_NO_SURFACE) - , mConfig(0) -{ } - QWaylandGLContext::~QWaylandGLContext() { - eglDestroyContext(mEglDisplay,mContext); + eglDestroyContext(m_eglDisplay, m_context); } -void QWaylandGLContext::makeCurrent() +bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) { - if (mSurface == EGL_NO_SURFACE) { - qWarning("makeCurrent with EGL_NO_SURFACE"); - } - eglMakeCurrent(mEglDisplay, mSurface, mSurface, mContext); + EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface(); + return eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context); } void QWaylandGLContext::doneCurrent() { - QPlatformGLContext::doneCurrent(); - eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -} - -void QWaylandGLContext::swapBuffers() -{ - eglSwapBuffers(mEglDisplay,mSurface); + eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); } -void *QWaylandGLContext::getProcAddress(const QString &string) +void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) { - return (void *) eglGetProcAddress(string.toLatin1().data()); + EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface(); + eglSwapBuffers(m_eglDisplay, eglSurface); } -void QWaylandGLContext::setEglSurface(EGLSurface surface) +void (*QWaylandGLContext::getProcAddress(const QByteArray &procName)) () { - doneCurrent(); - mSurface = surface; + return eglGetProcAddress(procName.constData()); } EGLConfig QWaylandGLContext::eglConfig() const { - return mConfig; + return m_config; } diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h index 47070f54b1..592f3d18f5 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h @@ -53,27 +53,27 @@ class QWaylandGLWindowSurface; class QWaylandGLContext : public QPlatformGLContext { public: - QWaylandGLContext(EGLDisplay eglDisplay, const QWindowFormat &format); + QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformGLContext *share); ~QWaylandGLContext(); - void makeCurrent(); + + void swapBuffers(QPlatformSurface *surface); + + bool makeCurrent(QPlatformSurface *surface); void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString&); - QWindowFormat windowFormat() const { return mFormat; } + void (*getProcAddress(const QByteArray &procName)) (); - void setEglSurface(EGLSurface surface); - EGLConfig eglConfig() const; -private: - EGLDisplay mEglDisplay; + QSurfaceFormat format() const { return m_format; } - EGLContext mContext; - EGLSurface mSurface; - EGLConfig mConfig; - QWindowFormat mFormat; + EGLConfig eglConfig() const; + EGLContext eglContext() const { return m_context; } - QWaylandGLContext(); +private: + EGLDisplay m_eglDisplay; + EGLContext m_context; + EGLConfig m_config; + QSurfaceFormat m_format; }; diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 45823fcc57..28b62b3aec 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -73,6 +73,21 @@ public: Q_GLOBAL_STATIC(QXcbResourceMap, qXcbResourceMap) +void *QXcbNativeInterface::nativeResourceForContext(const QByteArray &resourceString, QGuiGLContext *context) +{ + QByteArray lowerCaseResource = resourceString.toLower(); + ResourceType resource = qXcbResourceMap()->value(lowerCaseResource); + void *result = 0; + switch(resource) { + case EglContext: + result = eglContextForContext(context); + break; + default: + result = 0; + } + return result; +} + void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) { QByteArray lowerCaseResource = resourceString.toLower(); @@ -94,9 +109,6 @@ void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceStr case GraphicsDevice: result = graphicsDeviceForWindow(window); break; - case EglContext: - result = eglContextForWindow(window); - break; default: result = 0; } @@ -161,8 +173,13 @@ void *QXcbNativeInterface::graphicsDeviceForWindow(QWindow *window) } -void * QXcbNativeInterface::eglContextForWindow(QWindow *window) +void * QXcbNativeInterface::eglContextForContext(QGuiGLContext *context) { + Q_ASSERT(context); +#if defined(XCB_USE_EGL) + QEGLPlatformContext *eglPlatformContext = static_cast<QEGLPlatformContext *>(context->handle()); + return eglPlatformContext->eglContext(); +#endif #if 0 Q_ASSERT(window); QPlatformGLContext *platformContext = window->glContext()->handle(); diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index 10e3f6350c..e9b1df4511 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -59,6 +59,7 @@ public: EglContext }; + void *nativeResourceForContext(const QByteArray &resourceString, QGuiGLContext *context); void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window); void *displayForWindow(QWindow *window); @@ -66,7 +67,8 @@ public: void *connectionForWindow(QWindow *window); void *screenForWindow(QWindow *window); void *graphicsDeviceForWindow(QWindow *window); - void *eglContextForWindow(QWindow *window); + + void *eglContextForContext(QGuiGLContext *context); private: static QXcbScreen *qPlatformScreenForWindow(QWindow *window); diff --git a/src/widgets/kernel/qinputcontext.h b/src/widgets/kernel/qinputcontext.h index fba0c7cf2c..ac5f07549c 100644 --- a/src/widgets/kernel/qinputcontext.h +++ b/src/widgets/kernel/qinputcontext.h @@ -114,7 +114,6 @@ public: virtual bool isComposing() const { return false; } -private: enum StandardFormat { PreeditFormat, SelectionFormat |