[gtk+/wip/alexl/rendernode: 3/4] gsk: Add bounds member to RenderNode



commit ad5d7be1945785eb155deeb971bb730740df5e3c
Author: Alexander Larsson <alexl redhat com>
Date:   Wed Dec 21 11:21:38 2016 +0100

    gsk: Add bounds member to RenderNode
    
    Instead of constantly recalculating this (especially recursively for
    parents!) we do it only on construction, because everything is
    immutable anyway. Also, most nodes had a bounds already and can
    use the new parent member instead.
    
    We also do direct access to the node bounds rather than calling
    gsk_render_node_get_bounds in various places, which means
    we do less copying.

 gsk/gskglrenderer.c        |   24 ++---
 gsk/gskrendernode.c        |   18 +--
 gsk/gskrendernodeimpl.c    |  275 ++++++++++---------------------------------
 gsk/gskrendernodeprivate.h |    4 +-
 gsk/gskvulkanrenderpass.c  |   24 ++---
 5 files changed, 90 insertions(+), 255 deletions(-)
---
diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c
index 09a63ed..96786ca 100644
--- a/gsk/gskglrenderer.c
+++ b/gsk/gskglrenderer.c
@@ -604,7 +604,6 @@ gsk_gl_renderer_add_render_item (GskGLRenderer           *self,
                                  RenderItem              *parent)
 {
   graphene_rect_t viewport;
-  graphene_rect_t bounds;
   RenderItem item;
   RenderItem *ritem = NULL;
   int program_id;
@@ -618,24 +617,22 @@ gsk_gl_renderer_add_render_item (GskGLRenderer           *self,
   if (scale_factor < 1)
     scale_factor = 1;
 
-  gsk_render_node_get_bounds (node, &bounds);
-
   item.node = node;
   item.name = node->name != NULL ? node->name : "unnamed";
 
   /* The texture size */
-  item.size.width = bounds.size.width * scale_factor;
-  item.size.height = bounds.size.height * scale_factor;
+  item.size.width = node->bounds.size.width * scale_factor;
+  item.size.height = node->bounds.size.height * scale_factor;
 
   /* Each render item is an axis-aligned bounding box that we
    * transform using the given transformation matrix
    */
-  item.min.x = bounds.origin.x;
-  item.min.y = bounds.origin.y;
+  item.min.x = node->bounds.origin.x;
+  item.min.y = node->bounds.origin.y;
   item.min.z = 0.f;
 
-  item.max.x = item.min.x + bounds.size.width;
-  item.max.y = item.min.y + bounds.size.height;
+  item.max.x = item.min.x + node->bounds.size.width;
+  item.max.y = item.min.y + node->bounds.size.height;
   item.max.z = 0.f;
 
   /* The location of the item, in normalized world coordinates */
@@ -763,17 +760,14 @@ gsk_gl_renderer_add_render_item (GskGLRenderer           *self,
 
     default:
       {
-        graphene_rect_t bounds;
         cairo_surface_t *surface;
         cairo_t *cr;
 
-        gsk_render_node_get_bounds (node, &bounds);
-
         surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                              ceil (bounds.size.width),
-                                              ceil (bounds.size.height));
+                                              ceil (node->bounds.size.width),
+                                              ceil (node->bounds.size.height));
         cr = cairo_create (surface);
-        cairo_translate (cr, -bounds.origin.x, -bounds.origin.y);
+        cairo_translate (cr, -node->bounds.origin.x, -node->bounds.origin.y);
 
         gsk_render_node_draw (node, cr);
         
diff --git a/gsk/gskrendernode.c b/gsk/gskrendernode.c
index 1cd01f4..1955d74 100644
--- a/gsk/gskrendernode.c
+++ b/gsk/gskrendernode.c
@@ -176,7 +176,7 @@ gsk_render_node_get_bounds (GskRenderNode   *node,
   g_return_if_fail (GSK_IS_RENDER_NODE (node));
   g_return_if_fail (bounds != NULL);
 
-  node->node_class->get_bounds (node, bounds);
+  graphene_rect_init_from_rect (bounds, &node->bounds);
 }
 
 void
@@ -258,14 +258,11 @@ gsk_render_node_draw (GskRenderNode *node,
 
   if (!GSK_RENDER_MODE_CHECK (GEOMETRY))
     {
-      graphene_rect_t frame;
-
-      gsk_render_node_get_bounds (node, &frame);
       GSK_NOTE (CAIRO, g_print ("CLIP = { .x = %g, .y = %g, .width = %g, .height = %g }\n",
-                                frame.origin.x, frame.origin.y,
-                                frame.size.width, frame.size.height));
+                                node->bounds.origin.x, node->bounds.origin.y,
+                                node->bounds.size.width, node->bounds.size.height));
 
-      cairo_rectangle (cr, frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
+      cairo_rectangle (cr, node->bounds.origin.x, node->bounds.origin.y, node->bounds.size.width, 
node->bounds.size.height);
       cairo_clip (cr);
     }
 
@@ -277,12 +274,9 @@ gsk_render_node_draw (GskRenderNode *node,
 
   if (GSK_RENDER_MODE_CHECK (GEOMETRY))
     {
-      graphene_rect_t frame;
-
-      gsk_render_node_get_bounds (node, &frame);
-
       cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
-      cairo_rectangle (cr, frame.origin.x - 1, frame.origin.y - 1, frame.size.width + 2, frame.size.height + 
2);
+      cairo_rectangle (cr, node->bounds.origin.x - 1, node->bounds.origin.y - 1,
+                       node->bounds.size.width + 2, node->bounds.size.height + 2);
       cairo_set_line_width (cr, 2);
       cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
       cairo_stroke (cr);
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index 53c14e9..0dc2c70 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -33,7 +33,6 @@ struct _GskColorNode
   GskRenderNode render_node;
 
   GdkRGBA color;
-  graphene_rect_t bounds;
 };
 
 static void
@@ -50,27 +49,17 @@ gsk_color_node_draw (GskRenderNode *node,
   gdk_cairo_set_source_rgba (cr, &self->color);
 
   cairo_rectangle (cr,
-                   self->bounds.origin.x, self->bounds.origin.y,
-                   self->bounds.size.width, self->bounds.size.height);
+                   node->bounds.origin.x, node->bounds.origin.y,
+                   node->bounds.size.width, node->bounds.size.height);
   cairo_fill (cr);
 }
 
-static void
-gsk_color_node_get_bounds (GskRenderNode   *node,
-                           graphene_rect_t *bounds)
-{
-  GskColorNode *self = (GskColorNode *) node;
-
-  graphene_rect_init_from_rect (bounds, &self->bounds); 
-}
-
 static const GskRenderNodeClass GSK_COLOR_NODE_CLASS = {
   GSK_COLOR_NODE,
   sizeof (GskColorNode),
   "GskColorNode",
   gsk_color_node_finalize,
   gsk_color_node_draw,
-  gsk_color_node_get_bounds
 };
 
 const GdkRGBA *
@@ -105,7 +94,7 @@ gsk_color_node_new (const GdkRGBA         *rgba,
   self = (GskColorNode *) gsk_render_node_new (&GSK_COLOR_NODE_CLASS);
 
   self->color = *rgba;
-  graphene_rect_init_from_rect (&self->bounds, bounds);
+  graphene_rect_init_from_rect (&self->render_node.bounds, bounds);
 
   return &self->render_node;
 }
@@ -118,8 +107,6 @@ struct _GskLinearGradientNode
 {
   GskRenderNode render_node;
 
-  graphene_rect_t bounds;
-
   graphene_point_t start;
   graphene_point_t end;
 
@@ -163,27 +150,17 @@ gsk_linear_gradient_node_draw (GskRenderNode *node,
   cairo_pattern_destroy (pattern);
 
   cairo_rectangle (cr,
-                   self->bounds.origin.x, self->bounds.origin.y,
-                   self->bounds.size.width, self->bounds.size.height);
+                   node->bounds.origin.x, node->bounds.origin.y,
+                   node->bounds.size.width, node->bounds.size.height);
   cairo_fill (cr);
 }
 
-static void
-gsk_linear_gradient_node_get_bounds (GskRenderNode   *node,
-                                     graphene_rect_t *bounds)
-{
-  GskLinearGradientNode *self = (GskLinearGradientNode *) node;
-
-  graphene_rect_init_from_rect (bounds, &self->bounds); 
-}
-
 static const GskRenderNodeClass GSK_LINEAR_GRADIENT_NODE_CLASS = {
   GSK_LINEAR_GRADIENT_NODE,
   sizeof (GskLinearGradientNode),
   "GskLinearGradientNode",
   gsk_linear_gradient_node_finalize,
   gsk_linear_gradient_node_draw,
-  gsk_linear_gradient_node_get_bounds
 };
 
 static const GskRenderNodeClass GSK_REPEATING_LINEAR_GRADIENT_NODE_CLASS = {
@@ -192,7 +169,6 @@ static const GskRenderNodeClass GSK_REPEATING_LINEAR_GRADIENT_NODE_CLASS = {
   "GskLinearGradientNode",
   gsk_linear_gradient_node_finalize,
   gsk_linear_gradient_node_draw,
-  gsk_linear_gradient_node_get_bounds
 };
 
 /**
@@ -223,7 +199,7 @@ gsk_linear_gradient_node_new (const graphene_rect_t  *bounds,
 
   self = (GskLinearGradientNode *) gsk_render_node_new (&GSK_LINEAR_GRADIENT_NODE_CLASS);
 
-  graphene_rect_init_from_rect (&self->bounds, bounds);
+  graphene_rect_init_from_rect (&self->render_node.bounds, bounds);
   graphene_point_init_from_point (&self->start, start);
   graphene_point_init_from_point (&self->end, end);
 
@@ -249,7 +225,7 @@ gsk_repeating_linear_gradient_node_new (const graphene_rect_t  *bounds,
 
   self = (GskLinearGradientNode *) gsk_render_node_new (&GSK_REPEATING_LINEAR_GRADIENT_NODE_CLASS);
 
-  graphene_rect_init_from_rect (&self->bounds, bounds);
+  graphene_rect_init_from_rect (&self->render_node.bounds, bounds);
   graphene_point_init_from_point (&self->start, start);
   graphene_point_init_from_point (&self->end, end);
 
@@ -360,22 +336,12 @@ gsk_border_node_draw (GskRenderNode *node,
   cairo_restore (cr);
 }
 
-static void
-gsk_border_node_get_bounds (GskRenderNode   *node,
-                            graphene_rect_t *bounds)
-{
-  GskBorderNode *self = (GskBorderNode *) node;
-
-  graphene_rect_init_from_rect (bounds, &self->outline.bounds);
-}
-
 static const GskRenderNodeClass GSK_BORDER_NODE_CLASS = {
   GSK_BORDER_NODE,
   sizeof (GskBorderNode),
   "GskBorderNode",
   gsk_border_node_finalize,
   gsk_border_node_draw,
-  gsk_border_node_get_bounds
 };
 
 const GskRoundedRect *
@@ -436,6 +402,8 @@ gsk_border_node_new (const GskRoundedRect     *outline,
   memcpy (self->border_width, border_width, sizeof (self->border_width));
   memcpy (self->border_color, border_color, sizeof (self->border_color));
 
+  graphene_rect_init_from_rect (&self->render_node.bounds, &self->outline.bounds);
+
   return &self->render_node;
 }
 
@@ -448,7 +416,6 @@ struct _GskTextureNode
   GskRenderNode render_node;
 
   GskTexture *texture;
-  graphene_rect_t bounds;
 };
 
 static void
@@ -470,10 +437,10 @@ gsk_texture_node_draw (GskRenderNode *node,
 
   cairo_save (cr);
 
-  cairo_translate (cr, self->bounds.origin.x, self->bounds.origin.y);
+  cairo_translate (cr, node->bounds.origin.x, node->bounds.origin.y);
   cairo_scale (cr,
-               self->bounds.size.width / gsk_texture_get_width (self->texture),
-               self->bounds.size.height / gsk_texture_get_height (self->texture));
+               node->bounds.size.width / gsk_texture_get_width (self->texture),
+               node->bounds.size.height / gsk_texture_get_height (self->texture));
 
   cairo_set_source_surface (cr, surface, 0, 0);
   cairo_paint (cr);
@@ -483,22 +450,12 @@ gsk_texture_node_draw (GskRenderNode *node,
   cairo_surface_destroy (surface);
 }
 
-static void
-gsk_texture_node_get_bounds (GskRenderNode   *node,
-                             graphene_rect_t *bounds)
-{
-  GskTextureNode *self = (GskTextureNode *) node;
-
-  graphene_rect_init_from_rect (bounds, &self->bounds); 
-}
-
 static const GskRenderNodeClass GSK_TEXTURE_NODE_CLASS = {
   GSK_TEXTURE_NODE,
   sizeof (GskTextureNode),
   "GskTextureNode",
   gsk_texture_node_finalize,
   gsk_texture_node_draw,
-  gsk_texture_node_get_bounds
 };
 
 GskTexture *
@@ -535,7 +492,7 @@ gsk_texture_node_new (GskTexture            *texture,
   self = (GskTextureNode *) gsk_render_node_new (&GSK_TEXTURE_NODE_CLASS);
 
   self->texture = gsk_texture_ref (texture);
-  graphene_rect_init_from_rect (&self->bounds, bounds);
+  graphene_rect_init_from_rect (&self->render_node.bounds, bounds);
 
   return &self->render_node;
 }
@@ -944,22 +901,12 @@ gsk_inset_shadow_node_draw (GskRenderNode *node,
   cairo_restore (cr);
 }
 
-static void
-gsk_inset_shadow_node_get_bounds (GskRenderNode   *node,
-                                  graphene_rect_t *bounds)
-{
-  GskInsetShadowNode *self = (GskInsetShadowNode *) node;
-
-  graphene_rect_init_from_rect (bounds, &self->outline.bounds); 
-}
-
 static const GskRenderNodeClass GSK_INSET_SHADOW_NODE_CLASS = {
   GSK_INSET_SHADOW_NODE,
   sizeof (GskInsetShadowNode),
   "GskInsetShadowNode",
   gsk_inset_shadow_node_finalize,
   gsk_inset_shadow_node_draw,
-  gsk_inset_shadow_node_get_bounds
 };
 
 /**
@@ -1000,6 +947,8 @@ gsk_inset_shadow_node_new (const GskRoundedRect *outline,
   self->spread = spread;
   self->blur_radius = blur_radius;
 
+  graphene_rect_init_from_rect (&self->render_node.bounds, &self->outline.bounds);
+
   return &self->render_node;
 }
 
@@ -1144,30 +1093,12 @@ gsk_outset_shadow_node_draw (GskRenderNode *node,
   cairo_restore (cr);
 }
 
-static void
-gsk_outset_shadow_node_get_bounds (GskRenderNode   *node,
-                                   graphene_rect_t *bounds)
-{
-  GskOutsetShadowNode *self = (GskOutsetShadowNode *) node;
-  float top, right, bottom, left;
-
-  gsk_outset_shadow_get_extents (self, &top, &right, &bottom, &left);
-
-  graphene_rect_init_from_rect (bounds, &self->outline.bounds); 
-
-  bounds->origin.x -= left;
-  bounds->origin.y -= top;
-  bounds->size.width += left + right;
-  bounds->size.height += top + bottom;
-}
-
 static const GskRenderNodeClass GSK_OUTSET_SHADOW_NODE_CLASS = {
   GSK_OUTSET_SHADOW_NODE,
   sizeof (GskOutsetShadowNode),
   "GskOutsetShadowNode",
   gsk_outset_shadow_node_finalize,
   gsk_outset_shadow_node_draw,
-  gsk_outset_shadow_node_get_bounds
 };
 
 /**
@@ -1195,6 +1126,7 @@ gsk_outset_shadow_node_new (const GskRoundedRect *outline,
                             float                 blur_radius)
 {
   GskOutsetShadowNode *self;
+  float top, right, bottom, left;
 
   g_return_val_if_fail (outline != NULL, NULL);
   g_return_val_if_fail (color != NULL, NULL);
@@ -1208,6 +1140,15 @@ gsk_outset_shadow_node_new (const GskRoundedRect *outline,
   self->spread = spread;
   self->blur_radius = blur_radius;
 
+  gsk_outset_shadow_get_extents (self, &top, &right, &bottom, &left);
+
+  graphene_rect_init_from_rect (&self->render_node.bounds, &self->outline.bounds);
+
+  self->render_node.bounds.origin.x -= left;
+  self->render_node.bounds.origin.y -= top;
+  self->render_node.bounds.size.width += left + right;
+  self->render_node.bounds.size.height += top + bottom;
+
   return &self->render_node;
 }
 
@@ -1220,7 +1161,6 @@ struct _GskCairoNode
   GskRenderNode render_node;
 
   cairo_surface_t *surface;
-  graphene_rect_t bounds;
 };
 
 static void
@@ -1241,26 +1181,16 @@ gsk_cairo_node_draw (GskRenderNode *node,
   if (self->surface == NULL)
     return;
 
-  cairo_set_source_surface (cr, self->surface, self->bounds.origin.x, self->bounds.origin.y);
+  cairo_set_source_surface (cr, self->surface, node->bounds.origin.x, node->bounds.origin.y);
   cairo_paint (cr);
 }
 
-static void
-gsk_cairo_node_get_bounds (GskRenderNode   *node,
-                           graphene_rect_t *bounds)
-{
-  GskCairoNode *self = (GskCairoNode *) node;
-
-  graphene_rect_init_from_rect (bounds, &self->bounds); 
-}
-
 static const GskRenderNodeClass GSK_CAIRO_NODE_CLASS = {
   GSK_CAIRO_NODE,
   sizeof (GskCairoNode),
   "GskCairoNode",
   gsk_cairo_node_finalize,
   gsk_cairo_node_draw,
-  gsk_cairo_node_get_bounds
 };
 
 /*< private >
@@ -1302,7 +1232,7 @@ gsk_cairo_node_new (const graphene_rect_t *bounds)
 
   self = (GskCairoNode *) gsk_render_node_new (&GSK_CAIRO_NODE_CLASS);
 
-  graphene_rect_init_from_rect (&self->bounds, bounds);
+  graphene_rect_init_from_rect (&self->render_node.bounds, bounds);
 
   return &self->render_node;
 }
@@ -1333,8 +1263,8 @@ gsk_cairo_node_get_draw_context (GskRenderNode *node,
   g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CAIRO_NODE), NULL);
   g_return_val_if_fail (renderer == NULL || GSK_IS_RENDERER (renderer), NULL);
 
-  width = ceilf (self->bounds.size.width);
-  height = ceilf (self->bounds.size.height);
+  width = ceilf (node->bounds.size.width);
+  height = ceilf (node->bounds.size.height);
 
   if (width <= 0 || height <= 0)
     {
@@ -1348,14 +1278,14 @@ gsk_cairo_node_get_draw_context (GskRenderNode *node,
         {
           self->surface = gsk_renderer_create_cairo_surface (renderer,
                                                              CAIRO_FORMAT_ARGB32,
-                                                             ceilf (self->bounds.size.width),
-                                                             ceilf (self->bounds.size.height));
+                                                             ceilf (node->bounds.size.width),
+                                                             ceilf (node->bounds.size.height));
         }
       else
         {
           self->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                                      ceilf (self->bounds.size.width),
-                                                      ceilf (self->bounds.size.height));
+                                                      ceilf (node->bounds.size.width),
+                                                      ceilf (node->bounds.size.height));
         }
       res = cairo_create (self->surface);
     }
@@ -1364,11 +1294,11 @@ gsk_cairo_node_get_draw_context (GskRenderNode *node,
       res = cairo_create (self->surface);
     }
 
-  cairo_translate (res, -self->bounds.origin.x, -self->bounds.origin.y);
+  cairo_translate (res, -node->bounds.origin.x, -node->bounds.origin.y);
 
   cairo_rectangle (res,
-                   self->bounds.origin.x, self->bounds.origin.y,
-                   self->bounds.size.width, self->bounds.size.height);
+                   node->bounds.origin.x, node->bounds.origin.y,
+                   node->bounds.size.width, node->bounds.size.height);
   cairo_clip (res);
 
   if (GSK_DEBUG_CHECK (SURFACE))
@@ -1379,8 +1309,8 @@ gsk_cairo_node_get_draw_context (GskRenderNode *node,
         {
           cairo_save (res);
           cairo_rectangle (res,
-                           self->bounds.origin.x + 1, self->bounds.origin.y + 1,
-                           self->bounds.size.width - 2, self->bounds.size.height - 2);
+                           node->bounds.origin.x + 1, node->bounds.origin.y + 1,
+                           node->bounds.size.width - 2, node->bounds.size.height - 2);
           cairo_set_line_width (res, 2);
           cairo_set_source_rgb (res, 1, 0, 0);
           cairo_stroke (res);
@@ -1429,27 +1359,20 @@ gsk_container_node_draw (GskRenderNode *node,
 }
 
 static void
-gsk_container_node_get_bounds (GskRenderNode   *node,
+gsk_container_node_get_bounds (GskContainerNode *container,
                                graphene_rect_t *bounds)
 {
-  GskContainerNode *container = (GskContainerNode *) node;
   guint i;
 
   if (container->n_children == 0)
     {
-      graphene_rect_init_from_rect (bounds, graphene_rect_zero()); 
+      graphene_rect_init_from_rect (bounds, graphene_rect_zero());
       return;
     }
 
-  gsk_render_node_get_bounds (container->children[0], bounds);
-
+  graphene_rect_init_from_rect (bounds, &container->children[0]->bounds);
   for (i = 1; i < container->n_children; i++)
-    {
-      graphene_rect_t child_bounds;
-  
-      gsk_render_node_get_bounds (container->children[i], &child_bounds);
-      graphene_rect_union (bounds, &child_bounds, bounds);
-    }
+    graphene_rect_union (bounds, &container->children[i]->bounds, bounds);
 }
 
 static const GskRenderNodeClass GSK_CONTAINER_NODE_CLASS = {
@@ -1458,7 +1381,6 @@ static const GskRenderNodeClass GSK_CONTAINER_NODE_CLASS = {
   "GskContainerNode",
   gsk_container_node_finalize,
   gsk_container_node_draw,
-  gsk_container_node_get_bounds
 };
 
 /**
@@ -1488,6 +1410,8 @@ gsk_container_node_new (GskRenderNode **children,
   for (i = 0; i < container->n_children; i++)
     gsk_render_node_ref (container->children[i]);
 
+  gsk_container_node_get_bounds (container, &container->render_node.bounds);
+
   return &container->render_node;
 }
 
@@ -1562,37 +1486,18 @@ gsk_transform_node_draw (GskRenderNode *node,
     }
   else
     {
-      graphene_rect_t bounds;
-
-      gsk_render_node_get_bounds (node, &bounds);
-
       cairo_set_source_rgb (cr, 255 / 255., 105 / 255., 180 / 255.);
-      cairo_rectangle (cr, bounds.origin.x, bounds.origin.x, bounds.size.width, bounds.size.height);
+      cairo_rectangle (cr, node->bounds.origin.x, node->bounds.origin.x, node->bounds.size.width, 
node->bounds.size.height);
       cairo_fill (cr);
     }
 }
 
-static void
-gsk_transform_node_get_bounds (GskRenderNode   *node,
-                               graphene_rect_t *bounds)
-{
-  GskTransformNode *self = (GskTransformNode *) node;
-  graphene_rect_t child_bounds;
-
-  gsk_render_node_get_bounds (self->child, &child_bounds);
-
-  graphene_matrix_transform_bounds (&self->transform,
-                                    &child_bounds,
-                                    bounds);
-}
-
 static const GskRenderNodeClass GSK_TRANSFORM_NODE_CLASS = {
   GSK_TRANSFORM_NODE,
   sizeof (GskTransformNode),
   "GskTransformNode",
   gsk_transform_node_finalize,
   gsk_transform_node_draw,
-  gsk_transform_node_get_bounds
 };
 
 /**
@@ -1621,6 +1526,9 @@ gsk_transform_node_new (GskRenderNode           *child,
   self->child = gsk_render_node_ref (child);
   graphene_matrix_init_from_matrix (&self->transform, transform);
 
+  graphene_matrix_transform_bounds (&self->transform,
+                                    &child->bounds,
+                                    &self->render_node.bounds);
   return &self->render_node;
 }
 
@@ -1678,13 +1586,12 @@ gsk_opacity_node_draw (GskRenderNode *node,
                        cairo_t       *cr)
 {
   GskOpacityNode *self = (GskOpacityNode *) node;
-  graphene_rect_t bounds;
 
   cairo_save (cr);
 
   /* clip so the push_group() creates a smaller surface */
-  gsk_render_node_get_bounds (self->child, &bounds);
-  cairo_rectangle (cr, bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
+  cairo_rectangle (cr, node->bounds.origin.x, node->bounds.origin.y,
+                   node->bounds.size.width, node->bounds.size.height);
   cairo_clip (cr);
 
   cairo_push_group (cr);
@@ -1697,22 +1604,12 @@ gsk_opacity_node_draw (GskRenderNode *node,
   cairo_restore (cr);
 }
 
-static void
-gsk_opacity_node_get_bounds (GskRenderNode   *node,
-                             graphene_rect_t *bounds)
-{
-  GskOpacityNode *self = (GskOpacityNode *) node;
-
-  gsk_render_node_get_bounds (self->child, bounds);
-}
-
 static const GskRenderNodeClass GSK_OPACITY_NODE_CLASS = {
   GSK_OPACITY_NODE,
   sizeof (GskOpacityNode),
   "GskOpacityNode",
   gsk_opacity_node_finalize,
   gsk_opacity_node_draw,
-  gsk_opacity_node_get_bounds
 };
 
 /**
@@ -1740,6 +1637,8 @@ gsk_opacity_node_new (GskRenderNode *child,
   self->child = gsk_render_node_ref (child);
   self->opacity = CLAMP (opacity, 0.0, 1.0);
 
+  graphene_rect_init_from_rect (&self->render_node.bounds, &child->bounds);
+
   return &self->render_node;
 }
 
@@ -1809,25 +1708,12 @@ gsk_clip_node_draw (GskRenderNode *node,
   cairo_restore (cr);
 }
 
-static void
-gsk_clip_node_get_bounds (GskRenderNode   *node,
-                          graphene_rect_t *bounds)
-{
-  GskClipNode *self = (GskClipNode *) node;
-  graphene_rect_t child_bounds;
-
-  gsk_render_node_get_bounds (self->child, &child_bounds);
-
-  graphene_rect_intersection (&self->clip, &child_bounds, bounds);
-}
-
 static const GskRenderNodeClass GSK_CLIP_NODE_CLASS = {
   GSK_CLIP_NODE,
   sizeof (GskClipNode),
   "GskClipNode",
   gsk_clip_node_finalize,
   gsk_clip_node_draw,
-  gsk_clip_node_get_bounds
 };
 
 /**
@@ -1856,6 +1742,8 @@ gsk_clip_node_new (GskRenderNode         *child,
   self->child = gsk_render_node_ref (child);
   graphene_rect_normalize_r (clip, &self->clip);
 
+  graphene_rect_intersection (&self->clip, &child->bounds, &self->render_node.bounds);
+
   return &self->render_node;
 }
 
@@ -1923,25 +1811,12 @@ gsk_rounded_clip_node_draw (GskRenderNode *node,
   cairo_restore (cr);
 }
 
-static void
-gsk_rounded_clip_node_get_bounds (GskRenderNode   *node,
-                                  graphene_rect_t *bounds)
-{
-  GskRoundedClipNode *self = (GskRoundedClipNode *) node;
-  graphene_rect_t child_bounds;
-
-  gsk_render_node_get_bounds (self->child, &child_bounds);
-
-  graphene_rect_intersection (&self->clip.bounds, &child_bounds, bounds);
-}
-
 static const GskRenderNodeClass GSK_ROUNDED_CLIP_NODE_CLASS = {
   GSK_ROUNDED_CLIP_NODE,
   sizeof (GskRoundedClipNode),
   "GskRoundedClipNode",
   gsk_rounded_clip_node_finalize,
   gsk_rounded_clip_node_draw,
-  gsk_rounded_clip_node_get_bounds
 };
 
 /**
@@ -1970,6 +1845,8 @@ gsk_rounded_clip_node_new (GskRenderNode         *child,
   self->child = gsk_render_node_ref (child);
   gsk_rounded_rect_init_copy (&self->clip, clip);
 
+  graphene_rect_intersection (&self->clip.bounds, &child->bounds, &self->render_node.bounds);
+
   return &self->render_node;
 }
 
@@ -2063,14 +1940,13 @@ gsk_shadow_node_draw (GskRenderNode *node,
 }
 
 static void
-gsk_shadow_node_get_bounds (GskRenderNode   *node,
+gsk_shadow_node_get_bounds (GskShadowNode *self,
                             graphene_rect_t *bounds)
 {
-  GskShadowNode *self = (GskShadowNode *) node;
   float top = 0, right = 0, bottom = 0, left = 0;
   gsize i;
 
-  gsk_render_node_get_bounds (self->child, bounds);
+  graphene_rect_init_from_rect (bounds, &self->child->bounds);
 
   for (i = 0; i < self->n_shadows; i++)
     {
@@ -2093,7 +1969,6 @@ static const GskRenderNodeClass GSK_SHADOW_NODE_CLASS = {
   "GskShadowNode",
   gsk_shadow_node_finalize,
   gsk_shadow_node_draw,
-  gsk_shadow_node_get_bounds
 };
 
 /**
@@ -2126,6 +2001,8 @@ gsk_shadow_node_new (GskRenderNode         *child,
   self->shadows = g_memdup (shadows, n_shadows * sizeof (GskShadow));
   self->n_shadows = n_shadows;
 
+  gsk_shadow_node_get_bounds (self, &self->render_node.bounds);
+
   return &self->render_node;
 }
 
@@ -2245,26 +2122,12 @@ gsk_blend_node_draw (GskRenderNode *node,
   cairo_paint (cr);
 }
 
-static void
-gsk_blend_node_get_bounds (GskRenderNode   *node,
-                           graphene_rect_t *bounds)
-{
-  GskBlendNode *self = (GskBlendNode *) node;
-  graphene_rect_t bottom_bounds, top_bounds;
-
-  gsk_render_node_get_bounds (self->bottom, &bottom_bounds);
-  gsk_render_node_get_bounds (self->top, &top_bounds);
-
-  graphene_rect_union (&bottom_bounds, &top_bounds, bounds);
-}
-
 static const GskRenderNodeClass GSK_BLEND_NODE_CLASS = {
   GSK_BLEND_NODE,
   sizeof (GskBlendNode),
   "GskBlendNode",
   gsk_blend_node_finalize,
   gsk_blend_node_draw,
-  gsk_blend_node_get_bounds
 };
 
 /**
@@ -2296,6 +2159,8 @@ gsk_blend_node_new (GskRenderNode *bottom,
   self->top = gsk_render_node_ref (top);
   self->blend_mode = blend_mode;
 
+  graphene_rect_union (&bottom->bounds, &top->bounds, &self->render_node.bounds);
+
   return &self->render_node;
 }
 
@@ -2371,26 +2236,12 @@ gsk_cross_fade_node_draw (GskRenderNode *node,
   cairo_paint (cr);
 }
 
-static void
-gsk_cross_fade_node_get_bounds (GskRenderNode   *node,
-                                graphene_rect_t *bounds)
-{
-  GskCrossFadeNode *self = (GskCrossFadeNode *) node;
-  graphene_rect_t start_bounds, end_bounds;
-
-  gsk_render_node_get_bounds (self->start, &start_bounds);
-  gsk_render_node_get_bounds (self->end, &end_bounds);
-
-  graphene_rect_union (&start_bounds, &end_bounds, bounds);
-}
-
 static const GskRenderNodeClass GSK_CROSS_FADE_NODE_CLASS = {
   GSK_CROSS_FADE_NODE,
   sizeof (GskCrossFadeNode),
   "GskCrossFadeNode",
   gsk_cross_fade_node_finalize,
   gsk_cross_fade_node_draw,
-  gsk_cross_fade_node_get_bounds
 };
 
 /**
@@ -2422,6 +2273,8 @@ gsk_cross_fade_node_new (GskRenderNode *start,
   self->end = gsk_render_node_ref (end);
   self->progress = CLAMP (progress, 0.0, 1.0);
 
+  graphene_rect_union (&start->bounds, &end->bounds, &self->render_node.bounds);
+
   return &self->render_node;
 }
 
diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h
index 0566f8a..2f3d37b 100644
--- a/gsk/gskrendernodeprivate.h
+++ b/gsk/gskrendernodeprivate.h
@@ -22,6 +22,8 @@ struct _GskRenderNode
   /* Scaling filters */
   GskScalingFilter min_filter;
   GskScalingFilter mag_filter;
+
+  graphene_rect_t bounds;
 };
 
 struct _GskRenderNodeClass
@@ -32,8 +34,6 @@ struct _GskRenderNodeClass
   void (* finalize) (GskRenderNode *node);
   void (* draw) (GskRenderNode *node,
                  cairo_t       *cr);
-  void (* get_bounds) (GskRenderNode   *node,
-                       graphene_rect_t *bounds);
 };
 
 GskRenderNode *gsk_render_node_new (const GskRenderNodeClass *node_class);
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
index 2af91dc..389a2ef 100644
--- a/gsk/gskvulkanrenderpass.c
+++ b/gsk/gskvulkanrenderpass.c
@@ -171,20 +171,20 @@ gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass  *self,
                                         GskVulkanRender      *render,
                                         GskVulkanUploader    *uploader)
 {
-  graphene_rect_t bounds;
+  GskRenderNode *node;
   cairo_surface_t *surface;
   cairo_t *cr;
 
-  gsk_render_node_get_bounds (op->node, &bounds);
+  node = op->node;
 
   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                        ceil (bounds.size.width),
-                                        ceil (bounds.size.height));
+                                        ceil (node->bounds.size.width),
+                                        ceil (node->bounds.size.height));
   cr = cairo_create (surface);
