gsk: Allow diffing code to abort
authorBenjamin Otte <otte@redhat.com>
Mon, 20 Dec 2021 15:50:55 +0000 (16:50 +0100)
committerBenjamin Otte <otte@redhat.com>
Mon, 20 Dec 2021 16:08:15 +0000 (17:08 +0100)
Now the vfuncs can decide they don't want to diff anymore, not just the
actual diff function.

gsk/gskdiff.c
gsk/gskdiffprivate.h
gsk/gskrendernodeimpl.c

index cd2aa917b8610f72a51c3f31ef9decc5fa4b0278..dd2057e042981d26cac6c4536d2288fa92e471e5 100644 (file)
@@ -356,6 +356,8 @@ compare (gconstpointer             *elem1,
          const GskDiffSettings     *settings,
          gpointer                   data)
 {
+  GskDiffResult res;
+
   /*
    * Shrink the box by walking through each diagonal snake (SW and NE).
    */
@@ -364,7 +366,9 @@ compare (gconstpointer             *elem1,
       if (settings->compare_func (elem1[off1], elem2[off2], data) != 0)
         break;
 
-      settings->keep_func (elem1[off1], elem2[off2], data);
+      res = settings->keep_func (elem1[off1], elem2[off2], data);
+      if (res != GSK_DIFF_OK)
+        return res;
     }
 
   for (; off1 < lim1 && off2 < lim2; lim1--, lim2--)
@@ -372,7 +376,9 @@ compare (gconstpointer             *elem1,
       if (settings->compare_func (elem1[lim1 - 1], elem2[lim2 - 1], data) != 0)
         break;
 
-      settings->keep_func (elem1[lim1 - 1], elem2[lim2 - 1], data);
+      res = settings->keep_func (elem1[lim1 - 1], elem2[lim2 - 1], data);
+      if (res != GSK_DIFF_OK)
+        return res;
     }
 
   /*
@@ -383,20 +389,23 @@ compare (gconstpointer             *elem1,
     {
       for (; off2 < lim2; off2++)
         {
-          settings->insert_func (elem2[off2], off2, data);
+          res = settings->insert_func (elem2[off2], off2, data);
+          if (res != GSK_DIFF_OK)
+            return res;
         }
     }
   else if (off2 == lim2)
     {
       for (; off1 < lim1; off1++)
         {
-          settings->delete_func (elem1[off1], off1, data);
+          res = settings->delete_func (elem1[off1], off1, data);
+          if (res != GSK_DIFF_OK)
+            return res;
         }
     }
   else
     {
       SplitResult spl = { 0, };
-      GskDiffResult res;
 
       /*
        * Divide ...
index 9401ad85b22e94528f6fb7ffaf56ed9d925d6215..6c1c67664a3cd092175ca70813f805f0e080ce37 100644 (file)
@@ -29,9 +29,9 @@ typedef enum {
   GSK_DIFF_ABORTED,
 } GskDiffResult;
 
-typedef void (* GskKeepFunc)   (gconstpointer elem1, gconstpointer elem2, gpointer data);
-typedef void (* GskDeleteFunc) (gconstpointer elem, gsize idx, gpointer data);
-typedef void (* GskInsertFunc) (gconstpointer elem, gsize idx, gpointer data);
+typedef GskDiffResult (* GskKeepFunc)   (gconstpointer elem1, gconstpointer elem2, gpointer data);
+typedef GskDiffResult (* GskDeleteFunc) (gconstpointer elem, gsize idx, gpointer data);
+typedef GskDiffResult (* GskInsertFunc) (gconstpointer elem, gsize idx, gpointer data);
 
 typedef struct _GskDiffSettings GskDiffSettings;
 
index 207e3e68de02745a5e8c072a8f96ebc2e5d98f8c..24bf09baac5dc2998892764f660fa56db1063a1a 100644 (file)
@@ -2601,32 +2601,31 @@ gsk_container_node_draw (GskRenderNode *node,
     }
 }
 
-static void
-gsk_render_node_add_to_region (GskRenderNode  *node,
-                               cairo_region_t *region)
-{
-  cairo_rectangle_int_t rect;
-
-  rectangle_init_from_graphene (&rect, &node->bounds);
-  cairo_region_union_rectangle (region, &rect);
-}
-
 static int
 gsk_container_node_compare_func (gconstpointer elem1, gconstpointer elem2, gpointer data)
 {
   return gsk_render_node_can_diff ((const GskRenderNode *) elem1, (const GskRenderNode *) elem2) ? 0 : 1;
 }
 
-static void
+static GskDiffResult
 gsk_container_node_keep_func (gconstpointer elem1, gconstpointer elem2, gpointer data)
 {
   gsk_render_node_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, data);
+
+  return GSK_DIFF_OK;
 }
 
-static void
+static GskDiffResult
 gsk_container_node_change_func (gconstpointer elem, gsize idx, gpointer data)
 {
-  gsk_render_node_add_to_region ((GskRenderNode *) elem, data);
+  const GskRenderNode *node = elem;
+  cairo_region_t *region = data;
+  cairo_rectangle_int_t rect;
+
+  rectangle_init_from_graphene (&rect, &node->bounds);
+  cairo_region_union_rectangle (region, &rect);
+
+  return GSK_DIFF_OK;
 }
 
 static GskDiffSettings *