[gtk/glyphcache-fiddling: 4/6] Various tweaks to the GL glyph cache



commit 17c24792ee00f957043b7c9039a9a11c96836716
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Oct 9 21:49:43 2019 -0400

    Various tweaks to the GL glyph cache
    
    Try to reduce the cost of lookups.

 gsk/gl/gskglglyphcache.c        | 62 +++++++++++------------------------------
 gsk/gl/gskglglyphcacheprivate.h | 15 +++++-----
 gsk/gl/gskglrenderer.c          | 16 +++++------
 3 files changed, 31 insertions(+), 62 deletions(-)
---
diff --git a/gsk/gl/gskglglyphcache.c b/gsk/gl/gskglglyphcache.c
index d1cf5b06f7..c8f15ca49c 100644
--- a/gsk/gl/gskglglyphcache.c
+++ b/gsk/gl/gskglglyphcache.c
@@ -88,9 +88,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->glyph_and_shift ^
          key->scale;
 }
 
@@ -145,9 +143,9 @@ render_glyph (GlyphCacheKey    *key,
   cairo_set_scaled_font (cr, scaled_font);
   cairo_set_source_rgba (cr, 1, 1, 1, 1);
 
-  glyph_info.glyph = key->glyph;
+  glyph_info.glyph = GLYPH (key->glyph_and_shift);
   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;
@@ -189,7 +187,7 @@ upload_glyph (GlyphCacheKey    *key,
 
   gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
                                           "Uploading glyph %d",
-                                          key->glyph);
+                                          GLYPH (key->glyph_and_shift));
 
   if (render_glyph (key, value, &r))
     {
@@ -247,31 +245,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 +261,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, GLYPH (lookup->glyph_and_shift), &ink_rect, NULL);
       pango_extents_to_pixels (&ink_rect, NULL);
-      if (xshift != 0)
+      if (XSHIFT (lookup->glyph_and_shift) != 0)
         ink_rect.width += 1;
-      if (yshift != 0)
+      if (YSHIFT (lookup->glyph_and_shift) != 0)
         ink_rect.height += 1;
 
       value = g_new0 (GskGLCachedGlyph, 1);
@@ -316,11 +294,9 @@ 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_and_shift = lookup->glyph_and_shift;
+      key->scale = lookup->scale;
 
       if (key->scale > 0 &&
           value->draw_width * key->scale / 1024 > 0 &&
@@ -330,10 +306,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 8d669df6e1..46c7539330 100644
--- a/gsk/gl/gskglglyphcacheprivate.h
+++ b/gsk/gl/gskglglyphcacheprivate.h
@@ -21,12 +21,15 @@ typedef struct
 typedef struct
 {
   PangoFont *font;
-  PangoGlyph glyph;
-  guint xshift;
-  guint yshift;
+  PangoGlyph glyph_and_shift;
   guint scale; /* times 1024 */
 } GlyphCacheKey;
 
+#define GLYPH(x)   ((x) & 0xffffff)
+#define XSHIFT(x)  (((x) >> 24) & 3)
+#define YSHIFT(x)  (((x) >> 26) & 3)
+#define PHASE(x) ((int)(floor (4 * (x + 0.125)) - 4 * floor (x + 0.125)))
+
 typedef struct _GskGLCachedGlyph GskGLCachedGlyph;
 
 struct _GskGLCachedGlyph
@@ -55,11 +58,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 3835aaa2bb..6cec580d2d 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -567,6 +567,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 && font_has_color_glyphs (font))
@@ -579,6 +580,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++)
@@ -596,19 +600,13 @@ render_text_node (GskGLRenderer   *self,
       cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
       cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
 
+      lookup.glyph_and_shift = gi->glyph | (PHASE (x + cx) << 24) | (PHASE (y + cy) << 26);
+
       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]