summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wayland
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-04-07 14:25:02 (GMT)
committerSamuel Rødal <samuel.rodal@nokia.com>2011-04-07 14:26:59 (GMT)
commitc238398e8e120c870c7581dc3a415c5d8d910e88 (patch)
tree8ff6c62ce84ba6307c9678f6b1b53f8f83be9c3f /src/plugins/platforms/wayland
parent2149763b7293be2360beb3ec1fe9117c508eedd1 (diff)
downloadQt-c238398e8e120c870c7581dc3a415c5d8d910e88.zip
Qt-c238398e8e120c870c7581dc3a415c5d8d910e88.tar.gz
Qt-c238398e8e120c870c7581dc3a415c5d8d910e88.tar.bz2
Made wayland plugin single-threaded, yay :)
Not calling QApplication::processEvents() in qt_init any more, and not using a write socket notifier to send data over the wayland protocol.
Diffstat (limited to 'src/plugins/platforms/wayland')
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp111
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.h28
-rw-r--r--src/plugins/platforms/wayland/qwaylandeventthread.cpp158
-rw-r--r--src/plugins/platforms/wayland/qwaylandeventthread.h87
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp14
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.h1
-rw-r--r--src/plugins/platforms/wayland/wayland.pro6
7 files changed, 117 insertions, 288 deletions
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
index 4f456c9..e2bfaa2 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
@@ -45,12 +45,12 @@
#include "qwaylandscreen.h"
#include "qwaylandcursor.h"
#include "qwaylandinputdevice.h"
-#include "qwaylandeventthread.h"
#ifdef QT_WAYLAND_GL_SUPPORT
#include "gl_integration/qwaylandglintegration.h"
#endif
+#include <QtCore/QAbstractEventDispatcher>
#include <QtGui/QApplication>
#include <unistd.h>
@@ -113,24 +113,6 @@ const struct wl_shell_listener QWaylandDisplay::shellListener = {
QWaylandDisplay::shellHandleConfigure,
};
-void QWaylandDisplay::displayHandleGlobal(uint32_t id, QByteArray interface, uint32_t version)
-{
- Q_UNUSED(version);
-
- if (interface == "compositor") {
- mCompositor = wl_compositor_create(mDisplay, id);
- } else if (interface == "shm") {
- mShm = wl_shm_create(mDisplay, id);
- } else if (interface == "shell"){
- mShell = wl_shell_create(mDisplay, id);
- wl_shell_add_listener(mShell, &shellListener, this);
- } else if (interface == "input_device") {
- QWaylandInputDevice *inputDevice =
- new QWaylandInputDevice(mDisplay, id);
- mInputDevices.append(inputDevice);
- }
-}
-
QWaylandDisplay::QWaylandDisplay(void)
{
mDisplay = wl_display_connect(NULL);
@@ -142,24 +124,29 @@ QWaylandDisplay::QWaylandDisplay(void)
mEglIntegration = QWaylandGLIntegration::createGLIntegration(this);
#endif
- mEventThread = new QWaylandEventThread(this);
-
-
- mEventThread->waitForScreens();
+ qRegisterMetaType<uint32_t>("uint32_t");
#ifdef QT_WAYLAND_GL_SUPPORT
mEglIntegration->initialize();
#endif
+ connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(flushRequests()));
+
+ wl_display_add_global_listener(mDisplay, QWaylandDisplay::displayHandleGlobal, this);
+ mFd = wl_display_get_fd(mDisplay, sourceUpdate, this);
+ mReadNotifier = new QSocketNotifier(mFd, QSocketNotifier::Read, this);
+ connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(readEvents()));
+
+ waitForScreens();
}
QWaylandDisplay::~QWaylandDisplay(void)
{
+ close(mFd);
#ifdef QT_WAYLAND_GL_SUPPORT
delete mEglIntegration;
#endif
- delete mEventThread;
wl_display_destroy(mDisplay);
}
@@ -179,3 +166,79 @@ void QWaylandDisplay::frameCallback(wl_display_frame_func_t func, void *data)
wl_display_frame_callback(mDisplay, func, data);
}
+void QWaylandDisplay::flushRequests()
+{
+ if (mSocketMask & WL_DISPLAY_WRITABLE)
+ wl_display_iterate(mDisplay, WL_DISPLAY_WRITABLE);
+}
+
+void QWaylandDisplay::readEvents()
+{
+ wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
+}
+
+int QWaylandDisplay::sourceUpdate(uint32_t mask, void *data)
+{
+ QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data);
+ waylandDisplay->mSocketMask = mask;
+
+ return 0;
+}
+
+void QWaylandDisplay::outputHandleGeometry(void *data,
+ struct wl_output *output,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
+{
+ //call back function called from another thread;
+ //but its safe to call createScreen from another thread since
+ //QWaylandScreen does a moveToThread
+ QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data);
+ QRect outputRect = QRect(x, y, width, height);
+ waylandDisplay->createNewScreen(output,outputRect);
+}
+
+const struct wl_output_listener QWaylandDisplay::outputListener = {
+ QWaylandDisplay::outputHandleGeometry
+};
+
+void QWaylandDisplay::waitForScreens()
+{
+ flushRequests();
+ while (mScreens.isEmpty())
+ readEvents();
+}
+
+void QWaylandDisplay::displayHandleGlobal(struct wl_display *display,
+ uint32_t id,
+ const char *interface,
+ uint32_t version,
+ void *data)
+{
+ Q_UNUSED(display);
+ QWaylandDisplay *that = static_cast<QWaylandDisplay *>(data);
+ that->displayHandleGlobal(id, QByteArray(interface), version);
+}
+
+void QWaylandDisplay::displayHandleGlobal(uint32_t id,
+ const QByteArray &interface,
+ uint32_t version)
+{
+ Q_UNUSED(version);
+
+ if (interface == "output") {
+ struct wl_output *output = wl_output_create(mDisplay, id);
+ wl_output_add_listener(output, &outputListener, this);
+ } else if (interface == "compositor") {
+ mCompositor = wl_compositor_create(mDisplay, id);
+ } else if (interface == "shm") {
+ mShm = wl_shm_create(mDisplay, id);
+ } else if (interface == "shell"){
+ mShell = wl_shell_create(mDisplay, id);
+ wl_shell_add_listener(mShell, &shellListener, this);
+ } else if (interface == "input_device") {
+ QWaylandInputDevice *inputDevice =
+ new QWaylandInputDevice(mDisplay, id);
+ mInputDevices.append(inputDevice);
+ }
+}
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h
index 4cfb7b5..ac0ad71 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.h
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.h
@@ -55,8 +55,6 @@ class QWaylandBuffer;
class QPlatformScreen;
class QWaylandScreen;
class QWaylandGLIntegration;
-class QWaylandEventThread;
-
class QWaylandDisplay : public QObject {
Q_OBJECT
@@ -85,17 +83,39 @@ public:
struct wl_display *wl_display() const { return mDisplay; }
public slots:
void createNewScreen(struct wl_output *output, QRect geometry);
- void displayHandleGlobal(uint32_t id, QByteArray interface, uint32_t version);
+ void readEvents();
+ void flushRequests();
private:
+ void waitForScreens();
+ void displayHandleGlobal(uint32_t id,
+ const QByteArray &interface,
+ uint32_t version);
+
struct wl_display *mDisplay;
- QWaylandEventThread *mEventThread;
struct wl_compositor *mCompositor;
struct wl_shm *mShm;
struct wl_shell *mShell;
QList<QPlatformScreen *> mScreens;
QList<QWaylandInputDevice *> mInputDevices;
+ QSocketNotifier *mReadNotifier;
+ int mFd;
+ bool mScreensInitialized;
+
+ uint32_t mSocketMask;
+
+ static const struct wl_output_listener outputListener;
+ static int sourceUpdate(uint32_t mask, void *data);
+ static void displayHandleGlobal(struct wl_display *display,
+ uint32_t id,
+ const char *interface,
+ uint32_t version, void *data);
+ static void outputHandleGeometry(void *data,
+ struct wl_output *output,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height);
+
#ifdef QT_WAYLAND_GL_SUPPORT
QWaylandGLIntegration *mEglIntegration;
#endif
diff --git a/src/plugins/platforms/wayland/qwaylandeventthread.cpp b/src/plugins/platforms/wayland/qwaylandeventthread.cpp
deleted file mode 100644
index 1474d9c..0000000
--- a/src/plugins/platforms/wayland/qwaylandeventthread.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwaylandeventthread.h"
-
-#include <QtCore/QMetaType>
-
-QWaylandEventThread::QWaylandEventThread(QWaylandDisplay *display)
- : QObject()
- , mDisplay(display)
- , mReadNotifier(0)
- , mWriteNotifier(0)
- , mFd(0)
- , mScreensInitialized(false)
-{
- qRegisterMetaType<uint32_t>("uint32_t");
- QThread *thread = new QThread(this);
- moveToThread(thread);
- connect(thread,SIGNAL(started()),SLOT(runningInThread()));
- thread->start();
-
-}
-
-QWaylandEventThread::~QWaylandEventThread()
-{
- close(mFd);
-}
-
-void QWaylandEventThread::runningInThread()
-{
-
- wl_display_add_global_listener(mDisplay->wl_display(),
- QWaylandEventThread::displayHandleGlobal, this);
- int fd = wl_display_get_fd(mDisplay->wl_display(), sourceUpdate, this);
- mReadNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
- connect(mReadNotifier,
- SIGNAL(activated(int)), this, SLOT(readEvents()));
-
- mWriteNotifier = new QSocketNotifier(fd, QSocketNotifier::Write, this);
- connect(mWriteNotifier,
- SIGNAL(activated(int)), this, SLOT(flushRequests()));
- mWriteNotifier->setEnabled(false);
-
- readEvents();
-}
-
-
-int QWaylandEventThread::sourceUpdate(uint32_t mask, void *data)
-{
- QWaylandEventThread *eventThread = (QWaylandEventThread *) data;
-
- /* FIXME: We get a callback here when we ask wl_display for the
- * fd, but at that point we don't have the socket notifier as we
- * need the fd to create that. We'll probably need to split that
- * API into get_fd and set_update_func functions. */
- if (eventThread->mWriteNotifier == NULL)
- return 0;
-
- QMetaObject::invokeMethod(eventThread->mWriteNotifier,"setEnabled",Qt::QueuedConnection,
- Q_ARG(bool,mask & WL_DISPLAY_WRITABLE));
-// eventThread->mWriteNotifier->setEnabled(mask & WL_DISPLAY_WRITABLE);
-
- return 0;
-}
-
-void QWaylandEventThread::readEvents()
-{
- wl_display_iterate(mDisplay->wl_display(), WL_DISPLAY_READABLE);
-}
-
-
-void QWaylandEventThread::flushRequests()
-{
- wl_display_iterate(mDisplay->wl_display(), WL_DISPLAY_WRITABLE);
-}
-
-void QWaylandEventThread::outputHandleGeometry(void *data,
- struct wl_output *output,
- int32_t x, int32_t y,
- int32_t width, int32_t height)
-{
- //call back function called from another thread;
- //but its safe to call createScreen from another thread since
- //QWaylandScreen does a moveToThread
- QWaylandEventThread *waylandEventThread = static_cast<QWaylandEventThread *>(data);
- QRect outputRect = QRect(x, y, width, height);
- waylandEventThread->mDisplay->createNewScreen(output,outputRect);
- waylandEventThread->mScreensInitialized = true;
- waylandEventThread->mWaitForScreens.wakeAll();
-}
-
-const struct wl_output_listener QWaylandEventThread::outputListener = {
- QWaylandEventThread::outputHandleGeometry
-};
-
-void QWaylandEventThread::displayHandleGlobal(wl_display *display,
- uint32_t id,
- const char *interface,
- uint32_t version,
- void *data)
-{
- if (strcmp(interface, "output") == 0) {
- struct wl_output *output = wl_output_create(display, id);
- wl_output_add_listener(output, &outputListener, data);
- }
- Q_UNUSED(display);
- QWaylandEventThread *that = static_cast<QWaylandEventThread *>(data);
- QByteArray interfaceByteArray(interface);
- QMetaObject::invokeMethod(that->mDisplay,"displayHandleGlobal",Qt::QueuedConnection,
- Q_ARG(uint32_t,id),Q_ARG(QByteArray,interfaceByteArray),Q_ARG(uint32_t,version));
-}
-
-void QWaylandEventThread::waitForScreens()
-{
- QMutex lock;
- lock.lock();
- if (!mScreensInitialized) {
- mWaitForScreens.wait(&lock);
- }
-}
diff --git a/src/plugins/platforms/wayland/qwaylandeventthread.h b/src/plugins/platforms/wayland/qwaylandeventthread.h
deleted file mode 100644
index 7a5189e..0000000
--- a/src/plugins/platforms/wayland/qwaylandeventthread.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWAYLANDEVENTTHREAD_H
-#define QWAYLANDEVENTTHREAD_H
-
-#include "qwaylanddisplay.h"
-
-#include <QtCore/QObject>
-#include <QtCore/QThread>
-#include <QtCore/QSocketNotifier>
-#include <QtCore/QMutex>
-
-class QWaylandEventThread : public QObject
-{
- Q_OBJECT
-public:
- explicit QWaylandEventThread(QWaylandDisplay *display);
- ~QWaylandEventThread();
-
- static int sourceUpdate(uint32_t mask, void *data);
-
- void waitForScreens();
-
-signals:
-public slots:
- void runningInThread();
- void readEvents();
- void flushRequests();
-private:
- QWaylandDisplay *mDisplay;
- QSocketNotifier *mReadNotifier;
- QSocketNotifier *mWriteNotifier;
- int mFd;
- QWaitCondition mWaitForScreens;
- bool mScreensInitialized;
-
- static const struct wl_output_listener outputListener;
- static void displayHandleGlobal(struct wl_display *display,
- uint32_t id,
- const char *interface,
- uint32_t version, void *data);
- static void outputHandleGeometry(void *data,
- struct wl_output *output,
- int32_t x, int32_t y,
- int32_t width, int32_t height);
-};
-
-#endif // QWAYLANDEVENTTHREAD_H
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
index aa72ad5..c7cd147 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -142,18 +142,12 @@ void QWaylandWindow::frameCallback(void *data, uint32_t time)
{
Q_UNUSED(time);
QWaylandWindow *self = static_cast<QWaylandWindow*>(data);
- if (self->mWaitingForFrameSync) {
- self->mWaitingForFrameSync = false;
- self->mFrameSyncWait.wakeAll();
- }
+ self->mWaitingForFrameSync = false;
}
void QWaylandWindow::waitForFrameSync()
{
- if (!mWaitingForFrameSync) {
- return;
- }
- QMutex lock;
- lock.lock();
- mFrameSyncWait.wait(&lock);
+ mDisplay->flushRequests();
+ while (mWaitingForFrameSync)
+ mDisplay->readEvents();
}
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h
index ad4bba4..35b82bd 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.h
+++ b/src/plugins/platforms/wayland/qwaylandwindow.h
@@ -44,7 +44,6 @@
#include <QtGui/QPlatformWindow>
#include <QtCore/QWaitCondition>
-#include <QtCore/QMutex>
#include "qwaylanddisplay.h"
diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro
index 849299a..e5c866b 100644
--- a/src/plugins/platforms/wayland/wayland.pro
+++ b/src/plugins/platforms/wayland/wayland.pro
@@ -14,8 +14,7 @@ SOURCES = main.cpp \
qwaylanddisplay.cpp \
qwaylandwindow.cpp \
qwaylandscreen.cpp \
- qwaylandshmwindow.cpp \
- qwaylandeventthread.cpp
+ qwaylandshmwindow.cpp
HEADERS = qwaylandintegration.h \
qwaylandcursor.h \
@@ -24,8 +23,7 @@ HEADERS = qwaylandintegration.h \
qwaylandscreen.h \
qwaylandshmsurface.h \
qwaylandbuffer.h \
- qwaylandshmwindow.h \
- qwaylandeventthread.h
+ qwaylandshmwindow.h
INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND
LIBS += $$QMAKE_LIBS_WAYLAND