From e647ebae87950176738b382434a72749e2874bb6 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 9 Feb 2024 03:03:27 +0100 Subject: [PATCH 1/9] rendernode: Do full diff when starting/stopping offload When a subsurface goes from not offloaded to offloaded (or vice versa), we need to add the whole node to the diff region, because we switch from whatever contents were drawn to a punched hole. --- gsk/gskrendernodeimpl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index ec91dc8f79..e4e096143e 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -6984,11 +6984,17 @@ gsk_subsurface_node_diff (GskRenderNode *node1, info1 = gsk_offload_get_subsurface_info (data->offload, self1->subsurface); info2 = gsk_offload_get_subsurface_info (data->offload, self2->subsurface); - if (!info1 || !info2) + if (!info1 && !info2) { gsk_render_node_data_diff (self1->child, self2->child, data); return; } + else if (!info1 || !info2) + { + gsk_render_node_diff_impossible (node1, node2, data); + return; + } + if (info1->is_offloaded != info2->is_offloaded || info1->is_above != info2->is_above) From 30b5a334448a5f6a7de11b5a790b2b1f3804adfc Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 9 Feb 2024 03:46:50 +0100 Subject: [PATCH 2/9] rendernode: Fix subsurface diff code --- gsk/gskrendernodeimpl.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index e4e096143e..9aa103c5ba 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -6973,41 +6973,46 @@ gsk_subsurface_node_diff (GskRenderNode *node1, { GskSubsurfaceNode *self1 = (GskSubsurfaceNode *) node1; GskSubsurfaceNode *self2 = (GskSubsurfaceNode *) node2; - GskOffloadInfo *info1, *info2; + GskOffloadInfo *info; if (!data->offload) { + /* offloading not supported, so we know the children will be drawn */ gsk_render_node_data_diff (self1->child, self2->child, data); return; } - info1 = gsk_offload_get_subsurface_info (data->offload, self1->subsurface); - info2 = gsk_offload_get_subsurface_info (data->offload, self2->subsurface); - - if (!info1 && !info2) + if (self1->subsurface != self2->subsurface) { + /* different subsurfaces, can't compare */ + gsk_render_node_diff_impossible (node1, node2, data); + return; + } + + info = gsk_offload_get_subsurface_info (data->offload, self1->subsurface); + + if (!info) + { + /* No info, so offloading not supported */ gsk_render_node_data_diff (self1->child, self2->child, data); return; } - else if (!info1 || !info2) - { - gsk_render_node_diff_impossible (node1, node2, data); - return; - } - - if (info1->is_offloaded != info2->is_offloaded || - info1->is_above != info2->is_above) + if (info->is_offloaded != info->was_offloaded || + info->is_above != info->was_above) { + /* state changed between punching hole, drawing, and doing nothing. */ gsk_render_node_diff_impossible (node1, node2, data); } - else if (info1->is_offloaded && !info1->is_above && - !gsk_rect_equal (&info1->rect, &info2->rect)) + else if (info->is_offloaded && !info->is_above && + !gsk_rect_equal (&node1->bounds, &node2->bounds)) { + /* We're punching a hole and it moved */ gsk_render_node_diff_impossible (node1, node2, data); } - else if (!info1->is_offloaded) + else if (!info->is_offloaded) { + /* We aren't offloading and we weren't offloading (see above) */ gsk_render_node_data_diff (self1->child, self2->child, data); } } From e4ca3a285e2159234e2e073ae86d473e6bbcac2f Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 10 Feb 2024 06:31:16 +0100 Subject: [PATCH 3/9] gsk: Split out a function I want to use it elsewhere. I didn't come up with a better name, if anyone knows one, please rename. --- gsk/gskrectprivate.h | 10 ++++++++++ gsk/gskrendernodeimpl.c | 22 ++++++---------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/gsk/gskrectprivate.h b/gsk/gskrectprivate.h index cf062accd6..7fca3a86e6 100644 --- a/gsk/gskrectprivate.h +++ b/gsk/gskrectprivate.h @@ -101,6 +101,16 @@ gsk_rect_to_float (const graphene_rect_t *rect, values[3] = rect->size.height; } +static inline void +gsk_rect_to_cairo_grow (const graphene_rect_t *graphene, + cairo_rectangle_int_t *cairo) +{ + cairo->x = floorf (graphene->origin.x); + cairo->y = floorf (graphene->origin.y); + cairo->width = ceilf (graphene->origin.x + graphene->size.width) - cairo->x; + cairo->height = ceilf (graphene->origin.y + graphene->size.height) - cairo->y; +} + static inline gboolean gsk_rect_equal (const graphene_rect_t *r1, const graphene_rect_t *r2) diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index 9aa103c5ba..04f36bcbc5 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -109,16 +109,6 @@ gsk_cairo_rectangle_pixel_aligned (cairo_t *cr, cairo_restore (cr); } -static void -rectangle_init_from_graphene (cairo_rectangle_int_t *cairo, - const graphene_rect_t *graphene) -{ - cairo->x = floorf (graphene->origin.x); - cairo->y = floorf (graphene->origin.y); - cairo->width = ceilf (graphene->origin.x + graphene->size.width) - cairo->x; - cairo->height = ceilf (graphene->origin.y + graphene->size.height) - cairo->y; -} - static void _graphene_rect_init_from_clip_extents (graphene_rect_t *rect, cairo_t *cr) @@ -2457,7 +2447,7 @@ gsk_inset_shadow_node_draw (GskRenderNode *node, * We could remove the part of "box" where the blur doesn't * reach, but computing that is a bit tricky since the * rounded corners are on the "inside" of it. */ - rectangle_init_from_graphene (&r, &clip_box.bounds); + gsk_rect_to_cairo_grow (&clip_box.bounds, &r); remaining = cairo_region_create_rectangle (&r); /* First do the corners of box */ @@ -3214,7 +3204,7 @@ gsk_container_node_change_func (gconstpointer elem, gsize idx, gpointer data) GskDiffData *gd = data; cairo_rectangle_int_t rect; - rectangle_init_from_graphene (&rect, &node->bounds); + gsk_rect_to_cairo_grow (&node->bounds, &rect); cairo_region_union_rectangle (gd->region, &rect); if (cairo_region_num_rectangles (gd->region) > MAX_RECTS_IN_DIFF) return GSK_DIFF_ABORTED; @@ -4394,7 +4384,7 @@ gsk_clip_node_diff (GskRenderNode *node1, sub = cairo_region_create(); gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload }); - rectangle_init_from_graphene (&clip_rect, &self1->clip); + gsk_rect_to_cairo_grow (&self1->clip, &clip_rect); cairo_region_intersect_rectangle (sub, &clip_rect); cairo_region_union (data->region, sub); cairo_region_destroy (sub); @@ -4542,7 +4532,7 @@ gsk_rounded_clip_node_diff (GskRenderNode *node1, sub = cairo_region_create(); gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload }); - rectangle_init_from_graphene (&clip_rect, &self1->clip.bounds); + gsk_rect_to_cairo_grow (&self1->clip.bounds, &clip_rect); cairo_region_intersect_rectangle (sub, &clip_rect); cairo_region_union (data->region, sub); cairo_region_destroy (sub); @@ -4712,7 +4702,7 @@ gsk_fill_node_diff (GskRenderNode *node1, sub = cairo_region_create(); gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload }); - rectangle_init_from_graphene (&clip_rect, &node1->bounds); + gsk_rect_to_cairo_grow (&node1->bounds, &clip_rect); cairo_region_intersect_rectangle (sub, &clip_rect); cairo_region_union (data->region, sub); cairo_region_destroy (sub); @@ -4916,7 +4906,7 @@ gsk_stroke_node_diff (GskRenderNode *node1, sub = cairo_region_create(); gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload }); - rectangle_init_from_graphene (&clip_rect, &node1->bounds); + gsk_rect_to_cairo_grow (&node1->bounds, &clip_rect); cairo_region_intersect_rectangle (sub, &clip_rect); cairo_region_union (data->region, sub); cairo_region_destroy (sub); From dac56dd7573d7befcbe776a8a519dec57c964bb1 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 10 Feb 2024 06:32:20 +0100 Subject: [PATCH 4/9] offload: Change the way we compute damage regions Instead of relying on diffing subsurface nodes, we track damage generated by offloaded contents inside GskOffload. There are 3 stages a subsurface node can be in: 1. not offloaded Drawing is done by the renderer 2. offloaded above The renderer draws nothing 3. offloaded below The renderer needs to punch a hole. Whenever the stage changes, we need to repaint. And that can happen without the subsurface's contents changing, like when a widget is put above the subsurface and it needs to to go from offloaded above to below. So we now recruit GskOffload for tracking these changes, instead of relying on the subsurface diffing. But we still need the subsurface diffing code to work for the non-offloaded case, because then the offloading code is not used. So we keep using it whenever that happens. Not that when a subsurface transitions between being offloaded and not being offloaded, we may diff it twice - once in the offload code and once in the node diffing - but that shouldn't matter. --- gsk/gskoffload.c | 27 ++++++++++++++++++++++++-- gsk/gskoffloadprivate.h | 11 ++++++----- gsk/gskrenderer.c | 17 ++++++++-------- gsk/gskrendernodeimpl.c | 43 +++++++++++++++++------------------------ testsuite/gsk/offload.c | 8 +++++--- 5 files changed, 63 insertions(+), 43 deletions(-) diff --git a/gsk/gskoffload.c b/gsk/gskoffload.c index d7b0627dd7..086b904972 100644 --- a/gsk/gskoffload.c +++ b/gsk/gskoffload.c @@ -537,8 +537,9 @@ complex_clip: } GskOffload * -gsk_offload_new (GdkSurface *surface, - GskRenderNode *root) +gsk_offload_new (GdkSurface *surface, + GskRenderNode *root, + cairo_region_t *diff) { GdkDisplay *display = gdk_surface_get_display (surface); GskOffload *self; @@ -576,6 +577,28 @@ gsk_offload_new (GdkSurface *surface, for (gsize i = 0; i < self->n_subsurfaces; i++) { GskOffloadInfo *info = &self->subsurfaces[i]; + graphene_rect_t old_rect; + + gdk_subsurface_get_rect (info->subsurface, &old_rect); + + if (info->can_offload != (gdk_subsurface_get_texture (info->subsurface) != NULL) || + info->can_raise != gdk_subsurface_is_above_parent (info->subsurface) || + (info->can_offload && !gsk_rect_equal (&info->rect, &old_rect))) + { + /* We changed things, need to invalidate everything */ + cairo_rectangle_int_t int_rect; + + if (info->can_offload) + { + gsk_rect_to_cairo_grow (&info->rect, &int_rect); + cairo_region_union_rectangle (diff, &int_rect); + } + if (gdk_subsurface_get_texture (info->subsurface) != NULL) + { + gsk_rect_to_cairo_grow (&old_rect, &int_rect); + cairo_region_union_rectangle (diff, &int_rect); + } + } if (info->can_offload) { diff --git a/gsk/gskoffloadprivate.h b/gsk/gskoffloadprivate.h index c1fb8d97f6..7805310f4d 100644 --- a/gsk/gskoffloadprivate.h +++ b/gsk/gskoffloadprivate.h @@ -42,9 +42,10 @@ typedef struct guint is_above : 1; } GskOffloadInfo; -GskOffload * gsk_offload_new (GdkSurface *surface, - GskRenderNode *root); -void gsk_offload_free (GskOffload *self); +GskOffload * gsk_offload_new (GdkSurface *surface, + GskRenderNode *root, + cairo_region_t *diff); +void gsk_offload_free (GskOffload *self); -GskOffloadInfo * gsk_offload_get_subsurface_info (GskOffload *self, - GdkSubsurface *subsurface); +GskOffloadInfo * gsk_offload_get_subsurface_info (GskOffload *self, + GdkSubsurface *subsurface); diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index 380c2712f3..8d94bfb562 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -484,24 +484,25 @@ gsk_renderer_render (GskRenderer *renderer, renderer_class = GSK_RENDERER_GET_CLASS (renderer); + clip = cairo_region_copy (region); + if (renderer_class->supports_offload && !GSK_RENDERER_DEBUG_CHECK (renderer, OFFLOAD_DISABLE)) - offload = gsk_offload_new (priv->surface, root); + offload = gsk_offload_new (priv->surface, root, clip); else offload = NULL; if (region == NULL || priv->prev_node == NULL || GSK_RENDERER_DEBUG_CHECK (renderer, FULL_REDRAW)) { - clip = cairo_region_create_rectangle (&(GdkRectangle) { - 0, 0, - gdk_surface_get_width (priv->surface), - gdk_surface_get_height (priv->surface) - }); + cairo_region_union_rectangle (clip, + &(GdkRectangle) { + 0, 0, + gdk_surface_get_width (priv->surface), + gdk_surface_get_height (priv->surface) + }); } else { - clip = cairo_region_copy (region); - gsk_render_node_diff (priv->prev_node, root, clip, offload); } diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index 04f36bcbc5..08784689b2 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -6963,7 +6963,7 @@ gsk_subsurface_node_diff (GskRenderNode *node1, { GskSubsurfaceNode *self1 = (GskSubsurfaceNode *) node1; GskSubsurfaceNode *self2 = (GskSubsurfaceNode *) node2; - GskOffloadInfo *info; + gboolean is_offloaded1, is_offloaded2; if (!data->offload) { @@ -6972,38 +6972,31 @@ gsk_subsurface_node_diff (GskRenderNode *node1, return; } - if (self1->subsurface != self2->subsurface) + is_offloaded1 = self1->subsurface && gdk_subsurface_get_texture (self1->subsurface) != NULL; + is_offloaded2 = self2->subsurface && gdk_subsurface_get_texture (self2->subsurface) != NULL; + + if (is_offloaded1 && is_offloaded2) { - /* different subsurfaces, can't compare */ - gsk_render_node_diff_impossible (node1, node2, data); - return; + /* both are offloaded, no contents to compare */ } - - info = gsk_offload_get_subsurface_info (data->offload, self1->subsurface); - - if (!info) + else if (!is_offloaded1 && !is_offloaded2) { - /* No info, so offloading not supported */ + /* neither is offloaded, diff the children */ gsk_render_node_data_diff (self1->child, self2->child, data); - return; } - - if (info->is_offloaded != info->was_offloaded || - info->is_above != info->was_above) + else if (!is_offloaded1) { - /* state changed between punching hole, drawing, and doing nothing. */ - gsk_render_node_diff_impossible (node1, node2, data); + /* The first one isn't offloaded, take its contents */ + cairo_rectangle_int_t rect; + gsk_rect_to_cairo_grow (&node1->bounds, &rect); + cairo_region_union_rectangle (data->region, &rect); } - else if (info->is_offloaded && !info->is_above && - !gsk_rect_equal (&node1->bounds, &node2->bounds)) + else if (!is_offloaded2) { - /* We're punching a hole and it moved */ - gsk_render_node_diff_impossible (node1, node2, data); - } - else if (!info->is_offloaded) - { - /* We aren't offloading and we weren't offloading (see above) */ - gsk_render_node_data_diff (self1->child, self2->child, data); + /* The second one isn't offloaded, take its contents */ + cairo_rectangle_int_t rect; + gsk_rect_to_cairo_grow (&node2->bounds, &rect); + cairo_region_union_rectangle (data->region, &rect); } } diff --git a/testsuite/gsk/offload.c b/testsuite/gsk/offload.c index 273c55dbd3..a876f27c29 100644 --- a/testsuite/gsk/offload.c +++ b/testsuite/gsk/offload.c @@ -389,9 +389,11 @@ parse_node_file (GFile *file, const char *generate) gsk_render_node_unref (node); node = tmp; - offload = gsk_offload_new (surface, node); + region = cairo_region_create (); + offload = gsk_offload_new (surface, node, region); offload_state = collect_offload_info (surface, offload); gsk_offload_free (offload); + cairo_region_destroy (region); if (g_strcmp0 (generate, "offload") == 0) { @@ -425,7 +427,8 @@ parse_node_file (GFile *file, const char *generate) gsk_render_node_unref (node2); node2 = tmp; - offload = gsk_offload_new (surface, node2); + clip = cairo_region_create (); + offload = gsk_offload_new (surface, node2, clip); offload_state = collect_offload_info (surface, offload); if (g_strcmp0 (generate, "offload2") == 0) @@ -452,7 +455,6 @@ parse_node_file (GFile *file, const char *generate) g_clear_pointer (&diff, g_bytes_unref); g_clear_pointer (&reference_file, g_free); - clip = cairo_region_create (); gsk_render_node_diff (node, node2, clip, offload); if (g_strcmp0 (generate, "diff") == 0) From 30afac9a6bbad2b28cb7e227c6f2e0e1775e8a2d Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 10 Feb 2024 07:34:07 +0100 Subject: [PATCH 5/9] offload: No need to pass the offload to the diff We can just check if the subsurfaces contain content - and if they do, they will be offloading and we can ignore the diff. This essentially reverts 48740de71a2 --- gsk/gpu/gskgpunodeprocessor.c | 1 + gsk/gskrenderer.c | 2 +- gsk/gskrendernode.c | 38 ++---- gsk/gskrendernodeimpl.c | 218 ++++++++++++++++----------------- gsk/gskrendernodeprivate.h | 18 +-- gtk/gtksnapshotprivate.h | 1 + gtk/inspector/updatesoverlay.c | 2 +- testsuite/gsk/offload.c | 2 +- 8 files changed, 124 insertions(+), 158 deletions(-) diff --git a/gsk/gpu/gskgpunodeprocessor.c b/gsk/gpu/gskgpunodeprocessor.c index 05b4f71ec3..b0ffcaf42e 100644 --- a/gsk/gpu/gskgpunodeprocessor.c +++ b/gsk/gpu/gskgpunodeprocessor.c @@ -42,6 +42,7 @@ #include "gsktransformprivate.h" #include "gdk/gdkrgbaprivate.h" +#include "gdk/gdksubsurfaceprivate.h" /* A note about coordinate systems * diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index 8d94bfb562..5a42b0af0d 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -503,7 +503,7 @@ gsk_renderer_render (GskRenderer *renderer, } else { - gsk_render_node_diff (priv->prev_node, root, clip, offload); + gsk_render_node_diff (priv->prev_node, root, clip); } renderer_class->render (renderer, root, clip); diff --git a/gsk/gskrendernode.c b/gsk/gskrendernode.c index 47a70e91f5..fc70975359 100644 --- a/gsk/gskrendernode.c +++ b/gsk/gskrendernode.c @@ -154,9 +154,9 @@ gsk_render_node_real_can_diff (const GskRenderNode *node1, static void gsk_render_node_real_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } static void @@ -505,14 +505,14 @@ rectangle_init_from_graphene (cairo_rectangle_int_t *cairo, void gsk_render_node_diff_impossible (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { cairo_rectangle_int_t rect; rectangle_init_from_graphene (&rect, &node1->bounds); - cairo_region_union_rectangle (data->region, &rect); + cairo_region_union_rectangle (region, &rect); rectangle_init_from_graphene (&rect, &node2->bounds); - cairo_region_union_rectangle (data->region, &rect); + cairo_region_union_rectangle (region, &rect); } /** @@ -520,7 +520,6 @@ gsk_render_node_diff_impossible (GskRenderNode *node1, * @node1: a `GskRenderNode` * @node2: the `GskRenderNode` to compare with * @region: a `cairo_region_t` to add the differences to - * @subsurfaces: (nullable): array to add offload info to * * Compares @node1 and @node2 trying to compute the minimal region of changes. * @@ -533,47 +532,30 @@ gsk_render_node_diff_impossible (GskRenderNode *node1, * * Note that the passed in @region may already contain previous results from * previous node comparisons, so this function call will only add to it. - * - * If @subsurface_nodes is not `NULL`, then we treat subsurface nodes as - * identical if they refer to the same subsurface and have the same bounds. - * In this case, we collect subsurface nodes we see in @subsurface_nodes, - * for later updating of the attached textures. - * - * If @subsurface_area is not `NULL`, it will collect the full area of all - * subsurface nodes we meet. */ void gsk_render_node_diff (GskRenderNode *node1, GskRenderNode *node2, - cairo_region_t *region, - GskOffload *offload) -{ - gsk_render_node_data_diff (node1, node2, &(GskDiffData) { region, offload }); -} - -void -gsk_render_node_data_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { if (node1 == node2) return; if (_gsk_render_node_get_node_type (node1) == _gsk_render_node_get_node_type (node2)) { - GSK_RENDER_NODE_GET_CLASS (node1)->diff (node1, node2, data); + GSK_RENDER_NODE_GET_CLASS (node1)->diff (node1, node2, region); } else if (_gsk_render_node_get_node_type (node1) == GSK_CONTAINER_NODE) { - gsk_container_node_diff_with (node1, node2, data); + gsk_container_node_diff_with (node1, node2, region); } else if (_gsk_render_node_get_node_type (node2) == GSK_CONTAINER_NODE) { - gsk_container_node_diff_with (node2, node1, data); + gsk_container_node_diff_with (node2, node1, region); } else { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } } diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index 08784689b2..b3f1acb316 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -31,7 +31,6 @@ #include "gskroundedrectprivate.h" #include "gskstrokeprivate.h" #include "gsktransformprivate.h" -#include "gskoffloadprivate.h" #include "gdk/gdkmemoryformatprivate.h" #include "gdk/gdkprivate.h" @@ -167,7 +166,7 @@ gsk_color_node_draw (GskRenderNode *node, static void gsk_color_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskColorNode *self1 = (GskColorNode *) node1; GskColorNode *self2 = (GskColorNode *) node2; @@ -176,7 +175,7 @@ gsk_color_node_diff (GskRenderNode *node1, gdk_rgba_equal (&self1->color, &self2->color)) return; - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } static void @@ -323,7 +322,7 @@ gsk_linear_gradient_node_draw (GskRenderNode *node, static void gsk_linear_gradient_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskLinearGradientNode *self1 = (GskLinearGradientNode *) node1; GskLinearGradientNode *self2 = (GskLinearGradientNode *) node2; @@ -343,14 +342,14 @@ gsk_linear_gradient_node_diff (GskRenderNode *node1, gdk_rgba_equal (&stop1->color, &stop2->color)) continue; - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } return; } - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } static void @@ -652,7 +651,7 @@ gsk_radial_gradient_node_draw (GskRenderNode *node, static void gsk_radial_gradient_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskRadialGradientNode *self1 = (GskRadialGradientNode *) node1; GskRadialGradientNode *self2 = (GskRadialGradientNode *) node2; @@ -675,14 +674,14 @@ gsk_radial_gradient_node_diff (GskRenderNode *node1, gdk_rgba_equal (&stop1->color, &stop2->color)) continue; - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } return; } - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } static void @@ -1143,7 +1142,7 @@ gsk_conic_gradient_node_draw (GskRenderNode *node, static void gsk_conic_gradient_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskConicGradientNode *self1 = (GskConicGradientNode *) node1; GskConicGradientNode *self2 = (GskConicGradientNode *) node2; @@ -1153,7 +1152,7 @@ gsk_conic_gradient_node_diff (GskRenderNode *node1, self1->rotation != self2->rotation || self1->n_stops != self2->n_stops) { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } @@ -1165,7 +1164,7 @@ gsk_conic_gradient_node_diff (GskRenderNode *node1, if (stop1->offset != stop2->offset || !gdk_rgba_equal (&stop1->color, &stop2->color)) { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } } @@ -1495,7 +1494,7 @@ gsk_border_node_draw (GskRenderNode *node, static void gsk_border_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskBorderNode *self1 = (GskBorderNode *) node1; GskBorderNode *self2 = (GskBorderNode *) node2; @@ -1512,7 +1511,7 @@ gsk_border_node_diff (GskRenderNode *node1, /* Different uniformity -> diff impossible */ if (uniform1 ^ uniform2) { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } @@ -1527,7 +1526,7 @@ gsk_border_node_diff (GskRenderNode *node1, gsk_rounded_rect_equal (&self1->outline, &self2->outline)) return; - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } static void @@ -1786,7 +1785,7 @@ gsk_texture_node_draw (GskRenderNode *node, static void gsk_texture_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskTextureNode *self1 = (GskTextureNode *) node1; GskTextureNode *self2 = (GskTextureNode *) node2; @@ -1796,7 +1795,7 @@ gsk_texture_node_diff (GskRenderNode *node1, gdk_texture_get_width (self1->texture) != gdk_texture_get_width (self2->texture) || gdk_texture_get_height (self1->texture) != gdk_texture_get_height (self2->texture)) { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } @@ -1805,7 +1804,7 @@ gsk_texture_node_diff (GskRenderNode *node1, sub = cairo_region_create (); gdk_texture_diff (self1->texture, self2->texture, sub); - region_union_region_affine (data->region, + region_union_region_affine (region, sub, node1->bounds.size.width / gdk_texture_get_width (self1->texture), node1->bounds.size.height / gdk_texture_get_height (self1->texture), @@ -1972,7 +1971,7 @@ gsk_texture_scale_node_draw (GskRenderNode *node, static void gsk_texture_scale_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskTextureScaleNode *self1 = (GskTextureScaleNode *) node1; GskTextureScaleNode *self2 = (GskTextureScaleNode *) node2; @@ -1983,7 +1982,7 @@ gsk_texture_scale_node_diff (GskRenderNode *node1, gdk_texture_get_width (self1->texture) != gdk_texture_get_width (self2->texture) || gdk_texture_get_height (self1->texture) != gdk_texture_get_height (self2->texture)) { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } @@ -1992,7 +1991,7 @@ gsk_texture_scale_node_diff (GskRenderNode *node1, sub = cairo_region_create (); gdk_texture_diff (self1->texture, self2->texture, sub); - region_union_region_affine (data->region, + region_union_region_affine (region, sub, node1->bounds.size.width / gdk_texture_get_width (self1->texture), node1->bounds.size.height / gdk_texture_get_height (self1->texture), @@ -2495,7 +2494,7 @@ gsk_inset_shadow_node_draw (GskRenderNode *node, static void gsk_inset_shadow_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskInsetShadowNode *self1 = (GskInsetShadowNode *) node1; GskInsetShadowNode *self2 = (GskInsetShadowNode *) node2; @@ -2508,7 +2507,7 @@ gsk_inset_shadow_node_diff (GskRenderNode *node1, self1->blur_radius == self2->blur_radius) return; - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } static void @@ -2808,7 +2807,7 @@ gsk_outset_shadow_node_draw (GskRenderNode *node, static void gsk_outset_shadow_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskOutsetShadowNode *self1 = (GskOutsetShadowNode *) node1; GskOutsetShadowNode *self2 = (GskOutsetShadowNode *) node2; @@ -2821,7 +2820,7 @@ gsk_outset_shadow_node_diff (GskRenderNode *node1, self1->blur_radius == self2->blur_radius) return; - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } static void @@ -3188,10 +3187,8 @@ gsk_container_node_compare_func (gconstpointer elem1, gconstpointer elem2, gpoin static GskDiffResult gsk_container_node_keep_func (gconstpointer elem1, gconstpointer elem2, gpointer data) { - GskDiffData *gd = data; - - gsk_render_node_data_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, gd); - if (cairo_region_num_rectangles (gd->region) > MAX_RECTS_IN_DIFF) + gsk_render_node_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, data); + if (cairo_region_num_rectangles (data) > MAX_RECTS_IN_DIFF) return GSK_DIFF_ABORTED; return GSK_DIFF_OK; @@ -3201,12 +3198,12 @@ static GskDiffResult gsk_container_node_change_func (gconstpointer elem, gsize idx, gpointer data) { const GskRenderNode *node = elem; - GskDiffData *gd = data; + cairo_region_t *region = data; cairo_rectangle_int_t rect; gsk_rect_to_cairo_grow (&node->bounds, &rect); - cairo_region_union_rectangle (gd->region, &rect); - if (cairo_region_num_rectangles (gd->region) > MAX_RECTS_IN_DIFF) + cairo_region_union_rectangle (region, &rect); + if (cairo_region_num_rectangles (region) > MAX_RECTS_IN_DIFF) return GSK_DIFF_ABORTED; return GSK_DIFF_OK; @@ -3234,18 +3231,18 @@ gsk_render_node_diff_multiple (GskRenderNode **nodes1, gsize n_nodes1, GskRenderNode **nodes2, gsize n_nodes2, - GskDiffData *data) + cairo_region_t *region) { return gsk_diff ((gconstpointer *) nodes1, n_nodes1, (gconstpointer *) nodes2, n_nodes2, gsk_container_node_get_diff_settings (), - data) == GSK_DIFF_OK; + region) == GSK_DIFF_OK; } void gsk_container_node_diff_with (GskRenderNode *container, GskRenderNode *other, - GskDiffData *data) + cairo_region_t *region) { GskContainerNode *self = (GskContainerNode *) container; @@ -3253,16 +3250,16 @@ gsk_container_node_diff_with (GskRenderNode *container, self->n_children, &other, 1, - data)) + region)) return; - gsk_render_node_diff_impossible (container, other, data); + gsk_render_node_diff_impossible (container, other, region); } static void gsk_container_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskContainerNode *self1 = (GskContainerNode *) node1; GskContainerNode *self2 = (GskContainerNode *) node2; @@ -3271,10 +3268,10 @@ gsk_container_node_diff (GskRenderNode *node1, self1->n_children, self2->children, self2->n_children, - data)) + region)) return; - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } static void @@ -3491,14 +3488,14 @@ gsk_transform_node_can_diff (const GskRenderNode *node1, static void gsk_transform_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskTransformNode *self1 = (GskTransformNode *) node1; GskTransformNode *self2 = (GskTransformNode *) node2; if (!gsk_transform_equal (self1->transform, self2->transform)) { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } @@ -3508,7 +3505,7 @@ gsk_transform_node_diff (GskRenderNode *node1, switch (gsk_transform_get_category (self1->transform)) { case GSK_TRANSFORM_CATEGORY_IDENTITY: - gsk_render_node_data_diff (self1->child, self2->child, data); + gsk_render_node_diff (self1->child, self2->child, region); break; case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE: @@ -3517,7 +3514,7 @@ gsk_transform_node_diff (GskRenderNode *node1, float dx, dy; gsk_transform_to_translate (self1->transform, &dx, &dy); sub = cairo_region_create (); - gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload }); + gsk_render_node_diff (self1->child, self2->child, sub); cairo_region_translate (sub, floorf (dx), floorf (dy)); if (floorf (dx) != dx) { @@ -3533,7 +3530,7 @@ gsk_transform_node_diff (GskRenderNode *node1, cairo_region_union (sub, tmp); cairo_region_destroy (tmp); } - cairo_region_union (data->region, sub); + cairo_region_union (region, sub); cairo_region_destroy (sub); } break; @@ -3544,8 +3541,8 @@ gsk_transform_node_diff (GskRenderNode *node1, float scale_x, scale_y, dx, dy; gsk_transform_to_affine (self1->transform, &scale_x, &scale_y, &dx, &dy); sub = cairo_region_create (); - gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload }); - region_union_region_affine (data->region, sub, scale_x, scale_y, dx, dy); + gsk_render_node_diff (self1->child, self2->child, sub); + region_union_region_affine (region, sub, scale_x, scale_y, dx, dy); cairo_region_destroy (sub); } break; @@ -3555,7 +3552,7 @@ gsk_transform_node_diff (GskRenderNode *node1, case GSK_TRANSFORM_CATEGORY_3D: case GSK_TRANSFORM_CATEGORY_2D: default: - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); break; } } @@ -3709,15 +3706,15 @@ gsk_opacity_node_draw (GskRenderNode *node, static void gsk_opacity_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskOpacityNode *self1 = (GskOpacityNode *) node1; GskOpacityNode *self2 = (GskOpacityNode *) node2; if (self1->opacity == self2->opacity) - gsk_render_node_data_diff (self1->child, self2->child, data); + gsk_render_node_diff (self1->child, self2->child, region); else - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } static void @@ -3923,7 +3920,7 @@ gsk_color_matrix_node_draw (GskRenderNode *node, static void gsk_color_matrix_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskColorMatrixNode *self1 = (GskColorMatrixNode *) node1; GskColorMatrixNode *self2 = (GskColorMatrixNode *) node2; @@ -3934,11 +3931,11 @@ gsk_color_matrix_node_diff (GskRenderNode *node1, if (!graphene_matrix_equal_fast (&self1->color_matrix, &self2->color_matrix)) goto nope; - gsk_render_node_data_diff (self1->child, self2->child, data); + gsk_render_node_diff (self1->child, self2->child, region); return; nope: - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } @@ -4217,7 +4214,7 @@ gsk_repeat_node_draw (GskRenderNode *node, static void gsk_repeat_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskRepeatNode *self1 = (GskRepeatNode *) node1; GskRepeatNode *self2 = (GskRepeatNode *) node2; @@ -4228,7 +4225,7 @@ gsk_repeat_node_diff (GskRenderNode *node1, cairo_region_t *sub; sub = cairo_region_create(); - gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload }); + gsk_render_node_diff (self1->child, self2->child, sub); if (cairo_region_is_empty (sub)) { cairo_region_destroy (sub); @@ -4237,7 +4234,7 @@ gsk_repeat_node_diff (GskRenderNode *node1, cairo_region_destroy (sub); } - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } static void @@ -4372,7 +4369,7 @@ gsk_clip_node_draw (GskRenderNode *node, static void gsk_clip_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskClipNode *self1 = (GskClipNode *) node1; GskClipNode *self2 = (GskClipNode *) node2; @@ -4383,15 +4380,15 @@ gsk_clip_node_diff (GskRenderNode *node1, cairo_rectangle_int_t clip_rect; sub = cairo_region_create(); - gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload }); + gsk_render_node_diff (self1->child, self2->child, sub); gsk_rect_to_cairo_grow (&self1->clip, &clip_rect); cairo_region_intersect_rectangle (sub, &clip_rect); - cairo_region_union (data->region, sub); + cairo_region_union (region, sub); cairo_region_destroy (sub); } else { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } } @@ -4520,7 +4517,7 @@ gsk_rounded_clip_node_draw (GskRenderNode *node, static void gsk_rounded_clip_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskRoundedClipNode *self1 = (GskRoundedClipNode *) node1; GskRoundedClipNode *self2 = (GskRoundedClipNode *) node2; @@ -4531,15 +4528,15 @@ gsk_rounded_clip_node_diff (GskRenderNode *node1, cairo_rectangle_int_t clip_rect; sub = cairo_region_create(); - gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload }); + gsk_render_node_diff (self1->child, self2->child, sub); gsk_rect_to_cairo_grow (&self1->clip.bounds, &clip_rect); cairo_region_intersect_rectangle (sub, &clip_rect); - cairo_region_union (data->region, sub); + cairo_region_union (region, sub); cairo_region_destroy (sub); } else { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } } @@ -4690,7 +4687,7 @@ gsk_fill_node_draw (GskRenderNode *node, static void gsk_fill_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskFillNode *self1 = (GskFillNode *) node1; GskFillNode *self2 = (GskFillNode *) node2; @@ -4701,15 +4698,15 @@ gsk_fill_node_diff (GskRenderNode *node1, cairo_rectangle_int_t clip_rect; sub = cairo_region_create(); - gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload }); + gsk_render_node_diff (self1->child, self2->child, sub); gsk_rect_to_cairo_grow (&node1->bounds, &clip_rect); cairo_region_intersect_rectangle (sub, &clip_rect); - cairo_region_union (data->region, sub); + cairo_region_union (region, sub); cairo_region_destroy (sub); } else { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } } @@ -4893,7 +4890,7 @@ gsk_stroke_node_draw (GskRenderNode *node, static void gsk_stroke_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskStrokeNode *self1 = (GskStrokeNode *) node1; GskStrokeNode *self2 = (GskStrokeNode *) node2; @@ -4905,15 +4902,15 @@ gsk_stroke_node_diff (GskRenderNode *node1, cairo_rectangle_int_t clip_rect; sub = cairo_region_create(); - gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload }); + gsk_render_node_diff (self1->child, self2->child, sub); gsk_rect_to_cairo_grow (&node1->bounds, &clip_rect); cairo_region_intersect_rectangle (sub, &clip_rect); - cairo_region_union (data->region, sub); + cairo_region_union (region, sub); cairo_region_destroy (sub); } else { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } } @@ -5110,7 +5107,7 @@ gsk_shadow_node_draw (GskRenderNode *node, static void gsk_shadow_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskShadowNode *self1 = (GskShadowNode *) node1; GskShadowNode *self2 = (GskShadowNode *) node2; @@ -5121,7 +5118,7 @@ gsk_shadow_node_diff (GskRenderNode *node1, if (self1->n_shadows != self2->n_shadows) { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } @@ -5136,7 +5133,7 @@ gsk_shadow_node_diff (GskRenderNode *node1, shadow1->dy != shadow2->dy || shadow1->radius != shadow2->radius) { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } @@ -5148,7 +5145,7 @@ gsk_shadow_node_diff (GskRenderNode *node1, } sub = cairo_region_create (); - gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload }); + gsk_render_node_diff (self1->child, self2->child, sub); n = cairo_region_num_rectangles (sub); for (i = 0; i < n; i++) @@ -5158,7 +5155,7 @@ gsk_shadow_node_diff (GskRenderNode *node1, rect.y -= top; rect.width += left + right; rect.height += top + bottom; - cairo_region_union_rectangle (data->region, &rect); + cairo_region_union_rectangle (region, &rect); } cairo_region_destroy (sub); } @@ -5386,19 +5383,19 @@ gsk_blend_node_draw (GskRenderNode *node, static void gsk_blend_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskBlendNode *self1 = (GskBlendNode *) node1; GskBlendNode *self2 = (GskBlendNode *) node2; if (self1->blend_mode == self2->blend_mode) { - gsk_render_node_data_diff (self1->top, self2->top, data); - gsk_render_node_data_diff (self1->bottom, self2->bottom, data); + gsk_render_node_diff (self1->top, self2->top, region); + gsk_render_node_diff (self1->bottom, self2->bottom, region); } else { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } } @@ -5556,19 +5553,19 @@ gsk_cross_fade_node_draw (GskRenderNode *node, static void gsk_cross_fade_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskCrossFadeNode *self1 = (GskCrossFadeNode *) node1; GskCrossFadeNode *self2 = (GskCrossFadeNode *) node2; if (self1->progress == self2->progress) { - gsk_render_node_data_diff (self1->start, self2->start, data); - gsk_render_node_data_diff (self1->end, self2->end, data); + gsk_render_node_diff (self1->start, self2->start, region); + gsk_render_node_diff (self1->end, self2->end, region); return; } - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } static void @@ -5729,7 +5726,7 @@ gsk_text_node_draw (GskRenderNode *node, static void gsk_text_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskTextNode *self1 = (GskTextNode *) node1; GskTextNode *self2 = (GskTextNode *) node2; @@ -5754,14 +5751,14 @@ gsk_text_node_diff (GskRenderNode *node1, info1->attr.is_color == info2->attr.is_color) continue; - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } return; } - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } static void @@ -6175,7 +6172,7 @@ gsk_blur_node_draw (GskRenderNode *node, static void gsk_blur_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskBlurNode *self1 = (GskBlurNode *) node1; GskBlurNode *self2 = (GskBlurNode *) node2; @@ -6188,7 +6185,7 @@ gsk_blur_node_diff (GskRenderNode *node1, clip_radius = ceil (gsk_cairo_blur_compute_pixels (self1->radius / 2.0)); sub = cairo_region_create (); - gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload }); + gsk_render_node_diff (self1->child, self2->child, sub); n = cairo_region_num_rectangles (sub); for (i = 0; i < n; i++) @@ -6198,13 +6195,13 @@ gsk_blur_node_diff (GskRenderNode *node1, rect.y -= clip_radius; rect.width += 2 * clip_radius; rect.height += 2 * clip_radius; - cairo_region_union_rectangle (data->region, &rect); + cairo_region_union_rectangle (region, &rect); } cairo_region_destroy (sub); } else { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } } @@ -6420,19 +6417,19 @@ gsk_mask_node_draw (GskRenderNode *node, static void gsk_mask_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskMaskNode *self1 = (GskMaskNode *) node1; GskMaskNode *self2 = (GskMaskNode *) node2; if (self1->mask_mode != self2->mask_mode) { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); return; } - gsk_render_node_data_diff (self1->source, self2->source, data); - gsk_render_node_data_diff (self1->mask, self2->mask, data); + gsk_render_node_diff (self1->source, self2->source, region); + gsk_render_node_diff (self1->mask, self2->mask, region); } static void @@ -6598,12 +6595,12 @@ gsk_debug_node_can_diff (const GskRenderNode *node1, static void gsk_debug_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskDebugNode *self1 = (GskDebugNode *) node1; GskDebugNode *self2 = (GskDebugNode *) node2; - gsk_render_node_data_diff (self1->child, self2->child, data); + gsk_render_node_diff (self1->child, self2->child, region); } static void @@ -6734,7 +6731,7 @@ gsk_gl_shader_node_draw (GskRenderNode *node, static void gsk_gl_shader_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskGLShaderNode *self1 = (GskGLShaderNode *) node1; GskGLShaderNode *self2 = (GskGLShaderNode *) node2; @@ -6746,14 +6743,14 @@ gsk_gl_shader_node_diff (GskRenderNode *node1, { cairo_region_t *child_region = cairo_region_create(); for (guint i = 0; i < self1->n_children; i++) - gsk_render_node_data_diff (self1->children[i], self2->children[i], &(GskDiffData) {child_region, data->offload }); + gsk_render_node_diff (self1->children[i], self2->children[i], child_region); if (!cairo_region_is_empty (child_region)) - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); cairo_region_destroy (child_region); } else { - gsk_render_node_diff_impossible (node1, node2, data); + gsk_render_node_diff_impossible (node1, node2, region); } } @@ -6959,19 +6956,12 @@ gsk_subsurface_node_can_diff (const GskRenderNode *node1, static void gsk_subsurface_node_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data) + cairo_region_t *region) { GskSubsurfaceNode *self1 = (GskSubsurfaceNode *) node1; GskSubsurfaceNode *self2 = (GskSubsurfaceNode *) node2; gboolean is_offloaded1, is_offloaded2; - if (!data->offload) - { - /* offloading not supported, so we know the children will be drawn */ - gsk_render_node_data_diff (self1->child, self2->child, data); - return; - } - is_offloaded1 = self1->subsurface && gdk_subsurface_get_texture (self1->subsurface) != NULL; is_offloaded2 = self2->subsurface && gdk_subsurface_get_texture (self2->subsurface) != NULL; @@ -6982,21 +6972,21 @@ gsk_subsurface_node_diff (GskRenderNode *node1, else if (!is_offloaded1 && !is_offloaded2) { /* neither is offloaded, diff the children */ - gsk_render_node_data_diff (self1->child, self2->child, data); + gsk_render_node_diff (self1->child, self2->child, region); } else if (!is_offloaded1) { /* The first one isn't offloaded, take its contents */ cairo_rectangle_int_t rect; gsk_rect_to_cairo_grow (&node1->bounds, &rect); - cairo_region_union_rectangle (data->region, &rect); + cairo_region_union_rectangle (region, &rect); } else if (!is_offloaded2) { /* The second one isn't offloaded, take its contents */ cairo_rectangle_int_t rect; gsk_rect_to_cairo_grow (&node2->bounds, &rect); - cairo_region_union_rectangle (data->region, &rect); + cairo_region_union_rectangle (region, &rect); } } diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h index 939429d614..4b4cbbd4fc 100644 --- a/gsk/gskrendernodeprivate.h +++ b/gsk/gskrendernodeprivate.h @@ -1,7 +1,6 @@ #pragma once #include "gskrendernode.h" -#include "gskoffloadprivate.h" #include #include "gdk/gdkmemoryformatprivate.h" @@ -37,12 +36,6 @@ struct _GskRenderNode guint offscreen_for_opacity : 1; }; -typedef struct -{ - cairo_region_t *region; - GskOffload *offload; -} GskDiffData; - struct _GskRenderNodeClass { GTypeClass parent_class; @@ -56,7 +49,7 @@ struct _GskRenderNodeClass const GskRenderNode *node2); void (* diff) (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data); + cairo_region_t *region); }; void gsk_render_node_init_types (void); @@ -73,17 +66,16 @@ gboolean gsk_render_node_can_diff (const GskRenderNode const GskRenderNode *node2) G_GNUC_PURE; void gsk_render_node_diff (GskRenderNode *node1, GskRenderNode *node2, - cairo_region_t *region, - GskOffload *offload); + cairo_region_t *region); void gsk_render_node_data_diff (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data); + cairo_region_t *region); void gsk_render_node_diff_impossible (GskRenderNode *node1, GskRenderNode *node2, - GskDiffData *data); + cairo_region_t *region); void gsk_container_node_diff_with (GskRenderNode *container, GskRenderNode *other, - GskDiffData *data); + cairo_region_t *region); void gsk_render_node_draw_fallback (GskRenderNode *node, cairo_t *cr); diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h index cf2659c13b..0d8a5f5924 100644 --- a/gtk/gtksnapshotprivate.h +++ b/gtk/gtksnapshotprivate.h @@ -19,6 +19,7 @@ #include "gtksnapshot.h" +#include "gdk/gdksubsurfaceprivate.h" #include "gsk/gskrendernodeprivate.h" G_BEGIN_DECLS diff --git a/gtk/inspector/updatesoverlay.c b/gtk/inspector/updatesoverlay.c index 542dc59a71..002f47cd9c 100644 --- a/gtk/inspector/updatesoverlay.c +++ b/gtk/inspector/updatesoverlay.c @@ -183,7 +183,7 @@ gtk_updates_overlay_snapshot (GtkInspectorOverlay *overlay, cairo_region_t *diff; diff = cairo_region_create (); - gsk_render_node_diff (updates->last, node, diff, NULL); + gsk_render_node_diff (updates->last, node, diff); if (cairo_region_is_empty (diff)) cairo_region_destroy (diff); else diff --git a/testsuite/gsk/offload.c b/testsuite/gsk/offload.c index a876f27c29..933da5ddb9 100644 --- a/testsuite/gsk/offload.c +++ b/testsuite/gsk/offload.c @@ -455,7 +455,7 @@ parse_node_file (GFile *file, const char *generate) g_clear_pointer (&diff, g_bytes_unref); g_clear_pointer (&reference_file, g_free); - gsk_render_node_diff (node, node2, clip, offload); + gsk_render_node_diff (node, node2, clip); if (g_strcmp0 (generate, "diff") == 0) { From f8e89f2224b07ed1306ff9a62d45b6a2b88e3759 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 11 Feb 2024 11:39:48 -0500 Subject: [PATCH 6/9] offload: Do diff collection later We were collecting diffs based on the can_offload/can_raise information, but attaching the texture to the subsurface can fail (e.g. if its not a dmabuf texture), in which case can_offload turned out to be wrong. So move the diff collection to the end and do it based on the whether we actually succeeded in attaching the texture. --- gsk/gskoffload.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/gsk/gskoffload.c b/gsk/gskoffload.c index 086b904972..921fb3d94c 100644 --- a/gsk/gskoffload.c +++ b/gsk/gskoffload.c @@ -581,25 +581,6 @@ gsk_offload_new (GdkSurface *surface, gdk_subsurface_get_rect (info->subsurface, &old_rect); - if (info->can_offload != (gdk_subsurface_get_texture (info->subsurface) != NULL) || - info->can_raise != gdk_subsurface_is_above_parent (info->subsurface) || - (info->can_offload && !gsk_rect_equal (&info->rect, &old_rect))) - { - /* We changed things, need to invalidate everything */ - cairo_rectangle_int_t int_rect; - - if (info->can_offload) - { - gsk_rect_to_cairo_grow (&info->rect, &int_rect); - cairo_region_union_rectangle (diff, &int_rect); - } - if (gdk_subsurface_get_texture (info->subsurface) != NULL) - { - gsk_rect_to_cairo_grow (&old_rect, &int_rect); - cairo_region_union_rectangle (diff, &int_rect); - } - } - if (info->can_offload) { if (info->can_raise) @@ -629,6 +610,26 @@ gsk_offload_new (GdkSurface *surface, GDK_DISPLAY_DEBUG (display, OFFLOAD, "Raising subsurface %p", info->subsurface); info->is_above = TRUE; } + + if (info->is_offloaded != info->was_offloaded || + info->is_above != info->was_above || + (info->is_offloaded && !gsk_rect_equal (&info->rect, &old_rect))) + { + /* We changed things, need to invalidate everything */ + cairo_rectangle_int_t int_rect; + + if (info->is_offloaded) + { + gsk_rect_to_cairo_grow (&info->rect, &int_rect); + cairo_region_union_rectangle (diff, &int_rect); + } + if (info->was_offloaded) + { + gsk_rect_to_cairo_grow (&old_rect, &int_rect); + cairo_region_union_rectangle (diff, &int_rect); + } + } + } return self; From 2cf90b615802cff2e43a937ef90a472fec0480c7 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 11 Feb 2024 11:45:00 -0500 Subject: [PATCH 7/9] tests: Add a note Point out a little gotcha. --- testsuite/gsk/offload.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testsuite/gsk/offload.c b/testsuite/gsk/offload.c index 933da5ddb9..883f279bb4 100644 --- a/testsuite/gsk/offload.c +++ b/testsuite/gsk/offload.c @@ -196,6 +196,9 @@ collect_offload_info (GdkSurface *surface, else g_snprintf (above, sizeof (above), "-"); + /* NOTE: We look at can_offload here, not is_offloaded, since we don't have + * dmabuf textures here, so attaching them to subsurfaces won't succeed. + */ if (info->can_offload) { g_string_append_printf (s, "%u: offloaded, %s%sabove: %s, ", From 26c25cc6b74acc1e347c5e8ec4c5645e9ec8f275 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 11 Feb 2024 11:47:18 -0500 Subject: [PATCH 8/9] Simplify gsk_subsurface_node_diff Most of the time, the subsurfaces will be the same. And if they aren't, can_diff() will return FALSE anyway. --- gsk/gskrendernodeimpl.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index b3f1acb316..32f4258ffb 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -6960,34 +6960,21 @@ gsk_subsurface_node_diff (GskRenderNode *node1, { GskSubsurfaceNode *self1 = (GskSubsurfaceNode *) node1; GskSubsurfaceNode *self2 = (GskSubsurfaceNode *) node2; - gboolean is_offloaded1, is_offloaded2; - is_offloaded1 = self1->subsurface && gdk_subsurface_get_texture (self1->subsurface) != NULL; - is_offloaded2 = self2->subsurface && gdk_subsurface_get_texture (self2->subsurface) != NULL; - - if (is_offloaded1 && is_offloaded2) + if (self1->subsurface != self2->subsurface) { - /* both are offloaded, no contents to compare */ + /* Shouldn't happen, can_diff() avoids this, but to be sure */ + gsk_render_node_diff_impossible (node1, node2, region); } - else if (!is_offloaded1 && !is_offloaded2) + else if (self1->subsurface && gdk_subsurface_get_texture (self1->subsurface) != NULL) { - /* neither is offloaded, diff the children */ + /* offloaded, no contents to compare */ + } + else + { + /* not offloaded, diff the children */ gsk_render_node_diff (self1->child, self2->child, region); } - else if (!is_offloaded1) - { - /* The first one isn't offloaded, take its contents */ - cairo_rectangle_int_t rect; - gsk_rect_to_cairo_grow (&node1->bounds, &rect); - cairo_region_union_rectangle (region, &rect); - } - else if (!is_offloaded2) - { - /* The second one isn't offloaded, take its contents */ - cairo_rectangle_int_t rect; - gsk_rect_to_cairo_grow (&node2->bounds, &rect); - cairo_region_union_rectangle (region, &rect); - } } static void From 5b55456b755d06cf65f0bc353692bc1f694c4f0d Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 11 Feb 2024 15:53:37 -0500 Subject: [PATCH 9/9] Rework diffing one more time Pass the surface along. We need it to identify the inspector case in gsk_subsurface_node_diff. --- gsk/gskrenderer.c | 2 +- gsk/gskrendernode.c | 22 +- gsk/gskrendernodeimpl.c | 326 ++++++++++++++-------------- gsk/gskrendernodeprivate.h | 17 +- gtk/inspector/updatesoverlay.c | 2 +- testsuite/gsk/gtkrendernodeattach.h | 4 - testsuite/gsk/offload.c | 2 +- 7 files changed, 190 insertions(+), 185 deletions(-) diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index 5a42b0af0d..31477b84c7 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -503,7 +503,7 @@ gsk_renderer_render (GskRenderer *renderer, } else { - gsk_render_node_diff (priv->prev_node, root, clip); + gsk_render_node_diff (priv->prev_node, root, &(GskDiffData) { clip, priv->surface }); } renderer_class->render (renderer, root, clip); diff --git a/gsk/gskrendernode.c b/gsk/gskrendernode.c index fc70975359..42a0bb5a89 100644 --- a/gsk/gskrendernode.c +++ b/gsk/gskrendernode.c @@ -154,9 +154,9 @@ gsk_render_node_real_can_diff (const GskRenderNode *node1, static void gsk_render_node_real_diff (GskRenderNode *node1, GskRenderNode *node2, - cairo_region_t *region) + GskDiffData *data) { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } static void @@ -505,21 +505,21 @@ rectangle_init_from_graphene (cairo_rectangle_int_t *cairo, void gsk_render_node_diff_impossible (GskRenderNode *node1, GskRenderNode *node2, - cairo_region_t *region) + GskDiffData *data) { cairo_rectangle_int_t rect; rectangle_init_from_graphene (&rect, &node1->bounds); - cairo_region_union_rectangle (region, &rect); + cairo_region_union_rectangle (data->region, &rect); rectangle_init_from_graphene (&rect, &node2->bounds); - cairo_region_union_rectangle (region, &rect); + cairo_region_union_rectangle (data->region, &rect); } /** * gsk_render_node_diff: * @node1: a `GskRenderNode` * @node2: the `GskRenderNode` to compare with - * @region: a `cairo_region_t` to add the differences to + * @data: the diff data to use * * Compares @node1 and @node2 trying to compute the minimal region of changes. * @@ -536,26 +536,26 @@ gsk_render_node_diff_impossible (GskRenderNode *node1, void gsk_render_node_diff (GskRenderNode *node1, GskRenderNode *node2, - cairo_region_t *region) + GskDiffData *data) { if (node1 == node2) return; if (_gsk_render_node_get_node_type (node1) == _gsk_render_node_get_node_type (node2)) { - GSK_RENDER_NODE_GET_CLASS (node1)->diff (node1, node2, region); + GSK_RENDER_NODE_GET_CLASS (node1)->diff (node1, node2, data); } else if (_gsk_render_node_get_node_type (node1) == GSK_CONTAINER_NODE) { - gsk_container_node_diff_with (node1, node2, region); + gsk_container_node_diff_with (node1, node2, data); } else if (_gsk_render_node_get_node_type (node2) == GSK_CONTAINER_NODE) { - gsk_container_node_diff_with (node2, node1, region); + gsk_container_node_diff_with (node2, node1, data); } else { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } } diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index 32f4258ffb..a92bc41d3b 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -164,9 +164,9 @@ gsk_color_node_draw (GskRenderNode *node, } static void -gsk_color_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_color_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskColorNode *self1 = (GskColorNode *) node1; GskColorNode *self2 = (GskColorNode *) node2; @@ -175,7 +175,7 @@ gsk_color_node_diff (GskRenderNode *node1, gdk_rgba_equal (&self1->color, &self2->color)) return; - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } static void @@ -320,9 +320,9 @@ gsk_linear_gradient_node_draw (GskRenderNode *node, } static void -gsk_linear_gradient_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_linear_gradient_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskLinearGradientNode *self1 = (GskLinearGradientNode *) node1; GskLinearGradientNode *self2 = (GskLinearGradientNode *) node2; @@ -342,14 +342,14 @@ gsk_linear_gradient_node_diff (GskRenderNode *node1, gdk_rgba_equal (&stop1->color, &stop2->color)) continue; - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } return; } - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } static void @@ -649,9 +649,9 @@ gsk_radial_gradient_node_draw (GskRenderNode *node, } static void -gsk_radial_gradient_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_radial_gradient_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskRadialGradientNode *self1 = (GskRadialGradientNode *) node1; GskRadialGradientNode *self2 = (GskRadialGradientNode *) node2; @@ -674,14 +674,14 @@ gsk_radial_gradient_node_diff (GskRenderNode *node1, gdk_rgba_equal (&stop1->color, &stop2->color)) continue; - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } return; } - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } static void @@ -1140,9 +1140,9 @@ gsk_conic_gradient_node_draw (GskRenderNode *node, } static void -gsk_conic_gradient_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_conic_gradient_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskConicGradientNode *self1 = (GskConicGradientNode *) node1; GskConicGradientNode *self2 = (GskConicGradientNode *) node2; @@ -1152,7 +1152,7 @@ gsk_conic_gradient_node_diff (GskRenderNode *node1, self1->rotation != self2->rotation || self1->n_stops != self2->n_stops) { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } @@ -1164,7 +1164,7 @@ gsk_conic_gradient_node_diff (GskRenderNode *node1, if (stop1->offset != stop2->offset || !gdk_rgba_equal (&stop1->color, &stop2->color)) { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } } @@ -1492,9 +1492,9 @@ gsk_border_node_draw (GskRenderNode *node, } static void -gsk_border_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_border_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskBorderNode *self1 = (GskBorderNode *) node1; GskBorderNode *self2 = (GskBorderNode *) node2; @@ -1511,7 +1511,7 @@ gsk_border_node_diff (GskRenderNode *node1, /* Different uniformity -> diff impossible */ if (uniform1 ^ uniform2) { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } @@ -1526,7 +1526,7 @@ gsk_border_node_diff (GskRenderNode *node1, gsk_rounded_rect_equal (&self1->outline, &self2->outline)) return; - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } static void @@ -1783,9 +1783,9 @@ gsk_texture_node_draw (GskRenderNode *node, } static void -gsk_texture_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_texture_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskTextureNode *self1 = (GskTextureNode *) node1; GskTextureNode *self2 = (GskTextureNode *) node2; @@ -1795,7 +1795,7 @@ gsk_texture_node_diff (GskRenderNode *node1, gdk_texture_get_width (self1->texture) != gdk_texture_get_width (self2->texture) || gdk_texture_get_height (self1->texture) != gdk_texture_get_height (self2->texture)) { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } @@ -1804,7 +1804,7 @@ gsk_texture_node_diff (GskRenderNode *node1, sub = cairo_region_create (); gdk_texture_diff (self1->texture, self2->texture, sub); - region_union_region_affine (region, + region_union_region_affine (data->region, sub, node1->bounds.size.width / gdk_texture_get_width (self1->texture), node1->bounds.size.height / gdk_texture_get_height (self1->texture), @@ -1969,9 +1969,9 @@ gsk_texture_scale_node_draw (GskRenderNode *node, } static void -gsk_texture_scale_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_texture_scale_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskTextureScaleNode *self1 = (GskTextureScaleNode *) node1; GskTextureScaleNode *self2 = (GskTextureScaleNode *) node2; @@ -1982,7 +1982,7 @@ gsk_texture_scale_node_diff (GskRenderNode *node1, gdk_texture_get_width (self1->texture) != gdk_texture_get_width (self2->texture) || gdk_texture_get_height (self1->texture) != gdk_texture_get_height (self2->texture)) { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } @@ -1991,7 +1991,7 @@ gsk_texture_scale_node_diff (GskRenderNode *node1, sub = cairo_region_create (); gdk_texture_diff (self1->texture, self2->texture, sub); - region_union_region_affine (region, + region_union_region_affine (data->region, sub, node1->bounds.size.width / gdk_texture_get_width (self1->texture), node1->bounds.size.height / gdk_texture_get_height (self1->texture), @@ -2492,9 +2492,9 @@ gsk_inset_shadow_node_draw (GskRenderNode *node, } static void -gsk_inset_shadow_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_inset_shadow_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskInsetShadowNode *self1 = (GskInsetShadowNode *) node1; GskInsetShadowNode *self2 = (GskInsetShadowNode *) node2; @@ -2507,7 +2507,7 @@ gsk_inset_shadow_node_diff (GskRenderNode *node1, self1->blur_radius == self2->blur_radius) return; - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } static void @@ -2805,9 +2805,9 @@ gsk_outset_shadow_node_draw (GskRenderNode *node, } static void -gsk_outset_shadow_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_outset_shadow_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskOutsetShadowNode *self1 = (GskOutsetShadowNode *) node1; GskOutsetShadowNode *self2 = (GskOutsetShadowNode *) node2; @@ -2820,7 +2820,7 @@ gsk_outset_shadow_node_diff (GskRenderNode *node1, self1->blur_radius == self2->blur_radius) return; - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } static void @@ -3185,25 +3185,26 @@ gsk_container_node_compare_func (gconstpointer elem1, gconstpointer elem2, gpoin } static GskDiffResult -gsk_container_node_keep_func (gconstpointer elem1, gconstpointer elem2, gpointer data) +gsk_container_node_keep_func (gconstpointer elem1, gconstpointer elem2, gpointer user_data) { + GskDiffData *data = user_data; gsk_render_node_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, data); - if (cairo_region_num_rectangles (data) > MAX_RECTS_IN_DIFF) + if (cairo_region_num_rectangles (data->region) > MAX_RECTS_IN_DIFF) return GSK_DIFF_ABORTED; return GSK_DIFF_OK; } static GskDiffResult -gsk_container_node_change_func (gconstpointer elem, gsize idx, gpointer data) +gsk_container_node_change_func (gconstpointer elem, gsize idx, gpointer user_data) { const GskRenderNode *node = elem; - cairo_region_t *region = data; + GskDiffData *data = user_data; cairo_rectangle_int_t rect; gsk_rect_to_cairo_grow (&node->bounds, &rect); - cairo_region_union_rectangle (region, &rect); - if (cairo_region_num_rectangles (region) > MAX_RECTS_IN_DIFF) + cairo_region_union_rectangle (data->region, &rect); + if (cairo_region_num_rectangles (data->region) > MAX_RECTS_IN_DIFF) return GSK_DIFF_ABORTED; return GSK_DIFF_OK; @@ -3231,18 +3232,18 @@ gsk_render_node_diff_multiple (GskRenderNode **nodes1, gsize n_nodes1, GskRenderNode **nodes2, gsize n_nodes2, - cairo_region_t *region) + GskDiffData *data) { return gsk_diff ((gconstpointer *) nodes1, n_nodes1, (gconstpointer *) nodes2, n_nodes2, gsk_container_node_get_diff_settings (), - region) == GSK_DIFF_OK; + data) == GSK_DIFF_OK; } void -gsk_container_node_diff_with (GskRenderNode *container, - GskRenderNode *other, - cairo_region_t *region) +gsk_container_node_diff_with (GskRenderNode *container, + GskRenderNode *other, + GskDiffData *data) { GskContainerNode *self = (GskContainerNode *) container; @@ -3250,16 +3251,16 @@ gsk_container_node_diff_with (GskRenderNode *container, self->n_children, &other, 1, - region)) + data)) return; - gsk_render_node_diff_impossible (container, other, region); + gsk_render_node_diff_impossible (container, other, data); } static void -gsk_container_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_container_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskContainerNode *self1 = (GskContainerNode *) node1; GskContainerNode *self2 = (GskContainerNode *) node2; @@ -3268,10 +3269,10 @@ gsk_container_node_diff (GskRenderNode *node1, self1->n_children, self2->children, self2->n_children, - region)) + data)) return; - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } static void @@ -3486,16 +3487,16 @@ gsk_transform_node_can_diff (const GskRenderNode *node1, } static void -gsk_transform_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_transform_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskTransformNode *self1 = (GskTransformNode *) node1; GskTransformNode *self2 = (GskTransformNode *) node2; if (!gsk_transform_equal (self1->transform, self2->transform)) { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } @@ -3505,7 +3506,7 @@ gsk_transform_node_diff (GskRenderNode *node1, switch (gsk_transform_get_category (self1->transform)) { case GSK_TRANSFORM_CATEGORY_IDENTITY: - gsk_render_node_diff (self1->child, self2->child, region); + gsk_render_node_diff (self1->child, self2->child, data); break; case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE: @@ -3514,7 +3515,7 @@ gsk_transform_node_diff (GskRenderNode *node1, float dx, dy; gsk_transform_to_translate (self1->transform, &dx, &dy); sub = cairo_region_create (); - gsk_render_node_diff (self1->child, self2->child, sub); + gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface }); cairo_region_translate (sub, floorf (dx), floorf (dy)); if (floorf (dx) != dx) { @@ -3530,7 +3531,7 @@ gsk_transform_node_diff (GskRenderNode *node1, cairo_region_union (sub, tmp); cairo_region_destroy (tmp); } - cairo_region_union (region, sub); + cairo_region_union (data->region, sub); cairo_region_destroy (sub); } break; @@ -3541,8 +3542,8 @@ gsk_transform_node_diff (GskRenderNode *node1, float scale_x, scale_y, dx, dy; gsk_transform_to_affine (self1->transform, &scale_x, &scale_y, &dx, &dy); sub = cairo_region_create (); - gsk_render_node_diff (self1->child, self2->child, sub); - region_union_region_affine (region, sub, scale_x, scale_y, dx, dy); + gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface }); + region_union_region_affine (data->region, sub, scale_x, scale_y, dx, dy); cairo_region_destroy (sub); } break; @@ -3552,7 +3553,7 @@ gsk_transform_node_diff (GskRenderNode *node1, case GSK_TRANSFORM_CATEGORY_3D: case GSK_TRANSFORM_CATEGORY_2D: default: - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); break; } } @@ -3704,17 +3705,17 @@ gsk_opacity_node_draw (GskRenderNode *node, } static void -gsk_opacity_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_opacity_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskOpacityNode *self1 = (GskOpacityNode *) node1; GskOpacityNode *self2 = (GskOpacityNode *) node2; if (self1->opacity == self2->opacity) - gsk_render_node_diff (self1->child, self2->child, region); + gsk_render_node_diff (self1->child, self2->child, data); else - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } static void @@ -3918,9 +3919,9 @@ gsk_color_matrix_node_draw (GskRenderNode *node, } static void -gsk_color_matrix_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_color_matrix_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskColorMatrixNode *self1 = (GskColorMatrixNode *) node1; GskColorMatrixNode *self2 = (GskColorMatrixNode *) node2; @@ -3931,11 +3932,11 @@ gsk_color_matrix_node_diff (GskRenderNode *node1, if (!graphene_matrix_equal_fast (&self1->color_matrix, &self2->color_matrix)) goto nope; - gsk_render_node_diff (self1->child, self2->child, region); + gsk_render_node_diff (self1->child, self2->child, data); return; nope: - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } @@ -4212,9 +4213,9 @@ gsk_repeat_node_draw (GskRenderNode *node, } static void -gsk_repeat_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_repeat_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskRepeatNode *self1 = (GskRepeatNode *) node1; GskRepeatNode *self2 = (GskRepeatNode *) node2; @@ -4225,7 +4226,7 @@ gsk_repeat_node_diff (GskRenderNode *node1, cairo_region_t *sub; sub = cairo_region_create(); - gsk_render_node_diff (self1->child, self2->child, sub); + gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface }); if (cairo_region_is_empty (sub)) { cairo_region_destroy (sub); @@ -4234,7 +4235,7 @@ gsk_repeat_node_diff (GskRenderNode *node1, cairo_region_destroy (sub); } - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } static void @@ -4367,9 +4368,9 @@ gsk_clip_node_draw (GskRenderNode *node, } static void -gsk_clip_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_clip_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskClipNode *self1 = (GskClipNode *) node1; GskClipNode *self2 = (GskClipNode *) node2; @@ -4380,15 +4381,15 @@ gsk_clip_node_diff (GskRenderNode *node1, cairo_rectangle_int_t clip_rect; sub = cairo_region_create(); - gsk_render_node_diff (self1->child, self2->child, sub); + gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface }); gsk_rect_to_cairo_grow (&self1->clip, &clip_rect); cairo_region_intersect_rectangle (sub, &clip_rect); - cairo_region_union (region, sub); + cairo_region_union (data->region, sub); cairo_region_destroy (sub); } else { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } } @@ -4515,9 +4516,9 @@ gsk_rounded_clip_node_draw (GskRenderNode *node, } static void -gsk_rounded_clip_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_rounded_clip_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskRoundedClipNode *self1 = (GskRoundedClipNode *) node1; GskRoundedClipNode *self2 = (GskRoundedClipNode *) node2; @@ -4528,15 +4529,15 @@ gsk_rounded_clip_node_diff (GskRenderNode *node1, cairo_rectangle_int_t clip_rect; sub = cairo_region_create(); - gsk_render_node_diff (self1->child, self2->child, sub); + gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface }); gsk_rect_to_cairo_grow (&self1->clip.bounds, &clip_rect); cairo_region_intersect_rectangle (sub, &clip_rect); - cairo_region_union (region, sub); + cairo_region_union (data->region, sub); cairo_region_destroy (sub); } else { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } } @@ -4685,9 +4686,9 @@ gsk_fill_node_draw (GskRenderNode *node, } static void -gsk_fill_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_fill_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskFillNode *self1 = (GskFillNode *) node1; GskFillNode *self2 = (GskFillNode *) node2; @@ -4698,15 +4699,15 @@ gsk_fill_node_diff (GskRenderNode *node1, cairo_rectangle_int_t clip_rect; sub = cairo_region_create(); - gsk_render_node_diff (self1->child, self2->child, sub); + gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface }); gsk_rect_to_cairo_grow (&node1->bounds, &clip_rect); cairo_region_intersect_rectangle (sub, &clip_rect); - cairo_region_union (region, sub); + cairo_region_union (data->region, sub); cairo_region_destroy (sub); } else { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } } @@ -4888,9 +4889,9 @@ gsk_stroke_node_draw (GskRenderNode *node, } static void -gsk_stroke_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_stroke_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskStrokeNode *self1 = (GskStrokeNode *) node1; GskStrokeNode *self2 = (GskStrokeNode *) node2; @@ -4902,15 +4903,15 @@ gsk_stroke_node_diff (GskRenderNode *node1, cairo_rectangle_int_t clip_rect; sub = cairo_region_create(); - gsk_render_node_diff (self1->child, self2->child, sub); + gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface }); gsk_rect_to_cairo_grow (&node1->bounds, &clip_rect); cairo_region_intersect_rectangle (sub, &clip_rect); - cairo_region_union (region, sub); + cairo_region_union (data->region, sub); cairo_region_destroy (sub); } else { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } } @@ -5105,9 +5106,9 @@ gsk_shadow_node_draw (GskRenderNode *node, } static void -gsk_shadow_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_shadow_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskShadowNode *self1 = (GskShadowNode *) node1; GskShadowNode *self2 = (GskShadowNode *) node2; @@ -5118,7 +5119,7 @@ gsk_shadow_node_diff (GskRenderNode *node1, if (self1->n_shadows != self2->n_shadows) { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } @@ -5133,7 +5134,7 @@ gsk_shadow_node_diff (GskRenderNode *node1, shadow1->dy != shadow2->dy || shadow1->radius != shadow2->radius) { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } @@ -5145,7 +5146,7 @@ gsk_shadow_node_diff (GskRenderNode *node1, } sub = cairo_region_create (); - gsk_render_node_diff (self1->child, self2->child, sub); + gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface }); n = cairo_region_num_rectangles (sub); for (i = 0; i < n; i++) @@ -5155,7 +5156,7 @@ gsk_shadow_node_diff (GskRenderNode *node1, rect.y -= top; rect.width += left + right; rect.height += top + bottom; - cairo_region_union_rectangle (region, &rect); + cairo_region_union_rectangle (data->region, &rect); } cairo_region_destroy (sub); } @@ -5381,21 +5382,21 @@ gsk_blend_node_draw (GskRenderNode *node, } static void -gsk_blend_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_blend_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskBlendNode *self1 = (GskBlendNode *) node1; GskBlendNode *self2 = (GskBlendNode *) node2; if (self1->blend_mode == self2->blend_mode) { - gsk_render_node_diff (self1->top, self2->top, region); - gsk_render_node_diff (self1->bottom, self2->bottom, region); + gsk_render_node_diff (self1->top, self2->top, data); + gsk_render_node_diff (self1->bottom, self2->bottom, data); } else { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } } @@ -5551,21 +5552,21 @@ gsk_cross_fade_node_draw (GskRenderNode *node, } static void -gsk_cross_fade_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_cross_fade_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskCrossFadeNode *self1 = (GskCrossFadeNode *) node1; GskCrossFadeNode *self2 = (GskCrossFadeNode *) node2; if (self1->progress == self2->progress) { - gsk_render_node_diff (self1->start, self2->start, region); - gsk_render_node_diff (self1->end, self2->end, region); + gsk_render_node_diff (self1->start, self2->start, data); + gsk_render_node_diff (self1->end, self2->end, data); return; } - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } static void @@ -5724,9 +5725,9 @@ gsk_text_node_draw (GskRenderNode *node, } static void -gsk_text_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_text_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskTextNode *self1 = (GskTextNode *) node1; GskTextNode *self2 = (GskTextNode *) node2; @@ -5751,14 +5752,14 @@ gsk_text_node_diff (GskRenderNode *node1, info1->attr.is_color == info2->attr.is_color) continue; - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } return; } - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } static void @@ -6170,9 +6171,9 @@ gsk_blur_node_draw (GskRenderNode *node, } static void -gsk_blur_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_blur_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskBlurNode *self1 = (GskBlurNode *) node1; GskBlurNode *self2 = (GskBlurNode *) node2; @@ -6185,7 +6186,7 @@ gsk_blur_node_diff (GskRenderNode *node1, clip_radius = ceil (gsk_cairo_blur_compute_pixels (self1->radius / 2.0)); sub = cairo_region_create (); - gsk_render_node_diff (self1->child, self2->child, sub); + gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface }); n = cairo_region_num_rectangles (sub); for (i = 0; i < n; i++) @@ -6195,13 +6196,13 @@ gsk_blur_node_diff (GskRenderNode *node1, rect.y -= clip_radius; rect.width += 2 * clip_radius; rect.height += 2 * clip_radius; - cairo_region_union_rectangle (region, &rect); + cairo_region_union_rectangle (data->region, &rect); } cairo_region_destroy (sub); } else { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } } @@ -6415,21 +6416,21 @@ gsk_mask_node_draw (GskRenderNode *node, } static void -gsk_mask_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_mask_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskMaskNode *self1 = (GskMaskNode *) node1; GskMaskNode *self2 = (GskMaskNode *) node2; if (self1->mask_mode != self2->mask_mode) { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); return; } - gsk_render_node_diff (self1->source, self2->source, region); - gsk_render_node_diff (self1->mask, self2->mask, region); + gsk_render_node_diff (self1->source, self2->source, data); + gsk_render_node_diff (self1->mask, self2->mask, data); } static void @@ -6593,14 +6594,14 @@ gsk_debug_node_can_diff (const GskRenderNode *node1, } static void -gsk_debug_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_debug_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskDebugNode *self1 = (GskDebugNode *) node1; GskDebugNode *self2 = (GskDebugNode *) node2; - gsk_render_node_diff (self1->child, self2->child, region); + gsk_render_node_diff (self1->child, self2->child, data); } static void @@ -6729,9 +6730,9 @@ gsk_gl_shader_node_draw (GskRenderNode *node, } static void -gsk_gl_shader_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_gl_shader_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskGLShaderNode *self1 = (GskGLShaderNode *) node1; GskGLShaderNode *self2 = (GskGLShaderNode *) node2; @@ -6743,14 +6744,14 @@ gsk_gl_shader_node_diff (GskRenderNode *node1, { cairo_region_t *child_region = cairo_region_create(); for (guint i = 0; i < self1->n_children; i++) - gsk_render_node_diff (self1->children[i], self2->children[i], child_region); + gsk_render_node_diff (self1->children[i], self2->children[i], &(GskDiffData) { child_region, data->surface }); if (!cairo_region_is_empty (child_region)) - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); cairo_region_destroy (child_region); } else { - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); } } @@ -6954,9 +6955,9 @@ gsk_subsurface_node_can_diff (const GskRenderNode *node1, } static void -gsk_subsurface_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region) +gsk_subsurface_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskSubsurfaceNode *self1 = (GskSubsurfaceNode *) node1; GskSubsurfaceNode *self2 = (GskSubsurfaceNode *) node2; @@ -6964,7 +6965,12 @@ gsk_subsurface_node_diff (GskRenderNode *node1, if (self1->subsurface != self2->subsurface) { /* Shouldn't happen, can_diff() avoids this, but to be sure */ - gsk_render_node_diff_impossible (node1, node2, region); + gsk_render_node_diff_impossible (node1, node2, data); + } + else if (self1->subsurface->parent != data->surface) + { + /* The inspector case */ + gsk_render_node_diff (self1->child, self2->child, data); } else if (self1->subsurface && gdk_subsurface_get_texture (self1->subsurface) != NULL) { @@ -6973,7 +6979,7 @@ gsk_subsurface_node_diff (GskRenderNode *node1, else { /* not offloaded, diff the children */ - gsk_render_node_diff (self1->child, self2->child, region); + gsk_render_node_diff (self1->child, self2->child, data); } } diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h index 4b4cbbd4fc..9c8565cfb3 100644 --- a/gsk/gskrendernodeprivate.h +++ b/gsk/gskrendernodeprivate.h @@ -36,6 +36,12 @@ struct _GskRenderNode guint offscreen_for_opacity : 1; }; +typedef struct +{ + cairo_region_t *region; + GdkSurface *surface; +} GskDiffData; + struct _GskRenderNodeClass { GTypeClass parent_class; @@ -49,7 +55,7 @@ struct _GskRenderNodeClass const GskRenderNode *node2); void (* diff) (GskRenderNode *node1, GskRenderNode *node2, - cairo_region_t *region); + GskDiffData *data); }; void gsk_render_node_init_types (void); @@ -66,16 +72,13 @@ gboolean gsk_render_node_can_diff (const GskRenderNode const GskRenderNode *node2) G_GNUC_PURE; void gsk_render_node_diff (GskRenderNode *node1, GskRenderNode *node2, - cairo_region_t *region); -void gsk_render_node_data_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region); + GskDiffData *data); void gsk_render_node_diff_impossible (GskRenderNode *node1, GskRenderNode *node2, - cairo_region_t *region); + GskDiffData *data); void gsk_container_node_diff_with (GskRenderNode *container, GskRenderNode *other, - cairo_region_t *region); + GskDiffData *data); void gsk_render_node_draw_fallback (GskRenderNode *node, cairo_t *cr); diff --git a/gtk/inspector/updatesoverlay.c b/gtk/inspector/updatesoverlay.c index 002f47cd9c..45d8a3741c 100644 --- a/gtk/inspector/updatesoverlay.c +++ b/gtk/inspector/updatesoverlay.c @@ -183,7 +183,7 @@ gtk_updates_overlay_snapshot (GtkInspectorOverlay *overlay, cairo_region_t *diff; diff = cairo_region_create (); - gsk_render_node_diff (updates->last, node, diff); + gsk_render_node_diff (updates->last, node, &(GskDiffData) { diff, NULL }); if (cairo_region_is_empty (diff)) cairo_region_destroy (diff); else diff --git a/testsuite/gsk/gtkrendernodeattach.h b/testsuite/gsk/gtkrendernodeattach.h index 689be4516a..6162ae1045 100644 --- a/testsuite/gsk/gtkrendernodeattach.h +++ b/testsuite/gsk/gtkrendernodeattach.h @@ -72,10 +72,6 @@ void _gsk_render_node_unref (GskRenderNode gboolean gsk_render_node_can_diff (const GskRenderNode *node1, const GskRenderNode *node2) G_GNUC_PURE; void gsk_render_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - cairo_region_t *region, - GskOffload *offload); -void gsk_render_node_data_diff (GskRenderNode *node1, GskRenderNode *node2, GskDiffData *data); void gsk_render_node_diff_impossible (GskRenderNode *node1, diff --git a/testsuite/gsk/offload.c b/testsuite/gsk/offload.c index 883f279bb4..953da1b053 100644 --- a/testsuite/gsk/offload.c +++ b/testsuite/gsk/offload.c @@ -458,7 +458,7 @@ parse_node_file (GFile *file, const char *generate) g_clear_pointer (&diff, g_bytes_unref); g_clear_pointer (&reference_file, g_free); - gsk_render_node_diff (node, node2, clip); + gsk_render_node_diff (node, node2, &(GskDiffData) { clip, surface }); if (g_strcmp0 (generate, "diff") == 0) {