Merge branch 'master' into blender2.8
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 16 Apr 2018 08:19:03 +0000 (10:19 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 16 Apr 2018 08:19:03 +0000 (10:19 +0200)
1  2 
source/blender/blenkernel/intern/icons.c
source/blender/blenlib/CMakeLists.txt
tests/gtests/blenlib/CMakeLists.txt

index f3ff2c4425afc759c42fec7cfbf04b08d270e77c,6aa00b2c97d33d8404828f0518a58cb7ec50ce3f..25a3675896bb97fcf96078689cad24a521134282
  #include "DNA_material_types.h"
  #include "DNA_object_types.h"
  #include "DNA_scene_types.h"
 +#include "DNA_screen_types.h"
  #include "DNA_texture_types.h"
  #include "DNA_world_types.h"
  #include "DNA_brush_types.h"
  
  #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 -73,13 +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;
   * 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 */
  
  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__);
  
  void BKE_icons_free(void)
  {
+       BLI_assert(BLI_thread_is_main());
        if (gIcons) {
                BLI_ghash_free(gIcons, NULL, icon_free);
                gIcons = NULL;
                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)
@@@ -253,7 -284,6 +285,7 @@@ PreviewImage **BKE_previewimg_id_get_p(
                ID_PRV_CASE(ID_OB, Object);
                ID_PRV_CASE(ID_GR, Group);
                ID_PRV_CASE(ID_SCE, Scene);
 +              ID_PRV_CASE(ID_SCR, bScreen);
  #undef ID_PRV_CASE
                default:
                        break;
@@@ -435,6 -465,8 +467,8 @@@ void BKE_previewimg_ensure(PreviewImag
  
  void BKE_icon_changed(const int icon_id)
  {
+       BLI_assert(BLI_thread_is_main());
        Icon *icon = NULL;
        
        if (!icon_id || G.background) return;
  
  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 -590,8 +592,8 @@@ int BKE_icon_preview_ensure(ID *id, Pre
  
  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));
  
  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)) {
        *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);
  }
  
  /**
index 5bcf4303a841563bc1a273f1d108d5b5dcad1ff1,f8fc2bfdcff515be9a3f9f16047861c3e66e1e2a..80a8ef96eb3bb10e0f21ddc188e1c38e5ca0166d
@@@ -50,8 -50,8 +50,9 @@@ set(SR
        intern/BLI_kdopbvh.c
        intern/BLI_kdtree.c
        intern/BLI_linklist.c
+       intern/BLI_linklist_lockfree.c
        intern/BLI_memarena.c
 +      intern/BLI_memiter.c
        intern/BLI_mempool.c
        intern/DLRB_tree.c
        intern/array_store.c
        BLI_hash_md5.h
        BLI_hash_mm2a.h
        BLI_heap.h
 +      BLI_iterator.h
        BLI_jitter_2d.h
        BLI_kdopbvh.h
        BLI_kdtree.h
        BLI_lasso_2d.h
        BLI_link_utils.h
-       BLI_linklist.h
+       BLI_linklist_lockfree.h
        BLI_linklist_stack.h
        BLI_listbase.h
        BLI_math.h
        BLI_math_statistics.h
        BLI_math_vector.h
        BLI_memarena.h
 +      BLI_memiter.h
        BLI_memory_utils.h
        BLI_mempool.h
        BLI_noise.h
index ea2b2741f8c69ca0c862bb1c4133967c86815b50,a3f62d8a05d503b65cc781a974d34833be512855..7be18330ac3be3e758e6a8cccdabda992177b188
@@@ -47,11 -47,11 +47,12 @@@ BLENDER_TEST(BLI_ghash "bf_blenlib"
  BLENDER_TEST(BLI_hash_mm2a "bf_blenlib")
  BLENDER_TEST(BLI_heap "bf_blenlib")
  BLENDER_TEST(BLI_kdopbvh "bf_blenlib")
+ BLENDER_TEST(BLI_linklist_lockfree "bf_blenlib")
  BLENDER_TEST(BLI_listbase "bf_blenlib")
  BLENDER_TEST(BLI_math_base "bf_blenlib")
  BLENDER_TEST(BLI_math_color "bf_blenlib")
  BLENDER_TEST(BLI_math_geom "bf_blenlib")
 +BLENDER_TEST(BLI_memiter "bf_blenlib")
  BLENDER_TEST(BLI_path_util "${BLI_path_util_extra_libs}")
  BLENDER_TEST(BLI_polyfill_2d "bf_blenlib")
  BLENDER_TEST(BLI_stack "bf_blenlib")