Merge branch 'wip/otte/offload' into 'main'

Rework offload diff handling

See merge request GNOME/gtk!6879
This commit is contained in:
Matthias Clasen
2024-02-12 02:33:14 +00:00
12 changed files with 197 additions and 204 deletions

View File

@@ -42,6 +42,7 @@
#include "gsktransformprivate.h"
#include "gdk/gdkrgbaprivate.h"
#include "gdk/gdksubsurfaceprivate.h"
/* A note about coordinate systems
*

View File

@@ -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;

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -1,7 +1,6 @@
#pragma once
#include "gskrendernode.h"
#include "gskoffloadprivate.h"
#include <cairo.h>
#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,

View File

@@ -19,6 +19,7 @@
#include "gtksnapshot.h"
#include "gdk/gdksubsurfaceprivate.h"
#include "gsk/gskrendernodeprivate.h"
G_BEGIN_DECLS

View File

@@ -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

View File

@@ -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,

View File

@@ -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)
{