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, 4 May 2022 10:30:16 +0000 (11:30 +0100)
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/gsk/compare-render.c
testsuite/reftests/gtk-reftest.c
testsuite/reftests/reftest-compare.c
testsuite/reftests/reftest-compare.h

index 919957e70d7d0098a7a9fe64c081177e33c2b047..71453631f7c2f941a972f4dccbd2b00418da15bf 100644 (file)
@@ -227,12 +227,19 @@ main (int argc, char **argv)
   else
     {
       GdkTexture *diff_texture;
+      guint max_diff = 0;
+      guint pixels_changed = 0;
+      guint pixels = 0;
 
       /* Now compare the two */
-      diff_texture = reftest_compare_textures (rendered_texture, reference_texture);
+      diff_texture = reftest_compare_textures (rendered_texture, reference_texture,
+                                               &max_diff, &pixels_changed, &pixels);
 
       if (diff_texture)
         {
+          g_print ("%u (out of %u) pixels differ from reference by up to %u levels\n",
+                   pixels_changed, pixels, max_diff);
+
           save_image (diff_texture, node_file, ".diff.png");
           g_object_unref (diff_texture);
           success = FALSE;
index 4d3d57db4a9ff43417b00627b51c92a766e1985e..5136efafa743cd3ba5584f8861e63aea301b2391 100644 (file)
@@ -331,6 +331,9 @@ test_ui_file (GFile *file)
   char *ui_file, *reference_file;
   GdkTexture *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);
 
@@ -362,12 +365,16 @@ test_ui_file (GFile *file)
   if (reference_image == NULL)
     reference_image = gdk_memory_texture_new (1, 1, GDK_MEMORY_DEFAULT, g_bytes_new ((guchar[4]) {0, 0, 0, 0}, 4), 4);
 
-  diff_image = reftest_compare_textures (ui_image, reference_image);
+  diff_image = reftest_compare_textures (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_node (g_object_get_data (G_OBJECT (ui_image), "source-render-node"), ui_file, ".out.node");
       save_node (g_object_get_data (G_OBJECT (reference_image), "source-render-node"), ui_file, ".ref.node");
       save_image (diff_image, ui_file, ".diff.png");
index bb6c6ebc1a6f411bd8ee5fb2d18e26c3623970cf..202fcf53ad22a27e409dee1add5191ef81e2efa3 100644 (file)
@@ -35,12 +35,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;
   GdkTexture *diff = NULL;
+  guint max_diff = 0;
+  guint pixels_changed = 0;
 
   for (y = 0; y < height; y++)
     {
@@ -84,6 +88,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 */
@@ -92,6 +100,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 */
@@ -105,12 +115,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;
 }
 
 GdkTexture *
 reftest_compare_textures (GdkTexture *texture1,
-                          GdkTexture *texture2)
+                          GdkTexture *texture2,
+                          guint      *max_diff_out,
+                          guint      *pixels_changed_out,
+                          guint      *pixels_out)
 {
   int w, h;
   guchar *data1, *data2;
@@ -126,10 +145,13 @@ reftest_compare_textures (GdkTexture *texture1,
 
   diff = buffer_diff_core (data1, w * 4,
                            data2, w * 4,
-                           w, h);
+                           w, h, max_diff_out, pixels_changed_out);
 
   g_free (data1);
   g_free (data2);
 
+  if (pixels_out != NULL)
+    *pixels_out = w * h;
+
   return diff;
 }
index d5e02a1a7dd4619ffc0301f647c14a6d9877bd94..b71636e27c86ec6d30a10644ba34783d637ad948 100644 (file)
@@ -24,7 +24,10 @@ G_BEGIN_DECLS
 
 G_MODULE_EXPORT
 GdkTexture *            reftest_compare_textures        (GdkTexture             *texture1,
-                                                         GdkTexture             *texture2);
+                                                         GdkTexture             *texture2,
+                                                         guint                  *max_diff_out,
+                                                         guint                  *pixels_changed_out,
+                                                         guint                  *pixels_out);
 
 G_END_DECLS