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/gskoffload.c b/gsk/gskoffload.c index d7b0627dd7..921fb3d94c 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,9 @@ 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) { @@ -606,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; 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/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/gskrenderer.c b/gsk/gskrenderer.c index 380c2712f3..31477b84c7 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -484,25 +484,26 @@ 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); + 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 47a70e91f5..42a0bb5a89 100644 --- a/gsk/gskrendernode.c +++ b/gsk/gskrendernode.c @@ -519,8 +519,7 @@ gsk_render_node_diff_impossible (GskRenderNode *node1, * gsk_render_node_diff: * @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 + * @data: the diff data to use * * Compares @node1 and @node2 trying to compute the minimal region of changes. * @@ -533,28 +532,11 @@ 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) + GskDiffData *data) { if (node1 == node2) return; diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index ec91dc8f79..a92bc41d3b 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" @@ -109,16 +108,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) @@ -175,9 +164,9 @@ gsk_color_node_draw (GskRenderNode *node, } static void -gsk_color_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_color_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskColorNode *self1 = (GskColorNode *) node1; GskColorNode *self2 = (GskColorNode *) node2; @@ -331,9 +320,9 @@ gsk_linear_gradient_node_draw (GskRenderNode *node, } static void -gsk_linear_gradient_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_linear_gradient_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskLinearGradientNode *self1 = (GskLinearGradientNode *) node1; GskLinearGradientNode *self2 = (GskLinearGradientNode *) node2; @@ -660,9 +649,9 @@ gsk_radial_gradient_node_draw (GskRenderNode *node, } static void -gsk_radial_gradient_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_radial_gradient_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskRadialGradientNode *self1 = (GskRadialGradientNode *) node1; GskRadialGradientNode *self2 = (GskRadialGradientNode *) node2; @@ -1151,9 +1140,9 @@ gsk_conic_gradient_node_draw (GskRenderNode *node, } static void -gsk_conic_gradient_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_conic_gradient_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskConicGradientNode *self1 = (GskConicGradientNode *) node1; GskConicGradientNode *self2 = (GskConicGradientNode *) node2; @@ -1503,9 +1492,9 @@ gsk_border_node_draw (GskRenderNode *node, } static void -gsk_border_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_border_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskBorderNode *self1 = (GskBorderNode *) node1; GskBorderNode *self2 = (GskBorderNode *) node2; @@ -1794,9 +1783,9 @@ gsk_texture_node_draw (GskRenderNode *node, } static void -gsk_texture_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_texture_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskTextureNode *self1 = (GskTextureNode *) node1; GskTextureNode *self2 = (GskTextureNode *) node2; @@ -1980,9 +1969,9 @@ gsk_texture_scale_node_draw (GskRenderNode *node, } static void -gsk_texture_scale_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_texture_scale_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskTextureScaleNode *self1 = (GskTextureScaleNode *) node1; GskTextureScaleNode *self2 = (GskTextureScaleNode *) node2; @@ -2457,7 +2446,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 */ @@ -2503,9 +2492,9 @@ gsk_inset_shadow_node_draw (GskRenderNode *node, } static void -gsk_inset_shadow_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_inset_shadow_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskInsetShadowNode *self1 = (GskInsetShadowNode *) node1; GskInsetShadowNode *self2 = (GskInsetShadowNode *) node2; @@ -2816,9 +2805,9 @@ gsk_outset_shadow_node_draw (GskRenderNode *node, } static void -gsk_outset_shadow_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_outset_shadow_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskOutsetShadowNode *self1 = (GskOutsetShadowNode *) node1; GskOutsetShadowNode *self2 = (GskOutsetShadowNode *) node2; @@ -3196,27 +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 *gd = data; - - gsk_render_node_data_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, gd); - if (cairo_region_num_rectangles (gd->region) > MAX_RECTS_IN_DIFF) + GskDiffData *data = user_data; + gsk_render_node_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, data); + 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; - GskDiffData *gd = data; + GskDiffData *data = user_data; cairo_rectangle_int_t rect; - rectangle_init_from_graphene (&rect, &node->bounds); - cairo_region_union_rectangle (gd->region, &rect); - if (cairo_region_num_rectangles (gd->region) > MAX_RECTS_IN_DIFF) + gsk_rect_to_cairo_grow (&node->bounds, &rect); + 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; @@ -3253,9 +3241,9 @@ gsk_render_node_diff_multiple (GskRenderNode **nodes1, } void -gsk_container_node_diff_with (GskRenderNode *container, - GskRenderNode *other, - GskDiffData *data) +gsk_container_node_diff_with (GskRenderNode *container, + GskRenderNode *other, + GskDiffData *data) { GskContainerNode *self = (GskContainerNode *) container; @@ -3270,9 +3258,9 @@ gsk_container_node_diff_with (GskRenderNode *container, } static void -gsk_container_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_container_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskContainerNode *self1 = (GskContainerNode *) node1; GskContainerNode *self2 = (GskContainerNode *) node2; @@ -3499,9 +3487,9 @@ gsk_transform_node_can_diff (const GskRenderNode *node1, } static void -gsk_transform_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_transform_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskTransformNode *self1 = (GskTransformNode *) node1; GskTransformNode *self2 = (GskTransformNode *) node2; @@ -3518,7 +3506,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, data); break; case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE: @@ -3527,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_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload }); + gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface }); cairo_region_translate (sub, floorf (dx), floorf (dy)); if (floorf (dx) != dx) { @@ -3554,7 +3542,7 @@ 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 }); + 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); } @@ -3717,15 +3705,15 @@ gsk_opacity_node_draw (GskRenderNode *node, } static void -gsk_opacity_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +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_data_diff (self1->child, self2->child, data); + gsk_render_node_diff (self1->child, self2->child, data); else gsk_render_node_diff_impossible (node1, node2, data); } @@ -3931,9 +3919,9 @@ gsk_color_matrix_node_draw (GskRenderNode *node, } static void -gsk_color_matrix_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_color_matrix_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskColorMatrixNode *self1 = (GskColorMatrixNode *) node1; GskColorMatrixNode *self2 = (GskColorMatrixNode *) node2; @@ -3944,7 +3932,7 @@ 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, data); return; nope: @@ -4225,9 +4213,9 @@ gsk_repeat_node_draw (GskRenderNode *node, } static void -gsk_repeat_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_repeat_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskRepeatNode *self1 = (GskRepeatNode *) node1; GskRepeatNode *self2 = (GskRepeatNode *) node2; @@ -4238,7 +4226,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, &(GskDiffData) { sub, data->surface }); if (cairo_region_is_empty (sub)) { cairo_region_destroy (sub); @@ -4380,9 +4368,9 @@ gsk_clip_node_draw (GskRenderNode *node, } static void -gsk_clip_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_clip_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskClipNode *self1 = (GskClipNode *) node1; GskClipNode *self2 = (GskClipNode *) node2; @@ -4393,8 +4381,8 @@ 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 }); - rectangle_init_from_graphene (&clip_rect, &self1->clip); + 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 (data->region, sub); cairo_region_destroy (sub); @@ -4528,9 +4516,9 @@ gsk_rounded_clip_node_draw (GskRenderNode *node, } static void -gsk_rounded_clip_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_rounded_clip_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskRoundedClipNode *self1 = (GskRoundedClipNode *) node1; GskRoundedClipNode *self2 = (GskRoundedClipNode *) node2; @@ -4541,8 +4529,8 @@ 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 }); - rectangle_init_from_graphene (&clip_rect, &self1->clip.bounds); + 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 (data->region, sub); cairo_region_destroy (sub); @@ -4698,9 +4686,9 @@ gsk_fill_node_draw (GskRenderNode *node, } static void -gsk_fill_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_fill_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskFillNode *self1 = (GskFillNode *) node1; GskFillNode *self2 = (GskFillNode *) node2; @@ -4711,8 +4699,8 @@ 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 }); - rectangle_init_from_graphene (&clip_rect, &node1->bounds); + 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 (data->region, sub); cairo_region_destroy (sub); @@ -4901,9 +4889,9 @@ gsk_stroke_node_draw (GskRenderNode *node, } static void -gsk_stroke_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_stroke_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskStrokeNode *self1 = (GskStrokeNode *) node1; GskStrokeNode *self2 = (GskStrokeNode *) node2; @@ -4915,8 +4903,8 @@ 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 }); - rectangle_init_from_graphene (&clip_rect, &node1->bounds); + 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 (data->region, sub); cairo_region_destroy (sub); @@ -5118,9 +5106,9 @@ gsk_shadow_node_draw (GskRenderNode *node, } static void -gsk_shadow_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_shadow_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskShadowNode *self1 = (GskShadowNode *) node1; GskShadowNode *self2 = (GskShadowNode *) node2; @@ -5158,7 +5146,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, &(GskDiffData) { sub, data->surface }); n = cairo_region_num_rectangles (sub); for (i = 0; i < n; i++) @@ -5394,17 +5382,17 @@ gsk_blend_node_draw (GskRenderNode *node, } static void -gsk_blend_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +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_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, data); + gsk_render_node_diff (self1->bottom, self2->bottom, data); } else { @@ -5564,17 +5552,17 @@ gsk_cross_fade_node_draw (GskRenderNode *node, } static void -gsk_cross_fade_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +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_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, data); + gsk_render_node_diff (self1->end, self2->end, data); return; } @@ -5737,9 +5725,9 @@ gsk_text_node_draw (GskRenderNode *node, } static void -gsk_text_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_text_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskTextNode *self1 = (GskTextNode *) node1; GskTextNode *self2 = (GskTextNode *) node2; @@ -6183,9 +6171,9 @@ gsk_blur_node_draw (GskRenderNode *node, } static void -gsk_blur_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_blur_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskBlurNode *self1 = (GskBlurNode *) node1; GskBlurNode *self2 = (GskBlurNode *) node2; @@ -6198,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_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload }); + gsk_render_node_diff (self1->child, self2->child, &(GskDiffData) { sub, data->surface }); n = cairo_region_num_rectangles (sub); for (i = 0; i < n; i++) @@ -6428,9 +6416,9 @@ gsk_mask_node_draw (GskRenderNode *node, } static void -gsk_mask_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_mask_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskMaskNode *self1 = (GskMaskNode *) node1; GskMaskNode *self2 = (GskMaskNode *) node2; @@ -6441,8 +6429,8 @@ gsk_mask_node_diff (GskRenderNode *node1, 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, data); + gsk_render_node_diff (self1->mask, self2->mask, data); } static void @@ -6606,14 +6594,14 @@ gsk_debug_node_can_diff (const GskRenderNode *node1, } static void -gsk_debug_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_debug_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { 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, data); } static void @@ -6742,9 +6730,9 @@ gsk_gl_shader_node_draw (GskRenderNode *node, } static void -gsk_gl_shader_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_gl_shader_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskGLShaderNode *self1 = (GskGLShaderNode *) node1; GskGLShaderNode *self2 = (GskGLShaderNode *) node2; @@ -6756,7 +6744,7 @@ 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], &(GskDiffData) { child_region, data->surface }); if (!cairo_region_is_empty (child_region)) gsk_render_node_diff_impossible (node1, node2, data); cairo_region_destroy (child_region); @@ -6967,42 +6955,31 @@ gsk_subsurface_node_can_diff (const GskRenderNode *node1, } static void -gsk_subsurface_node_diff (GskRenderNode *node1, - GskRenderNode *node2, - GskDiffData *data) +gsk_subsurface_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + GskDiffData *data) { GskSubsurfaceNode *self1 = (GskSubsurfaceNode *) node1; GskSubsurfaceNode *self2 = (GskSubsurfaceNode *) node2; - GskOffloadInfo *info1, *info2; - if (!data->offload) - { - 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) - { - gsk_render_node_data_diff (self1->child, self2->child, data); - return; - } - - if (info1->is_offloaded != info2->is_offloaded || - info1->is_above != info2->is_above) + if (self1->subsurface != self2->subsurface) { + /* Shouldn't happen, can_diff() avoids this, but to be sure */ 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 (self1->subsurface->parent != data->surface) { - gsk_render_node_diff_impossible (node1, node2, data); + /* The inspector case */ + gsk_render_node_diff (self1->child, self2->child, data); } - else if (!info1->is_offloaded) + else if (self1->subsurface && gdk_subsurface_get_texture (self1->subsurface) != NULL) { - gsk_render_node_data_diff (self1->child, self2->child, data); + /* offloaded, no contents to compare */ + } + else + { + /* not offloaded, diff the children */ + gsk_render_node_diff (self1->child, self2->child, data); } } diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h index 939429d614..9c8565cfb3 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" @@ -40,7 +39,7 @@ struct _GskRenderNode typedef struct { cairo_region_t *region; - GskOffload *offload; + GdkSurface *surface; } GskDiffData; struct _GskRenderNodeClass @@ -72,10 +71,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/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..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, NULL); + 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 273c55dbd3..953da1b053 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, ", @@ -389,9 +392,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 +430,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,8 +458,7 @@ 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); + gsk_render_node_diff (node, node2, &(GskDiffData) { clip, surface }); if (g_strcmp0 (generate, "diff") == 0) {