diff options
Diffstat (limited to 'source/blender/blenkernel/intern/seqcache.c')
-rw-r--r-- | source/blender/blenkernel/intern/seqcache.c | 170 |
1 files changed, 138 insertions, 32 deletions
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c index c5761dcc456..be66797bc56 100644 --- a/source/blender/blenkernel/intern/seqcache.c +++ b/source/blender/blenkernel/intern/seqcache.c @@ -17,8 +17,6 @@ * * Peter Schlaile <peter [at] schlaile [dot] de> 2010 * - * Contributor(s): Sergey Sharybin - * * ***** END GPL LICENSE BLOCK ***** */ @@ -28,15 +26,22 @@ #include <stddef.h> - -#include "BLO_sys_types.h" /* for intptr_t */ +#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_utildefines.h" +#include "BLI_ghash.h" +#include "BLI_mempool.h" +#include <pthread.h> -#include "IMB_moviecache.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" typedef struct seqCacheKey { @@ -46,9 +51,20 @@ typedef struct seqCacheKey seq_stripelem_ibuf_t type; } seqCacheKey; -static struct MovieCache *moviecache = NULL; - -static unsigned int seqcache_hashhash(const void *key_) +typedef struct seqCacheEntry +{ + ImBuf * ibuf; + MEM_CacheLimiterHandleC * c_handle; +} seqCacheEntry; + +static GHash * hash = NULL; +static MEM_CacheLimiterC * limitor = NULL; +static struct BLI_mempool * entrypool = NULL; +static struct BLI_mempool * keypool = NULL; +static int ibufs_in = 0; +static int ibufs_rem = 0; + +static unsigned int HashHash(const void *key_) { const seqCacheKey *key = (seqCacheKey*) key_; unsigned int rval = seq_hash_render_data(&key->context); @@ -60,7 +76,7 @@ static unsigned int seqcache_hashhash(const void *key_) return rval; } -static int seqcache_hashcmp(const void *a_, const void *b_) +static int HashCmp(const void *a_, const void *b_) { const seqCacheKey * a = (seqCacheKey*) a_; const seqCacheKey * b = (seqCacheKey*) b_; @@ -89,37 +105,109 @@ static int seqcache_hashcmp(const void *a_, const void *b_) return seq_cmp_render_data(&a->context, &b->context); } +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 = NULL; + e->c_handle = NULL; + + 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 = NULL; + e->c_handle = NULL; + } +} + +void seq_stripelem_cache_init(void) +{ + 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, 0); + keypool = BLI_mempool_create(sizeof(seqCacheKey), 64, 64, 0, 0); +} + void seq_stripelem_cache_destruct(void) { - if(moviecache) - IMB_moviecache_free(moviecache); + 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(void) { - if(moviecache) { - IMB_moviecache_free(moviecache); - moviecache = IMB_moviecache_create(sizeof(seqCacheKey), seqcache_hashhash, - seqcache_hashcmp, NULL); + 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( SeqRenderData context, struct Sequence * seq, float cfra, seq_stripelem_ibuf_t type) { + seqCacheKey key; + seqCacheEntry * e; - if(moviecache && seq) { - seqCacheKey key; - - key.seq = seq; - key.context = context; - key.cfra = cfra - seq->start; - key.type = type; + if (!seq) { + return NULL; + } - return IMB_moviecache_get(moviecache, &key); + if (!entrypool) { + seq_stripelem_cache_init(); } + key.seq = seq; + key.context = context; + 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 NULL; } @@ -127,21 +215,39 @@ void seq_stripelem_cache_put( SeqRenderData context, struct Sequence * seq, float cfra, seq_stripelem_ibuf_t type, struct ImBuf * i) { - seqCacheKey key; + seqCacheKey * key; + seqCacheEntry * e; if (!i) { return; } - if(!moviecache) { - moviecache = IMB_moviecache_create(sizeof(seqCacheKey), seqcache_hashhash, - seqcache_hashcmp, NULL); + ibufs_in++; + + if (!entrypool) { + seq_stripelem_cache_init(); } - key.seq = seq; - key.context = context; - key.cfra = cfra - seq->start; - key.type = type; + key = (seqCacheKey*) BLI_mempool_alloc(keypool); + + key->seq = seq; + key->context = context; + key->cfra = cfra - seq->start; + key->type = type; + + IMB_refImBuf(i); + + e = (seqCacheEntry*) BLI_mempool_alloc(entrypool); + + e->ibuf = i; + e->c_handle = NULL; + + BLI_ghash_remove(hash, key, HashKeyFree, HashValFree); + BLI_ghash_insert(hash, key, e); + + e->c_handle = MEM_CacheLimiter_insert(limitor, e); - IMB_moviecache_put(moviecache, &key, i); + MEM_CacheLimiter_ref(e->c_handle); + MEM_CacheLimiter_enforce_limits(limitor); + MEM_CacheLimiter_unref(e->c_handle); } |