mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-11 03:10:09 +00:00
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
This commit is contained in:
parent
1c93bef0d5
commit
2c38b71ca5
@ -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,77 +207,53 @@ 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);
|
||||
if (width < MAX_GLYPH_SIZE && height < MAX_GLYPH_SIZE)
|
||||
{
|
||||
GskGLTextureAtlas *atlas = NULL;
|
||||
int packed_x = 0;
|
||||
int packed_y = 0;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
value->atlas = NULL;
|
||||
value->texture_id = gsk_gl_driver_create_texture (driver, width, height);
|
||||
|
||||
gsk_gl_driver_bind_source_texture (driver, value->texture_id);
|
||||
gsk_gl_driver_init_texture_empty (driver, value->texture_id, GL_NEAREST, GL_NEAREST);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
value->atlas = NULL;
|
||||
value->timestamp = 0;
|
||||
|
||||
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 = 0.0f;
|
||||
value->ty = 0.0f;
|
||||
value->tw = 1.0f;
|
||||
value->th = 1.0f;
|
||||
|
||||
width = value->draw_width * key.scale / 1024;
|
||||
height = value->draw_height * key.scale / 1024;
|
||||
|
||||
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->texture_id = texture_id;
|
||||
|
||||
upload_glyph (&key, value);
|
||||
}
|
||||
|
||||
gboolean
|
||||
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, driver, value);
|
||||
|
||||
if (key->scale > 0 &&
|
||||
ink_rect.width * key->scale > 0 &&
|
||||
ink_rect.height * key->scale > 0)
|
||||
add_to_cache (cache, key, 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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user