diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2008-05-07 23:25:43 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2008-05-07 23:25:43 +0400 |
commit | 1584d6a0069758d8b594b0e2c412677ab5a8f22f (patch) | |
tree | 4a44375539b720d3d7313149f472d7e24ccd64fe /source | |
parent | 5da47ddd02352a0860be5899c3d03734e44d0151 (diff) |
Possible fix for #9691: blender failing to allocate memory when rendering
particles on windows, now allocates smaller chunks of memory.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 85 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_particle_types.h | 22 |
3 files changed, 66 insertions, 43 deletions
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 2aa0d0ad0b8..fec3da752ff 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -152,6 +152,49 @@ char *psys_menu_string(Object *ob, int for_sb) return str; } + +/* we allocate path cache memory in chunks instead of a big continguous + * chunk, windows' memory allocater fails to find big blocks of memory often */ + +#define PATH_CACHE_BUF_SIZE 1024 + +static ParticleCacheKey **psys_alloc_path_cache_buffers(ListBase *bufs, int tot, int steps) +{ + LinkData *buf; + ParticleCacheKey **cache; + int i, totkey, totbufkey; + + tot= MAX2(tot, 1); + totkey = 0; + cache = MEM_callocN(tot*sizeof(void*), "PathCacheArray"); + + while(totkey < tot) { + totbufkey= MIN2(tot-totkey, PATH_CACHE_BUF_SIZE); + buf= MEM_callocN(sizeof(LinkData), "PathCacheLinkData"); + buf->data= MEM_callocN(sizeof(ParticleCacheKey)*totbufkey*steps, "ParticleCacheKey"); + + for(i=0; i<totbufkey; i++) + cache[totkey+i] = ((ParticleCacheKey*)buf->data) + i*steps; + + totkey += totbufkey; + BLI_addtail(bufs, buf); + } + + return cache; +} + +static void psys_free_path_cache_buffers(ParticleCacheKey **cache, ListBase *bufs) +{ + LinkData *buf; + + if(cache) + MEM_freeN(cache); + + for(buf= bufs->first; buf; buf=buf->next) + MEM_freeN(buf->data); + BLI_freelistN(bufs); +} + /************************************************/ /* Getting stuff */ /************************************************/ @@ -306,27 +349,16 @@ void free_keyed_keys(ParticleSystem *psys) } void free_child_path_cache(ParticleSystem *psys) { - if(psys->childcache){ - if(psys->childcache[0]) - MEM_freeN(psys->childcache[0]); - - MEM_freeN(psys->childcache); - - psys->childcache = NULL; - psys->totchildcache = 0; - } + psys_free_path_cache_buffers(psys->childcache, &psys->childcachebufs); + psys->childcache = NULL; + psys->totchildcache = 0; } void psys_free_path_cache(ParticleSystem *psys) { - if(psys->pathcache){ - if(psys->pathcache[0]) - MEM_freeN(psys->pathcache[0]); - - MEM_freeN(psys->pathcache); + psys_free_path_cache_buffers(psys->pathcache, &psys->pathcachebufs); + psys->pathcache= NULL; + psys->totcached= 0; - psys->pathcache = NULL; - psys->totcached = 0; - } free_child_path_cache(psys); } void psys_free_children(ParticleSystem *psys) @@ -2257,10 +2289,9 @@ void psys_cache_child_paths(Object *ob, ParticleSystem *psys, float cfra, int ed ParticleSettings *part = psys->part; ParticleThread *pthreads; ParticleThreadContext *ctx; - ParticleCacheKey **cache, *tcache; + ParticleCacheKey **cache; ListBase threads; int i, totchild, totparent, totthread; - unsigned long totchildstep; pthreads= psys_threads_create(ob, psys); @@ -2279,13 +2310,7 @@ void psys_cache_child_paths(Object *ob, ParticleSystem *psys, float cfra, int ed else { /* clear out old and create new empty path cache */ free_child_path_cache(psys); - - cache = psys->childcache = MEM_callocN(totchild*sizeof(void *), "Child path cache array"); - totchildstep= totchild*(ctx->steps + 1); - tcache = MEM_callocN(totchildstep*sizeof(ParticleCacheKey), "Child path cache"); - for(i=0; i<totchild; i++) - cache[i] = tcache + i * (ctx->steps + 1); - + psys->childcache= psys_alloc_path_cache_buffers(&psys->childcachebufs, totchild, ctx->steps+1); psys->totchildcache = totchild; } @@ -2372,12 +2397,8 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda else { /* clear out old and create new empty path cache */ psys_free_path_cache(psys); - - /* allocate cache array for fast access and set pointers to contiguous mem block */ - cache = psys->pathcache = MEM_callocN(MAX2(1, totpart) * sizeof(void *), "Path cache array"); - cache[0] = MEM_callocN(totpart * (steps + 1) * sizeof(ParticleCacheKey), "Path cache"); - for(i=1; i<totpart; i++) - cache[i] = cache[0] + i * (steps + 1); + cache= psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, steps+1); + psys->pathcache= cache; } if(edit==NULL && psys->soft && psys->softflag & OB_SB_ENABLE) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 24606bd822f..8d315ba37e1 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2615,6 +2615,8 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) psys->edit = 0; psys->pathcache = 0; psys->childcache = 0; + psys->pathcachebufs.first = psys->pathcachebufs.last = 0; + psys->childcachebufs.first = psys->childcachebufs.last = 0; psys->reactevents.first = psys->reactevents.last = 0; psys->pointcache= newdataadr(fd, psys->pointcache); diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 8122cdd9cc7..e5f781a3365 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -171,24 +171,24 @@ typedef struct ParticleSettings { typedef struct ParticleSystem{ struct ParticleSystem *next, *prev; - ParticleSettings *part; + ParticleSettings *part; /* particle settings */ - ParticleData *particles; + ParticleData *particles; /* (parent) particles */ + ChildParticle *child; /* child particles */ - ChildParticle *child; + struct ParticleEdit *edit; /* particle editmode (runtime) */ - struct ParticleEdit *edit; + struct ParticleCacheKey **pathcache; /* path cache (runtime) */ + struct ParticleCacheKey **childcache; /* child cache (runtime) */ + ListBase pathcachebufs, childcachebufs; /* buffers for the above */ - struct ParticleCacheKey **pathcache; - struct ParticleCacheKey **childcache; - - struct SoftBody *soft; + struct SoftBody *soft; /* hair softbody */ struct Object *target_ob; struct Object *keyed_ob; struct Object *lattice; - struct ListBase effectors, reactevents; + struct ListBase effectors, reactevents; /* runtime */ float imat[4][4]; /* used for duplicators */ float cfra; @@ -196,10 +196,10 @@ typedef struct ParticleSystem{ int flag, totpart, totchild, totcached, totchildcache, rt; short recalc, target_psys, keyed_psys, totkeyed, softflag, bakespace; - char bb_uvname[3][32]; + char bb_uvname[3][32]; /* billboard uv name */ /* if you change these remember to update array lengths to PSYS_TOT_VG! */ - short vgroup[11], vg_neg, rt3[2]; + short vgroup[11], vg_neg, rt3[2]; /* vertex groups */ /* temporary storage during render */ void *renderdata; |