[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [30661] trunk/blender/source/blender: == Sequencer ==

Peter Schlaile peter at schlaile.de
Fri Jul 23 18:57:11 CEST 2010


Revision: 30661
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=30661
Author:   schlaile
Date:     2010-07-23 18:57:11 +0200 (Fri, 23 Jul 2010)

Log Message:
-----------
== Sequencer ==

This patch cleans up the sequencer core by replacing the caching system
(TStripElems) with a hash based system, which is:

a) a lot faster
b) a lot more readable
c) a lot more memory conserving

The new caching system is also a good building ground for

a) sub frame precision rendering (even on scene strips)
b) multi core rendering (threaded rendering is still disabled, but can 
   be extended now to arbitrary core numbers)

I tested the code on an extensive editing session today and had no 
crashes during 4 hours of editing. So I consider it very stable.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_sequencer.h
    trunk/blender/source/blender/blenkernel/intern/blender.c
    trunk/blender/source/blender/blenkernel/intern/seqeffects.c
    trunk/blender/source/blender/blenkernel/intern/sequencer.c
    trunk/blender/source/blender/editors/space_sequencer/sequencer_draw.c
    trunk/blender/source/blender/render/intern/source/pipeline.c

Added Paths:
-----------
    trunk/blender/source/blender/blenkernel/intern/seqcache.c

Modified: trunk/blender/source/blender/blenkernel/BKE_sequencer.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_sequencer.h	2010-07-23 16:50:25 UTC (rev 30660)
+++ trunk/blender/source/blender/blenkernel/BKE_sequencer.h	2010-07-23 16:57:11 UTC (rev 30661)
@@ -164,6 +164,28 @@
 // intern?
 void update_changed_seq_and_deps(struct Scene *scene, struct Sequence *changed_seq, int len_change, int ibuf_change);
 
+/* seqcache.c */
+
+typedef enum {
+	SEQ_STRIPELEM_IBUF,
+	SEQ_STRIPELEM_IBUF_COMP,
+	SEQ_STRIPELEM_IBUF_STARTSTILL,
+	SEQ_STRIPELEM_IBUF_ENDSTILL
+} seq_stripelem_ibuf_t;
+
+void seq_stripelem_cache_init();
+void seq_stripelem_cache_destruct();
+
+void seq_stripelem_cache_cleanup();
+
+struct ImBuf * seq_stripelem_cache_get(
+	struct Sequence * seq, int rectx, int recty, 
+	float cfra, seq_stripelem_ibuf_t type);
+void seq_stripelem_cache_put(
+	struct Sequence * seq, int rectx, int recty, 
+	float cfra, seq_stripelem_ibuf_t type, struct ImBuf * nval);
+
+
 /* seqeffects.c */
 // intern?
 struct SeqEffectHandle get_sequence_blend(struct Sequence *seq);

Modified: trunk/blender/source/blender/blenkernel/intern/blender.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/blender.c	2010-07-23 16:50:25 UTC (rev 30660)
+++ trunk/blender/source/blender/blenkernel/intern/blender.c	2010-07-23 16:57:11 UTC (rev 30661)
@@ -102,6 +102,7 @@
 	BKE_spacetypes_free();		/* after free main, it uses space callbacks */
 	
 	IMB_exit();
+	seq_stripelem_cache_destruct();
 	
 	free_nodesystem();	
 }

