Fix ID types DAG update tagging.
authorKévin Dietrich <kevin.dietrich@mailoo.org>
Mon, 8 Aug 2016 15:51:15 +0000 (17:51 +0200)
committerKévin Dietrich <kevin.dietrich@mailoo.org>
Mon, 8 Aug 2016 15:51:15 +0000 (17:51 +0200)
The first character of the ID type was used to tag IDs for updates which
is weak since different IDs can have the same first character (for
example meshes, materials and metaballs), causing unnecessary updates of
unrelated IDs.

Now we use a unique index per ID type to tag for updates, unifying IDs
arrays indexing along the way.

Reviewers: sergey, mont29

Differential Revision: https://developer.blender.org/D2139

source/blender/blenkernel/BKE_idcode.h
source/blender/blenkernel/BKE_main.h
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/idcode.c
source/blender/blenkernel/intern/library.c
source/blender/depsgraph/intern/depsgraph_query.cc
source/blender/depsgraph/intern/depsgraph_tag.cc
source/blender/makesdna/DNA_ID.h

index 6de0efe27097e9d64585e5cd58d53ffe5da4585f..964a49435f157566ed77f2ed30a226cebce8b941 100644 (file)
@@ -42,6 +42,8 @@ bool        BKE_idcode_is_valid(short idcode);
 int         BKE_idcode_to_idfilter(const short idcode);
 short       BKE_idcode_from_idfilter(const int idfilter);
 
+int BKE_idcode_to_index(const short idcode);
+
 /**
  * Return an ID code and steps the index forward 1.
  *
index 29219a4f56efaee1be6f0919b4afd8eacbb8a070..a4f5c42528254c65279e8943037f80f0594b86e3 100644 (file)
@@ -42,6 +42,8 @@
  */
 #include "DNA_listBase.h"
 
+#include "BKE_library.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -104,7 +106,7 @@ typedef struct Main {
        ListBase linestyle;
        ListBase cachefiles;
 
-       char id_tag_update[256];
+       char id_tag_update[MAX_LIBARRAY];
 
        /* Evaluation context used by viewport */
        struct EvaluationContext *eval_ctx;
index 986c1d88bc91266d6ebcd3387fcbc0f7f880c333..45a23c39910c209d89b1642114c182503c98d677 100644 (file)
@@ -67,6 +67,7 @@
 #include "BKE_effect.h"
 #include "BKE_fcurve.h"
 #include "BKE_global.h"
+#include "BKE_idcode.h"
 #include "BKE_image.h"
 #include "BKE_key.h"
 #include "BKE_library.h"
@@ -2805,9 +2806,7 @@ void DAG_ids_flush_tagged(Main *bmain)
                ListBase *lb = lbarray[a];
                ID *id = lb->first;
 
