diff options
author | Paul Olav Tvete <paul.tvete@nokia.com> | 2011-12-01 09:24:55 +0100 |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2011-12-06 16:08:08 +0100 |
commit | 1b9f38bc95fdc195d0a5b32779de3fbd881302f2 (patch) | |
tree | b728076d21fb3e0e1ad8a8fe7ed8539f6dccece6 /patches | |
parent | 399f15bb87551ca085e4beada89e8fd9e0c32d37 (diff) |
Our patches to Wayland
Change-Id: I342ccda193cbfb809e9011aeb4a87a4ed94d7d52
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
Diffstat (limited to 'patches')
-rw-r--r-- | patches/0001-Removed-superfluous-call-to-wl_copy_connection.patch | 31 | ||||
-rw-r--r-- | patches/0002-Fix-for-issues-with-threaded-GL-drivers.patch | 171 | ||||
-rw-r--r-- | patches/README | 8 |
3 files changed, 210 insertions, 0 deletions
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 index 000000000..4a9ebf4cf --- /dev/null +++ b/patches/0001-Removed-superfluous-call-to-wl_copy_connection.patch @@ -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 index 000000000..902d7f4bf --- /dev/null +++ b/patches/0002-Fix-for-issues-with-threaded-GL-drivers.patch @@ -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 index 000000000..8bb86626e --- /dev/null +++ b/patches/README @@ -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. |