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

Signed-off-by: Bryce Harrington <[email protected]>
---
 tests/weston-test-client-helper.c | 116 ++++++++++++++++++++++++++++++++++++++
 tests/weston-test-client-helper.h |  15 +++++
 2 files changed, 131 insertions(+)

diff --git a/tests/weston-test-client-helper.c 
b/tests/weston-test-client-helper.c
index 080bb62..04b77d5 100644
--- a/tests/weston-test-client-helper.c
+++ b/tests/weston-test-client-helper.c
@@ -32,6 +32,10 @@
 #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 +865,115 @@ 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, const struct surface *b)
+{
+       int y;
+       void *p, *q;
+
+       if (a == NULL || b == NULL)
+               return false;
+       if (a->width != b->width || a->height != a->height)
+               return false;
+
+       if (a->stride == b->stride) {
+               printf("Checking data for equivalent strides\n");
+               return (memcmp(a->data, b->data, a->stride * a->height) == 0);
+       } else {
+               printf("Manually comparing due to differing strides\n");
+               for (y = 0; y < a->height; y++) {
+                       p = a->data + (y * a->stride);
+                       q = b->data + (y * b->stride);
+                       if (memcmp(p, q, a->stride) != 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, const struct surface *b, 
const struct rectangle *clip_rect)
+{
+       int i, j;
+       int a_bpp, b_bpp;
+       int x0, y0, x1, y1;
+       void *p, *q;
+       char a_char, b_char;
+
+       if (a == NULL || b == NULL || clip_rect == NULL)
+               return false;
+
+       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");
+       a_bpp = a->stride / a->width;
+       b_bpp = b->stride / b->width;
+       for (i=y0; i<y1; i++) {
+               p = a->data + i * a->stride + x0 * a_bpp;
+               q = b->data + i * b->stride + x0 * b_bpp;
+               if (a->stride == b->stride) {
+                       if (memcmp(p, q, (x1-x0)*a_bpp) != 0) {
+                               // Dump the bad row
+                               printf("Mismatched image on row %d\n", i);
+                               for (j=0; j<(x1-x0)*a_bpp; j++) {
+                                       a_char = *((char*)(p+j*a_bpp));
+                                       b_char = *((char*)(q+j*b_bpp));
+                                       printf("%d,%d: %8x %8x %s\n", i, j, 
a_char, b_char,
+                                              (a_char != b_char)? " <---": "");
+                               }
+                               return false;
+                       }
+               } else {
+                       /* account for bpp differences */
+                       for (j=0; j<x1-x0; j++) {
+                               a_char = *((char*)(p+j*a_bpp));
+                               b_char = *((char*)(q+j*b_bpp));
+                               if (a_char != b_char) {
+                                       printf("%d,%d: %8x %8x %s\n", i, j, 
a_char, b_char,
+                                              (a_char != b_char)? " <---": "");
+                                       return false;
+                               }
+                       }
+               }
+       }
+
+       return true;
+}
diff --git a/tests/weston-test-client-helper.h 
b/tests/weston-test-client-helper.h
index 43a5aa7..8cbd4ba 100644
--- a/tests/weston-test-client-helper.h
+++ b/tests/weston-test-client-helper.h
@@ -27,6 +27,7 @@
 
 #include <assert.h>
 #include <stdbool.h>
+
 #include "weston-test-runner.h"
 #include "weston-test-client-protocol.h"
 
@@ -129,9 +130,17 @@ struct surface {
        int y;
        int width;
        int height;
+       int stride;
        void *data;
 };
 
+struct rectangle {
+       int x;
+       int y;
+       int width;
+       int height;
+};
+
 void *
 fail_on_null(void *p);
 
@@ -190,4 +199,10 @@ screenshot_output_filename(const char *basename, uint32_t 
seq);
 char*
 screenshot_reference_filename(const char *basename, uint32_t seq);
 
+bool
+check_surfaces_equal(const struct surface *a, const struct surface *b);
+
+bool
+check_surfaces_match_in_clip(const struct surface *a, const struct surface *b, 
const struct rectangle *clip);
+
 #endif
-- 
1.9.1

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to