Added: trunk/blender/source/blender/blenkernel/intern/seqcache.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/seqcache.c	                        (rev 0)
+++ trunk/blender/source/blender/blenkernel/intern/seqcache.c	2010-07-23 16:57:11 UTC (rev 30661)
@@ -0,0 +1,267 @@
+/**
+* $Id: seqcache.c 29923 2010-07-04 10:51:10Z schlaile $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Peter Schlaile <peter [at] schlaile [dot] de> 2010
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+#include "MEM_CacheLimiterC-Api.h"
+
+#include "DNA_sequence_types.h"
+#include "BKE_sequencer.h"
+#include "BLI_ghash.h"
+#include "BLI_mempool.h"
+#include <pthread.h>
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+typedef struct seqCacheKey 
+{
+	struct Sequence * seq;
+	int rectx;
+	int recty;
+	float cfra;
+	seq_stripelem_ibuf_t type;
+} seqCacheKey;
+
+typedef struct seqCacheEntry
+{
+	ImBuf * ibuf;
+	MEM_CacheLimiterHandleC * c_handle;
+} seqCacheEntry;
+
+static GHash * hash = 0;
+static MEM_CacheLimiterC * limitor = 0;
+static struct BLI_mempool * entrypool = 0;
+static struct BLI_mempool * keypool = 0;
+static int ibufs_in  = 0;
+static int ibufs_rem = 0;
+
+static unsigned int HashHash(void *key_)
+{
+	seqCacheKey * key = (seqCacheKey*) key_;
+	unsigned int rval = key->rectx + key->recty;
+
+	rval ^= *(unsigned int*) &key->cfra;
+	rval += key->type;
+	rval ^= (unsigned int) key->seq;
+
+	return rval;
+}
+
+static int HashCmp(void *a_, void *b_)
+{
+	seqCacheKey * a = (seqCacheKey*) a_;
+	seqCacheKey * b = (seqCacheKey*) b_;
+
+	if (a->seq < b->seq) {
+		return -1;		
+	}
+	if (a->seq > b->seq) {
+		return 1;
+	}
+
+	if (a->cfra < b->cfra) {
+		return -1;
+	}
+	if (a->cfra > b->cfra) {
+		return 1;
+	}
+
+	if (a->type < b->type) {
+		return -1;
+	}
+	if (a->type > b->type) {
+		return 1;
+	}
+
+	if (a->rectx < b->rectx) {
+		return -1;
+	}
+	if (a->rectx > b->rectx) {
+		return 1;
+	}
+
+	if (a->recty < b->recty) {
+		return -1;
+	}
+	if (a->recty > b->recty) {
+		return 1;
+	}
+
+	return 0;
+}
+
+static void HashKeyFree(void *key)
+{
+	BLI_mempool_free(keypool, key);
+}
+
+static void HashValFree(void *val)
+{
+	seqCacheEntry* e = (seqCacheEntry*) val;
+
+	if (e->ibuf) {
+		/* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf, 
+		   e->ibuf->refcounter); */
+		IMB_freeImBuf(e->ibuf);
+		MEM_CacheLimiter_unmanage(e->c_handle);
+		ibufs_rem++;
+	}
+
+	e->ibuf = 0;
+	e->c_handle = 0;
+
+	BLI_mempool_free(entrypool, e);
+}
+
+static void IMB_seq_cache_destructor(void * p)
+{
+	seqCacheEntry* e = (seqCacheEntry*) p;
+	
+	if (e && e->ibuf) {
+		/* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf,
+		   e->ibuf->refcounter); */
+		IMB_freeImBuf(e->ibuf);
+		ibufs_rem++;
+
+		e->ibuf = 0;
+		e->c_handle = 0;
+	}
+}
+
+void seq_stripelem_cache_init()
+{
+	hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash");
+	limitor = new_MEM_CacheLimiter( IMB_seq_cache_destructor );
+
+	entrypool = BLI_mempool_create(sizeof(seqCacheEntry), 64, 64, 0);
+	keypool = BLI_mempool_create(sizeof(seqCacheKey), 64, 64, 0);
+}
+
+void seq_stripelem_cache_destruct()
+{
+	if (!entrypool) {
+		return;
+	}
+	BLI_ghash_free(hash, HashKeyFree, HashValFree);
+	delete_MEM_CacheLimiter(limitor);
+	BLI_mempool_destroy(entrypool);
+	BLI_mempool_destroy(keypool);
+}
+
+void seq_stripelem_cache_cleanup()
+{
+	if (!entrypool) {
+		seq_stripelem_cache_init();
+	}
+
+	/* fprintf(stderr, "Stats before cleanup: in: %d rem: %d\n",
+	   ibufs_in, ibufs_rem); */
+
+	BLI_ghash_free(hash, HashKeyFree, HashValFree);
+	hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash");
+
+	/* fprintf(stderr, "Stats after cleanup: in: %d rem: %d\n",
+	   ibufs_in, ibufs_rem); */
+
+}
+
+struct ImBuf * seq_stripelem_cache_get(
+	struct Sequence * seq, int rectx, int recty, 
+	float cfra, seq_stripelem_ibuf_t type)
+{
+	seqCacheKey key;
+	seqCacheEntry * e;
+
+	if (!seq) {
+		return 0;
+	}
+
+	if (!entrypool) {
+		seq_stripelem_cache_init();
+	}
+
+	key.seq = seq;
+	key.rectx = rectx;
+	key.recty = recty;
+	key.cfra = cfra - seq->start;
+	key.type = type;
+	
+	e = (seqCacheEntry*) BLI_ghash_lookup(hash, &key);
+
+	if (e && e->ibuf) {
+		IMB_refImBuf(e->ibuf);
+
+		MEM_CacheLimiter_touch(e->c_handle);
+		return e->ibuf;
+	}
+	return 0;
+}
+
+void seq_stripelem_cache_put(
+	struct Sequence * seq, int rectx, int recty, 
+	float cfra, seq_stripelem_ibuf_t type, struct ImBuf * i)
+{
+	seqCacheKey * key;
+	seqCacheEntry * e;
+
+	if (!i) {
+		return;
+	}
+
+	ibufs_in++;
+
+	if (!entrypool) {
+		seq_stripelem_cache_init();
+	}
+
+	key = (seqCacheKey*) BLI_mempool_alloc(keypool);
+
+	key->seq = seq;
+	key->rectx = rectx;
+	key->recty = recty;
+	key->cfra = cfra - seq->start;
+	key->type = type;
+
+	/* we want our own version */
+	IMB_refImBuf(i);
+
+	e = (seqCacheEntry*) BLI_mempool_alloc(entrypool);
+
+	e->ibuf = i;
+	e->c_handle = 0;
+
+	BLI_ghash_remove(hash, key, HashKeyFree, HashValFree);
+	BLI_ghash_insert(hash, key, e);
+
+	e->c_handle = MEM_CacheLimiter_insert(limitor, e);
+
+	MEM_CacheLimiter_ref(e->c_handle);
+	MEM_CacheLimiter_enforce_limits(limitor);
+	MEM_CacheLimiter_unref(e->c_handle);
+}

