Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2021-11-02 13:15:05 +0300
committerJacques Lucke <jacques@blender.org>2021-11-02 13:17:12 +0300
commit0c3b215e7d5456878b155d13440864f49ad1f230 (patch)
tree1a405cfe6fbf632442d6ce03821e1828d581bcf4 /source/blender/imbuf
parent2b3becf2be27286d68a49328a13c327d2fa94aeb (diff)
Images: refactor how failed image load attempts are remembered
Previously, `ImageTile->ok` and `ImageUser->ok` were used to indicate whether an image failed to load. There were three possible values which (probably) had the following meanings: * `0`: There was an error while loading the image. Don't try to load again. * `1`: Default value. Try to load the image. * `2`: The image was loaded successfully. This image-wide flag did not make sense unfortunately, because loading may work for some frames of an image sequence but not for others. Remember than an image data block can also contain a movie. The purpose of the `->ok` flag was to serve as an optimization to avoid trying to load a file over and over again when there is an error (e.g. the file does not exist or is invalid). To get the optimization back, the patch is changing `MovieCache` so that it can also cache failed load attempts. As a consequence, `ibuf` is allowed to be `NULL` in a few more places. I added the appropriate null checks. This also solves issues when image sequences are used with the Image Texture node in Geometry nodes (also see D12827). Differential Revision: https://developer.blender.org/D12957
Diffstat (limited to 'source/blender/imbuf')
-rw-r--r--source/blender/imbuf/IMB_moviecache.h2
-rw-r--r--source/blender/imbuf/intern/colormanagement.c2
-rw-r--r--source/blender/imbuf/intern/moviecache.c27
3 files changed, 24 insertions, 7 deletions
diff --git a/source/blender/imbuf/IMB_moviecache.h b/source/blender/imbuf/IMB_moviecache.h
index 8e5f15a64a0..d32346a8418 100644
--- a/source/blender/imbuf/IMB_moviecache.h
+++ b/source/blender/imbuf/IMB_moviecache.h
@@ -59,7 +59,7 @@ void IMB_moviecache_set_priority_callback(struct MovieCache *cache,
void IMB_moviecache_put(struct MovieCache *cache, void *userkey, struct ImBuf *ibuf);
bool IMB_moviecache_put_if_possible(struct MovieCache *cache, void *userkey, struct ImBuf *ibuf);
-struct ImBuf *IMB_moviecache_get(struct MovieCache *cache, void *userkey);
+struct ImBuf *IMB_moviecache_get(struct MovieCache *cache, void *userkey, bool *r_is_cached_empty);
void IMB_moviecache_remove(struct MovieCache *cache, void *userkey);
bool IMB_moviecache_has_frame(struct MovieCache *cache, void *userkey);
void IMB_moviecache_free(struct MovieCache *cache);
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 119ef3ff971..c8c6f39507f 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -342,7 +342,7 @@ static ImBuf *colormanage_cache_get_ibuf(ImBuf *ibuf,
*cache_handle = NULL;
- cache_ibuf = IMB_moviecache_get(moviecache, key);
+ cache_ibuf = IMB_moviecache_get(moviecache, key, NULL);
*cache_handle = cache_ibuf;
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index 6cc1932eff6..8d0f55f5007 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -87,6 +87,8 @@ typedef struct MovieCacheItem {
ImBuf *ibuf;
MEM_CacheLimiterHandleC *c_handle;
void *priority_data;
+ /* Indicates that #ibuf is null, because there was an error during load. */
+ bool added_empty;
} MovieCacheItem;
static unsigned int moviecache_hashhash(const void *keyv)
@@ -141,11 +143,16 @@ static void check_unused_keys(MovieCache *cache)
while (!BLI_ghashIterator_done(&gh_iter)) {
const MovieCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
const MovieCacheItem *item = BLI_ghashIterator_getValue(&gh_iter);
- bool remove;
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) {
PRINT("%s: cache '%s' remove item %p without buffer\n", __func__, cache->name, item);
@@ -309,7 +316,9 @@ static void do_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf, boo
IMB_moviecache_init();
}
- IMB_refImBuf(ibuf);
+ if (ibuf != NULL) {
+ IMB_refImBuf(ibuf);
+ }
key = BLI_mempool_alloc(cache->keys_pool);
key->cache_owner = cache;
@@ -324,6 +333,7 @@ static void do_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf, boo
item->cache_owner = cache;
item->c_handle = NULL;
item->priority_data = NULL;
+ item->added_empty = ibuf == NULL;
if (cache->getprioritydatafp) {
item->priority_data = cache->getprioritydatafp(userkey);
@@ -365,7 +375,7 @@ bool IMB_moviecache_put_if_possible(MovieCache *cache, void *userkey, ImBuf *ibu
size_t mem_in_use, mem_limit, elem_size;
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();
BLI_mutex_lock(&limitor_lock);
@@ -389,7 +399,7 @@ void IMB_moviecache_remove(MovieCache *cache, void *userkey)
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;
MovieCacheItem *item;
@@ -398,6 +408,10 @@ ImBuf *IMB_moviecache_get(MovieCache *cache, void *userkey)
key.userkey = userkey;
item = (MovieCacheItem *)BLI_ghash_lookup(cache->hash, &key);
+ if (r_is_cached_empty) {
+ *r_is_cached_empty = false;
+ }
+
if (item) {
if (item->ibuf) {
BLI_mutex_lock(&limitor_lock);
@@ -408,6 +422,9 @@ ImBuf *IMB_moviecache_get(MovieCache *cache, void *userkey)
return item->ibuf;
}
+ if (r_is_cached_empty) {
+ *r_is_cached_empty = true;
+ }
}
return NULL;