-               /* we tag based on first ID type character to avoid 
-                * looping over all ID's in case there are no tags */
-               if (id && bmain->id_tag_update[id->name[0]]) {
+               if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
                        for (; id; id = id->next) {
                                if (id->tag & (LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA)) {
                                        
@@ -2847,9 +2846,7 @@ void DAG_ids_check_recalc(Main *bmain, Scene *scene, bool time)
                ListBase *lb = lbarray[a];
                ID *id = lb->first;
 
-               /* we tag based on first ID type character to avoid 
-                * looping over all ID's in case there are no tags */
-               if (id && bmain->id_tag_update[id->name[0]]) {
+               if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
                        updated = true;
                        break;
                }
@@ -2930,9 +2927,7 @@ void DAG_ids_clear_recalc(Main *bmain)
                ListBase *lb = lbarray[a];
                ID *id = lb->first;
 
-               /* we tag based on first ID type character to avoid 
-                * looping over all ID's in case there are no tags */
-               if (id && bmain->id_tag_update[id->name[0]]) {
+               if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
                        for (; id; id = id->next) {
                                if (id->tag & (LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA))
                                        id->tag &= ~(LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA);
@@ -3053,12 +3048,12 @@ void DAG_id_type_tag(Main *bmain, short idtype)
                DAG_id_type_tag(bmain, ID_SCE);
        }
 
-       bmain->id_tag_update[((char *)&idtype)[0]] = 1;
+       bmain->id_tag_update[BKE_idcode_to_index(idtype)] = 1;
 }
 
 int DAG_id_type_tagged(Main *bmain, short idtype)
 {
-       return bmain->id_tag_update[((char *)&idtype)[0]];
+       return bmain->id_tag_update[BKE_idcode_to_index(idtype)];
 }
 
 #if 0 // UNUSED
index 1127d1d88daf6cf1bcfd1d4dcfdeaaccbaf8d6dc..70d037d85f35d8caddda767ded429bc1092f19f3 100644 (file)
@@ -261,6 +261,56 @@ short BKE_idcode_from_idfilter(const int idfilter)
 #undef CASE_IDFILTER
 }
 
+/**
+ * Convert an idcode into an index (e.g. ID_OB -> INDEX_ID_OB).
+ */
+int BKE_idcode_to_index(const short idcode)
+{
+#define CASE_IDINDEX(_id) case ID_##_id: return INDEX_ID_##_id
+
+       switch ((ID_Type)idcode) {
+               CASE_IDINDEX(AC);
+               CASE_IDINDEX(AR);
+               CASE_IDINDEX(BR);
+               CASE_IDINDEX(CA);
+               CASE_IDINDEX(CF);
+               CASE_IDINDEX(CU);
+               CASE_IDINDEX(GD);
+               CASE_IDINDEX(GR);
+               CASE_IDINDEX(IM);
+               CASE_IDINDEX(KE);
+               CASE_IDINDEX(IP);
+               CASE_IDINDEX(LA);
+               CASE_IDINDEX(LI);
+               CASE_IDINDEX(LS);
+               CASE_IDINDEX(LT);
+               CASE_IDINDEX(MA);
+               CASE_IDINDEX(MB);
+               CASE_IDINDEX(MC);
+               CASE_IDINDEX(ME);
+               CASE_IDINDEX(MSK);
+               CASE_IDINDEX(NT);
+               CASE_IDINDEX(OB);
+               CASE_IDINDEX(PA);
+               CASE_IDINDEX(PAL);
+               CASE_IDINDEX(PC);
+               CASE_IDINDEX(SCE);
+               CASE_IDINDEX(SCR);
+               CASE_IDINDEX(SPK);
+               CASE_IDINDEX(SO);
+               CASE_IDINDEX(TE);
+               CASE_IDINDEX(TXT);
+               CASE_IDINDEX(VF);
+               CASE_IDINDEX(WM);
+               CASE_IDINDEX(WO);
+       }
+
+       BLI_assert(0);
+       return -1;
+
+#undef CASE_IDINDEX
+}
+
 /**
  * Convert an idcode into a name (plural).
  *
index c5517265da37cad8c0e219dea15d172900407dc8..6d94cd28b31b04ba967dcd7a85a1b0bcdd80e887 100644 (file)
@@ -753,60 +753,56 @@ void BKE_main_lib_objects_recalc_all(Main *bmain)
  * \note MAX_LIBARRAY define should match this code */
 int set_listbasepointers(Main *main, ListBase **lb)
 {
-       int a = 0;
-
        /* BACKWARDS! also watch order of free-ing! (mesh<->mat), first items freed last.
         * This is important because freeing data decreases usercounts of other datablocks,
         * if this data is its self freed it can crash. */
-       lb[a++] = &(main->library);  /* Libraries may be accessed from pretty much any other ID... */
-       lb[a++] = &(main->ipo);
-       lb[a++] = &(main->action); /* moved here to avoid problems when freeing with animato (aligorith) */
-       lb[a++] = &(main->key);
-       lb[a++] = &(main->gpencil); /* referenced by nodes, objects, view, scene etc, before to free after. */
-       lb[a++] = &(main->nodetree);
-       lb[a++] = &(main->image);
-       lb[a++] = &(main->tex);
-       lb[a++] = &(main->mat);
-       lb[a++] = &(main->vfont);
+       lb[INDEX_ID_LI] = &(main->library);  /* Libraries may be accessed from pretty much any other ID... */
+       lb[INDEX_ID_IP] = &(main->ipo);
+       lb[INDEX_ID_AC] = &(main->action); /* moved here to avoid problems when freeing with animato (aligorith) */
+       lb[INDEX_ID_KE] = &(main->key);
+       lb[INDEX_ID_GD] = &(main->gpencil); /* referenced by nodes, objects, view, scene etc, before to free after. */
+       lb[INDEX_ID_NT] = &(main->nodetree);
+       lb[INDEX_ID_IM] = &(main->image);
+       lb[INDEX_ID_TE] = &(main->tex);
+       lb[INDEX_ID_MA] = &(main->mat);
+       lb[INDEX_ID_VF] = &(main->vfont);
        
        /* Important!: When adding a new object type,
         * the specific data should be inserted here 
         */
 
-       lb[a++] = &(main->armature);
-
-       lb[a++] = &(main->cachefiles);
-       lb[a++] = &(main->mesh);
-       lb[a++] = &(main->curve);
-       lb[a++] = &(main->mball);
-
-       lb[a++] = &(main->latt);
-       lb[a++] = &(main->lamp);
-       lb[a++] = &(main->camera);
-
-       lb[a++] = &(main->text);
-       lb[a++] = &(main->sound);
-       lb[a++] = &(main->group);
-       lb[a++] = &(main->palettes);
-       lb[a++] = &(main->paintcurves);
-       lb[a++] = &(main->brush);
-       lb[a++] = &(main->particle);
-       lb[a++] = &(main->speaker);
-
-       lb[a++] = &(main->world);
-       lb[a++] = &(main->movieclip);
-       lb[a++] = &(main->screen);
-       lb[a++] = &(main->object);
-       lb[a++] = &(main->linestyle); /* referenced by scenes */
-       lb[a++] = &(main->scene);
-       lb[a++] = &(main->wm);
-       lb[a++] = &(main->mask);
+       lb[INDEX_ID_AR] = &(main->armature);
+
+       lb[INDEX_ID_CF] = &(main->cachefiles);
+       lb[INDEX_ID_ME] = &(main->mesh);
+       lb[INDEX_ID_CU] = &(main->curve);
+       lb[INDEX_ID_MB] = &(main->mball);
+
+       lb[INDEX_ID_LT] = &(main->latt);
+       lb[INDEX_ID_LA] = &(main->lamp);
+       lb[INDEX_ID_CA] = &(main->camera);
+
+       lb[INDEX_ID_TXT] = &(main->text);
+       lb[INDEX_ID_SO]  = &(main->sound);
+       lb[INDEX_ID_GR]  = &(main->group);
+       lb[INDEX_ID_PAL] = &(main->palettes);
+       lb[INDEX_ID_PC]  = &(main->paintcurves);
+       lb[INDEX_ID_BR]  = &(main->brush);
+       lb[INDEX_ID_PA]  = &(main->particle);
+       lb[INDEX_ID_SPK] = &(main->speaker);
+
+       lb[INDEX_ID_WO]  = &(main->world);
+       lb[INDEX_ID_MC]  = &(main->movieclip);
+       lb[INDEX_ID_SCR] = &(main->screen);
+       lb[INDEX_ID_OB]  = &(main->object);
+       lb[INDEX_ID_LS]  = &(main->linestyle); /* referenced by scenes */
+       lb[INDEX_ID_SCE] = &(main->scene);
+       lb[INDEX_ID_WM]  = &(main->wm);
+       lb[INDEX_ID_MSK] = &(main->mask);
        
-       lb[a] = NULL;
-
-       BLI_assert(a + 1 == MAX_LIBARRAY);
+       lb[INDEX_ID_NULL] = NULL;
 
-       return a;
+       return (MAX_LIBARRAY - 1);
 }
 
 /* *********** ALLOC AND FREE *****************
index cac4eaae215ab3be42aaee07cb8b1e641c581655..7f2f6a65f5ef97687a1708f3b414b6bee200d771 100644 (file)
@@ -33,6 +33,7 @@
 #include "MEM_guardedalloc.h"
 
 extern "C" {
+#include "BKE_idcode.h"
 #include "BKE_main.h"
 
 #include "DEG_depsgraph_query.h"
@@ -42,7 +43,7 @@ extern "C" {
 
 bool DEG_id_type_tagged(Main *bmain, short idtype)
 {
-       return bmain->id_tag_update[((unsigned char *)&idtype)[0]] != 0;
+       return bmain->id_tag_update[BKE_idcode_to_index(idtype)] != 0;
 }
 
 short DEG_get_eval_flags_for_id(Depsgraph *graph, ID *id)
index ea5afaab3f7a0b714c252e8e2a7f90bbaccc9226..b7b62bd59f9d3b9735afa6a2a69f49e12bcba550 100644 (file)
@@ -44,6 +44,7 @@ extern "C" {
 
 #include "BLI_task.h"
 
+#include "BKE_idcode.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_node.h"
@@ -259,10 +260,8 @@ void DEG_id_type_tag(Main *bmain, short idtype)
                DEG_id_type_tag(bmain, ID_WO);
                DEG_id_type_tag(bmain, ID_SCE);
        }
-       /* We tag based on first ID type character to avoid
-        * looping over all ID's in case there are no tags.
-        */
-       bmain->id_tag_update[((unsigned char *)&idtype)[0]] = 1;
+
+       bmain->id_tag_update[BKE_idcode_to_index(idtype)] = 1;
 }
 
 /* Recursively push updates out to all nodes dependent on this,
@@ -373,10 +372,7 @@ void DEG_ids_check_recalc(Main *bmain, Scene *scene, bool time)
                ListBase *lb = lbarray[a];
                ID *id = (ID *)lb->first;
 
-               /* We tag based on first ID type character to avoid
-                * looping over all ID's in case there are no tags.
-                */
-               if (id && bmain->id_tag_update[(unsigned char)id->name[0]]) {
+               if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
                        updated = true;
                        break;
                }
@@ -401,10 +397,7 @@ void DEG_ids_clear_recalc(Main *bmain)
                ListBase *lb = lbarray[a];
                ID *id = (ID *)lb->first;
 
-               /* We tag based on first ID type character to avoid
-                * looping over all ID's in case there are no tags.
-                */
-               if (id && bmain->id_tag_update[(unsigned char)id->name[0]]) {
+               if (id && bmain->id_tag_update[BKE_idcode_to_index(GS(id->name))]) {
                        for (; id; id = (ID *)id->next) {
                                id->tag &= ~(LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA);
 
index 0f8cc8fa105ee80a16d9017a65c9e88a89e001ca..5c1bfc229da31ccc4af1de3782ffb32d620266d6 100644 (file)
@@ -381,6 +381,46 @@ enum {
        FILTER_ID_CF        = (1 << 28),
 };
 
+/* IMPORTANT: this enum matches the order currently use in set_lisbasepointers,
+ * keep them in sync! */
+enum {
+       INDEX_ID_LI = 0,
+       INDEX_ID_IP,
+       INDEX_ID_AC,
+       INDEX_ID_KE,
+       INDEX_ID_GD,
+       INDEX_ID_NT,
+       INDEX_ID_IM,
+       INDEX_ID_TE,
+       INDEX_ID_MA,
+       INDEX_ID_VF,
+       INDEX_ID_AR,
+       INDEX_ID_CF,
+       INDEX_ID_ME,
+       INDEX_ID_CU,
+       INDEX_ID_MB,
+       INDEX_ID_LT,
+       INDEX_ID_LA,
+       INDEX_ID_CA,
+       INDEX_ID_TXT,
+       INDEX_ID_SO,
+       INDEX_ID_GR,
+       INDEX_ID_PAL,
+       INDEX_ID_PC,
+       INDEX_ID_BR,
+       INDEX_ID_PA,
+       INDEX_ID_SPK,
+       INDEX_ID_WO,
+       INDEX_ID_MC,
+       INDEX_ID_SCR,
+       INDEX_ID_OB,
+       INDEX_ID_LS,
+       INDEX_ID_SCE,
+       INDEX_ID_WM,
+       INDEX_ID_MSK,
+       INDEX_ID_NULL,
+};
+
 #ifdef __cplusplus
 }
 #endif