From 5124bf982393114862f44ee62fa361027faa7c29 Mon Sep 17 00:00:00 2001 From: Charmaine Lee Date: Thu, 20 Jul 2017 11:04:14 -0700 Subject: st/mesa: add destroy_drawable interface With this patch, the st manager will maintain a hash table for the active framebuffer interface objects. A destroy_drawable interface is added to allow the state tracker to notify the st manager to remove the associated framebuffer interface object from the hash table, so the associated framebuffer and its resources can be deleted at framebuffers purge time. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101829 Fixes: 147d7fb772a ("st/mesa: add a winsys buffers list in st_context") Tested-by: Brad King Tested-by: Gert Wollny Reviewed-by: Brian Paul --- src/mesa/state_tracker/st_manager.c | 95 ++++++++++++++++++++++++++++++++++++- src/mesa/state_tracker/st_manager.h | 5 ++ 2 files changed, 99 insertions(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index cb816de8025..ebc7ca8b133 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -38,6 +38,7 @@ #include "main/fbobject.h" #include "main/renderbuffer.h" #include "main/version.h" +#include "util/hash_table.h" #include "st_texture.h" #include "st_context.h" @@ -59,6 +60,10 @@ #include "util/u_surface.h" #include "util/list.h" +struct hash_table; +static struct hash_table *st_fbi_ht; /* framebuffer iface objects hash table */ + +static mtx_t st_mutex = _MTX_INITIALIZER_NP; /** * Map an attachment to a buffer index. @@ -490,6 +495,76 @@ st_framebuffer_reference(struct st_framebuffer **ptr, _mesa_reference_framebuffer((struct gl_framebuffer **) ptr, fb); } + +static uint32_t +st_framebuffer_iface_hash(const void *key) +{ + return (uintptr_t)key; +} + + +static bool +st_framebuffer_iface_equal(const void *a, const void *b) +{ + return (struct st_framebuffer_iface *)a == (struct st_framebuffer_iface *)b; +} + + +static boolean +st_framebuffer_iface_lookup(const struct st_framebuffer_iface *stfbi) +{ + struct hash_entry *entry; + + mtx_lock(&st_mutex); + entry = _mesa_hash_table_search(st_fbi_ht, stfbi); + mtx_unlock(&st_mutex); + + return entry != NULL; +} + + +static boolean +st_framebuffer_iface_insert(struct st_framebuffer_iface *stfbi) +{ + struct hash_entry *entry; + + mtx_lock(&st_mutex); + entry = _mesa_hash_table_insert(st_fbi_ht, stfbi, stfbi); + mtx_unlock(&st_mutex); + + return entry != NULL; +} + + +static void +st_framebuffer_iface_remove(struct st_framebuffer_iface *stfbi) +{ + struct hash_entry *entry; + + mtx_lock(&st_mutex); + entry = _mesa_hash_table_search(st_fbi_ht, stfbi); + if (!entry) + goto unlock; + + _mesa_hash_table_remove(st_fbi_ht, entry); + +unlock: + mtx_unlock(&st_mutex); +} + + +/** + * The framebuffer interface object is no longer valid. + * Remove the object from the framebuffer interface hash table. + */ +static void +st_api_destroy_drawable(struct st_api *stapi, + struct st_framebuffer_iface *stfbi) +{ + st_framebuffer_iface_remove(stfbi); +} + + /** * Purge the winsys buffers list to remove any references to * non-existing framebuffer interface objects. @@ -506,7 +581,7 @@ st_framebuffers_purge(struct st_context *st) * and unreference the framebuffer object, so its resources can be * deleted. */ - if (stfb->iface->ID != stfb->iface_ID) { + if (!st_framebuffer_iface_lookup(stfb->iface)) { LIST_DEL(&stfb->head); st_framebuffer_reference(&stfb, NULL); } @@ -810,6 +885,14 @@ st_framebuffer_reuse_or_create(struct st_context *st, cur = st_framebuffer_create(st, stfbi); if (cur) { + /* add the referenced framebuffer interface object to + * the framebuffer interface object hash table. + */ + if (!st_framebuffer_iface_insert(stfbi)) { + st_framebuffer_reference(&cur, NULL); + return NULL; + } + /* add to the context's winsys buffers list */ LIST_ADD(&cur->head, &st->winsys_buffers); @@ -881,6 +964,8 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, static void st_api_destroy(struct st_api *stapi) { + _mesa_hash_table_destroy(st_fbi_ht, NULL); + mtx_destroy(&st_mutex); } /** @@ -1015,10 +1100,18 @@ static const struct st_api st_gl_api = { .create_context = st_api_create_context, .make_current = st_api_make_current, .get_current = st_api_get_current, + .destroy_drawable = st_api_destroy_drawable, }; struct st_api * st_gl_api_create(void) { + /* Create a hash table for all the framebuffer interface objects */ + + mtx_init(&st_mutex, mtx_plain); + st_fbi_ht = _mesa_hash_table_create(NULL, + st_framebuffer_iface_hash, + st_framebuffer_iface_equal); + return (struct st_api *) &st_gl_api; } diff --git a/src/mesa/state_tracker/st_manager.h b/src/mesa/state_tracker/st_manager.h index 68adf2fa1a4..c54f29e2941 100644 --- a/src/mesa/state_tracker/st_manager.h +++ b/src/mesa/state_tracker/st_manager.h @@ -34,6 +34,7 @@ struct st_context; struct st_framebuffer; +struct st_framebuffer_interface; void st_manager_flush_frontbuffer(struct st_context *st); @@ -48,4 +49,8 @@ st_manager_add_color_renderbuffer(struct st_context *st, struct gl_framebuffer * void st_framebuffer_reference(struct st_framebuffer **ptr, struct st_framebuffer *stfb); + +void +st_framebuffer_interface_destroy(struct st_framebuffer_interface *stfbi); + #endif /* ST_MANAGER_H */ -- cgit v1.2.3