[gtk/wip/matthiasc/opbuffer] wip: Cache glyph textures in render nodes
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/matthiasc/opbuffer] wip: Cache glyph textures in render nodes
- Date: Tue, 15 Oct 2019 04:16:58 +0000 (UTC)
commit f301e173b3faba13e66e8ba49345fabb7f01e267
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Oct 15 00:14:43 2019 -0400
wip: Cache glyph textures in render nodes
This is a quick implementation that avoids many
glyph cache lookups. We still need to revalidate
the entry since the atlas it points at may have
been reposessed.
gsk/gl/gskglglyphcache.c | 17 +++++++++++++++++
gsk/gl/gskglglyphcacheprivate.h | 2 ++
gsk/gl/gskglrenderer.c | 17 ++++++++++++-----
gsk/gskrendernodeimpl.c | 31 +++++++++++++++++++++++++++++++
gsk/gskrendernodeprivate.h | 7 +++++++
5 files changed, 69 insertions(+), 5 deletions(-)
---
diff --git a/gsk/gl/gskglglyphcache.c b/gsk/gl/gskglglyphcache.c
index 21121b1ce5..8d988369a3 100644
--- a/gsk/gl/gskglglyphcache.c
+++ b/gsk/gl/gskglglyphcache.c
@@ -358,3 +358,20 @@ gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self,
}
}
}
+
+gboolean
+gsk_gl_glyph_cache_entry_validate (GskGLGlyphCache *cache,
+ GskGLCachedGlyph *value)
+{
+ if (value->timestamp < cache->timestamp)
+ {
+ if (value->atlas)
+ {
+ if (!g_ptr_array_find (cache->atlases->atlases, value->atlas, NULL))
+ return FALSE;
+ }
+ }
+
+ value->timestamp = cache->timestamp;
+ return TRUE;
+}
diff --git a/gsk/gl/gskglglyphcacheprivate.h b/gsk/gl/gskglglyphcacheprivate.h
index 259688fbb7..576106b82a 100644
--- a/gsk/gl/gskglglyphcacheprivate.h
+++ b/gsk/gl/gskglglyphcacheprivate.h
@@ -78,5 +78,7 @@ void gsk_gl_glyph_cache_lookup_or_add (GskGLGlyphCache
GlyphCacheKey *lookup,
GskGLDriver *driver,
const GskGLCachedGlyph **cached_glyph_out);
+gboolean gsk_gl_glyph_cache_entry_validate (GskGLGlyphCache *cache,
+ GskGLCachedGlyph *entry);
#endif
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index b797ce682d..be02d8d250 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -565,6 +565,8 @@ render_text_node (GskGLRenderer *self,
ops_set_color (builder, color);
}
+ gsk_text_node_allocate_render_data (node);
+
lookup.font = (PangoFont *)font;
lookup.scale = (guint) (text_scale * 1024);
@@ -585,12 +587,17 @@ render_text_node (GskGLRenderer *self,
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 = gsk_text_node_get_render_data (node, i);
+ if (!glyph || !gsk_gl_glyph_cache_entry_validate (self->glyph_cache, 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);
+ gsk_gl_glyph_cache_lookup_or_add (self->glyph_cache,
+ &lookup,
+ self->gl_driver,
+ &glyph);
+ gsk_text_node_set_render_data (node, i, glyph);
+ }
if (glyph->texture_id == 0)
goto next;
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index 8c7be01555..80856de69c 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -3414,6 +3414,7 @@ struct _GskTextNode
GdkRGBA color;
graphene_point_t offset;
+ gpointer *render_data;
guint num_glyphs;
PangoGlyphInfo glyphs[];
};
@@ -3423,6 +3424,7 @@ gsk_text_node_finalize (GskRenderNode *node)
{
GskTextNode *self = (GskTextNode *) node;
+ g_free (self->render_data);
g_object_unref (self->font);
}
@@ -3625,6 +3627,35 @@ gsk_text_node_get_offset (GskRenderNode *node)
return &self->offset;
}
+void
+gsk_text_node_allocate_render_data (GskRenderNode *node)
+{
+ GskTextNode *self = (GskTextNode *) node;
+
+ if (!self->render_data)
+ self->render_data = g_new0 (gpointer, self->num_glyphs);
+}
+
+void
+gsk_text_node_set_render_data (GskRenderNode *node,
+ int pos,
+ gpointer data)
+{
+ GskTextNode *self = (GskTextNode *) node;
+
+ self->render_data[pos] = data;
+}
+
+gpointer
+gsk_text_node_get_render_data (GskRenderNode *node,
+ int pos)
+{
+ GskTextNode *self = (GskTextNode *) node;
+
+ return self->render_data[pos];
+}
+
+
/*** GSK_BLUR_NODE ***/
typedef struct _GskBlurNode GskBlurNode;
diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h
index 2ced79738b..f668734df2 100644
--- a/gsk/gskrendernodeprivate.h
+++ b/gsk/gskrendernodeprivate.h
@@ -46,6 +46,13 @@ void gsk_render_node_diff (GskRenderNode *nod
void gsk_render_node_diff_impossible (GskRenderNode *node1,
GskRenderNode *node2,
cairo_region_t *region);
+void gsk_text_node_allocate_render_data (GskRenderNode *node);
+void gsk_text_node_set_render_data (GskRenderNode *node,
+ int pos,
+ gpointer data);
+gpointer gsk_text_node_get_render_data (GskRenderNode *node,
+ int pos);
+
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]