forked from AuroraMiddleware/gtk
Merge branch 'glyphcache-fiddling' into 'master'
Glyphcache fiddling See merge request GNOME/gtk!1132
This commit is contained in:
commit
d3ad178d95
@ -15,9 +15,9 @@
|
||||
|
||||
/* Cache eviction strategy
|
||||
*
|
||||
* Each cached glyph has an age that gets reset every time a cached
|
||||
* glyph gets used. Glyphs that have not been used for the
|
||||
* MAX_FRAME_AGE frames are considered old.
|
||||
* We mark glyphs as accessed every time we use them. Every
|
||||
* few frames, we mark glyphs that haven't been accessed since
|
||||
* the last check as old.
|
||||
*
|
||||
* We keep count of the pixels of each atlas that are taken up by old
|
||||
* data. When the fraction of old pixels gets too high, we drop the
|
||||
@ -264,12 +264,12 @@ gsk_gl_glyph_cache_lookup_or_add (GskGLGlyphCache *cache,
|
||||
|
||||
if (value)
|
||||
{
|
||||
value->timestamp = cache->timestamp;
|
||||
if (value->atlas && !value->used)
|
||||
{
|
||||
gsk_gl_texture_atlas_mark_used (value->atlas, value->draw_width, value->draw_height);
|
||||
value->used = TRUE;
|
||||
}
|
||||
value->accessed = TRUE;
|
||||
|
||||
*cached_glyph_out = value;
|
||||
return;
|
||||
@ -292,7 +292,7 @@ gsk_gl_glyph_cache_lookup_or_add (GskGLGlyphCache *cache,
|
||||
value->draw_y = ink_rect.y;
|
||||
value->draw_width = ink_rect.width;
|
||||
value->draw_height = ink_rect.height;
|
||||
value->timestamp = cache->timestamp;
|
||||
value->accessed = TRUE;
|
||||
value->atlas = NULL; /* For now */
|
||||
|
||||
key = g_new0 (GlyphCacheKey, 1);
|
||||
@ -341,20 +341,21 @@ gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self,
|
||||
GSK_NOTE(GLYPH_CACHE, if (dropped > 0) g_message ("Dropped %d glyphs", dropped));
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, self->hash_table);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
|
||||
if (self->timestamp % MAX_FRAME_AGE == 0)
|
||||
{
|
||||
const guint age = self->timestamp - value->timestamp;
|
||||
|
||||
if (age > MAX_FRAME_AGE)
|
||||
g_hash_table_iter_init (&iter, self->hash_table);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
|
||||
{
|
||||
GskGLTextureAtlas *atlas = value->atlas;
|
||||
|
||||
if (atlas && value->used)
|
||||
if (!value->accessed)
|
||||
{
|
||||
gsk_gl_texture_atlas_mark_unused (atlas, value->draw_width, value->draw_height);
|
||||
value->used = FALSE;
|
||||
if (value->atlas && value->used)
|
||||
{
|
||||
gsk_gl_texture_atlas_mark_unused (value->atlas, value->draw_width, value->draw_height);
|
||||
value->used = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value->accessed = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ typedef struct
|
||||
GHashTable *hash_table;
|
||||
GskGLTextureAtlases *atlases;
|
||||
|
||||
guint64 timestamp;
|
||||
int timestamp;
|
||||
} GskGLGlyphCache;
|
||||
|
||||
typedef struct
|
||||
@ -63,8 +63,8 @@ struct _GskGLCachedGlyph
|
||||
int draw_width;
|
||||
int draw_height;
|
||||
|
||||
guint used: 1;
|
||||
guint64 timestamp;
|
||||
guint accessed : 1; /* accessed since last check */
|
||||
guint used : 1; /* accounted as used in the atlas */
|
||||
};
|
||||
|
||||
|
||||
|
@ -11,9 +11,9 @@ typedef struct
|
||||
{
|
||||
graphene_rect_t texture_rect;
|
||||
GskGLTextureAtlas *atlas;
|
||||
int frame_age; /* Number of frames this icon is unused */
|
||||
guint used: 1;
|
||||
GdkTexture *source_texture;
|
||||
guint accessed : 1;
|
||||
guint used : 1;
|
||||
} IconData;
|
||||
|
||||
static void
|
||||
@ -71,6 +71,8 @@ gsk_gl_icon_cache_begin_frame (GskGLIconCache *self,
|
||||
GdkTexture *texture;
|
||||
IconData *icon_data;
|
||||
|
||||
self->timestamp++;
|
||||
|
||||
/* Drop icons on removed atlases */
|
||||
if (removed_atlases->len > 0)
|
||||
{
|
||||
@ -82,25 +84,23 @@ gsk_gl_icon_cache_begin_frame (GskGLIconCache *self,
|
||||
}
|
||||
}
|
||||
|
||||
/* Increase frame age of all remaining icons */
|
||||
g_hash_table_iter_init (&iter, self->icons);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&texture, (gpointer *)&icon_data))
|
||||
if (self->timestamp % MAX_FRAME_AGE == 0)
|
||||
{
|
||||
icon_data->frame_age ++;
|
||||
|
||||
if (icon_data->frame_age > MAX_FRAME_AGE)
|
||||
g_hash_table_iter_init (&iter, self->icons);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&texture, (gpointer *)&icon_data))
|
||||
{
|
||||
if (icon_data->used)
|
||||
if (!icon_data->accessed)
|
||||
{
|
||||
const int w = icon_data->texture_rect.size.width * icon_data->atlas->width;
|
||||
const int h = icon_data->texture_rect.size.height * icon_data->atlas->height;
|
||||
gsk_gl_texture_atlas_mark_unused (icon_data->atlas, w + 2, h + 2);
|
||||
icon_data->used = FALSE;
|
||||
if (icon_data->used)
|
||||
{
|
||||
const int w = icon_data->texture_rect.size.width * icon_data->atlas->width;
|
||||
const int h = icon_data->texture_rect.size.height * icon_data->atlas->height;
|
||||
gsk_gl_texture_atlas_mark_unused (icon_data->atlas, w + 2, h + 2);
|
||||
icon_data->used = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* We do NOT remove the icon here. Instead, We wait until we drop the entire atlas.
|
||||
* This way we can revive it when we use it again.
|
||||
*/
|
||||
icon_data->accessed = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -115,7 +115,6 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
||||
|
||||
if (icon_data)
|
||||
{
|
||||
icon_data->frame_age = 0;
|
||||
if (!icon_data->used)
|
||||
{
|
||||
const int w = icon_data->texture_rect.size.width * icon_data->atlas->width;
|
||||
@ -124,6 +123,7 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
||||
gsk_gl_texture_atlas_mark_used (icon_data->atlas, w + 2, h + 2);
|
||||
icon_data->used = TRUE;
|
||||
}
|
||||
icon_data->accessed = TRUE;
|
||||
|
||||
*out_texture_id = icon_data->atlas->texture_id;
|
||||
*out_texture_rect = icon_data->texture_rect;
|
||||
@ -144,7 +144,7 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
||||
|
||||
icon_data = g_new0 (IconData, 1);
|
||||
icon_data->atlas = atlas;
|
||||
icon_data->frame_age = 0;
|
||||
icon_data->accessed = TRUE;
|
||||
icon_data->used = TRUE;
|
||||
icon_data->source_texture = g_object_ref (texture);
|
||||
graphene_rect_init (&icon_data->texture_rect,
|
||||
|
@ -18,6 +18,7 @@ typedef struct
|
||||
GskGLTextureAtlases *atlases;
|
||||
GHashTable *icons; /* GdkTexture -> IconData */
|
||||
|
||||
int timestamp;
|
||||
} GskGLIconCache;
|
||||
|
||||
GskGLIconCache * gsk_gl_icon_cache_new (GdkDisplay *display,
|
||||
|
Loading…
Reference in New Issue
Block a user