-  cairo_translate (cr, -bounds.origin.x, -bounds.origin.y);
+  cairo_translate (cr, -node->bounds.origin.x, -node->bounds.origin.y);
+
+  gsk_render_node_draw (node, cr);
 
-  gsk_render_node_draw (op->node, cr);
-  
   cairo_destroy (cr);
 
   op->source = gsk_vulkan_image_new_from_data (uploader,
@@ -303,26 +303,20 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
         case GSK_VULKAN_OP_SURFACE:
         case GSK_VULKAN_OP_TEXTURE:
           {
-            graphene_rect_t bounds;
-
-            gsk_render_node_get_bounds (op->render.node, &bounds);
             op->render.vertex_offset = offset + n_bytes;
             gsk_vulkan_blend_pipeline_collect_vertex_data (GSK_VULKAN_BLEND_PIPELINE (op->render.pipeline),
                                                            data + n_bytes + offset,
-                                                           &bounds);
+                                                           &op->render.node.bounds);
             n_bytes += op->render.vertex_count;
           }
           break;
 
         case GSK_VULKAN_OP_COLOR:
           {
-            graphene_rect_t bounds;
-
-            gsk_render_node_get_bounds (op->render.node, &bounds);
             op->render.vertex_offset = offset + n_bytes;
             gsk_vulkan_color_pipeline_collect_vertex_data (GSK_VULKAN_COLOR_PIPELINE (op->render.pipeline),
                                                            data + n_bytes + offset,
-                                                           &bounds,
+                                                           &op->render.node.bounds,
                                                            gsk_color_node_peek_color (op->render.node));
             n_bytes += op->render.vertex_count;
           }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]