Get declarative and wayland EGL backend working for Qt compositor.

This commit is contained in:
Samuel Rødal 2011-06-23 15:37:37 +02:00
parent 90ac74c771
commit 8ab2f3d9bd
14 changed files with 153 additions and 111 deletions

View File

@ -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
{

View File

@ -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

View File

@ -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);
};

View File

@ -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);

View File

@ -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
*/

View File

@ -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)

View File

@ -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;
EGLDisplay mEglDisplay;
private:
struct wl_display *m_waylandDisplay;
EGLDisplay m_eglDisplay;
};
#endif // QWAYLANDEGLINTEGRATION_H

View File

@ -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);
}
}
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(mEglIntegration->eglDisplay(),this->window()->requestedWindowFormat());
EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow));
EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL);
that->mGLContext->setEglSurface(surface);
}
return mGLContext;
if (m_waylandEglWindow)
wl_egl_window_resize(m_waylandEglWindow, rect.width(), rect.height(), 0, 0);
}
void QWaylandEglWindow::newSurfaceCreated()
{
if (mWaylandEglWindow) {
wl_egl_window_destroy(mWaylandEglWindow);
}
if (m_waylandEglWindow)
wl_egl_window_destroy(m_waylandEglWindow);
wl_visual *visual = QWaylandScreen::waylandScreenFromWindow(window())->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(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL);
mGLContext->setEglSurface(surface);
if (m_eglSurface) {
eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface);
m_eglSurface = 0;
}
m_waylandEglWindow = wl_egl_window_create(mSurface, size.width(), size.height(), visual);
}
QSurfaceFormat QWaylandEglWindow::format() const
{
return m_format;
}
EGLSurface QWaylandEglWindow::eglSurface() const
{
if (!m_waylandEglWindow)
return 0;
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;
}

View File

@ -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;
const QWaylandWindow *mParentWindow;
private:
QWaylandEglIntegration *m_eglIntegration;
struct wl_egl_window *m_waylandEglWindow;
const QWaylandWindow *m_parentWindow;
mutable EGLSurface m_eglSurface;
mutable EGLConfig m_eglConfig;
QSurfaceFormat m_format;
};
#endif // QWAYLANDEGLWINDOW_H

View File

@ -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);
eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
void QWaylandGLContext::swapBuffers()
void QWaylandGLContext::swapBuffers(QPlatformSurface *surface)
{
eglSwapBuffers(mEglDisplay,mSurface);
EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface();
eglSwapBuffers(m_eglDisplay, eglSurface);
}
void *QWaylandGLContext::getProcAddress(const QString &string)
void (*QWaylandGLContext::getProcAddress(const QByteArray &procName)) ()
{
return (void *) eglGetProcAddress(string.toLatin1().data());
}
void QWaylandGLContext::setEglSurface(EGLSurface surface)
{
doneCurrent();
mSurface = surface;
return eglGetProcAddress(procName.constData());
}
EGLConfig QWaylandGLContext::eglConfig() const
{
return mConfig;
return m_config;
}

View File

@ -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)) ();
QSurfaceFormat format() const { return m_format; }
void setEglSurface(EGLSurface surface);
EGLConfig eglConfig() const;
EGLContext eglContext() const { return m_context; }
private:
EGLDisplay mEglDisplay;
EGLContext mContext;
EGLSurface mSurface;
EGLConfig mConfig;
QWindowFormat mFormat;
QWaylandGLContext();
EGLDisplay m_eglDisplay;
EGLContext m_context;
EGLConfig m_config;
QSurfaceFormat m_format;
};

View File

@ -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();

View File

@ -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);

View File

@ -114,7 +114,6 @@ public:
virtual bool isComposing() const { return false; }
private:
enum StandardFormat {
PreeditFormat,
SelectionFormat