forked from AuroraMiddleware/gtk
gl: glyph cache tweaks
Reduce the cost of lookups by storing the hash value directly.
This commit is contained in:
parent
8937cd992d
commit
849b950763
@ -87,11 +87,7 @@ glyph_cache_hash (gconstpointer v)
|
||||
{
|
||||
const GlyphCacheKey *key = v;
|
||||
|
||||
return GPOINTER_TO_UINT (key->font) ^
|
||||
key->glyph ^
|
||||
(key->xshift << 24) ^
|
||||
(key->yshift << 26) ^
|
||||
key->scale;
|
||||
return key->hash;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -147,7 +143,7 @@ render_glyph (GlyphCacheKey *key,
|
||||
|
||||
glyph_info.glyph = key->glyph;
|
||||
glyph_info.geometry.width = value->draw_width * 1024;
|
||||
if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
|
||||
if (glyph_info.glyph & PANGO_GLYPH_UNKNOWN_FLAG)
|
||||
glyph_info.geometry.x_offset = 0;
|
||||
else
|
||||
glyph_info.geometry.x_offset = - value->draw_x * 1024;
|
||||
@ -247,31 +243,15 @@ add_to_cache (GskGLGlyphCache *self,
|
||||
upload_glyph (key, value);
|
||||
}
|
||||
|
||||
#define PHASE(x) ((int)(floor (4 * (x + 0.125)) - 4 * floor (x + 0.125)))
|
||||
|
||||
gboolean
|
||||
gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
float x,
|
||||
float y,
|
||||
float scale,
|
||||
GlyphCacheKey *lookup,
|
||||
GskGLDriver *driver,
|
||||
const GskGLCachedGlyph **cached_glyph_out)
|
||||
{
|
||||
GskGLCachedGlyph *value;
|
||||
guint xshift = PHASE (x);
|
||||
guint yshift = PHASE (y);
|
||||
const guint key_scale = (guint)(scale * 1024);
|
||||
|
||||
value = g_hash_table_lookup (cache->hash_table,
|
||||
&(GlyphCacheKey) {
|
||||
.font = font,
|
||||
.glyph = glyph,
|
||||
.xshift = xshift,
|
||||
.yshift = yshift,
|
||||
.scale = key_scale
|
||||
});
|
||||
value = g_hash_table_lookup (cache->hash_table, lookup);
|
||||
|
||||
if (value)
|
||||
{
|
||||
@ -279,30 +259,26 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
|
||||
|
||||
if (age > MAX_FRAME_AGE)
|
||||
{
|
||||
GskGLTextureAtlas *atlas = value->atlas;
|
||||
|
||||
if (atlas && !value->used)
|
||||
if (value->atlas && !value->used)
|
||||
{
|
||||
gsk_gl_texture_atlas_mark_used (atlas, value->draw_width, value->draw_height);
|
||||
gsk_gl_texture_atlas_mark_used (value->atlas, value->draw_width, value->draw_height);
|
||||
value->used = TRUE;
|
||||
}
|
||||
|
||||
value->timestamp = cache->timestamp;
|
||||
}
|
||||
|
||||
value->timestamp = cache->timestamp;
|
||||
*cached_glyph_out = value;
|
||||
}
|
||||
|
||||
if (value == NULL)
|
||||
else
|
||||
{
|
||||
GlyphCacheKey *key;
|
||||
PangoRectangle ink_rect;
|
||||
|
||||
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
|
||||
pango_font_get_glyph_extents (lookup->font, lookup->glyph, &ink_rect, NULL);
|
||||
pango_extents_to_pixels (&ink_rect, NULL);
|
||||
if (xshift != 0)
|
||||
if (lookup->xshift != 0)
|
||||
ink_rect.width += 1;
|
||||
if (yshift != 0)
|
||||
if (lookup->yshift != 0)
|
||||
ink_rect.height += 1;
|
||||
|
||||
value = g_new0 (GskGLCachedGlyph, 1);
|
||||
@ -316,11 +292,12 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
|
||||
|
||||
key = g_new0 (GlyphCacheKey, 1);
|
||||
|
||||
key->font = g_object_ref (font);
|
||||
key->glyph = glyph;
|
||||
key->xshift = xshift;
|
||||
key->yshift = yshift;
|
||||
key->scale = key_scale;
|
||||
key->font = g_object_ref (lookup->font);
|
||||
key->glyph = lookup->glyph;
|
||||
key->xshift = lookup->xshift;
|
||||
key->yshift = lookup->yshift;
|
||||
key->scale = lookup->scale;
|
||||
key->hash = lookup->hash;
|
||||
|
||||
if (key->scale > 0 &&
|
||||
value->draw_width * key->scale / 1024 > 0 &&
|
||||
@ -330,10 +307,6 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
|
||||
*cached_glyph_out = value;
|
||||
g_hash_table_insert (cache->hash_table, key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
*cached_glyph_out = value;
|
||||
}
|
||||
|
||||
return (*cached_glyph_out)->atlas != NULL;
|
||||
}
|
||||
|
@ -22,11 +22,30 @@ typedef struct
|
||||
{
|
||||
PangoFont *font;
|
||||
PangoGlyph glyph;
|
||||
guint xshift;
|
||||
guint yshift;
|
||||
guint scale; /* times 1024 */
|
||||
guint xshift : 3;
|
||||
guint yshift : 3;
|
||||
guint scale : 26; /* times 1024 */
|
||||
guint hash;
|
||||
} GlyphCacheKey;
|
||||
|
||||
#define PHASE(x) ((int)(floor (4 * (x + 0.125)) - 4 * floor (x + 0.125)))
|
||||
|
||||
static inline void
|
||||
glyph_cache_key_set_glyph_and_shift (GlyphCacheKey *key,
|
||||
PangoGlyph glyph,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
key->glyph = glyph;
|
||||
key->xshift = PHASE (x);
|
||||
key->yshift = PHASE (y);
|
||||
key->hash = GPOINTER_TO_UINT (key->font) ^
|
||||
key->glyph ^
|
||||
(key->xshift << 24) ^
|
||||
(key->yshift << 26) ^
|
||||
key->scale;
|
||||
}
|
||||
|
||||
typedef struct _GskGLCachedGlyph GskGLCachedGlyph;
|
||||
|
||||
struct _GskGLCachedGlyph
|
||||
@ -55,11 +74,7 @@ GskGLGlyphCache * gsk_gl_glyph_cache_ref (GskGLGlyphCache *se
|
||||
void gsk_gl_glyph_cache_unref (GskGLGlyphCache *self);
|
||||
void gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self);
|
||||
gboolean gsk_gl_glyph_cache_lookup (GskGLGlyphCache *self,
|
||||
PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
float x,
|
||||
float y,
|
||||
float scale,
|
||||
GlyphCacheKey *lookup,
|
||||
GskGLDriver *driver,
|
||||
const GskGLCachedGlyph **cached_glyph_out);
|
||||
|
||||
|
@ -552,6 +552,7 @@ render_text_node (GskGLRenderer *self,
|
||||
const graphene_point_t *offset = gsk_text_node_get_offset (node);
|
||||
float x = offset->x + builder->dx;
|
||||
float y = offset->y + builder->dy;
|
||||
GlyphCacheKey lookup;
|
||||
|
||||
/* If the font has color glyphs, we don't need to recolor anything */
|
||||
if (!force_color && gsk_text_node_has_color_glyphs (node))
|
||||
@ -564,6 +565,9 @@ render_text_node (GskGLRenderer *self,
|
||||
ops_set_color (builder, color);
|
||||
}
|
||||
|
||||
lookup.font = (PangoFont *)font;
|
||||
lookup.scale = (guint) (text_scale * 1024);
|
||||
|
||||
/* We use one quad per character, unlike the other nodes which
|
||||
* use at most one quad altogether */
|
||||
for (i = 0; i < num_glyphs; i++)
|
||||
@ -581,19 +585,13 @@ render_text_node (GskGLRenderer *self,
|
||||
cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
|
||||
cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
|
||||
|
||||
glyph_cache_key_set_glyph_and_shift (&lookup, gi->glyph, x + cx, y + cy);
|
||||
|
||||
gsk_gl_glyph_cache_lookup (self->glyph_cache,
|
||||
(PangoFont *)font,
|
||||
gi->glyph,
|
||||
x + cx,
|
||||
y + cy,
|
||||
text_scale,
|
||||
&lookup,
|
||||
self->gl_driver,
|
||||
&glyph);
|
||||
|
||||
/* e.g. whitespace */
|
||||
if (glyph->draw_width <= 0 || glyph->draw_height <= 0)
|
||||
goto next;
|
||||
|
||||
if (glyph->texture_id == 0)
|
||||
goto next;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user