[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [32147] trunk/blender/source/blender: Fixed: Showing pointcached frames in the timeline was terribly slow when using disk cache .
Janne Karhu
jhkarh at gmail.com
Mon Sep 27 11:58:37 CEST 2010
Revision: 32147
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=32147
Author: jhk
Date: 2010-09-27 11:58:37 +0200 (Mon, 27 Sep 2010)
Log Message:
-----------
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.
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/intern/pointcache.c
trunk/blender/source/blender/blenloader/intern/readfile.c
trunk/blender/source/blender/editors/space_time/space_time.c
trunk/blender/source/blender/makesdna/DNA_object_force.h
Modified: trunk/blender/source/blender/blenkernel/intern/pointcache.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/pointcache.c 2010-09-27 09:50:20 UTC (rev 32146)
+++ trunk/blender/source/blender/blenkernel/intern/pointcache.c 2010-09-27 09:58:37 UTC (rev 32147)
@@ -1876,6 +1876,9 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
}
+ if(pid->cache->cached_frames && cfra>=sta && cfra<=end)
+ pid->cache->cached_frames[cfra-sta] = 0;
break;
}
@@ -2014,6 +2031,12 @@
{
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 @@
*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 @@
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)
Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c 2010-09-27 09:50:20 UTC (rev 32146)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c 2010-09-27 09:58:37 UTC (rev 32147)
@@ -2937,6 +2937,7 @@
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)
Modified: trunk/blender/source/blender/editors/space_time/space_time.c
===================================================================
--- trunk/blender/source/blender/editors/space_time/space_time.c 2010-09-27 09:50:20 UTC (rev 32146)
+++ trunk/blender/source/blender/editors/space_time/space_time.c 2010-09-27 09:58:37 UTC (rev 32147)
@@ -181,6 +181,7 @@
SpaceTimeCache *stc;
float *fp, *array;
int i, len;
+ int sta, end;
switch(pid->type) {
case PTCACHE_TYPE_SOFTBODY:
@@ -197,7 +198,12 @@
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");
stc->type = pid->type;
@@ -208,14 +214,15 @@
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;
Modified: trunk/blender/source/blender/makesdna/DNA_object_force.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_object_force.h 2010-09-27 09:50:20 UTC (rev 32146)
+++ trunk/blender/source/blender/makesdna/DNA_object_force.h 2010-09-27 09:58:37 UTC (rev 32147)
@@ -167,6 +167,8 @@
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;
More information about the Bf-blender-cvs
mailing list