[gtk+] gsk: Scale glyphs in the glyph cache



commit a0bbd14325db6b36083e7b79e9938b997d060767
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Oct 28 13:13:31 2017 -0400

    gsk: Scale glyphs in the glyph cache
    
    Pass a scale factor when caching glyphs or looking them
    up in the cache. The glyphs in the cache are rendered
    with subpixel precision determined by the scale. Update
    all callers to pass a scale factor according to the window
    scale. This lets us render crisp glyphs on hidpi systems.

 gsk/gskvulkancolortextpipeline.c        |    5 +++--
 gsk/gskvulkancolortextpipelineprivate.h |    3 ++-
 gsk/gskvulkanglyphcache.c               |   30 +++++++++++++++++++-----------
 gsk/gskvulkanglyphcacheprivate.h        |    3 ++-
 gsk/gskvulkanrenderer.c                 |   10 ++++++----
 gsk/gskvulkanrendererprivate.h          |    6 ++++--
 gsk/gskvulkanrenderpass.c               |   10 +++++++---
 gsk/gskvulkantextpipeline.c             |    5 +++--
 gsk/gskvulkantextpipelineprivate.h      |    3 ++-
 9 files changed, 48 insertions(+), 27 deletions(-)
---
diff --git a/gsk/gskvulkancolortextpipeline.c b/gsk/gskvulkancolortextpipeline.c
index 654b30c..dd236da 100644
--- a/gsk/gskvulkancolortextpipeline.c
+++ b/gsk/gskvulkancolortextpipeline.c
@@ -103,7 +103,8 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
                                                     float                       x,
                                                     float                       y,
                                                     guint                       start_glyph,
-                                                    guint                       num_glyphs)
+                                                    guint                       num_glyphs,
+                                                    float                       scale)
 {
   GskVulkanColorTextInstance *instances = (GskVulkanColorTextInstance *) data;
   int i;
@@ -127,7 +128,7 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
               GskVulkanColorTextInstance *instance = &instances[count];
               GskVulkanCachedGlyph *glyph;
 
-              glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph);
+              glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
 
               instance->tex_rect[0] = glyph->tx;
               instance->tex_rect[1] = glyph->ty;
diff --git a/gsk/gskvulkancolortextpipelineprivate.h b/gsk/gskvulkancolortextpipelineprivate.h
index 9a933ef..2e46b1c 100644
--- a/gsk/gskvulkancolortextpipelineprivate.h
+++ b/gsk/gskvulkancolortextpipelineprivate.h
@@ -31,7 +31,8 @@ void                    gsk_vulkan_color_text_pipeline_collect_vertex_data   (Gs
                                                                               float                          
 x,
                                                                               float                          
 y,
                                                                               guint                          
 start_glyph,
-                                                                              guint                          
 num_glyphs);
+                                                                              guint                          
 num_glyphs,
+                                                                              float                          
 scale);
 gsize                   gsk_vulkan_color_text_pipeline_draw                  (GskVulkanColorTextPipeline     
*pipeline,
                                                                               VkCommandBuffer                
 command_buffer,
                                                                               gsize                          
 offset,
diff --git a/gsk/gskvulkanglyphcache.c b/gsk/gskvulkanglyphcache.c
index 544b26f..c326c56 100644
--- a/gsk/gskvulkanglyphcache.c
+++ b/gsk/gskvulkanglyphcache.c
@@ -116,6 +116,7 @@ gsk_vulkan_glyph_cache_class_init (GskVulkanGlyphCacheClass *klass)
 typedef struct {
   PangoFont *font;
   PangoGlyph glyph;
+  guint scale; /* times 1024 */
 } GlyphCacheKey;
 
 static gboolean
@@ -125,7 +126,8 @@ glyph_cache_equal (gconstpointer v1, gconstpointer v2)
   const GlyphCacheKey *key2 = v2;
 
   return key1->font == key2->font &&
-         key1->glyph == key2->glyph;
+         key1->glyph == key2->glyph &&
+         key1->scale == key2->scale;
 }
 
 static guint
@@ -133,7 +135,7 @@ glyph_cache_hash (gconstpointer v)
 {
   const GlyphCacheKey *key = v;
 
-  return GPOINTER_TO_UINT (key->font) ^ key->glyph;
+  return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ key->scale;
 }
 
 static void
