|
Blender
V2.59
|
00001 /* 00002 * $Id: seqcache.c 36197 2011-04-17 10:05:27Z schlaile $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * Peter Schlaile <peter [at] schlaile [dot] de> 2010 00021 * 00022 * ***** END GPL LICENSE BLOCK ***** 00023 */ 00024 00030 #include <stddef.h> 00031 #include <stdlib.h> 00032 #include <string.h> 00033 #include <math.h> 00034 00035 #include "MEM_guardedalloc.h" 00036 #include "MEM_CacheLimiterC-Api.h" 00037 00038 #include "DNA_sequence_types.h" 00039 #include "BKE_sequencer.h" 00040 #include "BLI_utildefines.h" 00041 #include "BLI_ghash.h" 00042 #include "BLI_mempool.h" 00043 #include <pthread.h> 00044 00045 #include "IMB_imbuf.h" 00046 #include "IMB_imbuf_types.h" 00047 00048 typedef struct seqCacheKey 00049 { 00050 struct Sequence * seq; 00051 SeqRenderData context; 00052 float cfra; 00053 seq_stripelem_ibuf_t type; 00054 } seqCacheKey; 00055 00056 typedef struct seqCacheEntry 00057 { 00058 ImBuf * ibuf; 00059 MEM_CacheLimiterHandleC * c_handle; 00060 } seqCacheEntry; 00061 00062 static GHash * hash = NULL; 00063 static MEM_CacheLimiterC * limitor = NULL; 00064 static struct BLI_mempool * entrypool = NULL; 00065 static struct BLI_mempool * keypool = NULL; 00066 static int ibufs_in = 0; 00067 static int ibufs_rem = 0; 00068 00069 static unsigned int HashHash(const void *key_) 00070 { 00071 const seqCacheKey *key = (seqCacheKey*) key_; 00072 unsigned int rval = seq_hash_render_data(&key->context); 00073 00074 rval ^= *(unsigned int*) &key->cfra; 00075 rval += key->type; 00076 rval ^= ((intptr_t) key->seq) << 6; 00077 00078 return rval; 00079 } 00080 00081 static int HashCmp(const void *a_, const void *b_) 00082 { 00083 const seqCacheKey * a = (seqCacheKey*) a_; 00084 const seqCacheKey * b = (seqCacheKey*) b_; 00085 00086 if (a->seq < b->seq) { 00087 return -1; 00088 } 00089 if (a->seq > b->seq) { 00090 return 1; 00091 } 00092 00093 if (a->cfra < b->cfra) { 00094 return -1; 00095 } 00096 if (a->cfra > b->cfra) { 00097 return 1; 00098 } 00099 00100 if (a->type < b->type) { 00101 return -1; 00102 } 00103 if (a->type > b->type) { 00104 return 1; 00105 } 00106 00107 return seq_cmp_render_data(&a->context, &b->context); 00108 } 00109 00110 static void HashKeyFree(void *key) 00111 { 00112 BLI_mempool_free(keypool, key); 00113 } 00114 00115 static void HashValFree(void *val) 00116 { 00117 seqCacheEntry* e = (seqCacheEntry*) val; 00118 00119 if (e->ibuf) { 00120 /* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf, 00121 e->ibuf->refcounter); */ 00122 IMB_freeImBuf(e->ibuf); 00123 MEM_CacheLimiter_unmanage(e->c_handle); 00124 ibufs_rem++; 00125 } 00126 00127 e->ibuf = NULL; 00128 e->c_handle = NULL; 00129 00130 BLI_mempool_free(entrypool, e); 00131 } 00132 00133 static void IMB_seq_cache_destructor(void * p) 00134 { 00135 seqCacheEntry* e = (seqCacheEntry*) p; 00136 00137 if (e && e->ibuf) { 00138 /* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf, 00139 e->ibuf->refcounter); */ 00140 IMB_freeImBuf(e->ibuf); 00141 ibufs_rem++; 00142 00143 e->ibuf = NULL; 00144 e->c_handle = NULL; 00145 } 00146 } 00147 00148 void seq_stripelem_cache_init(void) 00149 { 00150 hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash"); 00151 limitor = new_MEM_CacheLimiter( IMB_seq_cache_destructor ); 00152 00153 entrypool = BLI_mempool_create(sizeof(seqCacheEntry), 64, 64, 0); 00154 keypool = BLI_mempool_create(sizeof(seqCacheKey), 64, 64, 0); 00155 } 00156 00157 void seq_stripelem_cache_destruct(void) 00158 { 00159 if (!entrypool) { 00160 return; 00161 } 00162 BLI_ghash_free(hash, HashKeyFree, HashValFree); 00163 delete_MEM_CacheLimiter(limitor); 00164 BLI_mempool_destroy(entrypool); 00165 BLI_mempool_destroy(keypool); 00166 } 00167 00168 void seq_stripelem_cache_cleanup(void) 00169 { 00170 if (!entrypool) { 00171 seq_stripelem_cache_init(); 00172 } 00173 00174 /* fprintf(stderr, "Stats before cleanup: in: %d rem: %d\n", 00175 ibufs_in, ibufs_rem); */ 00176 00177 BLI_ghash_free(hash, HashKeyFree, HashValFree); 00178 hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash"); 00179 00180 /* fprintf(stderr, "Stats after cleanup: in: %d rem: %d\n", 00181 ibufs_in, ibufs_rem); */ 00182 00183 } 00184 00185 struct ImBuf * seq_stripelem_cache_get( 00186 SeqRenderData context, struct Sequence * seq, 00187 float cfra, seq_stripelem_ibuf_t type) 00188 { 00189 seqCacheKey key; 00190 seqCacheEntry * e; 00191 00192 if (!seq) { 00193 return NULL; 00194 } 00195 00196 if (!entrypool) { 00197 seq_stripelem_cache_init(); 00198 } 00199 00200 key.seq = seq; 00201 key.context = context; 00202 key.cfra = cfra - seq->start; 00203 key.type = type; 00204 00205 e = (seqCacheEntry*) BLI_ghash_lookup(hash, &key); 00206 00207 if (e && e->ibuf) { 00208 IMB_refImBuf(e->ibuf); 00209 00210 MEM_CacheLimiter_touch(e->c_handle); 00211 return e->ibuf; 00212 } 00213 return NULL; 00214 } 00215 00216 void seq_stripelem_cache_put( 00217 SeqRenderData context, struct Sequence * seq, 00218 float cfra, seq_stripelem_ibuf_t type, struct ImBuf * i) 00219 { 00220 seqCacheKey * key; 00221 seqCacheEntry * e; 00222 00223 if (!i) { 00224 return; 00225 } 00226 00227 ibufs_in++; 00228 00229 if (!entrypool) { 00230 seq_stripelem_cache_init(); 00231 } 00232 00233 key = (seqCacheKey*) BLI_mempool_alloc(keypool); 00234 00235 key->seq = seq; 00236 key->context = context; 00237 key->cfra = cfra - seq->start; 00238 key->type = type; 00239 00240 IMB_refImBuf(i); 00241 00242 e = (seqCacheEntry*) BLI_mempool_alloc(entrypool); 00243 00244 e->ibuf = i; 00245 e->c_handle = NULL; 00246 00247 BLI_ghash_remove(hash, key, HashKeyFree, HashValFree); 00248 BLI_ghash_insert(hash, key, e); 00249 00250 e->c_handle = MEM_CacheLimiter_insert(limitor, e); 00251 00252 MEM_CacheLimiter_ref(e->c_handle); 00253 MEM_CacheLimiter_enforce_limits(limitor); 00254 MEM_CacheLimiter_unref(e->c_handle); 00255 }