[gtk+] gsk: Make text nodes more compact



commit ea91ab1d9917bc4990728bda24c54f25f1e1b0ba
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Oct 27 17:13:40 2017 -0400

    gsk: Make text nodes more compact
    
    The copy of the PangoGlyphString we do here was showing up
    in some profiles. To avoid it, allocate the PangoGlyphInfo array
    as part of the node itself. Update all callers to deal with
    the slight api change required for this.

 gsk/gskrendernode.h                     |    6 +++-
 gsk/gskrendernodeimpl.c                 |   34 +++++++++++++++++++++----------
 gsk/gskvulkancolortextpipeline.c        |    9 ++++---
 gsk/gskvulkancolortextpipelineprivate.h |    3 +-
 gsk/gskvulkanrenderpass.c               |   13 +++++++----
 gsk/gskvulkantextpipeline.c             |    9 ++++---
 gsk/gskvulkantextpipelineprivate.h      |    3 +-
 gtk/inspector/recorder.c                |    9 ++++---
 8 files changed, 54 insertions(+), 32 deletions(-)
---
diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h
index 4e14038..c72cbd8 100644
--- a/gsk/gskrendernode.h
+++ b/gsk/gskrendernode.h
@@ -294,8 +294,10 @@ GskRenderNode *         gsk_text_node_new                       (PangoFont
                                                                  double                    y);
 GDK_AVAILABLE_IN_3_94
 const PangoFont *       gsk_text_node_peek_font                 (GskRenderNode            *node);
-GDK_AVAILABLE_IN_3_94 
-const PangoGlyphString *gsk_text_node_peek_glyphs               (GskRenderNode            *node);
+GDK_AVAILABLE_IN_3_94
+guint                   gsk_text_node_get_num_glyphs            (GskRenderNode            *node);
+GDK_AVAILABLE_IN_3_94
+const PangoGlyphInfo   *gsk_text_node_peek_glyphs               (GskRenderNode            *node);
 GDK_AVAILABLE_IN_3_94
 const GdkRGBA *         gsk_text_node_peek_color                (GskRenderNode            *node);
 GDK_AVAILABLE_IN_3_94
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index 6e502d0..621489b 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -3854,11 +3854,13 @@ struct _GskTextNode
   GskRenderNode render_node;
 
   PangoFont *font;
-  PangoGlyphString *glyphs;
 
   GdkRGBA color;
   double x;
   double y;
+
+  guint num_glyphs;
+  PangoGlyphInfo glyphs[];
 };
 
 static void
@@ -3867,7 +3869,6 @@ gsk_text_node_finalize (GskRenderNode *node)
   GskTextNode *self = (GskTextNode *) node;
 
   g_object_unref (self->font);
-  pango_glyph_string_free (self->glyphs);
 }
 
 #ifndef STACK_BUFFER_SIZE
