mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-09 10:20:07 +00:00
gpu: Be more aggressive about GC'ing dead textures
When we encounter many dead textures, we want to GC. Textures can take up fds (potentially even more than 1) and when we are not collecting them quickly enough, we may run out of fds. So GC when more then 50 dead textures exist. An example for this happening is recent Mesa with llvmpipe udmabuf support, which takes 2 fds per texture and the test in testsuite/gdk/memorytexture that creates 800 textures of ~1 pixel each, which it diligently releases but doesn't GC. Related: #6917
This commit is contained in:
parent
a196bf1132
commit
c7fabe2897
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 ());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user