[gtk/glyphy2: 20/28] Make glyphy cache size-independent




commit 8d04c85cdb9d7d0d1124be34176a6d17fae63d5b
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Mar 19 14:32:03 2022 -0400

    Make glyphy cache size-independent
    
    Use a hb font at nominal size when generating sdf
    contours, and use a cache key that is independent
    of the size.

 gsk/gl/gskglglyphylibrary.c        | 42 +++++++++++++++++++++++++++-----------
 gsk/gl/gskglglyphylibraryprivate.h | 40 +++++++++++++++++++++++++++++++++---
 gsk/gl/gskglrenderjob.c            | 15 ++++++++------
 3 files changed, 76 insertions(+), 21 deletions(-)
---
diff --git a/gsk/gl/gskglglyphylibrary.c b/gsk/gl/gskglglyphylibrary.c
index 9411081534..de3dddea7d 100644
--- a/gsk/gl/gskglglyphylibrary.c
+++ b/gsk/gl/gskglglyphylibrary.c
@@ -79,11 +79,7 @@ gsk_gl_glyphy_key_hash (gconstpointer data)
    * for us.
    */
 
-#if GLIB_SIZEOF_VOID_P == 4
-  return (guint)(GPOINTER_TO_SIZE (key->font) << 6) ^ key->glyph;
-#else
-  return (guint)(GPOINTER_TO_SIZE (key->font) << 5) ^ key->glyph;
-#endif
+  return (key->font << 8) ^ key->glyph;
 }
 
 static gboolean
@@ -98,7 +94,6 @@ gsk_gl_glyphy_key_free (gpointer data)
 {
   GskGLGlyphyKey *key = data;
 
-  g_clear_object (&key->font);
   g_slice_free (GskGLGlyphyKey, key);
 }
 
@@ -284,16 +279,39 @@ encode_glyph (GskGLGlyphyLibrary *self,
   return TRUE;
 }
 
