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.
This commit is contained in:
Matthias Clasen 2017-10-27 17:13:40 -04:00
parent 999848e0c6
commit ea91ab1d99
8 changed files with 54 additions and 32 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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