From aa0aac706e4381624482978110a54b5959414d14 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 19 Jun 2009 23:05:21 +0000 Subject: 2.5 * 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. --- source/blender/blenkernel/BKE_depsgraph.h | 1 + source/blender/blenkernel/depsgraph_private.h | 2 + source/blender/blenkernel/intern/depsgraph.c | 41 ++++++----- source/blender/makesrna/RNA_define.h | 2 + source/blender/makesrna/intern/makesrna.c | 8 ++- source/blender/makesrna/intern/rna_access.c | 83 ++++++++++++---------- source/blender/makesrna/intern/rna_define.c | 12 +++- source/blender/makesrna/intern/rna_internal.h | 1 + .../blender/makesrna/intern/rna_internal_types.h | 2 + source/blender/makesrna/intern/rna_rna.c | 47 ++++++++++++ source/creator/creator.c | 6 +- source/gameengine/GamePlayer/ghost/CMakeLists.txt | 1 + source/gameengine/GamePlayer/ghost/GPG_ghost.cpp | 4 ++ source/gameengine/GamePlayer/ghost/Makefile | 1 + source/gameengine/GamePlayer/ghost/SConscript | 1 + 15 files changed, 154 insertions(+), 58 deletions(-) diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index b86a58780dc..70b6c1d13f4 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -36,6 +36,7 @@ struct Scene; struct DagNodeQueue; struct DagForest; struct DagNode; +struct GHash; /* **** DAG relation types *** */ diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h index 78717393baf..47e33c0e81e 100644 --- a/source/blender/blenkernel/depsgraph_private.h +++ b/source/blender/blenkernel/depsgraph_private.h @@ -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 diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index dfe3b7ea279..8bb34bde122 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -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); diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index dfe072c4b8e..b620a315085 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -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 */ diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index c8273513711..75293d83346 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -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, "); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 8d0d87a72d3..ba893319ce9 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -32,6 +32,7 @@ #include "BLI_blenlib.h" #include "BLI_dynstr.h" +#include "BLI_ghash.h" #include "BKE_context.h" #include "BKE_idprop.h" @@ -46,10 +47,35 @@ #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; icont.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); diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 61cde5a01a3..362217e3123 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -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 */ diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index d93e6f4d7cf..8bae21cca2b 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -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; diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index bd3a8ae5580..6fa275cec91 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -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); diff --git a/source/creator/creator.c b/source/creator/creator.c index a19e5d0718c..9bf09a46461 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -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 */ diff --git a/source/gameengine/GamePlayer/ghost/CMakeLists.txt b/source/gameengine/GamePlayer/ghost/CMakeLists.txt index 71961f27339..0d4abf1e1fe 100644 --- a/source/gameengine/GamePlayer/ghost/CMakeLists.txt +++ b/source/gameengine/GamePlayer/ghost/CMakeLists.txt @@ -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 diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index b69188e5476..2433c587179 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -86,6 +86,8 @@ extern "C" #include "BKE_main.h" #include "BKE_utildefines.h" +#include "RNA_define.h" + #ifdef WIN32 #include #ifdef NDEBUG @@ -344,6 +346,8 @@ int main(int argc, char** argv) */ #endif // __APPLE__ + RNA_init(); + init_nodesystem(); initglobals(); diff --git a/source/gameengine/GamePlayer/ghost/Makefile b/source/gameengine/GamePlayer/ghost/Makefile index c82edca0d45..49ad9457ee3 100644 --- a/source/gameengine/GamePlayer/ghost/Makefile +++ b/source/gameengine/GamePlayer/ghost/Makefile @@ -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 diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript index 1cb7c9f2457..390b6f5e089 100644 --- a/source/gameengine/GamePlayer/ghost/SConscript +++ b/source/gameengine/GamePlayer/ghost/SConscript @@ -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', -- cgit v1.2.3