2.5
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 19 Jun 2009 23:05:21 +0000 (23:05 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 19 Jun 2009 23:05:21 +0000 (23:05 +0000)
* Optimized RNA property lookups and path resolving, still can be
  much better, but now the 1000 IPO example on bf-taskforce25
  runs at reasonable speed.
* Also an optimization in the depsgraph when dealing with many
  objects, this was actually also a bottleneck here.

15 files changed:
source/blender/blenkernel/BKE_depsgraph.h
source/blender/blenkernel/depsgraph_private.h
source/blender/blenkernel/intern/depsgraph.c
source/blender/makesrna/RNA_define.h
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_define.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_internal_types.h
source/blender/makesrna/intern/rna_rna.c
source/creator/creator.c
source/gameengine/GamePlayer/ghost/CMakeLists.txt
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/GamePlayer/ghost/Makefile
source/gameengine/GamePlayer/ghost/SConscript

index b86a58780dc92dd8f548e50028453e154963c8d1..70b6c1d13f4862e834e9795b1b901a2fb368a1c9 100644 (file)
@@ -36,6 +36,7 @@ struct Scene;
 struct DagNodeQueue;
 struct DagForest;
 struct DagNode;
+struct GHash;
 
 /* **** DAG relation types *** */
 
index 78717393bafd4c5b0b030e8a4728fecdfbba7d34..47e33c0e81e9eecaa6685c02b42c634ca4d140d9 100644 (file)
@@ -65,6 +65,7 @@ typedef struct DagNode
        void * first_ancestor;
        int ancestor_count;
        int lay;                        // accumulated layers of its relations + itself
+       int scelay;                     // layers due to being in scene
        int lasttime;           // if lasttime != DagForest->time, this node was not evaluated yet for flushing
        int BFS_dist;           // BFS distance
        int DFS_dist;           // DFS distance
@@ -93,6 +94,7 @@ typedef struct DagNodeQueue
 typedef struct DagForest 
 {
        ListBase DagNode;
+       struct GHash *nodeHash;
        int numNodes;
        int is_acyclic;
        int time;               // for flushing/tagging, compare with node->lasttime
index dfe3b7ea27943f5d2ca8301c4290a21f683c7709..8bb34bde12210802cad4ec89d84844e49281e232 100644 (file)
@@ -61,6 +61,8 @@
 #include "DNA_view2d_types.h"
 #include "DNA_view3d_types.h"
 
+#include "BLI_ghash.h"
+
 #include "BKE_action.h"
 #include "BKE_effect.h"
 #include "BKE_global.h"
@@ -754,6 +756,9 @@ void free_forest(DagForest *Dag)
                itN = itN->next;
                MEM_freeN(tempN);
        }
+
+       BLI_ghash_free(Dag->nodeHash, NULL, NULL);
+       Dag->nodeHash= NULL;
        Dag->DagNode.first = NULL;
        Dag->DagNode.last = NULL;
        Dag->numNodes = 0;
@@ -762,13 +767,9 @@ void free_forest(DagForest *Dag)
 
 DagNode * dag_find_node (DagForest *forest,void * fob)
 {
-       DagNode *node = forest->DagNode.first;
-       
-       while (node) {
-               if (node->ob == fob)
-                       return node;
-               node = node->next;
-       }
+       if(forest->nodeHash)
+               return BLI_ghash_lookup(forest->nodeHash, fob);
+
        return NULL;
 }
 
@@ -794,7 +795,12 @@ DagNode * dag_add_node (DagForest *forest, void * fob)
                        forest->DagNode.first = node;
                        forest->numNodes = 1;
                }
+
+               if(!forest->nodeHash)
+                       forest->nodeHash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+               BLI_ghash_insert(forest->nodeHash, fob, node);
        }
+
        return node;
 }
 
