gsk: Allow diffing code to abort

Now the vfuncs can decide they don't want to diff anymore, not just the
actual diff function.
This commit is contained in:
Benjamin Otte 2021-12-20 16:50:55 +01:00
parent 4b3247576a
commit 4e6ee28bcb
3 changed files with 29 additions and 21 deletions

View File

@ -356,6 +356,8 @@ compare (gconstpointer *elem1,
const GskDiffSettings *settings, const GskDiffSettings *settings,
gpointer data) gpointer data)
{ {
GskDiffResult res;
/* /*
* Shrink the box by walking through each diagonal snake (SW and NE). * 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) if (settings->compare_func (elem1[off1], elem2[off2], data) != 0)
break; 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--) 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) if (settings->compare_func (elem1[lim1 - 1], elem2[lim2 - 1], data) != 0)
break; 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++) 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) else if (off2 == lim2)
{ {
for (; off1 < lim1; off1++) 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 else
{ {
SplitResult spl = { 0, }; SplitResult spl = { 0, };
GskDiffResult res;
/* /*
* Divide ... * Divide ...

View File

@ -29,9 +29,9 @@ typedef enum {
GSK_DIFF_ABORTED, GSK_DIFF_ABORTED,
} GskDiffResult; } GskDiffResult;
typedef void (* GskKeepFunc) (gconstpointer elem1, gconstpointer elem2, gpointer data); typedef GskDiffResult (* GskKeepFunc) (gconstpointer elem1, gconstpointer elem2, gpointer data);
typedef void (* GskDeleteFunc) (gconstpointer elem, gsize idx, gpointer data); typedef GskDiffResult (* GskDeleteFunc) (gconstpointer elem, gsize idx, gpointer data);
typedef void (* GskInsertFunc) (gconstpointer elem, gsize idx, gpointer data); typedef GskDiffResult (* GskInsertFunc) (gconstpointer elem, gsize idx, gpointer data);
typedef struct _GskDiffSettings GskDiffSettings; typedef struct _GskDiffSettings GskDiffSettings;

View 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 static int
gsk_container_node_compare_func (gconstpointer elem1, gconstpointer elem2, gpointer data) 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; 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_container_node_keep_func (gconstpointer elem1, gconstpointer elem2, gpointer data)
{ {
gsk_render_node_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, 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_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 * static GskDiffSettings *