@@ -3897,15 +3898,15 @@ gsk_text_node_draw (GskRenderNode *node,
   cairo_set_scaled_font (cr, scaled_font);
   gdk_cairo_set_source_rgba (cr, &self->color);
 
-  if (self->glyphs->num_glyphs > (int) G_N_ELEMENTS (stack_glyphs))
-    cairo_glyphs = g_new (cairo_glyph_t, self->glyphs->num_glyphs);
+  if (self->num_glyphs > (int) G_N_ELEMENTS (stack_glyphs))
+    cairo_glyphs = g_new (cairo_glyph_t, self->num_glyphs);
   else
     cairo_glyphs = stack_glyphs;
 
   count = 0;
-  for (i = 0; i < self->glyphs->num_glyphs; i++)
+  for (i = 0; i < self->num_glyphs; i++)
     {
-      PangoGlyphInfo *gi = &self->glyphs->glyphs[i];
+      PangoGlyphInfo *gi = &self->glyphs[i];
 
       if (gi->glyph != PANGO_GLYPH_EMPTY)
         {
@@ -3947,9 +3948,9 @@ gsk_text_node_serialize (GskRenderNode *node)
   s = pango_font_description_to_string (desc);
 
   g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(uiiii)"));
-  for (i = 0; i < self->glyphs->num_glyphs; i++)
+  for (i = 0; i < self->num_glyphs; i++)
     {
-      PangoGlyphInfo *glyph = &self->glyphs->glyphs[i];
+      PangoGlyphInfo *glyph = &self->glyphs[i];
       g_variant_builder_add (&builder, "(uiiii)",
                              glyph->glyph,
                              glyph->geometry.width,
@@ -4071,13 +4072,14 @@ gsk_text_node_new (PangoFont        *font,
   if (ink_rect.width == 0 || ink_rect.height == 0)
     return NULL;
 
-  self = (GskTextNode *) gsk_render_node_new (&GSK_TEXT_NODE_CLASS, 0);
+  self = (GskTextNode *) gsk_render_node_new (&GSK_TEXT_NODE_CLASS, sizeof (PangoGlyphInfo) * 
glyphs->num_glyphs);
 
   self->font = g_object_ref (font);
-  self->glyphs = pango_glyph_string_copy (glyphs);
   self->color = *color;
   self->x = x;
   self->y = y;
+  self->num_glyphs = glyphs->num_glyphs;
+  memcpy (self->glyphs, glyphs->glyphs, sizeof (PangoGlyphInfo) * glyphs->num_glyphs);
 
   graphene_rect_init (&self->render_node.bounds,
                       x,
@@ -4108,7 +4110,17 @@ gsk_text_node_peek_font (GskRenderNode *node)
   return self->font;
 }
 
-const PangoGlyphString *
+guint
+gsk_text_node_get_num_glyphs (GskRenderNode *node)
+{
+  GskTextNode *self = (GskTextNode *) node;
+
+  g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_TEXT_NODE), 0);
+
+  return self->num_glyphs;
+}
+
+const PangoGlyphInfo *
 gsk_text_node_peek_glyphs (GskRenderNode *node)
 {
   GskTextNode *self = (GskTextNode *) node;
diff --git a/gsk/gskvulkancolortextpipeline.c b/gsk/gskvulkancolortextpipeline.c
index a35e734..654b30c 100644
--- a/gsk/gskvulkancolortextpipeline.c
+++ b/gsk/gskvulkancolortextpipeline.c
@@ -98,7 +98,8 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
                                                     GskVulkanRenderer          *renderer,
                                                     const graphene_rect_t      *rect,
                                                     PangoFont                  *font,
-                                                    PangoGlyphString           *glyphs,
+                                                    guint                       total_glyphs,
+                                                    const PangoGlyphInfo       *glyphs,
                                                     float                       x,
                                                     float                       y,
                                                     guint                       start_glyph,
@@ -110,11 +111,11 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
   int x_position = 0;
 
   for (i = 0; i < start_glyph; i++)
-    x_position += glyphs->glyphs[i].geometry.width;
+    x_position += glyphs[i].geometry.width;
 
-  for (; i < glyphs->num_glyphs && count < num_glyphs; i++)
+  for (; i < total_glyphs && count < num_glyphs; i++)
     {
-      PangoGlyphInfo *gi = &glyphs->glyphs[i];
+      const PangoGlyphInfo *gi = &glyphs[i];
 
       if (gi->glyph != PANGO_GLYPH_EMPTY)
         {
diff --git a/gsk/gskvulkancolortextpipelineprivate.h b/gsk/gskvulkancolortextpipelineprivate.h
index bf116c3..9a933ef 100644
--- a/gsk/gskvulkancolortextpipelineprivate.h
+++ b/gsk/gskvulkancolortextpipelineprivate.h
@@ -26,7 +26,8 @@ void                    gsk_vulkan_color_text_pipeline_collect_vertex_data   (Gs
                                                                               GskVulkanRenderer              
*renderer,
                                                                               const graphene_rect_t          
*rect,
                                                                               PangoFont                      
*font,
-                                                                              PangoGlyphString               
*glyphs,
+                                                                              guint                          
 total_glyphs,
+                                                                              const PangoGlyphInfo           
*glyphs,
                                                                               float                          
 x,
                                                                               float                          
 y,
                                                                               guint                          
 start_glyph,
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
index 029c99e..09ba756 100644
--- a/gsk/gskvulkanrenderpass.c
+++ b/gsk/gskvulkanrenderpass.c
@@ -371,7 +371,8 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass           *self,
     case GSK_TEXT_NODE:
       {
         const PangoFont *font = gsk_text_node_peek_font (node);
-        const PangoGlyphString *glyphs = gsk_text_node_peek_glyphs (node);
+        const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node);
+        guint num_glyphs = gsk_text_node_get_num_glyphs (node);
         int i;
         guint count;
         guint texture_index;
@@ -406,9 +407,9 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass           *self,
         op.text.start_glyph = 0;
         op.text.texture_index = G_MAXUINT;
 
-        for (i = 0, count = 0; i < glyphs->num_glyphs; i++)
+        for (i = 0, count = 0; i < num_glyphs; i++)
           {
-            PangoGlyphInfo *gi = &glyphs->glyphs[i];
+            const PangoGlyphInfo *gi = &glyphs[i];
 
             if (gi->glyph != PANGO_GLYPH_EMPTY && !(gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG))
               {
@@ -1225,7 +1226,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                           GSK_VULKAN_RENDERER 
(gsk_vulkan_render_get_renderer (render)),
                                                           &op->text.node->bounds,
                                                           (PangoFont *)gsk_text_node_peek_font 
(op->text.node),
-                                                          (PangoGlyphString *)gsk_text_node_peek_glyphs 
(op->text.node),
+                                                          gsk_text_node_get_num_glyphs (op->text.node),
+                                                          gsk_text_node_peek_glyphs (op->text.node),
                                                           gsk_text_node_peek_color (op->text.node),
                                                           gsk_text_node_get_x (op->text.node),
                                                           gsk_text_node_get_y (op->text.node),
@@ -1243,7 +1245,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                                 GSK_VULKAN_RENDERER 
(gsk_vulkan_render_get_renderer (render)),
                                                                 &op->text.node->bounds,
                                                                 (PangoFont *)gsk_text_node_peek_font 
(op->text.node),
-                                                                (PangoGlyphString 
*)gsk_text_node_peek_glyphs (op->text.node),
+                                                                gsk_text_node_get_num_glyphs (op->text.node),
+                                                                gsk_text_node_peek_glyphs (op->text.node),
                                                                 gsk_text_node_get_x (op->text.node),
                                                                 gsk_text_node_get_y (op->text.node),
                                                                 op->text.start_glyph,
diff --git a/gsk/gskvulkantextpipeline.c b/gsk/gskvulkantextpipeline.c
index 2539ad3..5cdeb15 100644
--- a/gsk/gskvulkantextpipeline.c
+++ b/gsk/gskvulkantextpipeline.c
@@ -105,7 +105,8 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline  *pipeline,
                                               GskVulkanRenderer      *renderer,
                                               const graphene_rect_t  *rect,
                                               PangoFont              *font,
-                                              PangoGlyphString       *glyphs,
+                                              guint                   total_glyphs,
+                                              const PangoGlyphInfo   *glyphs,
                                               const GdkRGBA          *color,
                                               float                   x,
                                               float                   y,
@@ -118,11 +119,11 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline  *pipeline,
   int x_position = 0;
 
   for (i = 0; i < start_glyph; i++)
-    x_position += glyphs->glyphs[i].geometry.width;
+    x_position += glyphs[i].geometry.width;
 
-  for (; i < glyphs->num_glyphs && count < num_glyphs; i++)
+  for (; i < total_glyphs && count < num_glyphs; i++)
     {
-      PangoGlyphInfo *gi = &glyphs->glyphs[i];
+      const PangoGlyphInfo *gi = &glyphs[i];
 
       if (gi->glyph != PANGO_GLYPH_EMPTY)
         {
diff --git a/gsk/gskvulkantextpipelineprivate.h b/gsk/gskvulkantextpipelineprivate.h
index 7701fbb..064045e 100644
--- a/gsk/gskvulkantextpipelineprivate.h
+++ b/gsk/gskvulkantextpipelineprivate.h
@@ -26,7 +26,8 @@ void                    gsk_vulkan_text_pipeline_collect_vertex_data   (GskVulka
                                                                         GskVulkanRenderer              
*renderer,
                                                                         const graphene_rect_t          *rect,
                                                                         PangoFont                      *font,
-                                                                        PangoGlyphString               
*glyphs,
+                                                                        guint                           
total_glyphs,
+                                                                        const PangoGlyphInfo           
*glyphs,
                                                                         const GdkRGBA                  
*color,
                                                                         float                           x,
                                                                         float                           y,
diff --git a/gtk/inspector/recorder.c b/gtk/inspector/recorder.c
index 6423693..be2c3a3 100644
--- a/gtk/inspector/recorder.c
+++ b/gtk/inspector/recorder.c
@@ -379,8 +379,9 @@ populate_render_node_properties (GtkListStore  *store,
     case GSK_TEXT_NODE:
       {
         const PangoFont *font = gsk_text_node_peek_font (node);
-        const PangoGlyphString *glyphs = gsk_text_node_peek_glyphs (node);
+        const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node);
         const GdkRGBA *color = gsk_text_node_peek_color (node);
+        guint num_glyphs = gsk_text_node_get_num_glyphs (node);
         float x = gsk_text_node_get_x (node);
         float y = gsk_text_node_get_y (node);
         PangoFontDescription *desc;
@@ -393,9 +394,9 @@ populate_render_node_properties (GtkListStore  *store,
         g_free (tmp);
         pango_font_description_free (desc);
 
-        s = g_string_sized_new (6 * glyphs->num_glyphs);
-        for (i = 0; i < glyphs->num_glyphs; i++)
-          g_string_append_printf (s, "%x ", glyphs->glyphs[i].glyph);
+        s = g_string_sized_new (6 * num_glyphs);
+        for (i = 0; i < num_glyphs; i++)
+          g_string_append_printf (s, "%x ", glyphs[i].glyph);
         add_text_row (store, "Glyphs", s->str);
         g_string_free (s, TRUE);
 


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