+static inline hb_font_t *
+get_nominal_size_hb_font (PangoFont *font)
+{
+  hb_font_t *hbfont;
+  const float *coords;
+  unsigned int length;
+
+  hbfont = (hb_font_t *) g_object_get_data ((GObject *)font, "glyph-nominal-size-font");
+  if (hbfont == NULL)
+    {
+      hbfont = hb_font_create (hb_font_get_face (pango_font_get_hb_font (font)));
+      coords = hb_font_get_var_coords_design (pango_font_get_hb_font (font), &length);
+      if (length > 0)
+        hb_font_set_var_coords_design (hbfont, coords, length);
+
+      g_object_set_data_full ((GObject *)font, "glyphy-nominal-size-font",
+                              hbfont, (GDestroyNotify)hb_font_destroy);
+    }
+
+  return hbfont;
+}
+
 gboolean
 gsk_gl_glyphy_library_add (GskGLGlyphyLibrary      *self,
                            GskGLGlyphyKey          *key,
+                           PangoFont               *font,
                            const GskGLGlyphyValue **out_value)
 {
   static glyphy_rgba_t buffer[4096 * 16];
   GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self;
   GskGLGlyphyValue *value;
   glyphy_extents_t extents;
-  hb_font_t *font;
+  hb_font_t *hbfont;
   guint packed_x;
   guint packed_y;
   guint nominal_w, nominal_h;
@@ -303,15 +321,15 @@ gsk_gl_glyphy_library_add (GskGLGlyphyLibrary      *self,
 
   g_assert (GSK_IS_GL_GLYPHY_LIBRARY (self));
   g_assert (key != NULL);
-  g_assert (key->font != NULL);
+  g_assert (font != NULL);
   g_assert (out_value != NULL);
 
+  hbfont = get_nominal_size_hb_font (font);
+
   /* Convert the glyph to a list of arcs */
-  font = pango_font_get_hb_font (key->font);
-  if (!encode_glyph (self, font, key->glyph, TOLERANCE,
+  if (!encode_glyph (self, hbfont, key->glyph, TOLERANCE,
                      buffer, sizeof buffer, &output_len,
-                     &nominal_w, &nominal_h,
-                     &extents))
+                     &nominal_w, &nominal_h, &extents))
     return FALSE;
 
   /* Allocate space for list within atlas */
diff --git a/gsk/gl/gskglglyphylibraryprivate.h b/gsk/gl/gskglglyphylibraryprivate.h
index 7bd83a5640..651668bd87 100644
--- a/gsk/gl/gskglglyphylibraryprivate.h
+++ b/gsk/gl/gskglglyphylibraryprivate.h
@@ -30,9 +30,42 @@ G_BEGIN_DECLS
 
 #define GSK_TYPE_GL_GLYPHY_LIBRARY (gsk_gl_glyphy_library_get_type())
 
+typedef guint FontKey;
+
+static inline FontKey
+gsk_gl_glyphy_library_get_font_key (PangoFont *font)
+{
+  FontKey key;
+
+  key = (FontKey) GPOINTER_TO_UINT (g_object_get_data ((GObject *)font, "glyphy-font-key"));
+  if (key == 0)
+    {
+      PangoFontDescription *desc = pango_font_describe (font);
+      pango_font_description_set_size (desc, 10 * PANGO_SCALE);
+      key = (FontKey) pango_font_description_hash (desc);
+      pango_font_description_free (desc);
+      g_object_set_data ((GObject *)font, "glyphy-font-key", GUINT_TO_POINTER (key));
+    }
+
+  return key;
+}
+
+static inline float
+gsk_gl_glyphy_library_get_font_scale (PangoFont *font)
+{
+  hb_font_t *hbfont;
+  int x_scale, y_scale;
+
+  hbfont = pango_font_get_hb_font (font);
+  hb_font_get_scale (hbfont, &x_scale, &y_scale);
+
+  return MAX (x_scale, y_scale) / 1000.0;
+}
+
+
 typedef struct _GskGLGlyphyKey
 {
-  PangoFont *font;
+  FontKey font;
   PangoGlyph glyph;
 } GskGLGlyphyKey;
 
@@ -69,11 +102,13 @@ struct _GskGLGlyphyLibrary
 GskGLGlyphyLibrary *gsk_gl_glyphy_library_new (GskGLDriver             *driver);
 gboolean            gsk_gl_glyphy_library_add (GskGLGlyphyLibrary      *self,
                                                GskGLGlyphyKey          *key,
+                                               PangoFont               *font,
                                                const GskGLGlyphyValue **out_value);
 
 static inline guint
 gsk_gl_glyphy_library_lookup_or_add (GskGLGlyphyLibrary      *self,
                                      const GskGLGlyphyKey    *key,
+                                     PangoFont               *font,
                                      const GskGLGlyphyValue **out_value)
 {
   GskGLTextureAtlasEntry *entry;
@@ -92,8 +127,7 @@ gsk_gl_glyphy_library_lookup_or_add (GskGLGlyphyLibrary      *self,
   else
     {
       GskGLGlyphyKey *k = g_slice_copy (sizeof *key, key);
-      g_object_ref (k->font);
-      gsk_gl_glyphy_library_add (self, k, out_value);
+      gsk_gl_glyphy_library_add (self, k, font, out_value);
       self->front[front_index].key = *key;
       self->front[front_index].value = *out_value;
     }
diff --git a/gsk/gl/gskglrenderjob.c b/gsk/gl/gskglrenderjob.c
index 7cdfd815db..2ffcf030a5 100644
--- a/gsk/gl/gskglrenderjob.c
+++ b/gsk/gl/gskglrenderjob.c
@@ -3133,7 +3133,7 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob      *job,
   const PangoGlyphInfo *gi;
   GskGLGlyphyLibrary *library;
   GskGLCommandBatch *batch;
-  const PangoFont *font;
+  PangoFont *font;
   GskGLDrawVertex *vertices;
   const guint16 *c;
   GskGLGlyphyKey lookup;
@@ -3145,6 +3145,7 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob      *job,
   guint used = 0;
   guint i;
   int x_position = 0;
+  float font_scale;
 
   g_assert (!gsk_text_node_has_color_glyphs (node));
 
@@ -3154,7 +3155,7 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob      *job,
   if (RGBA_IS_CLEAR (color))
     return;
 
-  font = gsk_text_node_get_font (node);
+  font = (PangoFont *)gsk_text_node_get_font (node);
   glyphs = gsk_text_node_get_glyphs (node, NULL);
   library = job->driver->glyphy_library;
   offset = gsk_text_node_get_offset (node);
@@ -3169,7 +3170,8 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob      *job,
   batch = gsk_gl_command_queue_get_batch (job->command_queue);
   vertices = gsk_gl_command_queue_add_n_vertices (job->command_queue, num_glyphs);
 
-  lookup.font = (PangoFont *)font;
+  lookup.font = gsk_gl_glyphy_library_get_font_key (font);
+  font_scale = gsk_gl_glyphy_library_get_font_scale (font);
 
   for (i = 0, gi = glyphs; i < num_glyphs; i++, gi++)
     {
@@ -3178,7 +3180,8 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob      *job,
       guint texture_id;
 
       lookup.glyph = gi->glyph;
-      texture_id = gsk_gl_glyphy_library_lookup_or_add (library, &lookup, &glyph);
+      texture_id = gsk_gl_glyphy_library_lookup_or_add (library, &lookup, font, &glyph);
+
       if G_UNLIKELY (texture_id == 0)
         continue;
 
@@ -3228,8 +3231,8 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob      *job,
       EncodedGlyph encoded[4];
 #define ENCODE_CORNER(_cx, _cy) \
   G_STMT_START { \
-    float _vx = x + cx + ((1-_cx) * glyph->extents.min_x + _cx * glyph->extents.max_x); \
-    float _vy = y + cy - ((1-_cy) * glyph->extents.min_y + _cy * glyph->extents.max_y); \
+    float _vx = x + cx + font_scale * ((1-_cx) * glyph->extents.min_x + _cx * glyph->extents.max_x); \
+    float _vy = y + cy - font_scale * ((1-_cy) * glyph->extents.min_y + _cy * glyph->extents.max_y); \
     encoded_glyph_init (&encoded[_cx * 2 + _cy], _vx, _vy, _cx, _cy, glyph); \
   } G_STMT_END
       ENCODE_CORNER (0, 0);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]