mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 13:41:07 +00:00
gl: Do less work to maintain caches
Remember which atlases were removed, and only check those when looking for icons or glyphs to remove. For most frames, we don't have to check at all since no atlases were removed.
This commit is contained in:
parent
9b61bfb3c8
commit
8839e10d44
@ -312,41 +312,46 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self)
|
||||
gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self,
|
||||
GPtrArray *removed_atlases)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
GlyphCacheKey *key;
|
||||
GskGLCachedGlyph *value;
|
||||
guint dropped = 0;
|
||||
|
||||
self->timestamp++;
|
||||
|
||||
if (removed_atlases->len > 0)
|
||||
{
|
||||
guint dropped = 0;
|
||||
|
||||
g_hash_table_iter_init (&iter, self->hash_table);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
|
||||
{
|
||||
if (g_ptr_array_find (removed_atlases, value->atlas, NULL))
|
||||
{
|
||||
g_hash_table_iter_remove (&iter);
|
||||
dropped++;
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
guint pos;
|
||||
const guint age = self->timestamp - value->timestamp;
|
||||
|
||||
if (!g_ptr_array_find (self->atlases->atlases, value->atlas, &pos))
|
||||
if (age > MAX_FRAME_AGE)
|
||||
{
|
||||
g_hash_table_iter_remove (&iter);
|
||||
dropped++;
|
||||
}
|
||||
else
|
||||
{
|
||||
const guint age = self->timestamp - value->timestamp;
|
||||
GskGLTextureAtlas *atlas = value->atlas;
|
||||
|
||||
if (age > MAX_FRAME_AGE)
|
||||
if (atlas && value->used)
|
||||
{
|
||||
GskGLTextureAtlas *atlas = value->atlas;
|
||||
|
||||
if (atlas && value->used)
|
||||
{
|
||||
gsk_gl_texture_atlas_mark_unused (atlas, value->draw_width, value->draw_height);
|
||||
value->used = FALSE;
|
||||
}
|
||||
gsk_gl_texture_atlas_mark_unused (atlas, value->draw_width, value->draw_height);
|
||||
value->used = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GSK_NOTE(GLYPH_CACHE, if (dropped > 0) g_message ("Dropped %d glyphs", dropped));
|
||||
}
|
||||
|
@ -72,7 +72,8 @@ GskGLGlyphCache * gsk_gl_glyph_cache_new (GdkDisplay *display
|
||||
GskGLTextureAtlases *atlases);
|
||||
GskGLGlyphCache * gsk_gl_glyph_cache_ref (GskGLGlyphCache *self);
|
||||
void gsk_gl_glyph_cache_unref (GskGLGlyphCache *self);
|
||||
void gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self);
|
||||
void gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self,
|
||||
GPtrArray *removed_atlases);
|
||||
gboolean gsk_gl_glyph_cache_lookup (GskGLGlyphCache *self,
|
||||
GlyphCacheKey *lookup,
|
||||
GskGLDriver *driver,
|
||||
|
@ -64,40 +64,43 @@ gsk_gl_icon_cache_unref (GskGLIconCache *self)
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gl_icon_cache_begin_frame (GskGLIconCache *self)
|
||||
gsk_gl_icon_cache_begin_frame (GskGLIconCache *self,
|
||||
GPtrArray *removed_atlases)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
GdkTexture *texture;
|
||||
IconData *icon_data;
|
||||
|
||||
/* Increase frame age of all icons */
|
||||
/* Drop icons on removed atlases */
|
||||
if (removed_atlases->len > 0)
|
||||
{
|
||||
g_hash_table_iter_init (&iter, self->icons);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&texture, (gpointer *)&icon_data))
|
||||
{
|
||||
if (g_ptr_array_find (removed_atlases, icon_data->atlas, NULL))
|
||||
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))
|
||||
{
|
||||
guint pos;
|
||||
icon_data->frame_age ++;
|
||||
|
||||
if (!g_ptr_array_find (self->atlases->atlases, icon_data->atlas, &pos))
|
||||
if (icon_data->frame_age > MAX_FRAME_AGE)
|
||||
{
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
icon_data->frame_age ++;
|
||||
|
||||
if (icon_data->frame_age > MAX_FRAME_AGE)
|
||||
if (icon_data->used)
|
||||
{
|
||||
|
||||
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. */
|
||||
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.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,8 @@ GskGLIconCache * gsk_gl_icon_cache_new (GdkDisplay *display,
|
||||
GskGLTextureAtlases *atlases);
|
||||
GskGLIconCache * gsk_gl_icon_cache_ref (GskGLIconCache *self);
|
||||
void gsk_gl_icon_cache_unref (GskGLIconCache *self);
|
||||
void gsk_gl_icon_cache_begin_frame (GskGLIconCache *self);
|
||||
void gsk_gl_icon_cache_begin_frame (GskGLIconCache *self,
|
||||
GPtrArray *removed_atlases);
|
||||
void gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
|
||||
GdkTexture *texture,
|
||||
int *out_texture_id,
|
||||
|
@ -3181,6 +3181,7 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
GskProfiler *profiler;
|
||||
gint64 gpu_time, cpu_time, start_time;
|
||||
#endif
|
||||
GPtrArray *removed;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
profiler = gsk_renderer_get_profiler (renderer);
|
||||
@ -3204,10 +3205,12 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
ORTHO_FAR_PLANE);
|
||||
graphene_matrix_scale (&projection, 1, -1, 1);
|
||||
|
||||
gsk_gl_texture_atlases_begin_frame (self->atlases);
|
||||
gsk_gl_glyph_cache_begin_frame (self->glyph_cache);
|
||||
gsk_gl_icon_cache_begin_frame (self->icon_cache);
|
||||
removed = g_ptr_array_new ();
|
||||
gsk_gl_texture_atlases_begin_frame (self->atlases, removed);
|
||||
gsk_gl_glyph_cache_begin_frame (self->glyph_cache, removed);
|
||||
gsk_gl_icon_cache_begin_frame (self->icon_cache, removed);
|
||||
gsk_gl_shadow_cache_begin_frame (&self->shadow_cache, self->gl_driver);
|
||||
g_ptr_array_unref (removed);
|
||||
|
||||
ops_set_projection (&self->op_builder, &projection);
|
||||
ops_set_viewport (&self->op_builder, viewport);
|
||||
|
@ -74,7 +74,8 @@ write_atlas_to_png (GskGLTextureAtlas *atlas,
|
||||
#endif
|
||||
|
||||
void
|
||||
gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *self)
|
||||
gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *self,
|
||||
GPtrArray *removed)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -94,6 +95,7 @@ gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *self)
|
||||
atlas->texture_id = 0;
|
||||
}
|
||||
|
||||
g_ptr_array_add (removed, atlas);
|
||||
g_ptr_array_remove_index (self->atlases, i);
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ GskGLTextureAtlases *gsk_gl_texture_atlases_new (void);
|
||||
GskGLTextureAtlases *gsk_gl_texture_atlases_ref (GskGLTextureAtlases *atlases);
|
||||
void gsk_gl_texture_atlases_unref (GskGLTextureAtlases *atlases);
|
||||
|
||||
void gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *atlases);
|
||||
void gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *atlases,
|
||||
GPtrArray *removed);
|
||||
gboolean gsk_gl_texture_atlases_pack (GskGLTextureAtlases *atlases,
|
||||
int width,
|
||||
int height,
|
||||
|
Loading…
Reference in New Issue
Block a user