[gtk] glyph cache: Upload large glyphs in lookup () directly



commit 2c38b71ca53023b843e9bba2fddd97612e2789ab
Author: Timm Bäder <mail baedert org>
Date:   Sun Jul 28 11:57:43 2019 +0200

    glyph cache: Upload large glyphs in lookup () directly
    
    Instead of relying on a texture id of 0, which can happen for other
    reasons, e.g. when the glyph is being scaled too small.
    
    Fixes part of #2046

 gsk/gl/gskglglyphcache.c        | 113 ++++++++++++++--------------------------
 gsk/gl/gskglglyphcacheprivate.h |   8 +--
 gsk/gl/gskglrenderer.c          |  13 ++---
 3 files changed, 45 insertions(+), 89 deletions(-)
---
diff --git a/gsk/gl/gskglglyphcache.c b/gsk/gl/gskglglyphcache.c
index 341d1032ef..9098c64120 100644
--- a/gsk/gl/gskglglyphcache.c
+++ b/gsk/gl/gskglglyphcache.c
@@ -24,6 +24,7 @@
  */
 
 #define MAX_FRAME_AGE (5 * 60)
+#define MAX_GLYPH_SIZE 128 /* Will get its own texture if bigger */
 
 static guint    glyph_cache_hash       (gconstpointer v);
 static gboolean glyph_cache_equal      (gconstpointer v1,
@@ -206,70 +207,45 @@ upload_glyph (GlyphCacheKey    *key,
 static void
 add_to_cache (GskGLGlyphCache  *self,
               GlyphCacheKey    *key,
+              GskGLDriver      *driver,
               GskGLCachedGlyph *value)
 {
   const int width = value->draw_width * key->scale / 1024;
   const int height = value->draw_height * key->scale / 1024;
-  GskGLTextureAtlas *atlas = NULL;
-  int packed_x = 0;
-  int packed_y = 0;
 
-  gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
-
-  value->tx = (float)(packed_x + 1) / atlas->width;
-  value->ty = (float)(packed_y + 1) / atlas->height;
-  value->tw = (float)width / atlas->width;
-  value->th = (float)height / atlas->height;
-  value->used = TRUE;
-
-  value->atlas = atlas;
-  value->texture_id = atlas->texture_id;
-
-  upload_glyph (key, value);
-}
-
-void
-gsk_gl_glyph_cache_get_texture (GskGLDriver      *driver,
-                                PangoFont        *font,
-                                PangoGlyph        glyph,
-                                float             scale,
-                                GskGLCachedGlyph *value)
-{
-  PangoRectangle ink_rect;
-  GlyphCacheKey key;
-  int width, height;
-  guint texture_id;
-
-  pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
-  pango_extents_to_pixels (&ink_rect, NULL);
-
-  key.font = font;
-  key.glyph = glyph;
-  key.scale = (guint)(scale * 1024);
+  if (width < MAX_GLYPH_SIZE && height < MAX_GLYPH_SIZE)
+    {
+      GskGLTextureAtlas *atlas = NULL;
+      int packed_x = 0;
+      int packed_y = 0;
 
-  value->atlas = NULL;
-  value->timestamp = 0;
+      gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
 
-  value->draw_x = ink_rect.x;
-  value->draw_y = ink_rect.y;
-  value->draw_width = ink_rect.width;
-  value->draw_height = ink_rect.height;
+      value->tx = (float)(packed_x + 1) / atlas->width;
+      value->ty = (float)(packed_y + 1) / atlas->height;
+      value->tw = (float)width / atlas->width;
+      value->th = (float)height / atlas->height;
+      value->used = TRUE;
 
-  value->tx = 0.0f;
-  value->ty = 0.0f;
-  value->tw = 1.0f;
-  value->th = 1.0f;
+      value->atlas = atlas;
+      value->texture_id = atlas->texture_id;
+    }
+  else
+    {
+      value->atlas = NULL;
+      value->texture_id = gsk_gl_driver_create_texture (driver, width, height);
 
-  width = value->draw_width * key.scale / 1024;
-  height = value->draw_height * key.scale / 1024;
+      gsk_gl_driver_bind_source_texture (driver, value->texture_id);
+      gsk_gl_driver_init_texture_empty (driver, value->texture_id, GL_NEAREST, GL_NEAREST);
 
-  texture_id = gsk_gl_driver_create_texture (driver, width, height);
-  gsk_gl_driver_bind_source_texture (driver, texture_id);
-  gsk_gl_driver_init_texture_empty (driver, texture_id, GL_NEAREST, GL_NEAREST);
+      value->tx = 0.0f;
+      value->ty = 0.0f;
+      value->tw = 1.0f;
+      value->th = 1.0f;
+    }
 
-  value->texture_id = texture_id;
 
-  upload_glyph (&key, value);
+  upload_glyph (key, value);
 }
 
 gboolean
@@ -277,6 +253,7 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache  *cache,
                            PangoFont        *font,
                            PangoGlyph        glyph,
                            float             scale,
+                           GskGLDriver      *driver,
                            GskGLCachedGlyph *cached_glyph_out)
 {
   GskGLCachedGlyph *value;
@@ -310,6 +287,7 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache  *cache,
 
   if (value == NULL)
     {
+      GlyphCacheKey *key;
       PangoRectangle ink_rect;
       const guint key_scale = (guint)(scale * 1024);
 
@@ -325,30 +303,19 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache  *cache,
       value->timestamp = cache->timestamp;
       value->atlas = NULL; /* For now */
 
-      if ((ink_rect.width * key_scale) < 128 &&
-          (ink_rect.height * key_scale) < 128)
-        {
-          GlyphCacheKey *key;
-
-          key = g_new0 (GlyphCacheKey, 1);
+      key = g_new0 (GlyphCacheKey, 1);
 
-          key->font = g_object_ref (font);
-          key->glyph = glyph;
-          key->scale =  key_scale;
+      key->font = g_object_ref (font);
+      key->glyph = glyph;
+      key->scale =  key_scale;
 
-          if (key->scale > 0 &&
-              ink_rect.width * key->scale > 0 &&
-              ink_rect.height * key->scale > 0)
-            add_to_cache (cache, key, value);
+      if (key->scale > 0 &&
+          ink_rect.width * key->scale > 0 &&
+          ink_rect.height * key->scale > 0)
+        add_to_cache (cache, key, driver, value);
 
-          *cached_glyph_out = *value;
-          g_hash_table_insert (cache->hash_table, key, value);
-        }
-      else
-        {
-          *cached_glyph_out = *value;
-          glyph_cache_value_free (value);
-        }
+      *cached_glyph_out = *value;
+      g_hash_table_insert (cache->hash_table, key, value);
     }
   else
     {
diff --git a/gsk/gl/gskglglyphcacheprivate.h b/gsk/gl/gskglglyphcacheprivate.h
index 72fce67539..a7f5d3e032 100644
--- a/gsk/gl/gskglglyphcacheprivate.h
+++ b/gsk/gl/gskglglyphcacheprivate.h
@@ -56,11 +56,7 @@ gboolean                 gsk_gl_glyph_cache_lookup          (GskGLGlyphCache
                                                              PangoFont              *font,
                                                              PangoGlyph              glyph,
                                                              float                   scale,
-                                                             GskGLCachedGlyph *cached_glyph_out);
-void                    gsk_gl_glyph_cache_get_texture      (GskGLDriver *driver,
-                                                             PangoFont   *font,
-                                                             PangoGlyph   glyph,
-                                                             float        scale,
-                                                             GskGLCachedGlyph *glyph_out);
+                                                             GskGLDriver            *driver,
+                                                             GskGLCachedGlyph       *cached_glyph_out);
 
 #endif
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index e77a9892cd..9438ce2513 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -596,22 +596,15 @@ render_text_node (GskGLRenderer   *self,
                                  (PangoFont *)font,
                                  gi->glyph,
                                  text_scale,
+                                 self->gl_driver,
                                  &glyph);
 
       /* e.g. whitespace */
       if (glyph.draw_width <= 0 || glyph.draw_height <= 0)
         goto next;
 
-      /* big glyphs are not cached */
-      if (!glyph.texture_id)
-        {
-          gsk_gl_glyph_cache_get_texture (self->gl_driver,
-                                          (PangoFont *)font,
-                                          gi->glyph,
-                                          text_scale,
-                                          &glyph);
-          g_assert (glyph.texture_id != 0);
-        }
+      if (glyph.texture_id == 0)
+        goto next;
 
       cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
       cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;


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