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 <br...@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 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel