[gtk+] gsk: Scale glyphs in the glyph cache
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] gsk: Scale glyphs in the glyph cache
- Date: Sat, 28 Oct 2017 17:15:41 +0000 (UTC)
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]