[PATCH 7/8] tests: presentation test, simple

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Tue Sep 23 19:08:48 PDT 2014


From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>

---
 Makefile.am               |   8 ++
 tests/presentation-test.c | 246 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 254 insertions(+)
 create mode 100644 tests/presentation-test.c

diff --git a/Makefile.am b/Makefile.am
index 6a91a8f..87204a6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -842,6 +842,7 @@ weston_tests =					\
 	event.weston				\
 	button.weston				\
 	text.weston				\
+	presentation.weston			\
 	subsurface.weston
 
 
@@ -944,6 +945,13 @@ subsurface_weston_SOURCES = tests/subsurface-test.c
 subsurface_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
 subsurface_weston_LDADD = libtest-client.la
 
+presentation_weston_SOURCES = tests/presentation-test.c
+nodist_presentation_weston_SOURCES =		\
+	protocol/presentation_timing-protocol.c	\
+	protocol/presentation_timing-client-protocol.h
+presentation_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
+presentation_weston_LDADD = libtest-client.la
+
 if ENABLE_EGL
 weston_tests += buffer-count.weston
 buffer_count_weston_SOURCES = tests/buffer-count-test.c
diff --git a/tests/presentation-test.c b/tests/presentation-test.c
new file mode 100644
index 0000000..57012fa
--- /dev/null
+++ b/tests/presentation-test.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2014 Collabora, Ltd.
+ *
+ * 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 "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+
+#include "weston-test-client-helper.h"
+#include "presentation_timing-client-protocol.h"
+
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
+
+static inline void *
+xzalloc(size_t size)
+{
+	void *p;
+
+	p = calloc(1, size);
+	assert(p);
+
+	return p;
+}
+
+static struct presentation *
+get_presentation(struct client *client)
+{
+	struct global *g;
+	struct global *global_pres = NULL;
+	static struct presentation *pres;
+
+	if (pres)
+		return pres;
+
+	wl_list_for_each(g, &client->global_list, link) {
+		if (strcmp(g->interface, "presentation"))
+			continue;
+
+		if (global_pres)
+			assert(0 && "multiple presentation objects");
+
+		global_pres = g;
+	}
+
+	assert(global_pres && "no presentation found");
+
+	assert(global_pres->version == 1);
+
+	pres = wl_registry_bind(client->wl_registry, global_pres->name,
+				&presentation_interface, 1);
+	assert(pres);
+
+	return pres;
+}
+
+struct feedback {
+	struct client *client;
+	struct presentation_feedback *obj;
+
+	enum {
+		FB_PENDING = 0,
+		FB_PRESENTED,
+		FB_DISCARDED
+	} result;
+
+	struct wl_output *sync_output;
+	uint64_t seq;
+	struct timespec time;
+	uint32_t refresh_nsec;
+	uint32_t flags;
+};
+
+static void
+timespec_from_proto(struct timespec *tm, uint32_t tv_sec_hi,
+		    uint32_t tv_sec_lo, uint32_t tv_nsec)
+{
+	tm->tv_sec = ((uint64_t)tv_sec_hi << 32) + tv_sec_lo;
+	tm->tv_nsec = tv_nsec;
+}
+
+static void
+feedback_sync_output(void *data,
+		     struct presentation_feedback *presentation_feedback,
+		     struct wl_output *output)
+{
+	struct feedback *fb = data;
+
+	assert(fb->result == FB_PENDING);
+
+	if (output)
+		fb->sync_output = output;
+}
+
+static void
+feedback_presented(void *data,
+		   struct presentation_feedback *presentation_feedback,
+		   uint32_t tv_sec_hi,
+		   uint32_t tv_sec_lo,
+		   uint32_t tv_nsec,
+		   uint32_t refresh_nsec,
+		   uint32_t seq_hi,
+		   uint32_t seq_lo,
+		   uint32_t flags)
+{
+	struct feedback *fb = data;
+
+	assert(fb->result == FB_PENDING);
+	fb->result = FB_PRESENTED;
+	fb->seq = ((uint64_t)seq_hi << 32) + seq_lo;
+	timespec_from_proto(&fb->time, tv_sec_hi, tv_sec_lo, tv_nsec);
+	fb->refresh_nsec = refresh_nsec;
+	fb->flags = flags;
+}
+
+static void
+feedback_discarded(void *data,
+		   struct presentation_feedback *presentation_feedback)
+{
+	struct feedback *fb = data;
+
+	assert(fb->result == FB_PENDING);
+	fb->result = FB_DISCARDED;
+}
+
+static const struct presentation_feedback_listener feedback_listener = {
+	feedback_sync_output,
+	feedback_presented,
+	feedback_discarded
+};
+
+static struct feedback *
+feedback_create(struct client *client, struct wl_surface *surface)
+{
+	struct feedback *fb;
+
+	fb = xzalloc(sizeof *fb);
+	fb->client = client;
+	fb->obj = presentation_feedback(get_presentation(client), surface);
+	presentation_feedback_add_listener(fb->obj, &feedback_listener, fb);
+
+	return fb;
+}
+
+static void
+feedback_wait(struct feedback *fb)
+{
+	while (fb->result == FB_PENDING) {
+		assert(wl_display_dispatch(fb->client->wl_display) >= 0);
+	}
+}
+
+static char *
+pflags_to_str(uint32_t flags, char *str, unsigned len)
+{
+	static const struct {
+		uint32_t flag;
+		char sym;
+	} desc[] = {
+	};
+	unsigned i;
+
+	*str = '\0';
+	if (len < ARRAY_LENGTH(desc) + 1)
+		return str;
+
+	for (i = 0; i < ARRAY_LENGTH(desc); i++)
+		str[i] = flags & desc[i].flag ? desc[i].sym : '_';
+	str[ARRAY_LENGTH(desc)] = '\0';
+
+	return str;
+}
+
+static void
+feedback_print(struct feedback *fb)
+{
+	char str[10];
+
+	switch (fb->result) {
+	case FB_PENDING:
+		printf("pending");
+		return;
+	case FB_DISCARDED:
+		printf("discarded");
+		return;
+	case FB_PRESENTED:
+		break;
+	}
+
+	pflags_to_str(fb->flags, str, sizeof str);
+	printf("presented %lld.%09lld, refresh %u us, [%s] seq %" PRIu64,
+		(long long)fb->time.tv_sec, (long long)fb->time.tv_nsec,
+		fb->refresh_nsec / 1000, str, fb->seq);
+}
+
+static void
+feedback_destroy(struct feedback *fb)
+{
+	presentation_feedback_destroy(fb->obj);
+	free(fb);
+}
+
+TEST(test_presentation_feedback_simple)
+{
+	struct client *client;
+	struct feedback *fb;
+
+	client = client_create(100, 50, 123, 77);
+	assert(client);
+
+	wl_surface_attach(client->surface->wl_surface,
+			  client->surface->wl_buffer, 0, 0);
+	fb = feedback_create(client, client->surface->wl_surface);
+	wl_surface_damage(client->surface->wl_surface, 0, 0, 100, 100);
+	wl_surface_commit(client->surface->wl_surface);
+
+	client_roundtrip(client);
+
+	feedback_wait(fb);
+
+	printf("%s feedback:", __func__);
+	feedback_print(fb);
+	printf("\n");
+
+	feedback_destroy(fb);
+}
-- 
1.9.3



More information about the wayland-devel mailing list