diff options
author | Alexander Larsson <alexl@redhat.com> | 2017-11-30 10:36:30 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2017-11-30 21:57:42 +0100 |
commit | 521b09cc964346e1eb5c3c9241cc68bef42f860c (patch) | |
tree | 2a9e1654c50bc73e9e898728f14757238958beb8 /gsk/gskbroadwayrenderer.c | |
parent | 3d4a9324e62b5ae106c335b20261f471ae8fba6b (diff) | |
download | gtk+-521b09cc964346e1eb5c3c9241cc68bef42f860c.tar.gz |
broadway: Send diffs of node trees
Reusing pre-created nodes is a lot faster both in terms of
dom modifications and of transfer sizes.
Diffstat (limited to 'gsk/gskbroadwayrenderer.c')
-rw-r--r-- | gsk/gskbroadwayrenderer.c | 130 |
1 files changed, 72 insertions, 58 deletions
diff --git a/gsk/gskbroadwayrenderer.c b/gsk/gskbroadwayrenderer.c index e388c31b1f..887befdd4a 100644 --- a/gsk/gskbroadwayrenderer.c +++ b/gsk/gskbroadwayrenderer.c @@ -116,10 +116,10 @@ add_float (GArray *nodes, float f) } static void -add_point (GArray *nodes, const graphene_point_t *point) +add_point (GArray *nodes, const graphene_point_t *point, float offset_x, float offset_y) { - add_float (nodes, point->x); - add_float (nodes, point->y); + add_float (nodes, point->x - offset_x); + add_float (nodes, point->y - offset_y); } static void @@ -130,17 +130,17 @@ add_size (GArray *nodes, const graphene_size_t *size) } static void -add_rect (GArray *nodes, const graphene_rect_t *rect) +add_rect (GArray *nodes, const graphene_rect_t *rect, float offset_x, float offset_y) { - add_point (nodes, &rect->origin); + add_point (nodes, &rect->origin, offset_x, offset_y); add_size (nodes, &rect->size); } static void -add_rounded_rect (GArray *nodes, const GskRoundedRect *rrect) +add_rounded_rect (GArray *nodes, const GskRoundedRect *rrect, float offset_x, float offset_y) { int i; - add_rect (nodes, &rrect->bounds); + add_rect (nodes, &rrect->bounds, offset_x, offset_y); for (i = 0; i < 4; i++) add_size (nodes, &rrect->corner[i]); } @@ -461,11 +461,17 @@ node_texture_fallback (GskRenderNode *node, return texture; } +/* Note: This tracks the offset so that we can convert + the absolute coordinates of the GskRenderNodes to + parent-relative which is what the dom uses, and + which is good for re-using subtrees. */ static void gsk_broadway_renderer_add_node (GskRenderer *self, GArray *nodes, GPtrArray *node_textures, - GskRenderNode *node) + GskRenderNode *node, + float offset_x, + float offset_y) { GdkDisplay *display = gsk_renderer_get_display (self); @@ -475,6 +481,8 @@ gsk_broadway_renderer_add_node (GskRenderer *self, g_assert_not_reached (); return; + /* Leaf nodes */ + case GSK_TEXTURE_NODE: { GdkTexture *texture = gsk_texture_node_get_texture (node); @@ -484,10 +492,7 @@ gsk_broadway_renderer_add_node (GskRenderer *self, texture_id = gdk_broadway_display_ensure_texture (display, texture); add_uint32 (nodes, BROADWAY_NODE_TEXTURE); - add_float (nodes, node->bounds.origin.x); - add_float (nodes, node->bounds.origin.y); - add_float (nodes, gdk_texture_get_width (texture)); - add_float (nodes, gdk_texture_get_height (texture)); + add_rect (nodes, &node->bounds, offset_x, offset_y); add_uint32 (nodes, texture_id); } return; @@ -495,39 +500,23 @@ gsk_broadway_renderer_add_node (GskRenderer *self, case GSK_CAIRO_NODE: { const cairo_surface_t *surface = gsk_cairo_node_peek_surface (node); - GdkTexture *texture; + GdkTexture *texture; guint32 texture_id; - texture = gdk_texture_new_for_surface ((cairo_surface_t *)surface); + texture = gdk_texture_new_for_surface ((cairo_surface_t *)surface); g_ptr_array_add (node_textures, g_object_ref (texture)); /* Transfers ownership to node_textures */ texture_id = gdk_broadway_display_ensure_texture (display, texture); add_uint32 (nodes, BROADWAY_NODE_TEXTURE); - add_float (nodes, node->bounds.origin.x); - add_float (nodes, node->bounds.origin.y); - add_float (nodes, node->bounds.size.width); - add_float (nodes, node->bounds.size.height); + add_rect (nodes, &node->bounds, offset_x, offset_y); add_uint32 (nodes, texture_id); } return; - case GSK_CONTAINER_NODE: - { - guint i; - - add_uint32 (nodes, BROADWAY_NODE_CONTAINER); - add_uint32 (nodes, gsk_container_node_get_n_children (node)); - - for (i = 0; i < gsk_container_node_get_n_children (node); i++) - gsk_broadway_renderer_add_node (self, nodes, node_textures, - gsk_container_node_get_child (node, i)); - } - return; - case GSK_COLOR_NODE: { add_uint32 (nodes, BROADWAY_NODE_COLOR); - add_rect (nodes, &node->bounds); + add_rect (nodes, &node->bounds, offset_x, offset_y); add_rgba (nodes, gsk_color_node_peek_color (node)); } return; @@ -536,7 +525,7 @@ gsk_broadway_renderer_add_node (GskRenderer *self, { int i; add_uint32 (nodes, BROADWAY_NODE_BORDER); - add_rounded_rect (nodes, gsk_border_node_peek_outline (node)); + add_rounded_rect (nodes, gsk_border_node_peek_outline (node), offset_x, offset_y); for (i = 0; i < 4; i++) add_float (nodes, gsk_border_node_peek_widths (node)[i]); for (i = 0; i < 4; i++) @@ -547,7 +536,7 @@ gsk_broadway_renderer_add_node (GskRenderer *self, case GSK_OUTSET_SHADOW_NODE: { add_uint32 (nodes, BROADWAY_NODE_OUTSET_SHADOW); - add_rounded_rect (nodes, gsk_outset_shadow_node_peek_outline (node)); + add_rounded_rect (nodes, gsk_outset_shadow_node_peek_outline (node), offset_x, offset_y); add_rgba (nodes, gsk_outset_shadow_node_peek_color (node)); add_float (nodes, gsk_outset_shadow_node_get_dx (node)); add_float (nodes, gsk_outset_shadow_node_get_dy (node)); @@ -559,7 +548,7 @@ gsk_broadway_renderer_add_node (GskRenderer *self, case GSK_INSET_SHADOW_NODE: { add_uint32 (nodes, BROADWAY_NODE_INSET_SHADOW); - add_rounded_rect (nodes, gsk_inset_shadow_node_peek_outline (node)); + add_rounded_rect (nodes, gsk_inset_shadow_node_peek_outline (node), offset_x, offset_y); add_rgba (nodes, gsk_inset_shadow_node_peek_color (node)); add_float (nodes, gsk_inset_shadow_node_get_dx (node)); add_float (nodes, gsk_inset_shadow_node_get_dy (node)); @@ -568,23 +557,14 @@ gsk_broadway_renderer_add_node (GskRenderer *self, } return; - case GSK_ROUNDED_CLIP_NODE: - { - add_uint32 (nodes, BROADWAY_NODE_ROUNDED_CLIP); - add_rounded_rect (nodes, gsk_rounded_clip_node_peek_clip (node)); - gsk_broadway_renderer_add_node (self, nodes, node_textures, - gsk_rounded_clip_node_get_child (node)); - } - return; - case GSK_LINEAR_GRADIENT_NODE: { guint i, n; add_uint32 (nodes, BROADWAY_NODE_LINEAR_GRADIENT); - add_rect (nodes, &node->bounds); - add_point (nodes, gsk_linear_gradient_node_peek_start (node)); - add_point (nodes, gsk_linear_gradient_node_peek_end (node)); + add_rect (nodes, &node->bounds, offset_x, offset_y); + add_point (nodes, gsk_linear_gradient_node_peek_start (node), offset_x, offset_y); + add_point (nodes, gsk_linear_gradient_node_peek_end (node), offset_x, offset_y); n = gsk_linear_gradient_node_get_n_color_stops (node); add_uint32 (nodes, n); for (i = 0; i < n; i++) @@ -592,6 +572,8 @@ gsk_broadway_renderer_add_node (GskRenderer *self, } return; + /* Bin nodes */ + case GSK_SHADOW_NODE: { gsize i, n_shadows = gsk_shadow_node_get_n_shadows (node); @@ -606,7 +588,8 @@ gsk_broadway_renderer_add_node (GskRenderer *self, add_float (nodes, shadow->radius); } gsk_broadway_renderer_add_node (self, nodes, node_textures, - gsk_shadow_node_get_child (node)); + gsk_shadow_node_get_child (node), + offset_x, offset_y); } return; @@ -615,16 +598,47 @@ gsk_broadway_renderer_add_node (GskRenderer *self, add_uint32 (nodes, BROADWAY_NODE_OPACITY); add_float (nodes, gsk_opacity_node_get_opacity (node)); gsk_broadway_renderer_add_node (self, nodes, node_textures, - gsk_opacity_node_get_child (node)); + gsk_opacity_node_get_child (node), + offset_x, offset_y); + } + return; + + case GSK_ROUNDED_CLIP_NODE: + { + const GskRoundedRect *rclip = gsk_rounded_clip_node_peek_clip (node); + add_uint32 (nodes, BROADWAY_NODE_ROUNDED_CLIP); + add_rounded_rect (nodes, rclip, offset_x, offset_y); + gsk_broadway_renderer_add_node (self, nodes, node_textures, + gsk_rounded_clip_node_get_child (node), + rclip->bounds.origin.x, + rclip->bounds.origin.y); } return; case GSK_CLIP_NODE: { + const graphene_rect_t *clip = gsk_clip_node_peek_clip (node); add_uint32 (nodes, BROADWAY_NODE_CLIP); - add_rect (nodes, gsk_clip_node_peek_clip (node)); + add_rect (nodes, clip, offset_x, offset_y); gsk_broadway_renderer_add_node (self, nodes, node_textures, - gsk_clip_node_get_child (node)); + gsk_clip_node_get_child (node), + clip->origin.x, + clip->origin.y); + } + return; + + /* Generic nodes */ + + case GSK_CONTAINER_NODE: + { + guint i; + + add_uint32 (nodes, BROADWAY_NODE_CONTAINER); + add_uint32 (nodes, gsk_container_node_get_n_children (node)); + + for (i = 0; i < gsk_container_node_get_n_children (node); i++) + gsk_broadway_renderer_add_node (self, nodes, node_textures, + gsk_container_node_get_child (node, i), offset_x, offset_y); } return; @@ -643,25 +657,25 @@ gsk_broadway_renderer_add_node (GskRenderer *self, { GdkTexture *texture; guint32 texture_id; - float off_x = 0, off_y = 0; + float t_off_x = 0, t_off_y = 0; - texture = node_cache_lookup (node, &off_x, &off_y); + texture = node_cache_lookup (node, &t_off_x, &t_off_y); if (!texture) { - texture = node_texture_fallback (node, &off_x, &off_y); + texture = node_texture_fallback (node, &t_off_x, &t_off_y); #if 0 g_print ("Fallback %p for %s\n", texture, node->node_class->type_name); #endif - node_cache_store (node, texture, off_x, off_y); + node_cache_store (node, texture, t_off_x, t_off_y); } g_ptr_array_add (node_textures, texture); /* Transfers ownership to node_textures */ texture_id = gdk_broadway_display_ensure_texture (display, texture); add_uint32 (nodes, BROADWAY_NODE_TEXTURE); - add_float (nodes, node->bounds.origin.x + off_x); - add_float (nodes, node->bounds.origin.y + off_y); + add_float (nodes, node->bounds.origin.x + t_off_x - offset_x); + add_float (nodes, node->bounds.origin.y + t_off_y - offset_y); add_float (nodes, gdk_texture_get_width (texture)); add_float (nodes, gdk_texture_get_height (texture)); add_uint32 (nodes, texture_id); @@ -676,7 +690,7 @@ gsk_broadway_renderer_render (GskRenderer *self, GArray *nodes = g_array_new (FALSE, FALSE, sizeof(guint32)); GPtrArray *node_textures = g_ptr_array_new_with_free_func (g_object_unref); - gsk_broadway_renderer_add_node (self, nodes, node_textures, root); + gsk_broadway_renderer_add_node (self, nodes, node_textures, root, 0, 0); gdk_broadway_window_set_nodes (window, nodes, node_textures); g_array_unref (nodes); g_ptr_array_unref (node_textures); |