gl: Make icon cache work like glyph cache

Replace timestamp tracking with an accessed bit
here too, to keep the glyph and icon cache code
similar.
This commit is contained in:
Matthias Clasen 2019-10-12 11:46:10 -04:00
parent 977ac2b31f
commit 123cbd42bb
2 changed files with 20 additions and 19 deletions

View File

@ -11,9 +11,9 @@ typedef struct
{ {
graphene_rect_t texture_rect; graphene_rect_t texture_rect;
GskGLTextureAtlas *atlas; GskGLTextureAtlas *atlas;
int frame_age; /* Number of frames this icon is unused */
guint used: 1;
GdkTexture *source_texture; GdkTexture *source_texture;
guint accessed : 1;
guint used : 1;
} IconData; } IconData;
static void static void
@ -71,6 +71,8 @@ gsk_gl_icon_cache_begin_frame (GskGLIconCache *self,
GdkTexture *texture; GdkTexture *texture;
IconData *icon_data; IconData *icon_data;
self->timestamp++;
/* Drop icons on removed atlases */ /* Drop icons on removed atlases */
if (removed_atlases->len > 0) if (removed_atlases->len > 0)
{ {
@ -81,26 +83,24 @@ gsk_gl_icon_cache_begin_frame (GskGLIconCache *self,
g_hash_table_iter_remove (&iter); g_hash_table_iter_remove (&iter);
} }
} }
/* 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))
{
icon_data->frame_age ++;
if (icon_data->frame_age > MAX_FRAME_AGE) if (self->timestamp % MAX_FRAME_AGE == 0)
{
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; if (icon_data->used)
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); const int w = icon_data->texture_rect.size.width * icon_data->atlas->width;
icon_data->used = FALSE; 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. icon_data->accessed = FALSE;
* This way we can revive it when we use it again.
*/
} }
} }
} }
@ -115,7 +115,6 @@ gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
if (icon_data) if (icon_data)
{ {
icon_data->frame_age = 0;
if (!icon_data->used) if (!icon_data->used)
{ {
const int w = icon_data->texture_rect.size.width * icon_data->atlas->width; 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); gsk_gl_texture_atlas_mark_used (icon_data->atlas, w + 2, h + 2);
icon_data->used = TRUE; icon_data->used = TRUE;
} }
icon_data->accessed = TRUE;
*out_texture_id = icon_data->atlas->texture_id; *out_texture_id = icon_data->atlas->texture_id;
*out_texture_rect = icon_data->texture_rect; *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 = g_new0 (IconData, 1);
icon_data->atlas = atlas; icon_data->atlas = atlas;
icon_data->frame_age = 0; icon_data->accessed = TRUE;
icon_data->used = TRUE; icon_data->used = TRUE;
icon_data->source_texture = g_object_ref (texture); icon_data->source_texture = g_object_ref (texture);
graphene_rect_init (&icon_data->texture_rect, graphene_rect_init (&icon_data->texture_rect,

View File

@ -18,6 +18,7 @@ typedef struct
GskGLTextureAtlases *atlases; GskGLTextureAtlases *atlases;
GHashTable *icons; /* GdkTexture -> IconData */ GHashTable *icons; /* GdkTexture -> IconData */
int timestamp;
} GskGLIconCache; } GskGLIconCache;
GskGLIconCache * gsk_gl_icon_cache_new (GdkDisplay *display, GskGLIconCache * gsk_gl_icon_cache_new (GdkDisplay *display,