tests: print image difference statistics
authorPekka Paalanen <pekka.paalanen@collabora.com>
Thu, 5 Mar 2020 14:11:33 +0000 (16:11 +0200)
committerDaniel Stone <daniel@fooishbar.org>
Tue, 10 Mar 2020 13:40:00 +0000 (13:40 +0000)
When a test fails and it produces a difference image, also compute the min/max
per-channel signed difference statistics. These numbers can be used to adjust
the fuzz needed for fuzzy_match_pixels() to pass. Otherwise one would have to
manually inspect the reference and result images and figure out the values.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
tests/weston-test-client-helper.c

index 6e270d379c24d5624e27849ff400bddbe8f723ce..f5f24025baed50a9b338e28d4fb84047f7a8b84c 100644 (file)
@@ -1262,21 +1262,47 @@ image_iter_get_row(struct image_iterator *it, int y)
        return (uint32_t *)(it->data + y * it->stride);
 }
 
+struct pixel_diff_stat {
+       struct pixel_diff_stat_channel {
+               int min_diff;
+               int max_diff;
+       } ch[4];
+};
+
+static void
+testlog_pixel_diff_stat(const struct pixel_diff_stat *stat)
+{
+       int i;
+
+       testlog("Image difference statistics:\n");
+       for (i = 0; i < 4; i++) {
+               testlog("\tch %d: [%d, %d]\n",
+                       i, stat->ch[i].min_diff, stat->ch[i].max_diff);
+       }
+}
+
 static bool
-fuzzy_match_pixels(uint32_t pix_a, uint32_t pix_b, const struct range *fuzz)
+fuzzy_match_pixels(uint32_t pix_a, uint32_t pix_b,
+                  const struct range *fuzz,
+                  struct pixel_diff_stat *stat)
 {
+       bool ret = true;
        int shift;
+       int i;
 
-       for (shift = 0; shift < 32; shift += 8) {
+       for (shift = 0, i = 0; i < 4; shift += 8, i++) {
                int val_a = (pix_a >> shift) & 0xffu;
                int val_b = (pix_b >> shift) & 0xffu;
                int d = val_b - val_a;
 
+               stat->ch[i].min_diff = min(stat->ch[i].min_diff, d);
+               stat->ch[i].max_diff = max(stat->ch[i].max_diff, d);
+
                if (d < fuzz->a || d > fuzz->b)
-                       return false;
+                       ret = false;
        }
 
-       return true;
+       return ret;
 }
 
 /**
@@ -1305,6 +1331,7 @@ check_images_match(pixman_image_t *img_a, pixman_image_t *img_b,
                   const struct rectangle *clip_rect, const struct range *prec)
 {
        struct range fuzz = range_get(prec);
+       struct pixel_diff_stat diffstat = {};
        struct image_iterator it_a;
        struct image_iterator it_b;
        pixman_box32_t box;
@@ -1322,7 +1349,8 @@ check_images_match(pixman_image_t *img_a, pixman_image_t *img_b,
                pix_b = image_iter_get_row(&it_b, y) + box.x1;
 
                for (x = box.x1; x < box.x2; x++) {
-                       if (!fuzzy_match_pixels(*pix_a, *pix_b, &fuzz))
+                       if (!fuzzy_match_pixels(*pix_a, *pix_b,
+                                               &fuzz, &diffstat))
                                return false;
 
                        pix_a++;
@@ -1385,6 +1413,7 @@ visualize_image_difference(pixman_image_t *img_a, pixman_image_t *img_b,
                           const struct range *prec)
 {
        struct range fuzz = range_get(prec);
+       struct pixel_diff_stat diffstat = {};
        pixman_image_t *diffimg;
        pixman_image_t *shade;
        struct image_iterator it_a;
@@ -1427,7 +1456,8 @@ visualize_image_difference(pixman_image_t *img_a, pixman_image_t *img_b,
                pix_d = image_iter_get_row(&it_d, y) + box.x1;
 
                for (x = box.x1; x < box.x2; x++) {
-                       if (fuzzy_match_pixels(*pix_a, *pix_b, &fuzz))
+                       if (fuzzy_match_pixels(*pix_a, *pix_b,
+                                              &fuzz, &diffstat))
                                *pix_d = tint(*pix_d, 0x00008000); /* green */
                        else
                                *pix_d = tint(*pix_d, 0x00c00000); /* red */
@@ -1438,6 +1468,8 @@ visualize_image_difference(pixman_image_t *img_a, pixman_image_t *img_b,
                }
        }
 
+       testlog_pixel_diff_stat(&diffstat);
+
        return diffimg;
 }