diff options
author | Charmaine Lee <[email protected]> | 2017-07-20 11:04:14 -0700 |
---|---|---|
committer | Charmaine Lee <[email protected]> | 2017-07-20 17:34:34 -0700 |
commit | 5124bf982393114862f44ee62fa361027faa7c29 (patch) | |
tree | ccf369ce57ec78bd9cb214d3584383caf8c6a035 /src/mesa/state_tracker | |
parent | 59a141c95a7f4008ba5d5d7804fa75e6b8604a06 (diff) |
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 <[email protected]>
Tested-by: Gert Wollny <[email protected]>
Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r-- | src/mesa/state_tracker/st_manager.c | 95 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_manager.h | 5 |
2 files changed, 99 insertions, 1 deletions
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 */ |