diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2016-08-04 12:37:54 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2016-08-09 17:31:55 +0100 |
commit | 82e35ddbd53461b7985ae9dfba43e00c63988979 (patch) | |
tree | 60b5a3d535730492da76bd8ffba85ad2ab1693e9 | |
parent | 79bace4f81a739adced16c80db552e337e4f3327 (diff) | |
download | gtk+-82e35ddbd53461b7985ae9dfba43e00c63988979.tar.gz |
gsk: Recycle textures across frames
We keep the textures used inside a frame around until the end of the
following frame; whenever we need a texture with the same size, and
it's not marked in use, then we just reuse the existing texture.
-rw-r--r-- | gsk/gskgldriver.c | 55 | ||||
-rw-r--r-- | gsk/gskgldriverprivate.h | 2 | ||||
-rw-r--r-- | gsk/gskglrenderer.c | 3 |
3 files changed, 59 insertions, 1 deletions
diff --git a/gsk/gskgldriver.c b/gsk/gskgldriver.c index 52d8631df5..443a0ad840 100644 --- a/gsk/gskgldriver.c +++ b/gsk/gskgldriver.c @@ -14,6 +14,7 @@ typedef struct { GLuint min_filter; GLuint mag_filter; GArray *fbos; + gboolean in_use : 1; } Texture; typedef struct { @@ -106,9 +107,14 @@ gsk_gl_driver_finalize (GObject *gobject) { GskGLDriver *self = GSK_GL_DRIVER (gobject); + gdk_gl_context_make_current (self->gl_context); + g_clear_pointer (&self->textures, g_hash_table_unref); g_clear_pointer (&self->vaos, g_hash_table_unref); + if (self->gl_context == gdk_gl_context_get_current ()) + gdk_gl_context_clear_current (); + g_clear_object (&self->gl_context); G_OBJECT_CLASS (gsk_gl_driver_parent_class)->finalize (gobject); @@ -232,6 +238,27 @@ gsk_gl_driver_end_frame (GskGLDriver *driver) driver->in_frame = FALSE; } +void +gsk_gl_driver_collect_textures (GskGLDriver *driver) +{ + GHashTableIter iter; + gpointer value_p = NULL; + + g_return_if_fail (GSK_IS_GL_DRIVER (driver)); + g_return_if_fail (!driver->in_frame); + + g_hash_table_iter_init (&iter, driver->textures); + while (g_hash_table_iter_next (&iter, NULL, &value_p)) + { + Texture *t = value_p; + + if (t->in_use) + t->in_use = FALSE; + else + g_hash_table_iter_remove (&iter); + } +} + static Texture * gsk_gl_driver_get_texture (GskGLDriver *driver, int texture_id) @@ -268,6 +295,26 @@ gsk_gl_driver_get_fbo (GskGLDriver *driver, return &g_array_index (t->fbos, Fbo, 0); } +static Texture * +find_texture_by_size (GHashTable *textures, + int width, + int height) +{ + GHashTableIter iter; + gpointer value_p = NULL; + + g_hash_table_iter_init (&iter, textures); + while (g_hash_table_iter_next (&iter, NULL, &value_p)) + { + Texture *t = value_p; + + if (t->width == width && t->height == height) + return t; + } + + return NULL; +} + int gsk_gl_driver_create_texture (GskGLDriver *driver, int width, @@ -278,6 +325,13 @@ gsk_gl_driver_create_texture (GskGLDriver *driver, g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), -1); + t = find_texture_by_size (driver->textures, width, height); + if (t != NULL && !t->in_use) + { + t->in_use = TRUE; + return t->texture_id; + } + glGenTextures (1, &texture_id); t = texture_new (); @@ -286,6 +340,7 @@ gsk_gl_driver_create_texture (GskGLDriver *driver, t->height = height; t->min_filter = GL_NEAREST; t->mag_filter = GL_NEAREST; + t->in_use = TRUE; g_hash_table_insert (driver->textures, GINT_TO_POINTER (texture_id), t); return t->texture_id; diff --git a/gsk/gskgldriverprivate.h b/gsk/gskgldriverprivate.h index 30eaffa1fb..b69a387ca7 100644 --- a/gsk/gskgldriverprivate.h +++ b/gsk/gskgldriverprivate.h @@ -56,6 +56,8 @@ void gsk_gl_driver_destroy_texture (GskGLDriver *driver void gsk_gl_driver_destroy_vao (GskGLDriver *driver, int vao_id); +void gsk_gl_driver_collect_textures (GskGLDriver *driver); + G_END_DECLS #endif /* __GSK_GL_DRIVER_PRIVATE_H__ */ diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c index de6b2c3d22..1e3dcd2e3d 100644 --- a/gsk/gskglrenderer.c +++ b/gsk/gskglrenderer.c @@ -798,7 +798,6 @@ static void render_item_clear (RenderItem *item, GskGLRenderer *self) { - gsk_gl_driver_destroy_texture (self->gl_driver, item->render_data.texture_id); gsk_gl_driver_destroy_vao (self->gl_driver, item->render_data.vao_id); } @@ -820,6 +819,8 @@ gsk_gl_renderer_clear_tree (GskGLRenderer *self) } g_clear_pointer (&self->render_items, g_array_unref); + + gsk_gl_driver_collect_textures (self->gl_driver); } static void |