Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/guardedalloc/intern/mallocn.c57
-rw-r--r--source/blender/blenkernel/intern/BME_Customdata.c2
-rw-r--r--source/blender/blenkernel/intern/BME_mesh.c8
-rw-r--r--source/blender/blenkernel/intern/customdata.c2
-rw-r--r--source/blender/blenlib/BLI_mempool.h2
-rw-r--r--source/blender/blenlib/intern/BLI_mempool.c63
-rw-r--r--source/blender/editors/screen/area.c11
-rw-r--r--source/blender/editors/space_action/space_action.c14
-rw-r--r--source/blender/makesdna/intern/SConscript2
-rw-r--r--source/blender/makesrna/intern/SConscript4
-rw-r--r--source/blender/windowmanager/WM_types.h2
11 files changed, 142 insertions, 25 deletions
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index d1114af2437..15236a2bee4 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -37,6 +37,8 @@
#include <string.h> /* memcpy */
#include <stdarg.h>
+#include "../../../source/blender/blenlib/BLI_mempool.h"
+
/* mmap exception */
#if defined(WIN32)
#include <sys/types.h>
@@ -138,6 +140,40 @@ static int malloc_debug_memset= 0;
/* implementation */
/* --------------------------------------------------------------------- */
+#ifdef OPTIMIZE_SMALL_BLOCKS
+
+/*allocator for small objects
+
+ basic strategy: most slowdowns from overuse of the system allocator tends
+ to be from relatively small allocations.
+*/
+
+/*this is a little bit bigger then it perhaps needs to be, to accomodate vgroup
+ allocations (which are one system alloc per vertex of a mesh, and is a major
+ source of performance loss)*/
+#define SMALL_BLOCK_LIMIT 1024
+#define POOL_CHUNK_SIZE 512 /*size in number of elements, not bytes*/
+
+static BLI_mempool *alloc_pools[SMALL_BLOCK_LIMIT+sizeof(MemHead)+sizeof(MemTail)] = {NULL,};
+
+static void *mempool_alloc_mem(int size) {
+ size += sizeof(MemHead)+sizeof(MemTail);
+
+ if (!alloc_pools[size]) {
+ alloc_pools[size] = BLI_mempool_create(size, 1, POOL_CHUNK_SIZE, 1);
+ }
+
+ return BLI_mempool_alloc(alloc_pools[size]);
+}
+
+static void mempool_free(void *mem, int size) {
+ size += sizeof(MemHead)+sizeof(MemTail);
+
+ BLI_mempool_free(alloc_pools[size], mem);
+}
+
+#endif
+
static void print_error(const char *str, ...)
{
char buf[1024];
@@ -254,7 +290,14 @@ void *MEM_mallocN(unsigned int len, const char *str)
len = (len + 3 ) & ~3; /* allocate in units of 4 */
+#ifdef OPTIMIZE_SMALL_BLOCKS
+ if (len < SMALL_BLOCK_LIMIT)
+ memh= mempool_alloc_mem(len);
+ else
+ memh= (MemHead *)malloc(len+sizeof(MemHead)+sizeof(MemTail));
+#else
memh= (MemHead *)malloc(len+sizeof(MemHead)+sizeof(MemTail));
+#endif
if(memh) {
make_memhead_header(memh, len, str);
@@ -276,7 +319,16 @@ void *MEM_callocN(unsigned int len, const char *str)
len = (len + 3 ) & ~3; /* allocate in units of 4 */
+#ifdef OPTIMIZE_SMALL_BLOCKS
+ if (len < SMALL_BLOCK_LIMIT) {
+ memh= mempool_alloc_mem(len);
+ memset(memh, 0, len+sizeof(MemHead)+sizeof(MemTail));
+ } else {
+ memh= (MemHead *)calloc(len+sizeof(MemHead)+sizeof(MemTail),1);
+ }
+#else
memh= (MemHead *)calloc(len+sizeof(MemHead)+sizeof(MemTail),1);
+#endif
if(memh) {
make_memhead_header(memh, len, str);
@@ -629,6 +681,11 @@ static void rem_memblock(MemHead *memh)
if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
printf("Couldn't unmap memory %s\n", memh->name);
}
+#ifdef OPTIMIZE_SMALL_BLOCKS
+ else if (memh->len < SMALL_BLOCK_LIMIT) {
+ mempool_free(memh, memh->len);
+ }
+#endif
else {
if(malloc_debug_memset && memh->len)
memset(memh+1, 255, memh->len);
diff --git a/source/blender/blenkernel/intern/BME_Customdata.c b/source/blender/blenkernel/intern/BME_Customdata.c
index ea149e03959..822a0d8a080 100644
--- a/source/blender/blenkernel/intern/BME_Customdata.c
+++ b/source/blender/blenkernel/intern/BME_Customdata.c
@@ -84,7 +84,7 @@ void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc
if(data->totlayer){
/*alloc memory*/
data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers");
- data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc);
+ data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc, 0);
/*initialize layer data*/
for(i=0; i < BME_CD_NUMTYPES; i++){
if(init->layout[i]){
diff --git a/source/blender/blenkernel/intern/BME_mesh.c b/source/blender/blenkernel/intern/BME_mesh.c
index f635cfcfcd2..3b769a11ccb 100644
--- a/source/blender/blenkernel/intern/BME_mesh.c
+++ b/source/blender/blenkernel/intern/BME_mesh.c
@@ -55,10 +55,10 @@ BME_Mesh *BME_make_mesh(int allocsize[4])
/*allocate the structure*/
BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh");
/*allocate the memory pools for the mesh elements*/
- bm->vpool = BLI_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0]);
- bm->epool = BLI_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1]);
- bm->lpool = BLI_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2]);
- bm->ppool = BLI_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3]);
+ bm->vpool = BLI_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0], 0);
+ bm->epool = BLI_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1], 0);
+ bm->lpool = BLI_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2], 0);
+ bm->ppool = BLI_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3], 0);
return bm;
}
/*
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index fb31ed3d610..3a8068ead56 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1922,7 +1922,7 @@ void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData
void CustomData_bmesh_init_pool(CustomData *data, int allocsize){
- if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize);
+ if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, 0);
}
void CustomData_bmesh_free_block(CustomData *data, void **block)
diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h
index 8b31459dd38..a2fd80de417 100644
--- a/source/blender/blenlib/BLI_mempool.h
+++ b/source/blender/blenlib/BLI_mempool.h
@@ -34,7 +34,7 @@
struct BLI_mempool;
typedef struct BLI_mempool BLI_mempool;
-BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk);
+BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk, int use_sysmalloc);
void *BLI_mempool_alloc(BLI_mempool *pool);
void *BLI_mempool_calloc(BLI_mempool *pool);
void BLI_mempool_free(BLI_mempool *pool, void *addr);
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c
index 485ba7cbd08..373b4d5add9 100644
--- a/source/blender/blenlib/intern/BLI_mempool.c
+++ b/source/blender/blenlib/intern/BLI_mempool.c
@@ -49,9 +49,11 @@ typedef struct BLI_mempool{
struct ListBase chunks;
int esize, csize, pchunk; /*size of elements and chunks in bytes and number of elements per chunk*/
struct BLI_freenode *free; /*free element list. Interleaved into chunk datas.*/
+ int totalloc, totused; /*total number of elements allocated in total, and currently in use*/
+ int use_sysmalloc;
}BLI_mempool;
-BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk)
+BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk, int use_sysmalloc)
{ BLI_mempool *pool = NULL;
BLI_freenode *lasttail = NULL, *curnode = NULL;
int i,j, maxchunks;
@@ -61,19 +63,20 @@ BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk)
esize = sizeof(void*);
/*allocate the pool structure*/
- pool = MEM_mallocN(sizeof(BLI_mempool),"memory pool");
+ pool = use_sysmalloc ? malloc(sizeof(BLI_mempool)) : MEM_mallocN(sizeof(BLI_mempool), "memory pool");
pool->esize = esize;
+ pool->use_sysmalloc = use_sysmalloc;
pool->pchunk = pchunk;
pool->csize = esize * pchunk;
pool->chunks.first = pool->chunks.last = NULL;
- maxchunks = tote / pchunk;
+ maxchunks = tote / pchunk + 1;
/*allocate the actual chunks*/
for(i=0; i < maxchunks; i++){
- BLI_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BLI_mempool_chunk), "BLI_Mempool Chunk");
+ BLI_mempool_chunk *mpchunk = use_sysmalloc ? malloc(sizeof(BLI_mempool_chunk)) : MEM_mallocN(sizeof(BLI_mempool_chunk), "BLI_Mempool Chunk");
mpchunk->next = mpchunk->prev = NULL;
- mpchunk->data = MEM_mallocN(pool->csize, "BLI Mempool Chunk Data");
+ mpchunk->data = use_sysmalloc ? malloc(pool->csize) : MEM_mallocN(pool->csize, "BLI Mempool Chunk Data");
BLI_addtail(&(pool->chunks), mpchunk);
if(i==0) pool->free = mpchunk->data; /*start of the list*/
@@ -87,6 +90,8 @@ BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk)
if(lasttail) lasttail->next = mpchunk->data;
/*set the end of this chunks memoryy to the new tail for next iteration*/
lasttail = curnode;
+
+ pool->totalloc += pool->pchunk;
}
/*terminate the list*/
curnode->next = NULL;
@@ -98,11 +103,13 @@ void *BLI_mempool_alloc(BLI_mempool *pool){
char *addr=NULL;
int j;
+ pool->totused++;
+
if(!(pool->free)){
/*need to allocate a new chunk*/
- BLI_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BLI_mempool_chunk), "BLI_Mempool Chunk");
+ BLI_mempool_chunk *mpchunk = pool->use_sysmalloc ? malloc(sizeof(BLI_mempool_chunk)) : MEM_mallocN(sizeof(BLI_mempool_chunk), "BLI_Mempool Chunk");
mpchunk->next = mpchunk->prev = NULL;
- mpchunk->data = MEM_mallocN(pool->csize, "BLI_Mempool Chunk Data");
+ mpchunk->data = pool->use_sysmalloc ? malloc(pool->csize) : MEM_mallocN(pool->csize, "BLI_Mempool Chunk Data");
BLI_addtail(&(pool->chunks), mpchunk);
pool->free = mpchunk->data; /*start of the list*/
@@ -112,6 +119,8 @@ void *BLI_mempool_alloc(BLI_mempool *pool){
curnode->next = (BLI_freenode*)addr;
}
curnode->next = NULL; /*terminate the list*/
+
+ pool->totalloc += pool->pchunk;
}
retval = pool->free;
@@ -128,16 +137,48 @@ void *BLI_mempool_calloc(BLI_mempool *pool){
}
-
void BLI_mempool_free(BLI_mempool *pool, void *addr){ //doesnt protect against double frees, dont be stupid!
BLI_freenode *newhead = addr;
+ BLI_freenode *curnode=NULL;
+ char *tmpaddr=NULL;
+ int i;
+
newhead->next = pool->free;
pool->free = newhead;
+
+ pool->totused--;
+
+ /*nothing is in use; free all the chunks except the first*/
+ if (pool->totused == 0) {
+ BLI_mempool_chunk *mpchunk=NULL, *first;
+
+ first = pool->chunks.first;
+ BLI_remlink(&pool->chunks, first);
+
+ for(mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk->next)
+ pool->use_sysmalloc ? free(mpchunk->data) : MEM_freeN(mpchunk->data);
+
+ pool->use_sysmalloc ? BLI_freelist(&(pool->chunks)) : BLI_freelistN(&(pool->chunks));
+
+ BLI_addtail(&pool->chunks, first);
+ pool->totalloc = pool->pchunk;
+
+ pool->free = first->data; /*start of the list*/
+ for(tmpaddr = first->data, i=0; i < pool->pchunk; i++){
+ curnode = ((BLI_freenode*)tmpaddr);
+ tmpaddr += pool->esize;
+ curnode->next = (BLI_freenode*)tmpaddr;
+ }
+ curnode->next = NULL; /*terminate the list*/
+ }
}
+
void BLI_mempool_destroy(BLI_mempool *pool)
{
BLI_mempool_chunk *mpchunk=NULL;
- for(mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk->next) MEM_freeN(mpchunk->data);
- BLI_freelistN(&(pool->chunks));
- MEM_freeN(pool);
+ for(mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk->next)
+ pool->use_sysmalloc ? free(mpchunk->data) : MEM_freeN(mpchunk->data);
+
+ pool->use_sysmalloc ? BLI_freelist(&(pool->chunks)) : BLI_freelistN(&(pool->chunks));
+ pool->use_sysmalloc ? free(pool) : MEM_freeN(pool);
}
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 2ee786a0fb8..7fb4dd57672 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1085,7 +1085,10 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type)
/* tell WM to refresh, cursor types etc */
WM_event_add_mousemove(C);
-
+
+ /*send space change notifyer*/
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CHANGED, sa);
+
ED_area_tag_redraw(sa);
ED_area_tag_refresh(sa);
}
@@ -1107,6 +1110,9 @@ void ED_area_prevspace(bContext *C, ScrArea *sa)
ED_area_newspace(C, sa, SPACE_INFO);
}
ED_area_tag_redraw(sa);
+
+ /*send space change notifyer*/
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CHANGED, sa);
}
static char *editortype_pup(void)
@@ -1152,6 +1158,9 @@ static void spacefunc(struct bContext *C, void *arg1, void *arg2)
{
ED_area_newspace(C, CTX_wm_area(C), CTX_wm_area(C)->butspacetype);
ED_area_tag_redraw(CTX_wm_area(C));
+
+ /*send space change notifyer*/
+ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CHANGED, CTX_wm_area(C));
}
/* returns offset for next button in header */
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 66e6e770ca4..05801d5efbe 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -137,7 +137,8 @@ static void action_free(SpaceLink *sl)
/* spacetype; init callback */
static void action_init(struct wmWindowManager *wm, ScrArea *sa)
{
-
+ SpaceAction *saction = sa->spacedata.first;
+ saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
}
static SpaceLink *action_duplicate(SpaceLink *sl)
@@ -392,8 +393,15 @@ static void action_listener(ScrArea *sa, wmNotifier *wmn)
}
break;
case NC_SPACE:
- if(wmn->data == ND_SPACE_DOPESHEET)
- ED_area_tag_redraw(sa);
+ switch (wmn->data) {
+ case ND_SPACE_DOPESHEET:
+ ED_area_tag_redraw(sa);
+ break;
+ case ND_SPACE_CHANGED:
+ saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
+ ED_area_tag_refresh(sa);
+ break;
+ }
break;
}
}
diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript
index 120398791a8..8a0e738080c 100644
--- a/source/blender/makesdna/intern/SConscript
+++ b/source/blender/makesdna/intern/SConscript
@@ -50,7 +50,7 @@ targetdir = normpath(root_build_dir + '/makesdna')
if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
targetdir = '#' + targetdir
-makesdna = makesdna_tool.Program (target = targetdir, source = source_files, LIBS=['bf_guardedalloc'])
+makesdna = makesdna_tool.Program (target = targetdir, source = source_files, LIBS=['bf_guardedalloc', 'bf_blenlib'])
dna_dict = dna.Dictionary()
dna.Depends ('dna.c', makesdna)
diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript
index e5a08c9aeea..9491c4cf30e 100644
--- a/source/blender/makesrna/intern/SConscript
+++ b/source/blender/makesrna/intern/SConscript
@@ -126,9 +126,9 @@ if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
targetpath = '#' + targetpath
if env['OURPLATFORM'] == 'linux2' and root_build_dir[0]==os.sep:
- makesrna = makesrna_tool.Program (target = targetpath, source = source_files, LIBS=['bf_guardedalloc', 'bf_dna'])
+ makesrna = makesrna_tool.Program (target = targetpath, source = source_files, LIBS=['bf_guardedalloc', 'bf_dna', 'bf_blenlib'])
else:
- makesrna = makesrna_tool.Program (target = targetpath, source = source_files, LIBS=['bf_guardedalloc', 'bf_dna'])
+ makesrna = makesrna_tool.Program (target = targetpath, source = source_files, LIBS=['bf_guardedalloc', 'bf_dna', 'bf_blenlib'])
rna_dict = rna.Dictionary()
rna.Depends (generated_files, makesrna)
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index eb8139ad62e..4caa4b973f1 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -157,6 +157,7 @@ typedef struct wmNotifier {
#define ND_SCREENCAST (3<<16)
#define ND_ANIMPLAY (4<<16)
#define ND_GPENCIL (5<<16)
+#define ND_EDITOR_CHANGED (6<<16) /*sent to new editors after switching to them*/
/* NC_SCENE Scene */
#define ND_SCENEBROWSE (1<<16)
@@ -241,6 +242,7 @@ typedef struct wmNotifier {
#define ND_SPACE_NLA (14<<16)
#define ND_SPACE_SEQUENCER (15<<16)
#define ND_SPACE_NODE_VIEW (16<<16)
+#define ND_SPACE_CHANGED (17<<16) /*sent to a new editor type after it's replaced an old one*/
/* subtype, 256 entries too */
#define NOTE_SUBTYPE 0x0000FF00