Our patches to Wayland
authorPaul Olav Tvete <paul.tvete@nokia.com>
Thu, 1 Dec 2011 08:24:55 +0000 (09:24 +0100)
committerJørgen Lind <jorgen.lind@nokia.com>
Tue, 6 Dec 2011 15:08:08 +0000 (16:08 +0100)
Change-Id: I342ccda193cbfb809e9011aeb4a87a4ed94d7d52
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
patches/0001-Removed-superfluous-call-to-wl_copy_connection.patch [new file with mode: 0644]
patches/0002-Fix-for-issues-with-threaded-GL-drivers.patch [new file with mode: 0644]
patches/README [new file with mode: 0644]

diff --git a/patches/0001-Removed-superfluous-call-to-wl_copy_connection.patch b/patches/0001-Removed-superfluous-call-to-wl_copy_connection.patch
new file mode 100644 (file)
index 0000000..4a9ebf4
--- /dev/null
@@ -0,0 +1,31 @@
+From 42a5ccf0f6e42c1487fef1d5422939bc6836044d Mon Sep 17 00:00:00 2001
+From: Andy Nichols <andy.nichols@nokia.com>
+Date: Thu, 24 Nov 2011 10:19:18 +0100
+Subject: [PATCH 1/2] Removed superfluous call to wl_copy_connection
+
+The only purpose those code seems to serve is to introduce a buffer
+overflow when events contain more than 128 bytes of data.
+---
+ src/wayland-client.c |    2 --
+ 1 files changed, 0 insertions(+), 2 deletions(-)
+
+diff --git a/src/wayland-client.c b/src/wayland-client.c
+index 939c17d..fd5a8fa 100644
+--- a/src/wayland-client.c
++++ b/src/wayland-client.c
+@@ -445,12 +445,10 @@ static void
+ handle_event(struct wl_display *display,
+            uint32_t id, uint32_t opcode, uint32_t size)
+ {
+-      uint32_t p[32];
+       struct wl_proxy *proxy;
+       struct wl_closure *closure;
+       const struct wl_message *message;
+-      wl_connection_copy(display->connection, p, size);
+       proxy = wl_map_lookup(&display->objects, id);
+       if (proxy == WL_ZOMBIE_OBJECT) {
+-- 
+1.7.8.rc2
+
diff --git a/patches/0002-Fix-for-issues-with-threaded-GL-drivers.patch b/patches/0002-Fix-for-issues-with-threaded-GL-drivers.patch
new file mode 100644 (file)
index 0000000..902d7f4
--- /dev/null
@@ -0,0 +1,171 @@
+From d0fb8027cea418531f25be8750c8da1d7fcfe5e2 Mon Sep 17 00:00:00 2001
+From: Paul Olav Tvete <paul.tvete@nokia.com>
+Date: Wed, 16 Nov 2011 16:55:33 +0100
+Subject: [PATCH 2/2] Fix for issues with threaded GL drivers
+
+Two problems arise with asynchronous GL drivers that allow issuing
+GL commands for the next frame before the GPU is done with the current frame:
+
+1. The client code never knows when it is necessary to call wl_display_iterate.
+
+Solution: Write to a pipe when there is data to be sent. The client can then select() on
+the pipe's fd.
+
+2. The GL library might call  wl_surface_attach/wl_surface_damage while the main thread is
+doing wl_display_iterate.
+
+Solution: Protect wl_display_iterate and wl_proxy_marshal with a mutex
+---
+ src/wayland-client.c |   61 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ src/wayland-client.h |    9 +++++++
+ 2 files changed, 69 insertions(+), 1 deletions(-)
+
+diff --git a/src/wayland-client.c b/src/wayland-client.c
+index fd5a8fa..979dadf 100644
+--- a/src/wayland-client.c
++++ b/src/wayland-client.c
+@@ -34,6 +34,7 @@
+ #include <assert.h>
+ #include <fcntl.h>
+ #include <sys/poll.h>
++#include <pthread.h>
+ #include "wayland-util.h"
+ #include "wayland-client.h"
+@@ -62,6 +63,9 @@ struct wl_display {
+       struct wl_proxy proxy;
+       struct wl_connection *connection;
+       int fd;
++#ifdef QTWAYLAND_EXPERIMENTAL_THREAD_SUPPORT
++      int pipefd[2];
++#endif
+       uint32_t mask;
+       struct wl_map objects;
+       struct wl_list global_listener_list;
+@@ -186,9 +190,42 @@ wl_proxy_add_listener(struct wl_proxy *proxy,
+       return 0;
+ }
++static void 
++display_signal_flush_needed(struct wl_display *display)
++{
++#ifdef QTWAYLAND_EXPERIMENTAL_THREAD_SUPPORT
++      const char data = '!';
++      if (display->pipefd[1])
++              write(display->pipefd[1], &data, 1);
++#endif
++}
++
++
++#ifdef QTWAYLAND_EXPERIMENTAL_THREAD_SUPPORT
++static pthread_mutex_t foo_mutex = PTHREAD_MUTEX_INITIALIZER;
++static pthread_t foo_locker;
++
++#define FOO_MUTEX_LOCK \
++    int foo_needLock = (pthread_self() != foo_locker); \
++      if (foo_needLock) { \
++              pthread_mutex_lock(&foo_mutex); \
++              foo_locker = pthread_self(); \
++      }
++
++#define FOO_MUTEX_UNLOCK \
++      if (foo_needLock) { \
++        foo_locker = 0; \
++              pthread_mutex_unlock(&foo_mutex); \
++    }
++#else
++#define FOO_MUTEX_LOCK
++#define FOO_MUTEX_UNLOCK
++#endif
++
+ WL_EXPORT void
+ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
+ {
++      FOO_MUTEX_LOCK;
+       struct wl_closure *closure;
+       va_list ap;
+@@ -204,6 +241,8 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
+               wl_closure_print(closure, &proxy->object, true);
+       wl_closure_destroy(closure);
++      display_signal_flush_needed(proxy->display);
++      FOO_MUTEX_UNLOCK;
+ }
+ /* Can't do this, there may be more than one instance of an
+@@ -414,6 +453,17 @@ wl_display_get_fd(struct wl_display *display,
+       return display->fd;
+ }
++#ifdef QTWAYLAND_EXPERIMENTAL_THREAD_SUPPORT
++WL_EXPORT int 
++wl_display_get_write_notification_fd(struct wl_display *display)
++{
++      if (!display->pipefd[0]) {
++              pipe2(display->pipefd, O_CLOEXEC | O_NONBLOCK);
++      }
++      return display->pipefd[0];
++}
++#endif
++
+ static void
+ sync_callback(void *data, struct wl_callback *callback, uint32_t time)
+ {
+@@ -482,16 +532,24 @@ handle_event(struct wl_display *display,
+ WL_EXPORT void
+ wl_display_iterate(struct wl_display *display, uint32_t mask)
+ {
++      FOO_MUTEX_LOCK;
+       uint32_t p[2], object, opcode, size;
+       int len;
+-
++#ifdef QTWAYLAND_EXPERIMENTAL_THREAD_SUPPORT
++      if ((mask & WL_DISPLAY_WRITABLE) && display->pipefd[0]) {
++              char buf[80];
++              int n = read(display->pipefd[0], buf, 80);
++      }
++#endif
+       mask &= display->mask;
+       if (mask == 0) {
+               fprintf(stderr,
+                       "wl_display_iterate called with unsolicited flags");
++              FOO_MUTEX_UNLOCK;
+               return;
+       }
++
+       len = wl_connection_data(display->connection, mask);
+       while (len > 0) {
+@@ -513,6 +571,7 @@ wl_display_iterate(struct wl_display *display, uint32_t mask)
+               fprintf(stderr, "read error: %m\n");
+               exit(EXIT_FAILURE);
+       }
++      FOO_MUTEX_UNLOCK;
+ }
+ WL_EXPORT void
+diff --git a/src/wayland-client.h b/src/wayland-client.h
+index efeee4a..050f7f2 100644
+--- a/src/wayland-client.h
++++ b/src/wayland-client.h
+@@ -94,6 +94,15 @@ uint32_t
+ wl_display_get_global(struct wl_display *display,
+                     const char *interface, uint32_t version);
++
++
++#define QTWAYLAND_EXPERIMENTAL_THREAD_SUPPORT
++
++#ifdef QTWAYLAND_EXPERIMENTAL_THREAD_SUPPORT
++int wl_display_get_write_notification_fd(struct wl_display *display);
++#endif
++
++
+ #ifdef  __cplusplus
+ }
+ #endif
+-- 
+1.7.8.rc2
+
diff --git a/patches/README b/patches/README
new file mode 100644 (file)
index 0000000..8bb8662
--- /dev/null
@@ -0,0 +1,8 @@
+Here are our patches to the Wayland repository that have not been upstreamed
+yet. They are available here as a convenience.
+
+Ground rules:
+
+1. We aim to get these patches into Wayland proper.
+
+2. QtWayland should compile and work without these patches.