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önne for helping me get a better fix put together.
This commit is contained in:
@@ -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 @@ static void lib_link_screen(FileData *fd, Main *main)
|
||||
}
|
||||
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 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
|
||||
}
|
||||
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 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user