[PATCH weston 04/10] tests: Add surface checks

Bryce Harrington bryce at osg.samsung.com
Wed May 6 17:44:23 PDT 2015


Introduce helper routines for testing surfaces against specific
conditions.  These allow tests to validate screen captures as displaying
the correct rendering results.

Since these routines operate on cairo surfaces, all tests need linked
against Cairo.

Signed-off-by: Bryce Harrington <bryce at osg.samsung.com>
---
 Makefile.am                       | 51 +++++++++++----------
 tests/weston-test-client-helper.c | 96 +++++++++++++++++++++++++++++++++++++++
 tests/weston-test-client-helper.h | 19 +++++++-
 3 files changed, 139 insertions(+), 27 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 2f16fac..1ba273b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -39,7 +39,7 @@ tests/weston-ivi.ini : $(srcdir)/ivi-shell/weston.ini.in
 
 all-local : weston.ini ivi-shell/weston.ini
 
-AM_CFLAGS = $(GCC_CFLAGS)
+AM_CFLAGS = $(GCC_CFLAGS)  $(CAIRO_CFLAGS)
 
 AM_CPPFLAGS = 					\
 	-I$(top_srcdir)/src			\
@@ -987,6 +987,7 @@ noinst_LTLIBRARIES +=			\
 
 noinst_PROGRAMS +=			\
 	$(setbacklight)			\
+	$(internal_tests)		\
 	$(shared_tests)			\
 	$(weston_tests)			\
 	$(ivi_tests)			\
@@ -1040,59 +1041,59 @@ libtest_client_la_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
 libtest_client_la_LIBADD = $(TEST_CLIENT_LIBS) libshared.la libtest-runner.la
 
 bad_buffer_weston_SOURCES = tests/bad-buffer-test.c
-bad_buffer_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
-bad_buffer_weston_LDADD = libtest-client.la
+bad_buffer_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS) $(CAIRO_CFLAGS)
+bad_buffer_weston_LDADD = libtest-client.la $(CAIRO_LIBS)
 
 keyboard_weston_SOURCES = tests/keyboard-test.c
-keyboard_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
-keyboard_weston_LDADD = libtest-client.la
+keyboard_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS) $(CAIRO_CFLAGS)
+keyboard_weston_LDADD = libtest-client.la $(CAIRO_LIBS)
 
 event_weston_SOURCES = tests/event-test.c
-event_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
-event_weston_LDADD = libtest-client.la
+event_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS) $(CAIRO_CFLAGS)
+event_weston_LDADD = libtest-client.la $(CAIRO_LIBS)
 
 button_weston_SOURCES = tests/button-test.c
-button_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
-button_weston_LDADD = libtest-client.la
+button_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS) $(CAIRO_CFLAGS)
+button_weston_LDADD = libtest-client.la $(CAIRO_LIBS)
 
 devices_weston_SOURCES = tests/devices-test.c
-devices_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
-devices_weston_LDADD = libtest-client.la
+devices_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS) $(CAIRO_CFLAGS)
+devices_weston_LDADD = libtest-client.la $(CAIRO_LIBS)
 
 text_weston_SOURCES = tests/text-test.c
 nodist_text_weston_SOURCES =			\
 	protocol/text-protocol.c		\
 	protocol/text-client-protocol.h
-text_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
-text_weston_LDADD = libtest-client.la
+text_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS) $(CAIRO_CFLAGS)
+text_weston_LDADD = libtest-client.la $(CAIRO_LIBS)
 
 subsurface_weston_SOURCES = tests/subsurface-test.c
-subsurface_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
-subsurface_weston_LDADD = libtest-client.la
+subsurface_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS) $(CAIRO_CFLAGS)
+subsurface_weston_LDADD = libtest-client.la $(CAIRO_LIBS)
 
 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
+presentation_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS) $(CAIRO_CFLAGS)
+presentation_weston_LDADD = libtest-client.la $(CAIRO_LIBS)
 
 roles_weston_SOURCES = tests/roles-test.c
