Changeset View
Changeset View
Standalone View
Standalone View
source/blender/imbuf/intern/moviecache.c
| Show First 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | typedef struct MovieCacheKey { | ||||
| void *userkey; | void *userkey; | ||||
| } MovieCacheKey; | } MovieCacheKey; | ||||
| typedef struct MovieCacheItem { | typedef struct MovieCacheItem { | ||||
| MovieCache *cache_owner; | MovieCache *cache_owner; | ||||
| ImBuf *ibuf; | ImBuf *ibuf; | ||||
| MEM_CacheLimiterHandleC *c_handle; | MEM_CacheLimiterHandleC *c_handle; | ||||
| void *priority_data; | void *priority_data; | ||||
| /* Indicates that #ibuf is null, because there was an error during load. */ | |||||
| bool added_empty; | |||||
| } MovieCacheItem; | } MovieCacheItem; | ||||
| static unsigned int moviecache_hashhash(const void *keyv) | static unsigned int moviecache_hashhash(const void *keyv) | ||||
| { | { | ||||
| const MovieCacheKey *key = keyv; | const MovieCacheKey *key = keyv; | ||||
| return key->cache_owner->hashfp(key->userkey); | return key->cache_owner->hashfp(key->userkey); | ||||
| } | } | ||||
| Show All 17 Lines | |||||
| static void moviecache_valfree(void *val) | static void moviecache_valfree(void *val) | ||||
| { | { | ||||
| MovieCacheItem *item = (MovieCacheItem *)val; | MovieCacheItem *item = (MovieCacheItem *)val; | ||||
| MovieCache *cache = item->cache_owner; | MovieCache *cache = item->cache_owner; | ||||
| PRINT("%s: cache '%s' free item %p buffer %p\n", __func__, cache->name, item, item->ibuf); | PRINT("%s: cache '%s' free item %p buffer %p\n", __func__, cache->name, item, item->ibuf); | ||||
| if (item->ibuf) { | |||||
| MEM_CacheLimiter_unmanage(item->c_handle); | MEM_CacheLimiter_unmanage(item->c_handle); | ||||
| if (item->ibuf) { | |||||
| IMB_freeImBuf(item->ibuf); | IMB_freeImBuf(item->ibuf); | ||||
| } | } | ||||
| if (item->priority_data && cache->prioritydeleterfp) { | if (item->priority_data && cache->prioritydeleterfp) { | ||||
| cache->prioritydeleterfp(item->priority_data); | cache->prioritydeleterfp(item->priority_data); | ||||
| } | } | ||||
| BLI_mempool_free(item->cache_owner->items_pool, item); | BLI_mempool_free(item->cache_owner->items_pool, item); | ||||
| } | } | ||||
| static void check_unused_keys(MovieCache *cache) | static void check_unused_keys(MovieCache *cache) | ||||
| { | { | ||||
| GHashIterator gh_iter; | GHashIterator gh_iter; | ||||
| BLI_ghashIterator_init(&gh_iter, cache->hash); | BLI_ghashIterator_init(&gh_iter, cache->hash); | ||||
| while (!BLI_ghashIterator_done(&gh_iter)) { | while (!BLI_ghashIterator_done(&gh_iter)) { | ||||
| const MovieCacheKey *key = BLI_ghashIterator_getKey(&gh_iter); | const MovieCacheKey *key = BLI_ghashIterator_getKey(&gh_iter); | ||||
| const MovieCacheItem *item = BLI_ghashIterator_getValue(&gh_iter); | const MovieCacheItem *item = BLI_ghashIterator_getValue(&gh_iter); | ||||
| bool remove; | |||||
| BLI_ghashIterator_step(&gh_iter); | BLI_ghashIterator_step(&gh_iter); | ||||
| remove = !item->ibuf; | if (item->added_empty) { | ||||
| /* Don't remove entries that have been added empty. Those indicate that the image couldn't be | |||||
| * loaded correctly. */ | |||||
| continue; | |||||
| } | |||||
| bool remove = !item->ibuf; | |||||
| if (remove) { | if (remove) { | ||||
| PRINT("%s: cache '%s' remove item %p without buffer\n", __func__, cache->name, item); | PRINT("%s: cache '%s' remove item %p without buffer\n", __func__, cache->name, item); | ||||
| } | } | ||||
| if (remove) { | if (remove) { | ||||
| BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree); | BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| MovieCacheKey *key; | MovieCacheKey *key; | ||||
| MovieCacheItem *item; | MovieCacheItem *item; | ||||
| if (!limitor) { | if (!limitor) { | ||||
| IMB_moviecache_init(); | IMB_moviecache_init(); | ||||
| } | } | ||||
| if (ibuf != NULL) { | |||||
| IMB_refImBuf(ibuf); | IMB_refImBuf(ibuf); | ||||
| } | |||||
| key = BLI_mempool_alloc(cache->keys_pool); | key = BLI_mempool_alloc(cache->keys_pool); | ||||
| key->cache_owner = cache; | key->cache_owner = cache; | ||||
| key->userkey = BLI_mempool_alloc(cache->userkeys_pool); | key->userkey = BLI_mempool_alloc(cache->userkeys_pool); | ||||
| memcpy(key->userkey, userkey, cache->keysize); | memcpy(key->userkey, userkey, cache->keysize); | ||||
| item = BLI_mempool_alloc(cache->items_pool); | item = BLI_mempool_alloc(cache->items_pool); | ||||
| PRINT("%s: cache '%s' put %p, item %p\n", __func__, cache->name, ibuf, item); | PRINT("%s: cache '%s' put %p, item %p\n", __func__, cache->name, ibuf, item); | ||||
| item->ibuf = ibuf; | item->ibuf = ibuf; | ||||
| item->cache_owner = cache; | item->cache_owner = cache; | ||||
| item->c_handle = NULL; | item->c_handle = NULL; | ||||
| item->priority_data = NULL; | item->priority_data = NULL; | ||||
| item->added_empty = ibuf == NULL; | |||||
| if (cache->getprioritydatafp) { | if (cache->getprioritydatafp) { | ||||
| item->priority_data = cache->getprioritydatafp(userkey); | item->priority_data = cache->getprioritydatafp(userkey); | ||||
| } | } | ||||
| BLI_ghash_reinsert(cache->hash, key, item, moviecache_keyfree, moviecache_valfree); | BLI_ghash_reinsert(cache->hash, key, item, moviecache_keyfree, moviecache_valfree); | ||||
| if (cache->last_userkey) { | if (cache->last_userkey) { | ||||
| Show All 25 Lines | void IMB_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf) | ||||
| do_moviecache_put(cache, userkey, ibuf, true); | do_moviecache_put(cache, userkey, ibuf, true); | ||||
| } | } | ||||
| bool IMB_moviecache_put_if_possible(MovieCache *cache, void *userkey, ImBuf *ibuf) | bool IMB_moviecache_put_if_possible(MovieCache *cache, void *userkey, ImBuf *ibuf) | ||||
| { | { | ||||
| size_t mem_in_use, mem_limit, elem_size; | size_t mem_in_use, mem_limit, elem_size; | ||||
| bool result = false; | bool result = false; | ||||
| elem_size = get_size_in_memory(ibuf); | elem_size = (ibuf == NULL) ? 0 : get_size_in_memory(ibuf); | ||||
| mem_limit = MEM_CacheLimiter_get_maximum(); | mem_limit = MEM_CacheLimiter_get_maximum(); | ||||
| BLI_mutex_lock(&limitor_lock); | BLI_mutex_lock(&limitor_lock); | ||||
| mem_in_use = MEM_CacheLimiter_get_memory_in_use(limitor); | mem_in_use = MEM_CacheLimiter_get_memory_in_use(limitor); | ||||
| if (mem_in_use + elem_size <= mem_limit) { | if (mem_in_use + elem_size <= mem_limit) { | ||||
| do_moviecache_put(cache, userkey, ibuf, false); | do_moviecache_put(cache, userkey, ibuf, false); | ||||
| result = true; | result = true; | ||||
| } | } | ||||
| BLI_mutex_unlock(&limitor_lock); | BLI_mutex_unlock(&limitor_lock); | ||||
| return result; | return result; | ||||
| } | } | ||||
| void IMB_moviecache_remove(MovieCache *cache, void *userkey) | void IMB_moviecache_remove(MovieCache *cache, void *userkey) | ||||
| { | { | ||||
| MovieCacheKey key; | MovieCacheKey key; | ||||
| key.cache_owner = cache; | key.cache_owner = cache; | ||||
| key.userkey = userkey; | key.userkey = userkey; | ||||
| BLI_ghash_remove(cache->hash, &key, moviecache_keyfree, moviecache_valfree); | BLI_ghash_remove(cache->hash, &key, moviecache_keyfree, moviecache_valfree); | ||||
| } | } | ||||
| ImBuf *IMB_moviecache_get(MovieCache *cache, void *userkey) | ImBuf *IMB_moviecache_get(MovieCache *cache, void *userkey, bool *r_is_cached_empty) | ||||
| { | { | ||||
| MovieCacheKey key; | MovieCacheKey key; | ||||
| MovieCacheItem *item; | MovieCacheItem *item; | ||||
| key.cache_owner = cache; | key.cache_owner = cache; | ||||
| key.userkey = userkey; | key.userkey = userkey; | ||||
| item = (MovieCacheItem *)BLI_ghash_lookup(cache->hash, &key); | item = (MovieCacheItem *)BLI_ghash_lookup(cache->hash, &key); | ||||
| if (r_is_cached_empty) { | |||||
| *r_is_cached_empty = false; | |||||
| } | |||||
| if (item) { | if (item) { | ||||
| if (item->ibuf) { | if (item->ibuf) { | ||||
| BLI_mutex_lock(&limitor_lock); | BLI_mutex_lock(&limitor_lock); | ||||
| MEM_CacheLimiter_touch(item->c_handle); | MEM_CacheLimiter_touch(item->c_handle); | ||||
| BLI_mutex_unlock(&limitor_lock); | BLI_mutex_unlock(&limitor_lock); | ||||
| IMB_refImBuf(item->ibuf); | IMB_refImBuf(item->ibuf); | ||||
| return item->ibuf; | return item->ibuf; | ||||
| } | } | ||||
| if (r_is_cached_empty) { | |||||
| *r_is_cached_empty = true; | |||||
| } | |||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| bool IMB_moviecache_has_frame(MovieCache *cache, void *userkey) | bool IMB_moviecache_has_frame(MovieCache *cache, void *userkey) | ||||
| { | { | ||||
| MovieCacheKey key; | MovieCacheKey key; | ||||
| ▲ Show 20 Lines • Show All 177 Lines • Show Last 20 Lines | |||||