The test attaches a buffer and then verifies that it doesn't get the
release event until a roundtrip is issued causing the event queue to
flush. It then sets the release mode to immediate and then verifies
that it doesn't need to do a roundtrip to get the release event. The
default mode is then used a second time to verify that setting it to
immediate only lasts for a single commit.
---
 tests/Makefile.am                 |   7 ++
 tests/delayed-release-test.c      | 150 ++++++++++++++++++++++++++++++++++++++
 tests/weston-test-client-helper.c |   2 +-
 3 files changed, 158 insertions(+), 1 deletion(-)
 create mode 100644 tests/delayed-release-test.c

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5be52c6..c1de1cb 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -16,6 +16,7 @@ weston_tests =                                \
        button.weston                   \
        text.weston                     \
        subsurface.weston               \
+       delayed-release.weston          \
        $(xwayland_test)
 
 AM_TESTS_ENVIRONMENT = \
@@ -117,6 +118,12 @@ text_weston_LDADD = $(weston_test_client_libs)
 subsurface_weston_SOURCES = subsurface-test.c $(weston_test_client_src)
 subsurface_weston_LDADD = $(weston_test_client_libs)
 
+delayed_release_weston_SOURCES = \
+       delayed-release-test.c \
+       $(weston_test_client_src)
+delayed_release_weston_LDADD = \
+       $(weston_test_client_libs)
+
 xwayland_weston_SOURCES = xwayland-test.c      $(weston_test_client_src)
 
 xwayland_weston_LDADD = $(weston_test_client_libs) $(XWAYLAND_TEST_LIBS)
diff --git a/tests/delayed-release-test.c b/tests/delayed-release-test.c
new file mode 100644
index 0000000..9d61bbc
--- /dev/null
+++ b/tests/delayed-release-test.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "weston-test-client-helper.h"
+#include <stdio.h>
+#include <poll.h>
+#include <time.h>
+
+struct test_data {
+       struct client *client;
+       int release_received;
+};
+
+static void
+buffer_release(void *data, struct wl_buffer *buffer)
+{
+       struct test_data *test_data = data;
+
+       test_data->release_received = 1;
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+       buffer_release
+};
+
+static long int
+timespec_diff(const struct timespec *a, const struct timespec *b)
+{
+       return ((a->tv_sec - b->tv_sec) * 1000 +
+               (a->tv_nsec - b->tv_nsec) / 1000000);
+}
+
+static void wait_release_event(struct test_data *test_data)
+{
+       struct timespec start_time, now;
+       struct pollfd pollfd;
+
+       test_data->release_received = 0;
+
+       clock_gettime(CLOCK_MONOTONIC, &start_time);
+
+       /* Wait for up to ¼ seconds for a release event from the
+        * compositor. We don't want to call wl_display_roundtrip
+        * because the callback that it installs would cause the event
+        * queue to be flushed */
+
+       pollfd.fd = wl_display_get_fd(test_data->client->wl_display);
+       pollfd.events = POLLIN;
+
+       while (!test_data->release_received) {
+               long int diff;
+
+               wl_display_dispatch_pending(test_data->client->wl_display);
+               wl_display_flush(test_data->client->wl_display);
+
+               clock_gettime(CLOCK_MONOTONIC, &now);
+
+               diff = timespec_diff(&now, &start_time);
+
+               if (diff >= 250)
+                       break;
+
+               pollfd.revents = 0;
+
+               poll(&pollfd, 1, 250 - diff);
+
+               if (pollfd.revents)
+                       wl_display_dispatch(test_data->client->wl_display);
+       }
+}
+
+static void assert_delayed_release(struct test_data *test_data)
+{
+       wait_release_event(test_data);
+       assert(!test_data->release_received);
+
+       /* Do a roundtrip to force the event queue to flush. This
+        * should guarantee we get the release event */
+       wl_display_roundtrip(test_data->client->wl_display);
+       assert(test_data->release_received);
+}
+
+static void assert_immediate_release(struct test_data *test_data)
+{
+       wait_release_event(test_data);
+       assert(test_data->release_received);
+}
+
+TEST(test_delayed_release)
+{
+       struct client *client;
+       struct test_data test_data;
+       struct surface *surface;
+
+       test_data.client = client = client_create(10, 10, 10, 10);
+       surface = client->surface;
+
+       wl_buffer_add_listener(surface->wl_buffer,
+                              &buffer_listener,
+                              &test_data);
+
+       /* First attach the buffer without disabling delayed release
+        * to ensure that we don't get the release straight away */
+       wl_surface_attach(client->surface->wl_surface,
+                         surface->wl_buffer,
+                         0, 0);
+       wl_surface_damage(client->surface->wl_surface, 0, 0, 10, 10);
+       wl_surface_commit(client->surface->wl_surface);
+       assert_delayed_release(&test_data);
+
+       /* Do the same again but this time we'll set the attach to
+        * immediate release */
+       wl_surface_attach(client->surface->wl_surface,
+                         surface->wl_buffer,
+                         0, 0);
+       wl_surface_damage(client->surface->wl_surface, 0, 0, 10, 10);
+       wl_surface_set_release(client->surface->wl_surface,
+                              WL_SURFACE_RELEASE_IMMEDIATE);
+       wl_surface_commit(client->surface->wl_surface);
+       assert_immediate_release(&test_data);
+
+       /* A subsequent attach should again default to delayed release */
+       wl_surface_attach(client->surface->wl_surface,
+                         surface->wl_buffer,
+                         0, 0);
+       wl_surface_damage(client->surface->wl_surface, 0, 0, 10, 10);
+       wl_surface_commit(client->surface->wl_surface);
+       assert_delayed_release(&test_data);
+}
diff --git a/tests/weston-test-client-helper.c 
b/tests/weston-test-client-helper.c
index b19be40..96da988 100644
--- a/tests/weston-test-client-helper.c
+++ b/tests/weston-test-client-helper.c
@@ -441,7 +441,7 @@ handle_global(void *data, struct wl_registry *registry,
        if (strcmp(interface, "wl_compositor") == 0) {
                client->wl_compositor =
                        wl_registry_bind(registry, id,
-                                        &wl_compositor_interface, 1);
+                                        &wl_compositor_interface, 4);
        } else if (strcmp(interface, "wl_seat") == 0) {
                input = xzalloc(sizeof *input);
                input->wl_seat =
-- 
1.8.3.1

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to