@@ -175,6 +177,8 @@ add_to_cache (GskVulkanGlyphCache  *cache,
   Atlas *atlas;
   int i;
   DirtyGlyph *dirty;
+  int width = value->draw_width * key->scale / 1024;
+  int height = value->draw_height * key->scale / 1024;
 
   for (i = 0; i < cache->atlases->len; i++)
     {
@@ -185,14 +189,14 @@ add_to_cache (GskVulkanGlyphCache  *cache,
       y = atlas->y;
       y0 = atlas->y0;
 
-      if (atlas->x + value->draw_width + 1 >= atlas->width)
+      if (atlas->x + width + 1 >= atlas->width)
         {
           /* start a new row */
           y0 = y + 1;
           x = 1;
         }
 
-      if (y0 + value->draw_height + 1 >= atlas->height)
+      if (y0 + height + 1 >= atlas->height)
         continue;
 
       atlas->y0 = y0;
@@ -209,8 +213,8 @@ add_to_cache (GskVulkanGlyphCache  *cache,
 
   value->tx = (float)atlas->x / atlas->width;
   value->ty = (float)atlas->y0 / atlas->height;
-  value->tw = (float)value->draw_width / atlas->width;
-  value->th = (float)value->draw_height / atlas->height;
+  value->tw = (float)width / atlas->width;
+  value->th = (float)height / atlas->height;
 
   value->texture_index = i;
 
@@ -219,8 +223,8 @@ add_to_cache (GskVulkanGlyphCache  *cache,
   dirty->value = value;
   atlas->dirty_glyphs = g_list_prepend (atlas->dirty_glyphs, dirty);
 
-  atlas->x = atlas->x + value->draw_width + 1;
-  atlas->y = MAX (atlas->y, atlas->y0 + value->draw_height + 1);
+  atlas->x = atlas->x + width + 1;
+  atlas->y = MAX (atlas->y, atlas->y0 + height + 1);
 
   atlas->num_glyphs++;
 
@@ -254,8 +258,9 @@ render_glyph (Atlas          *atlas,
   cairo_glyph_t cg;
 
   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                        value->draw_width,
-                                        value->draw_height);
+                                        value->draw_width * key->scale / 1024,
+                                        value->draw_height * key->scale / 1024);
+  cairo_surface_set_device_scale (surface, key->scale / 1024.0, key->scale / 1024.0);
 
   cr = cairo_create (surface);
 
@@ -324,13 +329,15 @@ GskVulkanCachedGlyph *
 gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
                                gboolean             create,
                                PangoFont           *font,
-                               PangoGlyph           glyph)
+                               PangoGlyph           glyph,
+                               float                scale)
 {
   GlyphCacheKey lookup_key;
   GskVulkanCachedGlyph *value;
 
   lookup_key.font = font;
   lookup_key.glyph = glyph;
+  lookup_key.scale = (guint)(scale * 1024);
 
   value = g_hash_table_lookup (cache->hash_table, &lookup_key);
 
@@ -364,6 +371,7 @@ gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
 
       key->font = g_object_ref (font);
       key->glyph = glyph;
+      key->scale = (guint)(scale * 1024);
 
       if (ink_rect.width > 0 && ink_rect.height > 0)
         add_to_cache (cache, key, value);
diff --git a/gsk/gskvulkanglyphcacheprivate.h b/gsk/gskvulkanglyphcacheprivate.h
index 3a9cddf..6cf223f 100644
--- a/gsk/gskvulkanglyphcacheprivate.h
+++ b/gsk/gskvulkanglyphcacheprivate.h
@@ -20,7 +20,8 @@ GskVulkanImage *     gsk_vulkan_glyph_cache_get_glyph_image (GskVulkanGlyphCache
 GskVulkanCachedGlyph *gsk_vulkan_glyph_cache_lookup         (GskVulkanGlyphCache *cache,
                                                              gboolean             create,
                                                              PangoFont           *font,
-                                                             PangoGlyph           glyph);
+                                                             PangoGlyph           glyph,
+                                                             float                scale);
 
 void                  gsk_vulkan_glyph_cache_begin_frame    (GskVulkanGlyphCache *cache);
 
diff --git a/gsk/gskvulkanrenderer.c b/gsk/gskvulkanrenderer.c
index fcc339f..7bc9431 100644
--- a/gsk/gskvulkanrenderer.c
+++ b/gsk/gskvulkanrenderer.c
@@ -350,9 +350,10 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
 guint
 gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
                                  PangoFont         *font,
-                                 PangoGlyph         glyph)
+                                 PangoGlyph         glyph,
+                                 float              scale)
 {
-  return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph)->texture_index;
+  return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph, scale)->texture_index;
 }
 
 GskVulkanImage *
@@ -366,7 +367,8 @@ gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer  *self,
 GskVulkanCachedGlyph *
 gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
                                       PangoFont         *font,
-                                      PangoGlyph         glyph)
+                                      PangoGlyph         glyph,
+                                      float              scale)
 {
-  return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph);
+  return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, scale);
 }
