Revision: 58855
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58855
Author:   lockal
Date:     2013-08-03 11:35:09 +0000 (Sat, 03 Aug 2013)
Log Message:
-----------
fix for [#36260] 2,300 Objects Makes Blender Unresponsive

- performance of outliner was low because of unoptimal data structures.
- now it uses BLI_mempool instead of custom mempool and GHash to make searches 
for duplicates faster.
- also fix undesired behaviour of BLI_mempool_as_arrayN

thanks to Campbell Barton and Lukas T?\195?\182nne for helping me get a better 
fix put together.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/object.c
    trunk/blender/source/blender/blenlib/intern/BLI_mempool.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/blenloader/intern/writefile.c
    trunk/blender/source/blender/editors/space_outliner/outliner_draw.c
    trunk/blender/source/blender/editors/space_outliner/outliner_edit.c
    trunk/blender/source/blender/editors/space_outliner/outliner_intern.h
    trunk/blender/source/blender/editors/space_outliner/outliner_select.c
    trunk/blender/source/blender/editors/space_outliner/outliner_tools.c
    trunk/blender/source/blender/editors/space_outliner/outliner_tree.c
    trunk/blender/source/blender/editors/space_outliner/space_outliner.c
    trunk/blender/source/blender/makesdna/DNA_outliner_types.h
    trunk/blender/source/blender/makesdna/DNA_space_types.h

Modified: trunk/blender/source/blender/blenkernel/intern/object.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/object.c     2013-08-03 
11:10:39 UTC (rev 58854)
+++ trunk/blender/source/blender/blenkernel/intern/object.c     2013-08-03 
11:35:09 UTC (rev 58855)
@@ -678,9 +678,10 @@
                                        SpaceOops *so = (SpaceOops *)sl;
 
                                        if (so->treestore) {
-                                               TreeStoreElem *tselem = 
so->treestore->data;
-                                               int i;
-                                               for (i = 0; i < 
so->treestore->usedelem; i++, tselem++) {
+                                               TreeStoreElem *tselem;
+                                               BLI_mempool_iter iter;
+                                               
BLI_mempool_iternew(so->treestore, &iter);
+                                               while ((tselem = 
BLI_mempool_iterstep(&iter))) {
                                                        if (tselem->id == (ID 
*)ob) tselem->id = NULL;
                                                }
                                        }

Modified: trunk/blender/source/blender/blenlib/intern/BLI_mempool.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/BLI_mempool.c   2013-08-03 
11:10:39 UTC (rev 58854)
+++ trunk/blender/source/blender/blenlib/intern/BLI_mempool.c   2013-08-03 
11:35:09 UTC (rev 58855)
@@ -354,8 +354,18 @@
  */
 void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr)
 {
-       void *data = MEM_mallocN((size_t)(BLI_mempool_count(pool) * 
pool->esize), allocstr);
-       BLI_mempool_as_array(pool, data);
+       char *data = MEM_mallocN((size_t)(pool->totused * pool->esize), 
allocstr);
+       BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
+       if (data) {
+               BLI_mempool_iter iter;
+               char *elem, *p = data;
+               BLI_mempool_iternew(pool, &iter);
+               for (elem = BLI_mempool_iterstep(&iter); elem; elem = 
BLI_mempool_iterstep(&iter)) {
+                       memcpy(p, elem, (size_t)pool->esize);
+                       p += pool->esize;
+               }
+               BLI_assert((p - data) == pool->totused * pool->esize);
+       }
        return data;
 }
 

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c   2013-08-03 
11:10:39 UTC (rev 58854)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c   2013-08-03 
11:35:09 UTC (rev 58855)
@@ -108,6 +108,7 @@
 #include "BLI_math.h"
 #include "BLI_edgehash.h"
 #include "BLI_threads.h"
+#include "BLI_mempool.h"
 
 #include "BLF_translation.h"
 
@@ -5684,16 +5685,24 @@
                                        }
                                        else if (sl->spacetype == 
SPACE_OUTLINER) {
                                                SpaceOops *so= (SpaceOops *)sl;
-                                               TreeStoreElem *tselem;
-                                               int a;
-                                               
                                                so->search_tse.id = 
newlibadr(fd, NULL, so->search_tse.id);
                                                
                                                if (so->treestore) {
-                                                       tselem = 
so->treestore->data;
-                                                       for (a=0; a < 
so->treestore->usedelem; a++, tselem++) {
+                                                       TreeStoreElem *tselem;
+                                                       BLI_mempool_iter iter;
+
+                                                       
BLI_mempool_iternew(so->treestore, &iter);
+                                                       while ((tselem = 
BLI_mempool_iterstep(&iter))) {
                                                                tselem->id = 
newlibadr(fd, NULL, tselem->id);
                                                        }
+                                                       if (so->treehash) {
+                                                               /* update hash 
table, because it depends on ids too */
+                                                               
BLI_ghash_clear(so->treehash, NULL, NULL);
+                                                               
BLI_mempool_iternew(so->treestore, &iter);
+                                                               while ((tselem 
= BLI_mempool_iterstep(&iter))) {
+                                                                       
BLI_ghash_insert(so->treehash, tselem, tselem);
+                                                               }
+                                                       }
                                                }
                                        }
                                        else if (sl->spacetype == SPACE_NODE) {
@@ -6016,16 +6025,25 @@
                                }
                                else if (sl->spacetype == SPACE_OUTLINER) {
                                        SpaceOops *so= (SpaceOops *)sl;
-                                       int a;
                                        
                                        so->search_tse.id = 
restore_pointer_by_name(newmain, so->search_tse.id, 0);
                                        
                                        if (so->treestore) {
-                                               TreeStore *ts = so->treestore;
-                                               TreeStoreElem *tselem = 
ts->data;
-                                               for (a = 0; a < ts->usedelem; 
a++, tselem++) {
+                                               TreeStoreElem *tselem;
+                                               BLI_mempool_iter iter;
+
+                                               
BLI_mempool_iternew(so->treestore, &iter);
+                                               while ((tselem = 
BLI_mempool_iterstep(&iter))) {
                                                        tselem->id = 
restore_pointer_by_name(newmain, tselem->id, 0);
                                                }
+                                               if (so->treehash) {
+                                                       /* update hash table, 
because it depends on ids too */
+                                                       
BLI_ghash_clear(so->treehash, NULL, NULL);
+                                                       
BLI_mempool_iternew(so->treestore, &iter);
+                                                       while ((tselem = 
BLI_mempool_iterstep(&iter))) {
+                                                               
BLI_ghash_insert(so->treehash, tselem, tselem);
+                                                       }
+                                               }
                                        }
                                }
                                else if (sl->spacetype == SPACE_NODE) {
@@ -6283,13 +6301,27 @@
                        else if (sl->spacetype == SPACE_OUTLINER) {
                                SpaceOops *soops = (SpaceOops *) sl;
                                
-                               soops->treestore = newdataadr(fd, 
soops->treestore);
-                               if (soops->treestore) {
-                                       soops->treestore->data = newdataadr(fd, 
soops->treestore->data);
+                               TreeStore *ts = newdataadr(fd, 
soops->treestore);
+                               soops->treestore = NULL;
+                               if (ts) {
+                                       TreeStoreElem *elems = newdataadr(fd, 
ts->data);
+                                       
+                                       soops->treestore = 
BLI_mempool_create(sizeof(TreeStoreElem), ts->usedelem,
+                                                                             
512, BLI_MEMPOOL_ALLOW_ITER);
+                                       if (ts->usedelem && elems) {
+                                               int i;
+                                               for (i = 0; i < ts->usedelem; 
i++) {
+                                                       TreeStoreElem *new_elem 
= BLI_mempool_alloc(soops->treestore);
+                                                       *new_elem = elems[i];
+                                               }
+                                               MEM_freeN(elems);
+                                       }
                                        /* we only saved what was used */
-                                       soops->treestore->totelem = 
soops->treestore->usedelem;
                                        soops->storeflag |= 
SO_TREESTORE_CLEANUP;       // at first draw
+                                       
+                                       MEM_freeN(ts);
                                }
+                               soops->treehash = NULL;
                                soops->tree.first = soops->tree.last= NULL;
                        }
                        else if (sl->spacetype == SPACE_IMAGE) {

Modified: trunk/blender/source/blender/blenloader/intern/writefile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/writefile.c  2013-08-03 
11:10:39 UTC (rev 58854)
+++ trunk/blender/source/blender/blenloader/intern/writefile.c  2013-08-03 
11:35:09 UTC (rev 58855)
@@ -144,12 +144,13 @@
 #include "BLI_bitmap.h"
 #include "BLI_blenlib.h"
 #include "BLI_linklist.h"
-#include "BKE_bpath.h"
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
+#include "BLI_mempool.h"
 
 #include "BKE_action.h"
 #include "BKE_blender.h"
+#include "BKE_bpath.h"
 #include "BKE_curve.h"
 #include "BKE_constraint.h"
 #include "BKE_global.h" // for G
@@ -2393,6 +2394,31 @@
        }
 }
 
+static void write_soops(WriteData *wd, SpaceOops *so)
+{
+       BLI_mempool *ts = so->treestore;
+       
+       if (ts) {
+               int elems = BLI_mempool_count(ts);
+               /* linearize mempool to array */
+               TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, 
"TreeStoreElem") : NULL;
+               TreeStore ts_flat = {elems, elems, data};
+               
+               /* temporarily replace mempool-treestore by flat-treestore */
+               so->treestore = (BLI_mempool *)&ts_flat;
+               writestruct(wd, DATA, "SpaceOops", 1, so);
+               /* restore old treestore */
+               so->treestore = ts;
+               writestruct(wd, DATA, "TreeStore", 1, &ts_flat);
+               if (data) {
+                       writestruct(wd, DATA, "TreeStoreElem", elems, data);
+                       MEM_freeN(data);
+               }
+       } else {
+               writestruct(wd, DATA, "SpaceOops", 1, so);
+       }
+}
+
 static void write_screens(WriteData *wd, ListBase *scrbase)
 {
        bScreen *sc;
@@ -2475,15 +2501,7 @@
                                }
                                else if (sl->spacetype==SPACE_OUTLINER) {
                                        SpaceOops *so= (SpaceOops *)sl;
-                                       
-                                       writestruct(wd, DATA, "SpaceOops", 1, 
so);
-
-                                       /* outliner */
-                                       if (so->treestore) {
-                                               writestruct(wd, DATA, 
"TreeStore", 1, so->treestore);
-                                               if (so->treestore->data)
-                                                       writestruct(wd, DATA, 
"TreeStoreElem", so->treestore->usedelem, so->treestore->data);
-                                       }
+                                       write_soops(wd, so);
                                }
                                else if (sl->spacetype==SPACE_IMAGE) {
                                        SpaceImage *sima= (SpaceImage *)sl;

Modified: trunk/blender/source/blender/editors/space_outliner/outliner_draw.c
===================================================================
--- trunk/blender/source/blender/editors/space_outliner/outliner_draw.c 
2013-08-03 11:10:39 UTC (rev 58854)
+++ trunk/blender/source/blender/editors/space_outliner/outliner_draw.c 
2013-08-03 11:35:09 UTC (rev 58855)
@@ -40,6 +40,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
 #include "BLI_ghash.h"
+#include "BLI_mempool.h"
 
 #include "BLF_translation.h"
 
@@ -407,7 +408,7 @@
        SpaceOops *soops = CTX_wm_space_outliner(C);
        Scene *scene = CTX_data_scene(C);
        Object *obedit = CTX_data_edit_object(C);
-       TreeStore *ts = soops->treestore;
+       BLI_mempool *ts = soops->treestore;
        TreeStoreElem *tselem = tsep;
        
        if (ts && tselem) {

Modified: trunk/blender/source/blender/editors/space_outliner/outliner_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_outliner/outliner_edit.c 
2013-08-03 11:10:39 UTC (rev 58854)
+++ trunk/blender/source/blender/editors/space_outliner/outliner_edit.c 
2013-08-03 11:35:09 UTC (rev 58855)
@@ -984,7 +984,7 @@
  * NOTE: the caller must zero-out all values of the pointers that it passes 
here first, as
  * this function does not do that yet 
  */
-static void tree_element_to_path(SpaceOops *soops, TreeElement *te, 
TreeStoreElem *tselem, 
+static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem,
                                  ID **id, char **path, int *array_index, short 
*flag, short *UNUSED(groupmode))
 {
        ListBase hierarchy = {NULL, NULL};
@@ -1152,7 +1152,7 @@
                            RNA_property_animateable(&te->rnaptr, 
te->directdata))
                        {
                                /* get id + path + index info from the selected 
element */
-                               tree_element_to_path(soops, te, tselem, 
+                               tree_element_to_path(te, tselem,
                                                     &id, &path, &array_index, 
&flag, &groupmode);
                        }
                        
@@ -1333,7 +1333,7 @@
                            RNA_property_animateable(&te->rnaptr, 
te->directdata))
                        {
                                /* get id + path + index info from the selected 
element */
-                               tree_element_to_path(soops, te, tselem, 
+                               tree_element_to_path(te, tselem,
                                                     &id, &path, &array_index, 
&flag, &groupmode);
                        }
                        

Modified: trunk/blender/source/blender/editors/space_outliner/outliner_intern.h
===================================================================
--- trunk/blender/source/blender/editors/space_outliner/outliner_intern.h       
2013-08-03 11:10:39 UTC (rev 58854)
+++ trunk/blender/source/blender/editors/space_outliner/outliner_intern.h       
2013-08-03 11:35:09 UTC (rev 58855)
@@ -48,15 +48,15 @@
 typedef struct TreeElement {
        struct TreeElement *next, *prev, *parent;
        ListBase subtree;
-       int xs, ys;         // do selection
-       int store_index;    // offset in tree store
-       short flag;         // flag for non-saved stuff

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to