forked from AuroraMiddleware/gtk
glyph cache: Fix handling of big glyphs
We were putting big glyphs in the cache, in their own texture, but forgetting to mark the texture as permanent, so it could be reused, leading to occasional misrendering. Fix this by marking these textures as permanent, and explicitly freeing them when the cache entry gets old.
This commit is contained in:
parent
e46a7ca706
commit
7bff3abe8e
@ -15,13 +15,17 @@
|
||||
|
||||
/* Cache eviction strategy
|
||||
*
|
||||
* 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 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
|
||||
* atlas and all the items it contained.
|
||||
* 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 atlas and all the items it
|
||||
* contained.
|
||||
*
|
||||
* Big glyphs are not stored in the atlas, they get their
|
||||
* own texture, but they are still cached.
|
||||
*/
|
||||
|
||||
#define MAX_FRAME_AGE (60)
|
||||
@ -239,6 +243,7 @@ add_to_cache (GskGLGlyphCache *self,
|
||||
{
|
||||
value->atlas = NULL;
|
||||
value->texture_id = gsk_gl_driver_create_texture (driver, width, height);
|
||||
gsk_gl_driver_mark_texture_permanent (driver, value->texture_id);
|
||||
|
||||
gsk_gl_driver_bind_source_texture (driver, value->texture_id);
|
||||
gsk_gl_driver_init_texture_empty (driver, value->texture_id, GL_LINEAR, GL_LINEAR);
|
||||
@ -316,6 +321,7 @@ gsk_gl_glyph_cache_lookup_or_add (GskGLGlyphCache *cache,
|
||||
|
||||
void
|
||||
gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self,
|
||||
GskGLDriver *driver,
|
||||
GPtrArray *removed_atlases)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
@ -348,14 +354,22 @@ gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self,
|
||||
{
|
||||
if (!value->accessed)
|
||||
{
|
||||
if (value->atlas && value->used)
|
||||
if (value->atlas)
|
||||
{
|
||||
gsk_gl_texture_atlas_mark_unused (value->atlas, value->draw_width, value->draw_height);
|
||||
value->used = FALSE;
|
||||
if (value->used)
|
||||
{
|
||||
gsk_gl_texture_atlas_mark_unused (value->atlas, value->draw_width, value->draw_height);
|
||||
value->used = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_gl_driver_destroy_texture (driver, value->texture_id);
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
}
|
||||
|
||||
value->accessed = FALSE;
|
||||
else
|
||||
value->accessed = FALSE;
|
||||
}
|
||||
|
||||
GSK_NOTE(GLYPH_CACHE, g_message ("%d glyphs cached", g_hash_table_size (self->hash_table)));
|
||||
|
@ -73,6 +73,7 @@ GskGLGlyphCache * gsk_gl_glyph_cache_new (GdkDisplay *display
|
||||
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,
|
||||
GskGLDriver *driver,
|
||||
GPtrArray *removed_atlases);
|
||||
void gsk_gl_glyph_cache_lookup_or_add (GskGLGlyphCache *self,
|
||||
GlyphCacheKey *lookup,
|
||||
|
@ -3207,7 +3207,7 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
|
||||
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_glyph_cache_begin_frame (self->glyph_cache, self->gl_driver, 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);
|
||||
|
Loading…
Reference in New Issue
Block a user