reftest_compare_surfaces: Report how much the images differ
authorSimon McVittie <smcv@debian.org>
Sat, 13 Feb 2021 18:26:24 +0000 (18:26 +0000)
committerSimon McVittie <smcv@debian.org>
Wed, 8 Nov 2023 16:30:21 +0000 (16:30 +0000)
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 <smcv@debian.org>
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/reftests/gtk-reftest.c
testsuite/reftests/reftest-compare.c
testsuite/reftests/reftest-compare.h

index 1a51a9756bdf826aee16e4c97b416f68452cc989..5b3d21aee82fe27faedb4aaf524136cc44f714cd 100644 (file)
@@ -266,6 +266,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);
 
@@ -285,12 +288,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");
       g_test_fail ();
     }
index 84c560cabc0e90b7cb1e3a014d226055e4513396..33379eb6657851d6767ac37697d4520d91d10350 100644 (file)
@@ -84,12 +84,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++)
     {
@@ -125,6 +129,10 @@ buffer_diff_core (const guchar *buf_a,
               guint diff;
 
               diff = ABS (value_a - value_b);
+
+              if (diff > max_diff)
+                max_diff = diff;
+
               diff *= 4;  /* emphasize */
               if (diff)
                 diff += 128; /* make sure it's visible */
@@ -133,6 +141,8 @@ buffer_diff_core (const guchar *buf_a,
               diff_pixel |= diff << (channel*8);
             }
 
+          pixels_changed++;
+
           if ((diff_pixel & 0x00ffffff) == 0)
             {
               /* alpha only difference, convert to luminance */
@@ -144,12 +154,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 *diff;
@@ -165,7 +184,10 @@ reftest_compare_surfaces (cairo_surface_t *surface1,
                            cairo_image_surface_get_stride (surface1),
                            cairo_image_surface_get_data (surface2),
                            cairo_image_surface_get_stride (surface2),
-                           w, h);
+                           w, h, max_diff_out, pixels_changed_out);
+
+  if (pixels_out != NULL)
+    *pixels_out = w * h;
 
   return diff;
 }
index 551b1c5a9291002a396b2049bede8aef44df9b0e..c6e001c505ba6f126c76f4c3f8621189cd2cbf2c 100644 (file)
@@ -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