[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58855] trunk/blender/source/blender: fix for [#36260] 2, 300 Objects Makes Blender Unresponsive

Sv. Lockal lockalsash at gmail.com
Sat Aug 3 13:35:10 CEST 2013


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. @@



More information about the Bf-blender-cvs mailing list