diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2018-04-16 16:02:40 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2018-04-16 16:02:40 +0300 |
commit | 4ed21f13608901b10f8f4b37cee9a054a91da0bd (patch) | |
tree | 1ecceb241a3fca144dcf863fcaf1cd36d24fd02e /source/blender/blenkernel | |
parent | 410810d42f92f6726f859601d2517df1ee7e6f75 (diff) | |
parent | a3c80615d580c5e0b76ae120bf65ea23c9c771a5 (diff) |
Merge branch 'blender2.8' into blender2.8-workbench
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_icons.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/icons.c | 64 |
2 files changed, 63 insertions, 4 deletions
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h index a9ca5cc8bbb..c3f5d7bf7c2 100644 --- a/source/blender/blenkernel/BKE_icons.h +++ b/source/blender/blenkernel/BKE_icons.h @@ -75,6 +75,9 @@ void BKE_icon_changed(const int icon_id); /* free all icons */ void BKE_icons_free(void); +/* free all icons marked for deferred deletion */ +void BKE_icons_deferred_free(void); + /* free the preview image for use in list */ void BKE_previewimg_freefunc(void *link); diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index f3ff2c4425a..25a3675896b 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -49,7 +49,9 @@ #include "BLI_utildefines.h" #include "BLI_ghash.h" +#include "BLI_linklist_lockfree.h" #include "BLI_string.h" +#include "BLI_threads.h" #include "BKE_icons.h" #include "BKE_global.h" /* only for G.background test */ @@ -72,6 +74,13 @@ static int gFirstIconId = 1; static GHash *gCachedPreviews = NULL; +/* Queue of icons for deferred deletion. */ +typedef struct DeferredIconDeleteNode { + struct DeferredIconDeleteNode *next; + int icon_id; +} DeferredIconDeleteNode; +static LockfreeLinkList g_icon_delete_queue; + static void icon_free(void *val) { Icon *icon = val; @@ -91,6 +100,7 @@ static void icon_free(void *val) * after the integer number range is used up */ static int get_next_free_id(void) { + BLI_assert(BLI_thread_is_main()); int startId = gFirstIconId; /* if we haven't used up the int number range, we just return the next int */ @@ -111,11 +121,15 @@ static int get_next_free_id(void) void BKE_icons_init(int first_dyn_id) { + BLI_assert(BLI_thread_is_main()); + gNextIconId = first_dyn_id; gFirstIconId = first_dyn_id; - if (!gIcons) + if (!gIcons) { gIcons = BLI_ghash_int_new(__func__); + BLI_linklist_lockfree_init(&g_icon_delete_queue); + } if (!gCachedPreviews) { gCachedPreviews = BLI_ghash_str_new(__func__); @@ -124,6 +138,8 @@ void BKE_icons_init(int first_dyn_id) void BKE_icons_free(void) { + BLI_assert(BLI_thread_is_main()); + if (gIcons) { BLI_ghash_free(gIcons, NULL, icon_free); gIcons = NULL; @@ -133,6 +149,22 @@ void BKE_icons_free(void) BLI_ghash_free(gCachedPreviews, MEM_freeN, BKE_previewimg_freefunc); gCachedPreviews = NULL; } + + BLI_linklist_lockfree_free(&g_icon_delete_queue, MEM_freeN); +} + +void BKE_icons_deferred_free(void) +{ + BLI_assert(BLI_thread_is_main()); + + for (DeferredIconDeleteNode *node = + (DeferredIconDeleteNode *)BLI_linklist_lockfree_begin(&g_icon_delete_queue); + node != NULL; + node = node->next) + { + BLI_ghash_remove(gIcons, SET_INT_IN_POINTER(node->icon_id), NULL, icon_free); + } + BLI_linklist_lockfree_clear(&g_icon_delete_queue, MEM_freeN); } static PreviewImage *previewimg_create_ex(size_t deferred_data_size) @@ -435,6 +467,8 @@ void BKE_previewimg_ensure(PreviewImage *prv, const int size) void BKE_icon_changed(const int icon_id) { + BLI_assert(BLI_thread_is_main()); + Icon *icon = NULL; if (!icon_id || G.background) return; @@ -462,6 +496,8 @@ void BKE_icon_changed(const int icon_id) static int icon_id_ensure_create_icon(struct ID *id) { + BLI_assert(BLI_thread_is_main()); + Icon *new_icon = NULL; new_icon = MEM_mallocN(sizeof(Icon), __func__); @@ -556,6 +592,8 @@ int BKE_icon_preview_ensure(ID *id, PreviewImage *preview) Icon *BKE_icon_get(const int icon_id) { + BLI_assert(BLI_thread_is_main()); + Icon *icon = NULL; icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(icon_id)); @@ -570,6 +608,8 @@ Icon *BKE_icon_get(const int icon_id) void BKE_icon_set(const int icon_id, struct Icon *icon) { + BLI_assert(BLI_thread_is_main()); + void **val_p; if (BLI_ghash_ensure_p(gIcons, SET_INT_IN_POINTER(icon_id), &val_p)) { @@ -580,12 +620,28 @@ void BKE_icon_set(const int icon_id, struct Icon *icon) *val_p = icon; } -void BKE_icon_id_delete(struct ID *id) +static void icon_add_to_deferred_delete_queue(int icon_id) { - if (!id->icon_id) return; /* no icon defined for library object */ + DeferredIconDeleteNode *node = + MEM_mallocN(sizeof(DeferredIconDeleteNode), __func__); + node->icon_id = icon_id; + BLI_linklist_lockfree_insert(&g_icon_delete_queue, + (LockfreeLinkNode *)node); +} - BLI_ghash_remove(gIcons, SET_INT_IN_POINTER(id->icon_id), NULL, icon_free); +void BKE_icon_id_delete(struct ID *id) +{ + const int icon_id = id->icon_id; + if (!icon_id) return; /* no icon defined for library object */ id->icon_id = 0; + + if (!BLI_thread_is_main()) { + icon_add_to_deferred_delete_queue(icon_id); + return; + } + + BKE_icons_deferred_free(); + BLI_ghash_remove(gIcons, SET_INT_IN_POINTER(icon_id), NULL, icon_free); } /** |