[gtk] gl: glyph cache tweaks



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]