Merge branch 'wip/otte/i-see-dead-textures' into 'main'

gpu: Be more aggressive about GC'ing dead textures

See merge request GNOME/gtk!7636
This commit is contained in:
Benjamin Otte
2024-08-21 08:18:53 +00:00
3 changed files with 26 additions and 5 deletions

View File

@@ -48,6 +48,7 @@ struct _GskGpuCache
GskGpuCachedAtlas *current_atlas;
/* atomic */ gsize dead_textures;
/* atomic */ gsize dead_texture_pixels;
};
@@ -372,6 +373,7 @@ struct _GskGpuCachedTexture
* weak ref.
*/
gsize *dead_textures_counter;
gsize *dead_pixels_counter;
GdkTexture *texture;
@@ -470,7 +472,10 @@ gsk_gpu_cached_texture_destroy_cb (gpointer data)
GskGpuCachedTexture *self = data;
if (!gsk_gpu_cached_texture_is_invalid (self))
g_atomic_pointer_add (self->dead_pixels_counter, ((GskGpuCached *) self)->pixels);
{
g_atomic_pointer_add (self->dead_textures_counter, 1);
g_atomic_pointer_add (self->dead_pixels_counter, ((GskGpuCached *) self)->pixels);
}
if (g_atomic_int_dec_and_test (&self->use_count))
g_free (self);
@@ -508,6 +513,7 @@ gsk_gpu_cached_texture_new (GskGpuCache *cache,
self->image = g_object_ref (image);
self->color_state = color_state;
((GskGpuCached *)self)->pixels = gsk_gpu_image_get_width (image) * gsk_gpu_image_get_height (image);
self->dead_textures_counter = &cache->dead_textures;
self->dead_pixels_counter = &cache->dead_texture_pixels;
self->use_count = 2;
@@ -537,6 +543,7 @@ struct _GskGpuCachedTile
* list) and by the texture (via weak ref)
*/
gsize *dead_textures_counter;
gsize *dead_pixels_counter;
GskGpuImage *image;
@@ -609,7 +616,10 @@ gsk_gpu_cached_tile_destroy_cb (gpointer data)
GskGpuCachedTile *self = data;
if (!gsk_gpu_cached_tile_is_invalid (self))
g_atomic_pointer_add (self->dead_pixels_counter, ((GskGpuCached *) self)->pixels);
{
g_atomic_pointer_add (self->dead_textures_counter, 1);
g_atomic_pointer_add (self->dead_pixels_counter, ((GskGpuCached *) self)->pixels);
}
if (g_atomic_int_dec_and_test (&self->use_count))
g_free (self);
@@ -649,6 +659,7 @@ gsk_gpu_cached_tile_new (GskGpuCache *cache,
self->image = g_object_ref (image);
self->color_state = gdk_color_state_ref (color_state);
((GskGpuCached *)self)->pixels = gsk_gpu_image_get_width (image) * gsk_gpu_image_get_height (image);
self->dead_textures_counter = &cache->dead_textures;
self->dead_pixels_counter = &cache->dead_texture_pixels;
self->use_count = 2;
@@ -894,6 +905,7 @@ gsk_gpu_cache_gc (GskGpuCache *self,
is_empty &= cached->stale;
}
g_atomic_pointer_set (&self->dead_textures, 0);
g_atomic_pointer_set (&self->dead_texture_pixels, 0);
if (GSK_DEBUG_CHECK (CACHE))
@@ -904,6 +916,12 @@ gsk_gpu_cache_gc (GskGpuCache *self,
return is_empty;
}
gsize
gsk_gpu_cache_get_dead_textures (GskGpuCache *self)
{
return GPOINTER_TO_SIZE (g_atomic_pointer_get (&self->dead_textures));
}
gsize
gsk_gpu_cache_get_dead_texture_pixels (GskGpuCache *self)
{

View File

@@ -64,6 +64,7 @@ void gsk_gpu_cache_set_time (GskGpuC
gboolean gsk_gpu_cache_gc (GskGpuCache *self,
gint64 cache_timeout,
gint64 timestamp);
gsize gsk_gpu_cache_get_dead_textures (GskGpuCache *self);
gsize gsk_gpu_cache_get_dead_texture_pixels (GskGpuCache *self);
GskGpuImage * gsk_gpu_cache_get_atlas_image (GskGpuCache *self);

View File

@@ -80,7 +80,7 @@ void
gsk_gpu_device_maybe_gc (GskGpuDevice *self)
{
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
gsize dead_texture_pixels;
gsize dead_texture_pixels, dead_textures;
if (priv->cache_timeout < 0)
return;
@@ -88,11 +88,13 @@ gsk_gpu_device_maybe_gc (GskGpuDevice *self)
if (priv->cache == NULL)
return;
dead_textures = gsk_gpu_cache_get_dead_textures (priv->cache);
dead_texture_pixels = gsk_gpu_cache_get_dead_texture_pixels (priv->cache);
if (priv->cache_timeout == 0 || dead_texture_pixels > 1000000)
if (priv->cache_timeout == 0 || dead_textures > 50 || dead_texture_pixels > 1000 * 1000)
{
GSK_DEBUG (CACHE, "Pre-frame GC (%" G_GSIZE_FORMAT " dead pixels)", dead_texture_pixels);
GSK_DEBUG (CACHE, "Pre-frame GC (%" G_GSIZE_FORMAT " dead textures, %" G_GSIZE_FORMAT " dead pixels)",
dead_textures, dead_texture_pixels);
gsk_gpu_device_gc (self, g_get_monotonic_time ());
}
}