-roles_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
-roles_weston_LDADD = libtest-client.la
+roles_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS) $(CAIRO_CFLAGS)
+roles_weston_LDADD = libtest-client.la $(CAIRO_LIBS)
 
 if ENABLE_EGL
 weston_tests += buffer-count.weston
 buffer_count_weston_SOURCES = tests/buffer-count-test.c
-buffer_count_weston_CFLAGS = $(GCC_CFLAGS) $(EGL_TESTS_CFLAGS)
-buffer_count_weston_LDADD = libtest-client.la $(EGL_TESTS_LIBS)
+buffer_count_weston_CFLAGS = $(GCC_CFLAGS) $(EGL_TESTS_CFLAGS) $(CAIRO_CFLAGS)
+buffer_count_weston_LDADD = libtest-client.la $(EGL_TESTS_LIBS) $(CAIRO_LIBS)
 endif
 
 if ENABLE_XWAYLAND_TEST
 weston_tests +=	xwayland-test.weston
 xwayland_test_weston_SOURCES = tests/xwayland-test.c
-xwayland_test_weston_CFLAGS = $(GCC_CFLAGS) $(XWAYLAND_TEST_CFLAGS)
-xwayland_test_weston_LDADD = libtest-client.la $(XWAYLAND_TEST_LIBS)
+xwayland_test_weston_CFLAGS = $(GCC_CFLAGS) $(XWAYLAND_TEST_CFLAGS) $(CAIRO_CFLAGS)
+xwayland_test_weston_LDADD = libtest-client.la $(XWAYLAND_TEST_LIBS) $(CAIRO_LIBS)
 endif
 
 matrix_test_SOURCES =				\
@@ -1131,7 +1132,7 @@ nodist_ivi_shell_app_weston_SOURCES =		\
 	protocol/ivi-application-protocol.c	\
 	protocol/ivi-application-client-protocol.h
 ivi_shell_app_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
-ivi_shell_app_weston_LDADD = libtest-client.la
+ivi_shell_app_weston_LDADD = libtest-client.la $(CAIRO_LIBS)
 
 noinst_PROGRAMS += ivi-layout.ivi
 
@@ -1142,7 +1143,7 @@ nodist_ivi_layout_ivi_SOURCES = 		\
 	protocol/ivi-application-protocol.c	\
 	protocol/ivi-application-client-protocol.h
 ivi_layout_ivi_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS)
-ivi_layout_ivi_LDADD = libtest-client.la
+ivi_layout_ivi_LDADD = libtest-client.la $(CAIRO_LIBS)
 endif
 
 if BUILD_SETBACKLIGHT
diff --git a/tests/weston-test-client-helper.c b/tests/weston-test-client-helper.c
index 54b6c95..017338d 100644
--- a/tests/weston-test-client-helper.c
+++ b/tests/weston-test-client-helper.c
@@ -28,10 +28,15 @@
 #include <unistd.h>
 #include <errno.h>
 #include <sys/mman.h>
