[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