[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