diff options
author | Timm Bäder <mail@baedert.org> | 2019-07-28 11:57:43 +0200 |
---|---|---|
committer | Timm Bäder <mail@baedert.org> | 2019-07-28 12:00:15 +0200 |
commit | 2c38b71ca53023b843e9bba2fddd97612e2789ab (patch) | |
tree | 725b9ca1f93ba4393f8c414655e6ac9a8a570467 /gsk | |
parent | 1c93bef0d5ba08012a275815ae3549911d1ef459 (diff) | |
download | gtk+-2c38b71ca53023b843e9bba2fddd97612e2789ab.tar.gz |
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
Diffstat (limited to 'gsk')
-rw-r--r-- | gsk/gl/gskglglyphcache.c | 113 | ||||
-rw-r--r-- | gsk/gl/gskglglyphcacheprivate.h | 8 | ||||
-rw-r--r-- | 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; |