[gtk/subpixel-positioning: 1/2] vulkan: implement subpixel positioning
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/subpixel-positioning: 1/2] vulkan: implement subpixel positioning
- Date: Sat, 27 Jul 2019 03:34:06 +0000 (UTC)
commit daa8780552c1baec3c9554b036944e3ba074ae08
Author: Matthias Clasen <mclasen redhat com>
Date: Thu Jul 25 17:50:31 2019 -0400
vulkan: implement subpixel positioning
Pass the glyph position into the glyph caching functions,
not just the glyph index. This allows us to cache different
images for different subpixel positions.
gsk/vulkan/gskvulkancolortextpipeline.c | 11 ++++++++---
gsk/vulkan/gskvulkanglyphcache.c | 25 +++++++++++++++++++++----
gsk/vulkan/gskvulkanglyphcacheprivate.h | 3 +++
gsk/vulkan/gskvulkanrenderer.c | 24 ++++++++++++++----------
gsk/vulkan/gskvulkanrendererprivate.h | 4 ++++
gsk/vulkan/gskvulkanrenderpass.c | 11 ++++++++++-
gsk/vulkan/gskvulkantextpipeline.c | 11 ++++++++---
7 files changed, 68 insertions(+), 21 deletions(-)
---
diff --git a/gsk/vulkan/gskvulkancolortextpipeline.c b/gsk/vulkan/gskvulkancolortextpipeline.c
index a7b0ad39a7..5ffe62adcc 100644
--- a/gsk/vulkan/gskvulkancolortextpipeline.c
+++ b/gsk/vulkan/gskvulkancolortextpipeline.c
@@ -119,12 +119,17 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
if (gi->glyph != PANGO_GLYPH_EMPTY)
{
- double cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
- double cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
+ double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
+ double cy = gi->geometry.y_offset / PANGO_SCALE;
GskVulkanColorTextInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;
- glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
+ glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,
+ font,
+ gi->glyph,
+ x_position + gi->geometry.x_offset,
+ gi->geometry.y_offset,
+ scale);
instance->tex_rect[0] = glyph->tx;
instance->tex_rect[1] = glyph->ty;
diff --git a/gsk/vulkan/gskvulkanglyphcache.c b/gsk/vulkan/gskvulkanglyphcache.c
index ce3a6947e6..830b4d70c9 100644
--- a/gsk/vulkan/gskvulkanglyphcache.c
+++ b/gsk/vulkan/gskvulkanglyphcache.c
@@ -115,6 +115,8 @@ gsk_vulkan_glyph_cache_class_init (GskVulkanGlyphCacheClass *klass)
typedef struct {
PangoFont *font;
PangoGlyph glyph;
+ guint xshift;
+ guint yshift;
guint scale; /* times 1024 */
} GlyphCacheKey;
@@ -126,6 +128,8 @@ glyph_cache_equal (gconstpointer v1, gconstpointer v2)
return key1->font == key2->font &&
key1->glyph == key2->glyph &&
+ key1->xshift == key2->xshift &&
+ key1->yshift == key2->yshift &&
key1->scale == key2->scale;
}
@@ -134,7 +138,7 @@ glyph_cache_hash (gconstpointer v)
{
const GlyphCacheKey *key = v;
- return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ key->scale;
+ return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ (key->xshift << 24) ^ (key->yshift << 26) ^ key->scale;
}
static void
@@ -267,10 +271,10 @@ render_glyph (Atlas *atlas,
gi.glyph = key->glyph;
gi.geometry.width = value->draw_width * 1024;
if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
- gi.geometry.x_offset = 0;
+ gi.geometry.x_offset = key->xshift * 256;
else
- gi.geometry.x_offset = - value->draw_x * 1024;
- gi.geometry.y_offset = - value->draw_y * 1024;
+ gi.geometry.x_offset = key->xshift * 256 - value->draw_x * 1024;
+ gi.geometry.y_offset = key->yshift * 256 - value->draw_y * 1024;
glyphs.num_glyphs = 1;
glyphs.glyphs = &gi;
@@ -328,18 +332,29 @@ gsk_vulkan_glyph_cache_new (GskRenderer *renderer,
return cache;
}
+#define PHASE(x) ((x % PANGO_SCALE) * 4 / PANGO_SCALE)
+
GskVulkanCachedGlyph *
gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
gboolean create,
PangoFont *font,
PangoGlyph glyph,
+ int x,
+ int y,
float scale)
{
GlyphCacheKey lookup_key;
GskVulkanCachedGlyph *value;
+ guint xshift;
+ guint yshift;
+
+ xshift = PHASE (x);
+ yshift = PHASE (y);
lookup_key.font = font;
lookup_key.glyph = glyph;
+ lookup_key.xshift = xshift;
+ lookup_key.yshift = yshift;
lookup_key.scale = (guint)(scale * 1024);
value = g_hash_table_lookup (cache->hash_table, &lookup_key);
@@ -374,6 +389,8 @@ gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
key->font = g_object_ref (font);
key->glyph = glyph;
+ key->xshift = xshift;
+ key->yshift = yshift;
key->scale = (guint)(scale * 1024);
if (ink_rect.width > 0 && ink_rect.height > 0)
diff --git a/gsk/vulkan/gskvulkanglyphcacheprivate.h b/gsk/vulkan/gskvulkanglyphcacheprivate.h
index b566e5b9bc..b31711fe6d 100644
--- a/gsk/vulkan/gskvulkanglyphcacheprivate.h
+++ b/gsk/vulkan/gskvulkanglyphcacheprivate.h
@@ -22,6 +22,9 @@ GskVulkanCachedGlyph *gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache
gboolean create,
PangoFont *font,
PangoGlyph glyph,
+ int x,
+ int y,
+
float scale);
void gsk_vulkan_glyph_cache_begin_frame (GskVulkanGlyphCache *cache);
diff --git a/gsk/vulkan/gskvulkanrenderer.c b/gsk/vulkan/gskvulkanrenderer.c
index 6fc59758c6..867f51b5d6 100644
--- a/gsk/vulkan/gskvulkanrenderer.c
+++ b/gsk/vulkan/gskvulkanrenderer.c
@@ -362,15 +362,6 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
return image;
}
-guint
-gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
- PangoFont *font,
- PangoGlyph glyph,
- float scale)
-{
- return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph, scale)->texture_index;
-}
-
GskVulkanImage *
gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
GskVulkanUploader *uploader,
@@ -379,13 +370,26 @@ gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
return g_object_ref (gsk_vulkan_glyph_cache_get_glyph_image (self->glyph_cache, uploader, index));
}
+guint
+gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
+ PangoFont *font,
+ PangoGlyph glyph,
+ int x,
+ int y,
+ float scale)
+{
+ return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, TRUE, font, glyph, x, y, scale)->texture_index;
+}
+
GskVulkanCachedGlyph *
gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
PangoFont *font,
PangoGlyph glyph,
+ int x,
+ int y,
float scale)
{
- return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, scale);
+ return gsk_vulkan_glyph_cache_lookup (self->glyph_cache, FALSE, font, glyph, x, y, scale);
}
/**
diff --git a/gsk/vulkan/gskvulkanrendererprivate.h b/gsk/vulkan/gskvulkanrendererprivate.h
index d492a85b1f..eca34ccabd 100644
--- a/gsk/vulkan/gskvulkanrendererprivate.h
+++ b/gsk/vulkan/gskvulkanrendererprivate.h
@@ -30,6 +30,8 @@ typedef struct
guint gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *renderer,
PangoFont *font,
PangoGlyph glyph,
+ int x,
+ int y,
float scale);
GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
@@ -39,6 +41,8 @@ GskVulkanImage * gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *
GskVulkanCachedGlyph * gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
PangoFont *font,
PangoGlyph glyph,
+ int x,
+ int y,
float scale);
diff --git a/gsk/vulkan/gskvulkanrenderpass.c b/gsk/vulkan/gskvulkanrenderpass.c
index 55f96456a8..00fd658d8b 100644
--- a/gsk/vulkan/gskvulkanrenderpass.c
+++ b/gsk/vulkan/gskvulkanrenderpass.c
@@ -370,6 +370,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
int i;
guint count;
guint texture_index;
+ gint x_position;
GskVulkanRenderer *renderer = GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render));
if (font_has_color_glyphs (font))
@@ -402,11 +403,17 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
op.text.texture_index = G_MAXUINT;
op.text.scale = self->scale_factor;
+ x_position = 0;
for (i = 0, count = 0; i < num_glyphs; i++)
{
const PangoGlyphInfo *gi = &glyphs[i];
- texture_index = gsk_vulkan_renderer_cache_glyph (renderer, (PangoFont *)font, gi->glyph,
op.text.scale);
+ texture_index = gsk_vulkan_renderer_cache_glyph (renderer,
+ (PangoFont *)font,
+ gi->glyph,
+ x_position + gi->geometry.x_offset,
+ gi->geometry.y_offset,
+ op.text.scale);
if (op.text.texture_index == G_MAXUINT)
op.text.texture_index = texture_index;
if (texture_index != op.text.texture_index)
@@ -421,6 +428,8 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
}
else
count++;
+
+ x_position += gi->geometry.width;
}
if (op.text.texture_index != G_MAXUINT && count != 0)
diff --git a/gsk/vulkan/gskvulkantextpipeline.c b/gsk/vulkan/gskvulkantextpipeline.c
index 7cd85c5d9a..de1ba6a084 100644
--- a/gsk/vulkan/gskvulkantextpipeline.c
+++ b/gsk/vulkan/gskvulkantextpipeline.c
@@ -127,12 +127,17 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline,
if (gi->glyph != PANGO_GLYPH_EMPTY)
{
- double cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
- double cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
+ double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
+ double cy = gi->geometry.y_offset / PANGO_SCALE;
GskVulkanTextInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;
- glyph = gsk_vulkan_renderer_get_cached_glyph (renderer, font, gi->glyph, scale);
+ glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,
+ font,
+ gi->glyph,
+ x_position + gi->geometry.x_offset,
+ gi->geometry.y_offset;
+ scale);
instance->tex_rect[0] = glyph->tx;
instance->tex_rect[1] = glyph->ty;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]