From d8a4e292859599f57544552cb9c70cb7d6dcbf9c Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 13 Feb 2021 18:26:24 +0000 Subject: [PATCH] reftest_compare_surfaces: Report how much the images differ In unattended/non-interactive/autobuilder environments where the images are not trivially accessible, this provides a way to distinguish between totally different rendering and more subtle issues. Signed-off-by: Simon McVittie Forwarded: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3195 Applied-upstream: no, upstream want reftests to be a strict pass/fail with identical results required Gbp-Pq: Name reftest_compare_surfaces-Report-how-much-the-images-diffe.patch --- testsuite/gsk/compare-render.c | 10 +++++++++- testsuite/reftests/gtk-reftest.c | 9 ++++++++- testsuite/reftests/reftest-compare.c | 28 +++++++++++++++++++++++++--- testsuite/reftests/reftest-compare.h | 5 ++++- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/testsuite/gsk/compare-render.c b/testsuite/gsk/compare-render.c index a62252ab35..9742358b5b 100644 --- a/testsuite/gsk/compare-render.c +++ b/testsuite/gsk/compare-render.c @@ -236,11 +236,19 @@ main (int argc, char **argv) } else { + guint max_diff = 0; + guint pixels_changed = 0; + guint pixels = 0; + /* Now compare the two */ - diff_surface = reftest_compare_surfaces (rendered_surface, reference_surface); + diff_surface = reftest_compare_surfaces (rendered_surface, reference_surface, + &max_diff, &pixels_changed, &pixels); if (diff_surface) { + g_print ("%u (out of %u) pixels differ from reference by up to %u levels\n", + pixels_changed, pixels, max_diff); + save_image (diff_surface, node_file, ".diff.png"); cairo_surface_destroy (diff_surface); success = FALSE; diff --git a/testsuite/reftests/gtk-reftest.c b/testsuite/reftests/gtk-reftest.c index cd153969a8..3ae54133bb 100644 --- a/testsuite/reftests/gtk-reftest.c +++ b/testsuite/reftests/gtk-reftest.c @@ -298,6 +298,9 @@ test_ui_file (GFile *file) char *ui_file, *reference_file; cairo_surface_t *ui_image, *reference_image, *diff_image; GtkStyleProvider *provider; + guint max_diff = 0; + guint pixels_changed = 0; + guint pixels = 0; ui_file = g_file_get_path (file); @@ -317,12 +320,16 @@ test_ui_file (GFile *file) } g_free (reference_file); - diff_image = reftest_compare_surfaces (ui_image, reference_image); + diff_image = reftest_compare_surfaces (ui_image, reference_image, + &max_diff, &pixels_changed, &pixels); save_image (ui_image, ui_file, ".out.png"); save_image (reference_image, ui_file, ".ref.png"); + if (diff_image) { + g_test_message ("%u (out of %u) pixels differ from reference by up to %u levels", + pixels_changed, pixels, max_diff); save_image (diff_image, ui_file, ".diff.png"); cairo_surface_destroy (diff_image); g_test_fail (); diff --git a/testsuite/reftests/reftest-compare.c b/testsuite/reftests/reftest-compare.c index 5bccb697b8..ac72c61c04 100644 --- a/testsuite/reftests/reftest-compare.c +++ b/testsuite/reftests/reftest-compare.c @@ -83,12 +83,16 @@ buffer_diff_core (const guchar *buf_a, const guchar *buf_b, int stride_b, int width, - int height) + int height, + guint *max_diff_out, + guint *pixels_changed_out) { int x, y; guchar *buf_diff = NULL; int stride_diff = 0; cairo_surface_t *diff = NULL; + guint max_diff = 0; + guint pixels_changed = 0; for (y = 0; y < height; y++) { @@ -129,6 +133,10 @@ buffer_diff_core (const guchar *buf_a, guint channel_diff; channel_diff = ABS (value_a - value_b); + + if (channel_diff > max_diff) + max_diff = channel_diff; + channel_diff *= 4; /* emphasize */ if (channel_diff) channel_diff += 128; /* make sure it's visible */ @@ -137,6 +145,8 @@ buffer_diff_core (const guchar *buf_a, diff_pixel |= channel_diff << (channel * 8); } + pixels_changed++; + if ((diff_pixel & 0x00ffffff) == 0) { /* alpha only difference, convert to luminance */ @@ -148,12 +158,21 @@ buffer_diff_core (const guchar *buf_a, } } + if (max_diff_out != NULL) + *max_diff_out = max_diff; + + if (pixels_changed_out != NULL) + *pixels_changed_out = pixels_changed; + return diff; } cairo_surface_t * reftest_compare_surfaces (cairo_surface_t *surface1, - cairo_surface_t *surface2) + cairo_surface_t *surface2, + guint *max_diff_out, + guint *pixels_changed_out, + guint *pixels_out) { int w1, h1, w2, h2, w, h; cairo_surface_t *coerced1, *coerced2, *diff; @@ -169,11 +188,14 @@ reftest_compare_surfaces (cairo_surface_t *surface1, cairo_image_surface_get_stride (coerced1), cairo_image_surface_get_data (coerced2), cairo_image_surface_get_stride (coerced2), - w, h); + w, h, max_diff_out, pixels_changed_out); cairo_surface_destroy (coerced1); cairo_surface_destroy (coerced2); + if (pixels_out != NULL) + *pixels_out = w * h; + return diff; } diff --git a/testsuite/reftests/reftest-compare.h b/testsuite/reftests/reftest-compare.h index 551b1c5a92..c6e001c505 100644 --- a/testsuite/reftests/reftest-compare.h +++ b/testsuite/reftests/reftest-compare.h @@ -24,7 +24,10 @@ G_BEGIN_DECLS G_MODULE_EXPORT cairo_surface_t * reftest_compare_surfaces (cairo_surface_t *surface1, - cairo_surface_t *surface2); + cairo_surface_t *surface2, + guint *max_diff_out, + guint *pixels_changed_out, + guint *pixels_out); G_END_DECLS -- 2.30.2