diff --git a/gsk/gskvulkanrendererprivate.h b/gsk/gskvulkanrendererprivate.h
index 19f0d3b..d86734c 100644
--- a/gsk/gskvulkanrendererprivate.h
+++ b/gsk/gskvulkanrendererprivate.h
@@ -44,7 +44,8 @@ typedef struct
 
 guint                  gsk_vulkan_renderer_cache_glyph      (GskVulkanRenderer *renderer,
                                                              PangoFont         *font,
-                                                             PangoGlyph         glyph);
+                                                             PangoGlyph         glyph,
+                                                             float              scale);
 
 GskVulkanImage *       gsk_vulkan_renderer_ref_glyph_image  (GskVulkanRenderer *self,
                                                              GskVulkanUploader *uploader,
@@ -52,7 +53,8 @@ GskVulkanImage *       gsk_vulkan_renderer_ref_glyph_image  (GskVulkanRenderer *
 
 GskVulkanCachedGlyph * gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
                                                              PangoFont         *font,
-                                                             PangoGlyph         glyph);
+                                                             PangoGlyph         glyph,
+                                                             float              scale);
 
 
 G_END_DECLS
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
index 09ba756..00f79be 100644
--- a/gsk/gskvulkanrenderpass.c
+++ b/gsk/gskvulkanrenderpass.c
@@ -90,6 +90,7 @@ struct _GskVulkanOpText
   guint                texture_index; /* index of the texture in the glyph cache */
   guint                start_glyph; /* the first glyph in nodes glyphstring that we render */
   guint                num_glyphs; /* number of *non-empty* glyphs (== instances) we render */
+  float                scale;
 };
 
 struct _GskVulkanOpPushConstants
@@ -406,6 +407,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass           *self,
 
         op.text.start_glyph = 0;
         op.text.texture_index = G_MAXUINT;
+        op.text.scale = gdk_window_get_scale_factor (gsk_renderer_get_window (GSK_RENDERER (renderer)));
 
         for (i = 0, count = 0; i < num_glyphs; i++)
           {
@@ -413,7 +415,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass           *self,
 
             if (gi->glyph != PANGO_GLYPH_EMPTY && !(gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG))
               {
-                texture_index = gsk_vulkan_renderer_cache_glyph (renderer, (PangoFont *)font, gi->glyph);
+                texture_index = gsk_vulkan_renderer_cache_glyph (renderer, (PangoFont *)font, gi->glyph, 
op.text.scale);
                 if (op.text.texture_index == G_MAXUINT)
                   op.text.texture_index = texture_index;
                 if (texture_index != op.text.texture_index)
@@ -1232,7 +1234,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                           gsk_text_node_get_x (op->text.node),
                                                           gsk_text_node_get_y (op->text.node),
                                                           op->text.start_glyph,
-                                                          op->text.num_glyphs);
+                                                          op->text.num_glyphs,
+                                                          op->text.scale);
             n_bytes += op->text.vertex_count;
           }
           break;
@@ -1250,7 +1253,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                                 gsk_text_node_get_x (op->text.node),
                                                                 gsk_text_node_get_y (op->text.node),
                                                                 op->text.start_glyph,
-                                                                op->text.num_glyphs);
+                                                                op->text.num_glyphs,
+                                                                op->text.scale);
             n_bytes += op->text.vertex_count;
           }
           break;
diff --git a/gsk/gskvulkantextpipeline.c b/gsk/gskvulkantextpipeline.c
index 5cdeb15..5ca2d7e 100644
--- a/gsk/gskvulkantextpipeline.c
+++ b/gsk/gskvulkantextpipeline.c
@@ -111,7 +111,8 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline  *pipeline,
                                               float                   x,
                                               float                   y,
                                               guint                   start_glyph,
-                                              guint                   num_glyphs)
+                                              guint                   num_glyphs,
+                                              float                   scale)
 {
   GskVulkanTextInstance *instances = (GskVulkanTextInstance *) data;
   int i;
@@ -135,7 +136,7 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline  *pipeline,
               GskVulkanTextInstance *instance = &instances[count];
               GskVulkanCachedGlyph *glyph;
 
-              glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph);
+              glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
 
               instance->tex_rect[0] = glyph->tx;
               instance->tex_rect[1] = glyph->ty;
diff --git a/gsk/gskvulkantextpipelineprivate.h b/gsk/gskvulkantextpipelineprivate.h
index 064045e..47517de 100644
--- a/gsk/gskvulkantextpipelineprivate.h
+++ b/gsk/gskvulkantextpipelineprivate.h
@@ -32,7 +32,8 @@ void                    gsk_vulkan_text_pipeline_collect_vertex_data   (GskVulka
                                                                         float                           x,
                                                                         float                           y,
                                                                         guint                           
start_glyph,
-                                                                        guint                           
num_glyphs);
+                                                                        guint                           
num_glyphs,
+                                                                        float                           
scale);
 gsize                   gsk_vulkan_text_pipeline_draw                  (GskVulkanTextPipeline         
*pipeline,
                                                                         VkCommandBuffer                 
command_buffer,
                                                                         gsize                           
offset,


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