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:
authorJanne Karhu <jhkarh@gmail.com>2010-09-27 13:58:37 +0400
committerJanne Karhu <jhkarh@gmail.com>2010-09-27 13:58:37 +0400
commitafa4b855caa874d32d0cd0e02524846da58628c1 (patch)
treee9f7da1bb430aa309ddf32672802d559e1c3e578 /source/blender
parent03c65a0c01cd463f87bc9ccafebb3e10a7db5527 (diff)
Fixed: Showing pointcached frames in the timeline was terribly slow when using disk cache.
* The existence of cached frames was checked each frame causing hundreds of disk operations per frame update. * Pointcache now keeps an updated array of the cached frames for fast "frame exists in cache" queries. * This fix also speeds up some other pointcache operations nicely.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/pointcache.c92
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/editors/space_time/space_time.c15
-rw-r--r--source/blender/makesdna/DNA_object_force.h2
4 files changed, 106 insertions, 4 deletions
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 741580048cf..f503858a70f 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1876,6 +1876,9 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
else
cache->flag |= PTCACHE_FRAMES_SKIPPED;
}
+
+ if(cache->cached_frames)
+ cache->cached_frames[cfra] = 1;
if(pf) ptcache_file_close(pf);
@@ -1893,6 +1896,9 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
{
int len; /* store the length of the string */
+ int i;
+ int sta = pid->cache->startframe;
+ int end = pid->cache->endframe;
/* mode is same as fopen's modes */
DIR *dir;
@@ -1936,6 +1942,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
BLI_join_dirfile(path_full, path, de->d_name);
BLI_delete(path_full, 0, 0);
+ if(pid->cache->cached_frames) for(i=0; i<end-sta+1; i++)
+ pid->cache->cached_frames[i] = 0;
} else {
/* read the number of the file */
int frame, len2 = (int)strlen(de->d_name);
@@ -1950,6 +1958,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
BLI_join_dirfile(path_full, path, de->d_name);
BLI_delete(path_full, 0, 0);
+ if(frame >=sta && frame <= end)
+ pid->cache->cached_frames[frame-sta] = 0;
}
}
}
@@ -1970,11 +1980,16 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
for(; pm; pm=pm->next)
ptcache_free_data(pm);
BLI_freelistN(&pid->cache->mem_cache);
+
+ if(pid->cache->cached_frames) for(i=0; i<end-sta+1; i++)
+ pid->cache->cached_frames[i] = 0;
} else {
while(pm) {
if((mode==PTCACHE_CLEAR_BEFORE && pm->frame < cfra) ||
(mode==PTCACHE_CLEAR_AFTER && pm->frame > cfra) ) {
link = pm;
+ if(pm->frame >=sta && pm->frame <= end)
+ pid->cache->cached_frames[pm->frame-sta] = 0;
ptcache_free_data(pm);
pm = pm->next;
BLI_freelinkN(&pid->cache->mem_cache, link);
@@ -2004,6 +2019,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
}
}
}
+ if(pid->cache->cached_frames && cfra>=sta && cfra<=end)
+ pid->cache->cached_frames[cfra-sta] = 0;
break;
}
@@ -2014,6 +2031,12 @@ int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
{
if(!pid->cache)
return 0;
+
+ if(cfra<pid->cache->startframe || cfra > pid->cache->endframe)
+ return 0;
+
+ if(pid->cache->cached_frames && pid->cache->cached_frames[cfra-pid->cache->startframe]==0)
+ return 0;
if(pid->cache->flag & PTCACHE_DISK_CACHE) {
char filename[MAX_PTCACHE_FILE];
@@ -2073,6 +2096,73 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
*endframe += (int)(offset+0.5f);
}
}
+
+ /* verify cached_frames array is up to date */
+ if(cache->cached_frames) {
+ if(MEM_allocN_len(cache->cached_frames) != sizeof(char) * (cache->endframe-cache->startframe+1)) {
+ MEM_freeN(cache->cached_frames);
+ cache->cached_frames = NULL;
+ }
+ }
+
+ if(cache->cached_frames==NULL) {
+ int sta=cache->startframe;
+ int end=cache->endframe;
+ int i=0;
+
+ cache->cached_frames = MEM_callocN(sizeof(char) * (cache->endframe-cache->startframe+1), "cached frames array");
+
+ if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+ /* mode is same as fopen's modes */
+ DIR *dir;
+ struct dirent *de;
+ char path[MAX_PTCACHE_PATH];
+ char filename[MAX_PTCACHE_FILE];
+ char ext[MAX_PTCACHE_PATH];
+ int len; /* store the length of the string */
+
+ ptcache_path(pid, path);
+
+ len = BKE_ptcache_id_filename(pid, filename, (int)cfra, 0, 0); /* no path */
+
+ dir = opendir(path);
+ if (dir==NULL)
+ return;
+
+ snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, pid->stack_index);
+
+ while ((de = readdir(dir)) != NULL) {
+ if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
+ if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
+ /* read the number of the file */
+ int frame, len2 = (int)strlen(de->d_name);
+ char num[7];
+
+ if (len2 > 15) { /* could crash if trying to copy a string out of this range*/
+ BLI_strncpy(num, de->d_name + (strlen(de->d_name) - 15), sizeof(num));
+ frame = atoi(num);
+
+ if(frame >= sta && frame <= end)
+ cache->cached_frames[frame-sta] = 1;
+ }
+ }
+ }
+ }
+ closedir(dir);
+ }
+ else {
+ PTCacheMem *pm= pid->cache->mem_cache.first;
+ PTCacheMem *link= NULL;
+
+ pm= pid->cache->mem_cache.first;
+
+ while(pm) {
+ if(pm->frame >= sta && pm->frame <= end)
+ cache->cached_frames[pm->frame-sta] = 1;
+ pm = pm->next;
+ }
+ }
+ }
}
int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
@@ -2293,6 +2383,8 @@ void BKE_ptcache_free(PointCache *cache)
BKE_ptcache_free_mem(&cache->mem_cache);
if(cache->edit && cache->free_edit)
cache->free_edit(cache->edit);
+ if(cache->cached_frames)
+ MEM_freeN(cache->cached_frames);
MEM_freeN(cache);
}
void BKE_ptcache_free_list(ListBase *ptcaches)
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index fc700c8db8b..bccbc451427 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2937,6 +2937,7 @@ static void direct_link_pointcache(FileData *fd, PointCache *cache)
cache->simframe= 0;
cache->edit= NULL;
cache->free_edit= NULL;
+ cache->cached_frames= NULL;
}
static void direct_link_pointcache_list(FileData *fd, ListBase *ptcaches, PointCache **ocache)
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index de9c063f069..bbdd6891199 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -181,6 +181,7 @@ static void time_cache_refresh(const bContext *C, SpaceTime *stime, ARegion *ar)
SpaceTimeCache *stc;
float *fp, *array;
int i, len;
+ int sta, end;
switch(pid->type) {
case PTCACHE_TYPE_SOFTBODY:
@@ -197,6 +198,11 @@ static void time_cache_refresh(const bContext *C, SpaceTime *stime, ARegion *ar)
if (!(stime->cache_display & TIME_CACHE_SMOKE)) continue;
break;
}
+
+ BKE_ptcache_id_time(pid, CTX_data_scene(C), 0, &sta, &end, NULL);
+
+ if(pid->cache->cached_frames==NULL)
+ continue;
stc= MEM_callocN(sizeof(SpaceTimeCache), "spacetimecache");
@@ -208,14 +214,15 @@ static void time_cache_refresh(const bContext *C, SpaceTime *stime, ARegion *ar)
stc->flag |= PTCACHE_DISK_CACHE;
/* first allocate with maximum number of frames needed */
- BKE_ptcache_id_time(pid, CTX_data_scene(C), 0, &stc->startframe, &stc->endframe, NULL);
- len = (stc->endframe - stc->startframe + 1)*4;
+ stc->startframe = sta;
+ stc->endframe = end;
+ len = (end - sta + 1)*4;
fp = array = MEM_callocN(len*2*sizeof(float), "temporary timeline cache array");
/* fill the vertex array with a quad for each cached frame */
- for (i=stc->startframe; i<=stc->endframe; i++) {
+ for (i=sta; i<=end; i++) {
- if (BKE_ptcache_id_exist(pid, i)) {
+ if (pid->cache->cached_frames[i-sta]) {
fp[0] = (float)i;
fp[1] = 0.0;
fp+=2;
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h
index 63a6b8fbe4a..d07db66cb0f 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force.h
@@ -167,6 +167,8 @@ typedef struct PointCache {
char prev_name[64];
char info[64];
char path[240]; /* file path */
+ char *cached_frames; /* array of length endframe-startframe+1 with flags to indicate cached frames */
+ /* can be later used for other per frame flags too if needed */
struct ListBase mem_cache;
struct PTCacheEdit *edit;