+#include <cairo.h>
 
 #include "../shared/os-compatibility.h"
 #include "weston-test-client-helper.h"
 
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+#define min(a, b) (((a) > (b)) ? (b) : (a))
+#define clip(x, a, b)  min(max(x, a), b)
+
 void *
 fail_on_null(void *p)
 {
@@ -861,3 +866,94 @@ screenshot_reference_filename(const char* basename, uint32_t seq) {
 		return NULL;
 	return filename;
 }
+
+/**
+ * check_surfaces_equal() - tests if two surfaces are pixel-identical
+ *
+ * Returns true if surface buffers have all the same byte values,
+ * false if the surfaces don't match or can't be compared due to
+ * different dimensions.
+ */
+bool
+check_surfaces_equal(const struct surface *a, cairo_surface_t *b)
+{
+	if (a == NULL || b == NULL)
+		return false;
+	if (a->width != cairo_image_surface_get_width(b) ||
+	    a->height != cairo_image_surface_get_height(b))
+		return false;
+
+	if (memcmp(a->data, cairo_image_surface_get_data(b), a->width * a->height) != 0)
+		return false;
+
+	return true;
+}
+
+/**
+ * check_surfaces_match_in_clip() - tests if a given region within two
+ * surfaces are pixel-identical.
+ *
+ * Returns true if the two surfaces have the same byte values within the
+ * given clipping region, or false if they don't match or the surfaces
+ * can't be compared.
+ */
+bool
+check_surfaces_match_in_clip(const struct surface *a, cairo_surface_t *b, const struct rectangle *clip_rect)
+{
+	int i, x0, y0, x1, y1;
+	int a_width, a_height, b_width, b_height;
+	void *p, *q, *a_data, *b_data;
+	int j;
+
+	if (a == NULL || b == NULL || clip_rect == NULL)
+		return false;
+
+	a_width = a->width;
+	a_height = a->height;
+	b_width = cairo_image_surface_get_width(b);
+	b_height = cairo_image_surface_get_height(b);
+	a_data = a->data;
+	b_data = cairo_image_surface_get_data(b);
+
+	if (a_data == NULL || b_data == NULL) {
+		printf("Undefined data\n");
+		return false;
+	}
+	if (a_width != b_width || a_height != b_height) {
+		printf("Mismatched dimensions:  %d,%d != %d,%d\n",
+		       a_width, a_height, b_width, b_height);
+		return false;
+	}
+	if (clip_rect->x > a->width || clip_rect->y > a->height) {
+		printf("Clip outside image boundaries\n");
+		return true;
+	}
+
+	x0 = max(0, clip_rect->x);
+	y0 = max(0, clip_rect->y);
+	x1 = min(a->width,  clip_rect->x + clip_rect->width);
+	y1 = min(a->height, clip_rect->y + clip_rect->height);
+
+	if (x0 == x1 || y0 == y1) {
+		printf("Degenerate comparison\n");
+		return true;
+	}
+
+	printf("Bytewise comparison inside clip\n");
+	for (i=y0; i<y1; i++) {
+		p = a_data + i * a_width + x0;
+		q = b_data + i * b_width + x0;
+
+		if (memcmp(p, q, x1-x0) != 0) {
+			// Dump the bad row
+			printf("Mismatched image on row %d\n", i);
+			for (j=0; j<x1-x0; j++) {
+				printf("%d,%d: %8x %8x %s\n", i, j, *((char*)(p+j)), *((char*)(q+j)),
+				       (*((char*)(p+j)) != *((char*)(q+j)))? " <---": "");
+			}
+			return false;
+		}
+	}
+
+	return true;
+}
diff --git a/tests/weston-test-client-helper.h b/tests/weston-test-client-helper.h
index 0378804..9732b9f 100644
--- a/tests/weston-test-client-helper.h
+++ b/tests/weston-test-client-helper.h
@@ -27,6 +27,8 @@
 
 #include <assert.h>
 #include <stdbool.h>
+#include <cairo.h>
+
 #include "weston-test-runner.h"
 #include "weston-test-client-protocol.h"
 
@@ -132,6 +134,13 @@ struct surface {
 	void *data;
 };
 
+struct rectangle {
+	int x;
+	int y;
+	int width;
+	int height;
+};
+
 void *
 fail_on_null(void *p);
 
@@ -185,9 +194,15 @@ expect_protocol_error(struct client *client,
 		      const struct wl_interface *intf, uint32_t code);
 
 char*
-screenshot_output_filename(const char* basename, uint32_t seq);
+screenshot_output_filename(const char *basename, uint32_t seq);
 
 char*
-screenshot_reference_filename(const char* basename, uint32_t seq);
+screenshot_reference_filename(const char *basename, uint32_t seq);
+
+bool
+check_surfaces_equal(const struct surface *a, cairo_surface_t *b);
+
+bool
+check_surfaces_match_in_clip(const struct surface *a, cairo_surface_t *b, const struct rectangle *clip);
 
 #endif
-- 
1.9.1



More information about the wayland-devel mailing list