[gtk] gl: glyph cache tweaks
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk] gl: glyph cache tweaks
- Date: Fri, 11 Oct 2019 20:18:30 +0000 (UTC)
commit 849b950763ce39dcd0f33d7e075e90a6b48e7d0f
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Oct 9 21:49:43 2019 -0400
gl: glyph cache tweaks
Reduce the cost of lookups by storing
the hash value directly.
gsk/gl/gskglglyphcache.c | 63 ++++++++++++-----------------------------
gsk/gl/gskglglyphcacheprivate.h | 31 ++++++++++++++------
gsk/gl/gskglrenderer.c | 16 +++++------
3 files changed, 48 insertions(+), 62 deletions(-)
---
diff --git a/gsk/gl/gskglglyphcache.c b/gsk/gl/gskglglyphcache.c
index d1cf5b06f7..f6206ca1f4 100644
--- a/gsk/gl/gskglglyphcache.c
+++ b/gsk/gl/gskglglyphcache.c
@@ -87,11 +87,7 @@ glyph_cache_hash (gconstpointer v)
{
const GlyphCacheKey *key = v;
- return GPOINTER_TO_UINT (key->font) ^
- key->glyph ^
- (key->xshift << 24) ^
- (key->yshift << 26) ^
- key->scale;
+ return key->hash;
}
static void
@@ -147,7 +143,7 @@ render_glyph (GlyphCacheKey *key,
glyph_info.glyph = key->glyph;
glyph_info.geometry.width = value->draw_width * 1024;
- if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
+ if (glyph_info.glyph & PANGO_GLYPH_UNKNOWN_FLAG)
glyph_info.geometry.x_offset = 0;
else
glyph_info.geometry.x_offset = - value->draw_x * 1024;
@@ -247,31 +243,15 @@ add_to_cache (GskGLGlyphCache *self,
upload_glyph (key, value);
}
-#define PHASE(x) ((int)(floor (4 * (x + 0.125)) - 4 * floor (x + 0.125)))
-
gboolean
gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
- PangoFont *font,
- PangoGlyph glyph,
- float x,
- float y,
- float scale,
+ GlyphCacheKey *lookup,
GskGLDriver *driver,
const GskGLCachedGlyph **cached_glyph_out)
{
GskGLCachedGlyph *value;
- guint xshift = PHASE (x);
- guint yshift = PHASE (y);
- const guint key_scale = (guint)(scale * 1024);
-
- value = g_hash_table_lookup (cache->hash_table,
- &(GlyphCacheKey) {
- .font = font,
- .glyph = glyph,
- .xshift = xshift,
- .yshift = yshift,
- .scale = key_scale
- });
+
+ value = g_hash_table_lookup (cache->hash_table, lookup);
if (value)
{
@@ -279,30 +259,26 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
if (age > MAX_FRAME_AGE)
{
- GskGLTextureAtlas *atlas = value->atlas;
-
- if (atlas && !value->used)
+ if (value->atlas && !value->used)
{
- gsk_gl_texture_atlas_mark_used (atlas, value->draw_width, value->draw_height);
+ gsk_gl_texture_atlas_mark_used (value->atlas, value->draw_width, value->draw_height);
value->used = TRUE;
}
-
- value->timestamp = cache->timestamp;
}
value->timestamp = cache->timestamp;
+ *cached_glyph_out = value;
}
-
- if (value == NULL)
+ else
{
GlyphCacheKey *key;
PangoRectangle ink_rect;
- pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
+ pango_font_get_glyph_extents (lookup->font, lookup->glyph, &ink_rect, NULL);
pango_extents_to_pixels (&ink_rect, NULL);
- if (xshift != 0)
+ if (lookup->xshift != 0)
ink_rect.width += 1;
- if (yshift != 0)
+ if (lookup->yshift != 0)
ink_rect.height += 1;
value = g_new0 (GskGLCachedGlyph, 1);
@@ -316,11 +292,12 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
key = g_new0 (GlyphCacheKey, 1);
- key->font = g_object_ref (font);
- key->glyph = glyph;
- key->xshift = xshift;
- key->yshift = yshift;
- key->scale = key_scale;
+ key->font = g_object_ref (lookup->font);
+ key->glyph = lookup->glyph;
+ key->xshift = lookup->xshift;
+ key->yshift = lookup->yshift;
+ key->scale = lookup->scale;
+ key->hash = lookup->hash;
if (key->scale > 0 &&
value->draw_width * key->scale / 1024 > 0 &&
@@ -330,10 +307,6 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
*cached_glyph_out = value;
g_hash_table_insert (cache->hash_table, key, value);
}
- else
- {
- *cached_glyph_out = value;
- }
return (*cached_glyph_out)->atlas != NULL;
}
diff --git a/gsk/gl/gskglglyphcacheprivate.h b/gsk/gl/gskglglyphcacheprivate.h
index aca44c9835..da1b018fd3 100644
--- a/gsk/gl/gskglglyphcacheprivate.h
+++ b/gsk/gl/gskglglyphcacheprivate.h
@@ -22,11 +22,30 @@ typedef struct
{
PangoFont *font;
PangoGlyph glyph;
- guint xshift;
- guint yshift;
- guint scale; /* times 1024 */
+ guint xshift : 3;
+ guint yshift : 3;
+ guint scale : 26; /* times 1024 */
+ guint hash;
} GlyphCacheKey;
+#define PHASE(x) ((int)(floor (4 * (x + 0.125)) - 4 * floor (x + 0.125)))
+
+static inline void
+glyph_cache_key_set_glyph_and_shift (GlyphCacheKey *key,
+ PangoGlyph glyph,
+ float x,
+ float y)
+{
+ key->glyph = glyph;
+ key->xshift = PHASE (x);
+ key->yshift = PHASE (y);
+ key->hash = GPOINTER_TO_UINT (key->font) ^
+ key->glyph ^
+ (key->xshift << 24) ^
+ (key->yshift << 26) ^
+ key->scale;
+}
+
typedef struct _GskGLCachedGlyph GskGLCachedGlyph;
struct _GskGLCachedGlyph
@@ -55,11 +74,7 @@ GskGLGlyphCache * gsk_gl_glyph_cache_ref (GskGLGlyphCache *se
void gsk_gl_glyph_cache_unref (GskGLGlyphCache *self);
void gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self);
gboolean gsk_gl_glyph_cache_lookup (GskGLGlyphCache *self,
- PangoFont *font,
- PangoGlyph glyph,
- float x,
- float y,
- float scale,
+ GlyphCacheKey *lookup,
GskGLDriver *driver,
const GskGLCachedGlyph **cached_glyph_out);
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 8ea44f9b0f..2ed9d1e9a6 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -552,6 +552,7 @@ render_text_node (GskGLRenderer *self,
const graphene_point_t *offset = gsk_text_node_get_offset (node);
float x = offset->x + builder->dx;
float y = offset->y + builder->dy;
+ GlyphCacheKey lookup;
/* If the font has color glyphs, we don't need to recolor anything */
if (!force_color && gsk_text_node_has_color_glyphs (node))
@@ -564,6 +565,9 @@ render_text_node (GskGLRenderer *self,
ops_set_color (builder, color);
}
+ lookup.font = (PangoFont *)font;
+ lookup.scale = (guint) (text_scale * 1024);
+
/* We use one quad per character, unlike the other nodes which
* use at most one quad altogether */
for (i = 0; i < num_glyphs; i++)
@@ -581,19 +585,13 @@ render_text_node (GskGLRenderer *self,
cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
+ glyph_cache_key_set_glyph_and_shift (&lookup, gi->glyph, x + cx, y + cy);
+
gsk_gl_glyph_cache_lookup (self->glyph_cache,
- (PangoFont *)font,
- gi->glyph,
- x + cx,
- y + cy,
- text_scale,
+ &lookup,
self->gl_driver,
&glyph);
- /* e.g. whitespace */
- if (glyph->draw_width <= 0 || glyph->draw_height <= 0)
- goto next;
-
if (glyph->texture_id == 0)
goto next;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]