@@ -1805,17 +1811,10 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
 /* node was checked to have lasttime != curtime , and is of type ID_OB */
 static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime)
 {
-       Base *base;
        DagAdjList *itA;
        
        node->lasttime= curtime;
-       node->lay= 0;
-       for(base= sce->base.first; base; base= base->next) {
-               if(node->ob == base->object) {
-                       node->lay= ((Object *)node->ob)->lay;
-                       break;
-               }
-       }
+       node->lay= node->scelay;
        
        for(itA = node->child; itA; itA= itA->next) {
                if(itA->node->type==ID_OB) {
@@ -1860,9 +1859,10 @@ static void flush_pointcache_reset(DagNode *node, int curtime, int reset)
 /* flushes all recalc flags in objects down the dependency tree */
 void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time)
 {
-       DagNode *firstnode;
+       DagNode *firstnode, *node;
        DagAdjList *itA;
        Object *ob;
+       Base *base;
        int lasttime;
        
        if(sce->theDag==NULL) {
@@ -1879,6 +1879,15 @@ void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time)
        sce->theDag->time++;    // so we know which nodes were accessed
        lasttime= sce->theDag->time;
 
+
+       for(base= sce->base.first; base; base= base->next) {
+               node= dag_get_node(sce->theDag, base->object);
+               if(node)
+                       node->scelay= base->object->lay;
+               else
+                       node->scelay= 0;
+       }
+
        for(itA = firstnode->child; itA; itA= itA->next)
                if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB) 
                        flush_layer_node(sce, itA->node, lasttime);
index dfe072c4b8e1f250e0cd3afb7b01e8087fc7c06b..b620a31508532134d936ef4dc8843fd7d43820a2 100644 (file)
@@ -42,6 +42,8 @@ extern "C" {
 BlenderRNA *RNA_create(void);
 void RNA_define_free(BlenderRNA *brna);
 void RNA_free(BlenderRNA *brna);
+
+void RNA_init(void);
 void RNA_exit(void);
 
 /* Struct */
index c827351371161afb3bc0645daafaec3ad5d3c8a6..75293d83346228ddc4c63e3a860c7c0692c84952 100644 (file)
@@ -1488,8 +1488,8 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
        if(nest != NULL) {
                len= strlen(nest);
 
-               strnest= MEM_mallocN(sizeof(char)*(len+1), "rna_generate_property -> strnest");
-               errnest= MEM_mallocN(sizeof(char)*(len+1), "rna_generate_property -> errnest");
+               strnest= MEM_mallocN(sizeof(char)*(len+2), "rna_generate_property -> strnest");
+               errnest= MEM_mallocN(sizeof(char)*(len+2), "rna_generate_property -> errnest");
 
                strcpy(strnest, "_"); strcat(strnest, nest);
                strcpy(errnest, "."); strcat(errnest, nest);
@@ -1713,6 +1713,8 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
                if(func->cont.prev) fprintf(f, "(FunctionRNA*)&rna_%s_%s_func,\n", srna->identifier, ((FunctionRNA*)func->cont.prev)->identifier);
                else fprintf(f, "NULL,\n");
 
+               fprintf(f, "\tNULL,\n");
+
                parm= func->cont.properties.first;
                if(parm) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s_%s, ", srna->identifier, func->identifier, parm->identifier);
                else fprintf(f, "\t{NULL, ");
@@ -1744,6 +1746,8 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
        if(srna->cont.prev) fprintf(f, "(ContainerRNA *)&RNA_%s,\n", ((StructRNA*)srna->cont.prev)->identifier);
        else fprintf(f, "NULL,\n");
 
+       fprintf(f, "\tNULL,\n");
+
        prop= srna->cont.properties.first;
        if(prop) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s, ", srna->identifier, prop->identifier);
        else fprintf(f, "\t{NULL, ");
index 8d0d87a72d3d09389104e66814c231e4c70d810e..ba893319ce98f0ffb3029de71d40dc74c4ef25ca 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "BLI_blenlib.h"
 #include "BLI_dynstr.h"
+#include "BLI_ghash.h"
 
 #include "BKE_context.h"
 #include "BKE_idprop.h"
 
 #include "rna_internal.h"
 
-/* Exit */
+/* Init/Exit */
+
+void RNA_init()
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
+               if(!srna->cont.prophash) {
+                       srna->cont.prophash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
+
+                       for(prop=srna->cont.properties.first; prop; prop=prop->next)
+                               if(!(prop->flag & PROP_BUILTIN))
+                                       BLI_ghash_insert(srna->cont.prophash, (void*)prop->identifier, prop);
+               }
+       }
+}
 
 void RNA_exit()
 {
+       StructRNA *srna;
+
+       for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
+               if(srna->cont.prophash) {
+                       BLI_ghash_free(srna->cont.prophash, NULL, NULL);
+                       srna->cont.prophash= NULL;
+               }
+       }
+
        RNA_free(&BLENDER_RNA);
 }
 
@@ -388,24 +414,13 @@ int RNA_struct_is_a(StructRNA *type, StructRNA *srna)
 
 PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
 {
-       CollectionPropertyIterator iter;
-       PropertyRNA *iterprop, *prop;
-       int i = 0;
-
-       iterprop= RNA_struct_iterator_property(ptr->type);
-       RNA_property_collection_begin(ptr, iterprop, &iter);
-       prop= NULL;
-
-       for(; iter.valid; RNA_property_collection_next(&iter), i++) {
-               if(strcmp(identifier, RNA_property_identifier(iter.ptr.data)) == 0) {
-                       prop= iter.ptr.data;
-                       break;
-               }
-       }
-
-       RNA_property_collection_end(&iter);
+       PropertyRNA *iterprop= RNA_struct_iterator_property(ptr->type);
+       PointerRNA propptr;
 
-       return prop;
+       if(RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
+               return propptr.data;
+       
+       return NULL;
 }
 
 /* Find the property which uses the given nested struct */
@@ -1643,12 +1658,18 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int
                buf= MEM_callocN(sizeof(char)*(len+1), "rna_path_token");
 
        /* copy string, taking into account escaped ] */
-       for(p=*path, i=0, j=0; i<len; i++, p++) {
-               if(*p == '\\' && *(p+1) == ']');
-               else buf[j++]= *p;
-       }
+       if(bracket) {
+               for(p=*path, i=0, j=0; i<len; i++, p++) {
+                       if(*p == '\\' && *(p+1) == ']');
+                       else buf[j++]= *p;
+               }
 
-       buf[j]= 0;
+               buf[j]= 0;
+       }
+       else {
+               memcpy(buf, *path, sizeof(char)*len);
+               buf[len]= '\0';
+       }
 
        /* set path to start of next token */
        if(*p == ']') p++;
@@ -1660,8 +1681,7 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int
 
 int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
 {
-       CollectionPropertyIterator iter;
-       PropertyRNA *prop, *iterprop;
+       PropertyRNA *prop;
        PointerRNA curptr, nextptr;
        char fixedbuf[256], *token;
        int len, intkey;
@@ -1676,18 +1696,7 @@ int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, Prope
                if(!token)
                        return 0;
 
-               iterprop= RNA_struct_iterator_property(curptr.type);
-               RNA_property_collection_begin(&curptr, iterprop, &iter);
-               prop= NULL;
-
-               for(; iter.valid; RNA_property_collection_next(&iter)) {
-                       if(strcmp(token, RNA_property_identifier(iter.ptr.data)) == 0) {
-                               prop= iter.ptr.data;
-                               break;
-                       }
-               }
-
-               RNA_property_collection_end(&iter);
+               prop= RNA_struct_find_property(&curptr, token);
 
                if(token != fixedbuf)
                        MEM_freeN(token);
index d91f538d412f91965def0accb35f4e213b09c8f2..51c1818eed98c0e43c53f79de1b8aed3ee9b5602 100644 (file)
@@ -38,6 +38,8 @@
 #include "RNA_define.h"
 #include "RNA_types.h"
 
+#include "BLI_ghash.h"
+
 #include "rna_internal.h"
 
 /* Global used during defining */
@@ -557,6 +559,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
                /* copy from struct to derive stuff, a bit clumsy since we can't
                 * use MEM_dupallocN, data structs may not be alloced but builtin */
                memcpy(srna, srnafrom, sizeof(StructRNA));
+               srna->cont.prophash= NULL;
                srna->cont.properties.first= srna->cont.properties.last= NULL;
                srna->functions.first= srna->functions.last= NULL;
                srna->py_type= NULL;
@@ -604,7 +607,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
 
                if(DefRNA.preprocess) {
                        RNA_def_property_struct_type(prop, "Property");
-                       RNA_def_property_collection_funcs(prop, "rna_builtin_properties_begin", "rna_builtin_properties_next", "rna_iterator_listbase_end", "rna_builtin_properties_get", 0, 0, 0, 0, 0);
+                       RNA_def_property_collection_funcs(prop, "rna_builtin_properties_begin", "rna_builtin_properties_next", "rna_iterator_listbase_end", "rna_builtin_properties_get", 0, 0, "rna_builtin_properties_lookup_string", 0, 0);
                }
                else {
 #ifdef RNA_RUNTIME
@@ -923,8 +926,13 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
                                break;
                }
        }
-       else
+       else {
                prop->flag |= PROP_IDPROPERTY|PROP_RUNTIME;
+#ifdef RNA_RUNTIME
+               if(cont->prophash)
+                       BLI_ghash_insert(cont->prophash, (void*)prop->identifier, prop);
+#endif
+       }
 
        rna_addtail(&cont->properties, prop);
 
index 61cde5a01a3a18c377eb27036a7c3c57e83ac981..362217e31230cc7b2237f4296d6efd2b2077a6b3 100644 (file)
@@ -217,6 +217,7 @@ void rna_builtin_properties_begin(struct CollectionPropertyIterator *iter, struc
 void rna_builtin_properties_next(struct CollectionPropertyIterator *iter);
 PointerRNA rna_builtin_properties_get(struct CollectionPropertyIterator *iter);
 PointerRNA rna_builtin_type_get(struct PointerRNA *ptr);
+PointerRNA rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key);
 
 /* Iterators */
 
index d93e6f4d7cfbb63a1f49354163b98a1727a9a1bd..8bae21cca2b1f622e7492b1433d86f341499c7e9 100644 (file)
@@ -37,6 +37,7 @@ struct ReportList;
 struct CollectionPropertyIterator;
 struct bContext;
 struct IDProperty;
+struct GHash;
 
 #define RNA_MAX_ARRAY 32
 
@@ -83,6 +84,7 @@ typedef PointerRNA (*PropCollectionLookupStringFunc)(struct PointerRNA *ptr, con
 typedef struct ContainerRNA {
        void *next, *prev;
 
+       struct GHash *prophash;
        ListBase properties;
 } ContainerRNA;
 
index bd3a8ae55807eb32c11d46afa7fc2d51257a5b08..6fa275cec910f5ba70e6c45d749fbe07566f57fe 100644 (file)
@@ -34,6 +34,8 @@
 
 #ifdef RNA_RUNTIME
 
+#include "BLI_ghash.h"
+
 /* Struct */
 
 static void rna_Struct_identifier_get(PointerRNA *ptr, char *value)
@@ -277,6 +279,51 @@ PointerRNA rna_builtin_properties_get(CollectionPropertyIterator *iter)
        return rna_Struct_properties_get(iter);
 }
 
+PointerRNA rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+       IDProperty *group, *idp;
+       PointerRNA propptr;
+
+       memset(&propptr, 0, sizeof(propptr));
+       srna= ptr->type;
+
+       do {
+               if(srna->cont.prophash) {
+                       prop= BLI_ghash_lookup(srna->cont.prophash, (void*)key);
+
+                       if(prop) {
+                               propptr.type= &RNA_Property;
+                               propptr.data= prop;
+                               return propptr;
+                       }
+               }
+
+               for(prop=srna->cont.properties.first; prop; prop=prop->next) {
+                       if(!(prop->flag & PROP_BUILTIN) && strcmp(prop->identifier, key)==0) {
+                               propptr.type= &RNA_Property;
+                               propptr.data= prop;
+                               return propptr;
+                       }
+               }
+       } while((srna=srna->base));
+
+       group= RNA_struct_idproperties(ptr, 0);
+
+       if(group) {
+               for(idp=group->data.group.first; idp; idp=idp->next) {
+                       if(strcmp(idp->name, key) == 0) {
+                               propptr.type= &RNA_Property;
+                               propptr.data= idp;
+                               return propptr;
+                       }
+               }
+       }
+
+       return propptr;
+}
+
 PointerRNA rna_builtin_type_get(PointerRNA *ptr)
 {
        return rna_pointer_inherit_refine(ptr, &RNA_Struct, ptr->type);
index a19e5d0718cee6eb725c57ebffd3b9736263b5b1..9bf09a464617a7f765ba8968040faae602c3659f 100644 (file)
@@ -77,6 +77,8 @@
 
 #include "WM_api.h"
 
+#include "RNA_define.h"
+
 #include "GPU_draw.h"
 #include "GPU_extensions.h"
 
@@ -310,11 +312,13 @@ int main(int argc, char **argv)
 
        BLI_where_am_i(bprogname, argv[0]);
        
+       RNA_init();
+
                /* Hack - force inclusion of the plugin api functions,
                 * see blenpluginapi:pluginapi.c
                 */
        pluginapi_force_ref();
-       
+
        init_nodesystem();
        
        initglobals();  /* blender.c */
index 71961f273397de37811849ebda1ba786d9c64fc0..0d4abf1e1fea885dfb5115ff5d1716f60b0b070c 100644 (file)
@@ -51,6 +51,7 @@ SET(INC
   ../../../../source/blender
   ../../../../source/blender/include
   ../../../../source/blender/makesdna
+  ../../../../source/blender/makesrna
   ../../../../source/gameengine/Rasterizer
   ../../../../source/gameengine/GameLogic
   ../../../../source/gameengine/Expressions
index b69188e54765533b1e490a4e70b53b98a5d58707..2433c58717965813e687635915d0ca3700af0a68 100644 (file)
@@ -86,6 +86,8 @@ extern "C"
 #include "BKE_main.h"
 #include "BKE_utildefines.h"
 
+#include "RNA_define.h"
+
 #ifdef WIN32
 #include <windows.h>
 #ifdef NDEBUG
@@ -344,6 +346,8 @@ int main(int argc, char** argv)
     */
 #endif // __APPLE__
 
+       RNA_init();
+
        init_nodesystem();
        
        initglobals();
index c82edca0d455e21bb2a858a40a61d684250bf7a8..49ad9457ee30e3390710d77beb187996347b6fb3 100644 (file)
@@ -68,6 +68,7 @@ CPPFLAGS += -I../../../blender/blenlib
 CPPFLAGS += -I../../../blender/blenloader
 CPPFLAGS += -I../../../blender/imbuf
 CPPFLAGS += -I../../../blender/makesdna
+CPPFLAGS += -I../../../blender/makesrna
 CPPFLAGS += -I../../../blender/readblenfile
 CPPFLAGS += -I../../../blender/gpu
 
index 1cb7c9f2457eaa795cb1fafda765c320c14fe3dd..390b6f5e089903956698f33d22eb2f39fdd574d1 100644 (file)
@@ -26,6 +26,7 @@ incs = ['.',
         '#source/blender',
         '#source/blender/include',
         '#source/blender/makesdna',
+        '#source/blender/makesrna',
         '#source/gameengine/BlenderRoutines',
         '#source/gameengine/Rasterizer',
         '#source/gameengine/GameLogic',