Modified: trunk/blender/source/blender/blenkernel/intern/seqeffects.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/seqeffects.c	2010-07-23 16:50:25 UTC (rev 30660)
+++ trunk/blender/source/blender/blenkernel/intern/seqeffects.c	2010-07-23 16:57:11 UTC (rev 30661)
@@ -2786,6 +2786,7 @@
 		IMB_float_from_rect_simple(i);
 		memcpy(out->rect_float, i->rect_float, out->x * out->y *4*sizeof(float));
 	}
+	IMB_freeImBuf(i);
 }
 
 /* **********************************************************************

Modified: trunk/blender/source/blender/blenkernel/intern/sequencer.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/sequencer.c	2010-07-23 16:50:25 UTC (rev 30660)
+++ trunk/blender/source/blender/blenkernel/intern/sequencer.c	2010-07-23 16:57:11 UTC (rev 30661)
@@ -116,53 +116,11 @@
    alloc / free functions
    ********************************************************************** */
 
-static void free_tstripdata(int len, TStripElem *se)
-{
-	TStripElem *seo;
-	int a;
 
-	seo= se;
-	if (!se)
-		return;
 
-	for(a=0; a<len; a++, se++) {
-		if(se->ibuf) {
-			IMB_freeImBuf(se->ibuf);
-			se->ibuf = 0;
-		}
-		if(se->ibuf_comp) {
-			IMB_freeImBuf(se->ibuf_comp);
-			se->ibuf_comp = 0;
-		}
-	}
-
-	MEM_freeN(seo);
-}
-
-
 void new_tstripdata(Sequence *seq)
 {
 	if(seq->strip) {
-		free_tstripdata(seq->strip->len, seq->strip->tstripdata);
-		free_tstripdata(seq->strip->endstill, 
-				seq->strip->tstripdata_endstill);
-		free_tstripdata(seq->strip->startstill, 
-				seq->strip->tstripdata_startstill);
-
-		seq->strip->tstripdata= 0;
-		seq->strip->tstripdata_endstill= 0;
-		seq->strip->tstripdata_startstill= 0;
-
-		if(seq->strip->ibuf_startstill) {
-			IMB_freeImBuf(seq->strip->ibuf_startstill);
-			seq->strip->ibuf_startstill = 0;
-		}
-
-		if(seq->strip->ibuf_endstill) {
-			IMB_freeImBuf(seq->strip->ibuf_endstill);
-			seq->strip->ibuf_endstill = 0;
-		}
-
 		seq->strip->len= seq->len;
 	}
 }
@@ -208,20 +166,6 @@
 		MEM_freeN(strip->color_balance);
 	}
 
-	free_tstripdata(strip->len, strip->tstripdata);
-	free_tstripdata(strip->endstill, strip->tstripdata_endstill);
-	free_tstripdata(strip->startstill, strip->tstripdata_startstill);
-
-	if(strip->ibuf_startstill) {
-		IMB_freeImBuf(strip->ibuf_startstill);
-		strip->ibuf_startstill = 0;
-	}
-
-	if(strip->ibuf_endstill) {
-		IMB_freeImBuf(strip->ibuf_endstill);
-		strip->ibuf_endstill = 0;
-	}
-
 	MEM_freeN(strip);
 }
 
@@ -950,138 +894,10 @@
 	}
 }
 
-static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se,
-		      int render_size)
+static float give_stripelem_index(Sequence *seq, float cfra)
 {
-	TStripElem *se1, *se2, *se3;
-	float fac, facf;
-	int x, y;
-	int early_out;
-	struct SeqEffectHandle sh = get_sequence_effect(seq);
-	FCurve *fcu= NULL;
+	float nr;
 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list