From 1b9f38bc95fdc195d0a5b32779de3fbd881302f2 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Thu, 1 Dec 2011 09:24:55 +0100 Subject: [PATCH] Our patches to Wayland MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I342ccda193cbfb809e9011aeb4a87a4ed94d7d52 Reviewed-by: Samuel Rødal Reviewed-by: Jørgen Lind --- ...ed-superfluous-call-to-wl_copy_connection.patch | 31 ++++ ...2-Fix-for-issues-with-threaded-GL-drivers.patch | 171 +++++++++++++++++++++ patches/README | 8 + 3 files changed, 210 insertions(+) create mode 100644 patches/0001-Removed-superfluous-call-to-wl_copy_connection.patch create mode 100644 patches/0002-Fix-for-issues-with-threaded-GL-drivers.patch create mode 100644 patches/README 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 0000000..4a9ebf4 --- /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 +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 0000000..902d7f4 --- /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 +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 + #include + #include ++#include + + #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 0000000..8bb8662 --- /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. -- 2.7.4