if (value)
{
- if (value->atlas && !value->used)
- {
- gsk_gl_texture_atlas_mark_used (value->atlas, value->draw_width, value->draw_height);
- value->used = TRUE;
- }
- value->accessed = TRUE;
-
+ gsk_gl_glyph_cache_entry_validate (cache, value);
*cached_glyph_out = value;
return;
}
{
guint dropped = 0;
+ self->atlas_timestamp++;
+
g_hash_table_iter_init (&iter, self->hash_table);
while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
{
GSK_NOTE(GLYPH_CACHE, g_message ("%d glyphs cached", g_hash_table_size (self->hash_table)));
}
}
+
+void
+gsk_gl_glyph_cache_entry_validate (GskGLGlyphCache *cache,
+ GskGLCachedGlyph *value)
+{
+ value->accessed = TRUE;
+ if (value->atlas && !value->used)
+ {
+ gsk_gl_texture_atlas_mark_used (value->atlas, value->draw_width, value->draw_height);
+ value->used = TRUE;
+ }
+}
ops_draw (builder, offscreen_vertex_data);
}
+typedef struct {
+ int timestamp;
+ GskGLCachedGlyph *glyphs[];
+} TextRenderData;
+
+static inline TextRenderData *
+ensure_render_data (GskRenderNode *node,
+ GskGLGlyphCache *cache)
+{
+ TextRenderData *data;
+ int num_glyphs;
+
+ num_glyphs = gsk_text_node_get_num_glyphs (node);
+ data = gsk_text_node_get_render_data (node);
+ if (data)
+ {
+ if (data->timestamp < cache->atlas_timestamp)
+ {
+ memset (data->glyphs, 0, sizeof (gpointer) * num_glyphs);
+ data->timestamp = cache->atlas_timestamp;
+ }
+ }
+ else
+ {
+ data = g_new0 (TextRenderData, sizeof (TextRenderData) + sizeof (gpointer) * num_glyphs);
+ data->timestamp = cache->atlas_timestamp;
+
+ gsk_text_node_set_render_data (node, data);
+ }
+
+ return data;
+}
+
static inline void
render_text_node (GskGLRenderer *self,
GskRenderNode *node,
float x = offset->x + builder->dx;
float y = offset->y + builder->dy;
GlyphCacheKey lookup;
+ TextRenderData *render_data;
/* If the font has color glyphs, we don't need to recolor anything */
if (!force_color && gsk_text_node_has_color_glyphs (node))
ops_set_color (builder, color);
}
+ render_data = ensure_render_data (node, self->glyph_cache);
+
lookup.font = (PangoFont *)font;
lookup.scale = (guint) (text_scale * 1024);
cx = (float)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
cy = (float)(gi->geometry.y_offset) / PANGO_SCALE;
- glyph_cache_key_set_glyph_and_shift (&lookup, gi->glyph, x + cx, y + cy);
+ glyph = render_data->glyphs[i];
+ if (!glyph)
+ {
+ glyph_cache_key_set_glyph_and_shift (&lookup, gi->glyph, x + cx, y + cy);
+
+ gsk_gl_glyph_cache_lookup_or_add (self->glyph_cache,
+ &lookup,
+ self->gl_driver,
+ &glyph);
+ render_data->glyphs[i] = (GskGLCachedGlyph *)glyph;
+ }
- gsk_gl_glyph_cache_lookup_or_add (self->glyph_cache,
- &lookup,
- self->gl_driver,
- &glyph);
+ gsk_gl_glyph_cache_entry_validate (self->glyph_cache, render_data->glyphs[i]);
if (glyph->texture_id == 0)
goto next;
GdkRGBA color;
graphene_point_t offset;
+ gpointer render_data;
guint num_glyphs;
PangoGlyphInfo glyphs[];
};
{
GskTextNode *self = (GskTextNode *) node;
+ g_free (self->render_data);
g_object_unref (self->font);
}
return &self->offset;
}
+void
+gsk_text_node_set_render_data (GskRenderNode *node,
+ gpointer data)
+{
+ GskTextNode *self = (GskTextNode *) node;
+
+ self->render_data = data;
+}
+
+gpointer
+gsk_text_node_get_render_data (GskRenderNode *node)
+{
+ GskTextNode *self = (GskTextNode *) node;
+
+ return self->render_data;
+}
+
+
/*** GSK_BLUR_NODE ***/
typedef struct _GskBlurNode GskBlurNode;