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:
authorRichard Antalik <richardantalik@gmail.com>2019-04-29 00:13:41 +0300
committerRichard Antalik <richardantalik@gmail.com>2019-04-29 00:50:48 +0300
commit337cac760ba9d198fc45459f4274a94a87558528 (patch)
treed9f1c3cb901547ef4434c38c2a390795d0fff8f1 /source/blender/blenkernel/intern
parent1b65ec0a9b9be2aef7db88be3c6deaaa135ab382 (diff)
VSE: Cache rewrite
This patch implements new cache system. Aim is to give user more control over cache, so it can be maximally utilized. This is done through sequencer timeline side panel in category proxy & cache. Cached images are also visualized in timeline, controled by sequencer timeline view->cache menu Functional changes: - NOT use IMB_moviecache API - refactor names of cached image types - each scene owns 1 sequencer cache - merge preprocess cache into per-sequencer cache - cache links images rendered per frame in order as they are created - add cache content visualization tool - add RNA properties to control the cache More info can be found in design notes in blenkernel/intern/seqcache.c and in https://developer.blender.org/D4443 Reviewed By: brecht Differential Revision: https://developer.blender.org/D4443
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/blender.c1
-rw-r--r--source/blender/blenkernel/intern/seqcache.c614
-rw-r--r--source/blender/blenkernel/intern/sequencer.c301
3 files changed, 600 insertions, 316 deletions
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index d6599498a65..48b271cf277 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -97,7 +97,6 @@ void BKE_blender_free(void)
BLI_callback_global_finalize();
- BKE_sequencer_cache_destruct();
IMB_moviecache_destruct();
free_nodesystem();
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index b022819ca8c..c50f3f3f141 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -21,49 +21,84 @@
*/
#include <stddef.h>
-
-#include "BLI_sys_types.h" /* for intptr_t */
+#include <memory.h>
#include "MEM_guardedalloc.h"
#include "DNA_sequence_types.h"
#include "DNA_scene_types.h"
-#include "IMB_moviecache.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "BLI_mempool.h"
+#include "BLI_threads.h"
#include "BLI_listbase.h"
+#include "BLI_ghash.h"
#include "BKE_sequencer.h"
#include "BKE_scene.h"
+#include "BKE_main.h"
+
+/* ***************************** Sequencer cache design notes ******************************
+ *
+ * Cache key members:
+ * is_temp_cache - this cache entry will be freed before rendering next frame
+ * creator_id - ID of thread that created entry
+ * cost - In short: render time divided by playback frame rate
+ * link_prev/next - link to another entry created during rendering of the frame
+ *
+ * Linking: We use links to reduce number of iterations needed to manage cache.
+ * Entries are linked in order as they are put into cache.
+ * Only pernament (is_temp_cache = 0) cache entries are linked.
+ * Putting SEQ_CACHE_STORE_FINAL_OUT will reset linking
+ *
+ * Function:
+ * All images created during rendering are added to cache, even if the cache is already full.
+ * This is because:
+ * - one image may be needed multiple times during rendering.
+ * - keeping the last rendered frame allows us for faster re-render when user edits strip in stack
+ * - we can decide if we keep frame only when it's completely rendered. Otherwise we risk having
+ * "holes" in the cache, which can be annoying
+ * If the cache is full all entries for pending frame will have is_temp_cache set.
+ *
+ * Only entire frame can be freed to release resources for new entries (recycling).
+ * Once again, this is to reduce number of iterations, but also more controllable than removing
+ * entries one by one in reverse order to their creation.
+ *
+ * User can exclude caching of some images. Such entries will have is_temp_cache set.
+ */
+
+typedef struct SeqCache {
+ struct GHash *hash;
+ ThreadMutex iterator_mutex;
+ struct BLI_mempool *keys_pool;
+ struct BLI_mempool *items_pool;
+ struct SeqCacheKey *last_key;
+ size_t memory_used;
+} SeqCache;
+
+typedef struct SeqCacheItem {
+ struct SeqCache *cache_owner;
+ struct ImBuf *ibuf;
+} SeqCacheItem;
typedef struct SeqCacheKey {
+ struct SeqCache *cache_owner;
+ void *userkey;
+ struct SeqCacheKey *link_prev; /* Used for linking intermediate items to final frame */
+ struct SeqCacheKey *link_next; /* Used for linking intermediate items to final frame */
struct Sequence *seq;
SeqRenderData context;
float cfra;
- eSeqStripElemIBuf type;
+ float nfra;
+ float cost;
+ bool is_temp_cache;
+ short creator_id;
+ int type;
} SeqCacheKey;
-typedef struct SeqPreprocessCacheElem {
- struct SeqPreprocessCacheElem *next, *prev;
-
- struct Sequence *seq;
- SeqRenderData context;
- eSeqStripElemIBuf type;
-
- ImBuf *ibuf;
-} SeqPreprocessCacheElem;
-
-typedef struct SeqPreprocessCache {
- int cfra;
- ListBase elems;
-} SeqPreprocessCache;
-
-static struct MovieCache *moviecache = NULL;
-static struct SeqPreprocessCache *preprocess_cache = NULL;
-
-static void preprocessed_cache_destruct(void);
+static ThreadMutex cache_create_lock = BLI_MUTEX_INITIALIZER;
static bool seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b)
{
@@ -88,209 +123,536 @@ static unsigned int seq_hash_render_data(const SeqRenderData *a)
return rval;
}
-static unsigned int seqcache_hashhash(const void *key_)
+static unsigned int seq_cache_hashhash(const void *key_)
{
const SeqCacheKey *key = key_;
unsigned int rval = seq_hash_render_data(&key->context);
- rval ^= *(const unsigned int *)&key->cfra;
+ rval ^= *(const unsigned int *)&key->nfra;
rval += key->type;
rval ^= ((intptr_t)key->seq) << 6;
return rval;
}
-static bool seqcache_hashcmp(const void *a_, const void *b_)
+static bool seq_cache_hashcmp(const void *a_, const void *b_)
{
const SeqCacheKey *a = a_;
const SeqCacheKey *b = b_;
- return ((a->seq != b->seq) || (a->cfra != b->cfra) || (a->type != b->type) ||
+ return ((a->seq != b->seq) || (a->nfra != b->nfra) || (a->type != b->type) ||
seq_cmp_render_data(&a->context, &b->context));
}
-void BKE_sequencer_cache_destruct(void)
+static SeqCache *seq_cache_get_from_scene(Scene *scene)
{
- if (moviecache) {
- IMB_moviecache_free(moviecache);
+ if (scene && scene->ed && scene->ed->cache) {
+ return scene->ed->cache;
}
- preprocessed_cache_destruct();
+ return NULL;
+}
+
+static void seq_cache_lock(Scene *scene)
+{
+ SeqCache *cache = seq_cache_get_from_scene(scene);
+
+ if (cache) {
+ BLI_mutex_lock(&cache->iterator_mutex);
+ }
}
-void BKE_sequencer_cache_cleanup(void)
+static void seq_cache_unlock(Scene *scene)
{
- if (moviecache) {
- IMB_moviecache_free(moviecache);
- moviecache = IMB_moviecache_create(
- "seqcache", sizeof(SeqCacheKey), seqcache_hashhash, seqcache_hashcmp);
+ SeqCache *cache = seq_cache_get_from_scene(scene);
+
+ if (cache) {
+ BLI_mutex_unlock(&cache->iterator_mutex);
}
+}
- BKE_sequencer_preprocessed_cache_cleanup();
+static void seq_cache_keyfree(void *val)
+{
+ SeqCacheKey *key = val;
+ BLI_mempool_free(key->cache_owner->keys_pool, key);
}
-static bool seqcache_key_check_seq(ImBuf *UNUSED(ibuf), void *userkey, void *userdata)
+static void seq_cache_valfree(void *val)
{
- SeqCacheKey *key = (SeqCacheKey *)userkey;
- Sequence *seq = (Sequence *)userdata;
+ SeqCacheItem *item = (SeqCacheItem *)val;
+ SeqCache *cache = item->cache_owner;
+
+ if (item->ibuf) {
+ cache->memory_used -= IMB_get_size_in_memory(item->ibuf);
+ IMB_freeImBuf(item->ibuf);
+ }
- return key->seq == seq;
+ BLI_mempool_free(item->cache_owner->items_pool, item);
}
-void BKE_sequencer_cache_cleanup_sequence(Sequence *seq)
+static void seq_cache_put(SeqCache *cache, SeqCacheKey *key, ImBuf *ibuf)
{
- if (moviecache) {
- IMB_moviecache_cleanup(moviecache, seqcache_key_check_seq, seq);
+ SeqCacheItem *item;
+ item = BLI_mempool_alloc(cache->items_pool);
+ item->cache_owner = cache;
+ item->ibuf = ibuf;
+
+ if (BLI_ghash_reinsert(cache->hash, key, item, seq_cache_keyfree, seq_cache_valfree)) {
+ IMB_refImBuf(ibuf);
+ cache->last_key = key;
+ cache->memory_used += IMB_get_size_in_memory(ibuf);
}
}
-struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context,
- Sequence *seq,
- float cfra,
- eSeqStripElemIBuf type)
+static ImBuf *seq_cache_get(SeqCache *cache, void *key)
{
- if (moviecache && seq) {
- SeqCacheKey key;
+ SeqCacheItem *item = BLI_ghash_lookup(cache->hash, key);
- key.seq = seq;
- key.context = *context;
- key.cfra = cfra - seq->start;
- key.type = type;
+ if (item && item->ibuf) {
+ IMB_refImBuf(item->ibuf);
- return IMB_moviecache_get(moviecache, &key);
+ return item->ibuf;
}
return NULL;
}
-void BKE_sequencer_cache_put(
- const SeqRenderData *context, Sequence *seq, float cfra, eSeqStripElemIBuf type, ImBuf *i)
+static void seq_cache_relink_keys(SeqCacheKey *link_next, SeqCacheKey *link_prev)
+{
+ if (link_next) {
+ link_next->link_prev = link_prev;
+ }
+ if (link_prev) {
+ link_prev->link_next = link_next;
+ }
+}
+
+static SeqCacheKey *seq_cache_choose_key(Scene *scene, SeqCacheKey *lkey, SeqCacheKey *rkey)
{
- SeqCacheKey key;
+ SeqCacheKey *finalkey = NULL;
+
+ if (rkey && lkey) {
+ if (lkey->cfra > rkey->cfra) {
+ SeqCacheKey *swapkey = lkey;
+ lkey = rkey;
+ rkey = swapkey;
+ }
+
+ int l_diff = scene->r.cfra - lkey->cfra;
+ int r_diff = rkey->cfra - scene->r.cfra;
+
+ if (l_diff > r_diff) {
+ finalkey = lkey;
+ }
+ else {
+ finalkey = rkey;
+ }
+ }
+ else {
+ if (lkey) {
+ finalkey = lkey;
+ }
+ else {
+ finalkey = rkey;
+ }
+ }
+ return finalkey;
+}
- if (i == NULL || context->skip_cache) {
+static void seq_cache_recycle_linked(Scene *scene, SeqCacheKey *base)
+{
+ SeqCache *cache = seq_cache_get_from_scene(scene);
+ if (!cache) {
return;
}
- if (!moviecache) {
- moviecache = IMB_moviecache_create(
- "seqcache", sizeof(SeqCacheKey), seqcache_hashhash, seqcache_hashcmp);
+ SeqCacheKey *next = base->link_next;
+
+ while (base) {
+ SeqCacheKey *prev = base->link_prev;
+ BLI_ghash_remove(cache->hash, base, seq_cache_keyfree, seq_cache_valfree);
+ base = prev;
+ }
+
+ base = next;
+ while (base) {
+ next = base->link_next;
+ BLI_ghash_remove(cache->hash, base, seq_cache_keyfree, seq_cache_valfree);
+ base = next;
+ }
+}
+
+static SeqCacheKey *seq_cache_get_item_for_removal(Scene *scene)
+{
+ SeqCache *cache = seq_cache_get_from_scene(scene);
+ SeqCacheKey *finalkey = NULL;
+ /*leftmost key*/
+ SeqCacheKey *lkey = NULL;
+ /*rightmost key*/
+ SeqCacheKey *rkey = NULL;
+ SeqCacheKey *key = NULL;
+
+ GHashIterator gh_iter;
+ BLI_ghashIterator_init(&gh_iter, cache->hash);
+ int total_count = 0;
+ int cheap_count = 0;
+
+ while (!BLI_ghashIterator_done(&gh_iter)) {
+ key = BLI_ghashIterator_getKey(&gh_iter);
+ SeqCacheItem *item = BLI_ghashIterator_getValue(&gh_iter);
+ BLI_ghashIterator_step(&gh_iter);
+
+ /* this shouldn't happen, but better be safe than sorry */
+ if (!item->ibuf) {
+ seq_cache_recycle_linked(scene, key);
+ /* can not continue iterating after linked remove */
+ BLI_ghashIterator_init(&gh_iter, cache->hash);
+ continue;
+ }
+
+ if (key->is_temp_cache || key->link_next != NULL) {
+ continue;
+ }
+
+ total_count++;
+
+ if (key->cost <= scene->ed->recycle_max_cost) {
+ cheap_count++;
+ if (lkey) {
+ if (key->cfra < lkey->cfra) {
+ lkey = key;
+ }
+ }
+ else {
+ lkey = key;
+ }
+ if (rkey) {
+ if (key->cfra > rkey->cfra) {
+ rkey = key;
+ }
+ }
+ else {
+ rkey = key;
+ }
+ }
+ }
+
+ finalkey = seq_cache_choose_key(scene, lkey, rkey);
+ return finalkey;
+}
+
+/* Find only "base" keys
+ * Sources(other types) for a frame must be freed all at once
+ */
+static bool seq_cache_recycle_item(Scene *scene)
+{
+ size_t memory_total = ((size_t)U.memcachelimit) * 1024 * 1024;
+ SeqCache *cache = seq_cache_get_from_scene(scene);
+ if (!cache) {
+ return false;
}
- key.seq = seq;
- key.context = *context;
- key.cfra = cfra - seq->start;
- key.type = type;
+ seq_cache_lock(scene);
+
+ while (cache->memory_used > memory_total) {
+ SeqCacheKey *finalkey = seq_cache_get_item_for_removal(scene);
- IMB_moviecache_put(moviecache, &key, i);
+ if (finalkey) {
+ seq_cache_recycle_linked(scene, finalkey);
+ }
+ else {
+ seq_cache_unlock(scene);
+ return false;
+ }
+ }
+ seq_cache_unlock(scene);
+ return true;
}
-void BKE_sequencer_preprocessed_cache_cleanup(void)
+static void seq_cache_set_temp_cache_linked(Scene *scene, SeqCacheKey *base)
{
- SeqPreprocessCacheElem *elem;
+ SeqCache *cache = seq_cache_get_from_scene(scene);
- if (!preprocess_cache) {
+ if (!cache || !base) {
return;
}
- for (elem = preprocess_cache->elems.first; elem; elem = elem->next) {
- IMB_freeImBuf(elem->ibuf);
+ SeqCacheKey *next = base->link_next;
+
+ while (base) {
+ SeqCacheKey *prev = base->link_prev;
+ base->is_temp_cache = true;
+ base = prev;
}
- BLI_freelistN(&preprocess_cache->elems);
- BLI_listbase_clear(&preprocess_cache->elems);
+ base = next;
+ while (base) {
+ next = base->link_next;
+ base->is_temp_cache = true;
+ base = next;
+ }
}
-static void preprocessed_cache_destruct(void)
+static void BKE_sequencer_cache_create(Scene *scene)
{
- if (!preprocess_cache) {
+ BLI_mutex_lock(&cache_create_lock);
+ if (scene->ed->cache == NULL) {
+ SeqCache *cache = MEM_callocN(sizeof(SeqCache), "SeqCache");
+ cache->keys_pool = BLI_mempool_create(sizeof(SeqCacheKey), 0, 64, BLI_MEMPOOL_NOP);
+ cache->items_pool = BLI_mempool_create(sizeof(SeqCacheItem), 0, 64, BLI_MEMPOOL_NOP);
+ cache->hash = BLI_ghash_new(seq_cache_hashhash, seq_cache_hashcmp, "SeqCache hash");
+ cache->last_key = NULL;
+ BLI_mutex_init(&cache->iterator_mutex);
+ scene->ed->cache = cache;
+ }
+ BLI_mutex_unlock(&cache_create_lock);
+}
+
+/* ***************************** API ****************************** */
+
+void BKE_sequencer_cache_free_temp_cache(Scene *scene, short id, int cfra)
+{
+ SeqCache *cache = seq_cache_get_from_scene(scene);
+ if (!cache) {
return;
}
- BKE_sequencer_preprocessed_cache_cleanup();
+ seq_cache_lock(scene);
- MEM_freeN(preprocess_cache);
- preprocess_cache = NULL;
+ GHashIterator gh_iter;
+ BLI_ghashIterator_init(&gh_iter, cache->hash);
+ while (!BLI_ghashIterator_done(&gh_iter)) {
+ SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_ghashIterator_step(&gh_iter);
+
+ if (key->is_temp_cache && key->creator_id == id && key->cfra != cfra) {
+ BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree);
+ }
+ }
+ seq_cache_unlock(scene);
}
-ImBuf *BKE_sequencer_preprocessed_cache_get(const SeqRenderData *context,
- Sequence *seq,
- float cfra,
- eSeqStripElemIBuf type)
+void BKE_sequencer_cache_destruct(Scene *scene)
{
- SeqPreprocessCacheElem *elem;
+ SeqCache *cache = seq_cache_get_from_scene(scene);
+ if (!cache) {
+ return;
+ }
- if (!preprocess_cache) {
- return NULL;
+ BLI_ghash_free(cache->hash, seq_cache_keyfree, seq_cache_valfree);
+ BLI_mempool_destroy(cache->keys_pool);
+ BLI_mempool_destroy(cache->items_pool);
+ BLI_mutex_end(&cache->iterator_mutex);
+ MEM_freeN(cache);
+ scene->ed->cache = NULL;
+}
+
+void BKE_sequencer_cache_cleanup_all(Main *bmain)
+{
+ for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
+ BKE_sequencer_cache_cleanup(scene);
+ }
+}
+void BKE_sequencer_cache_cleanup(Scene *scene)
+{
+ SeqCache *cache = seq_cache_get_from_scene(scene);
+ if (!cache) {
+ return;
}
- if (preprocess_cache->cfra != cfra) {
- return NULL;
+ seq_cache_lock(scene);
+
+ GHashIterator gh_iter;
+ BLI_ghashIterator_init(&gh_iter, cache->hash);
+ while (!BLI_ghashIterator_done(&gh_iter)) {
+ SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
+
+ BLI_ghashIterator_step(&gh_iter);
+ BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree);
}
+ cache->last_key = NULL;
+ seq_cache_unlock(scene);
+}
- for (elem = preprocess_cache->elems.first; elem; elem = elem->next) {
- if (elem->seq != seq) {
- continue;
- }
+void BKE_sequencer_cache_cleanup_sequence(Scene *scene, Sequence *seq)
+{
+ SeqCache *cache = seq_cache_get_from_scene(scene);
+ if (!cache) {
+ return;
+ }
- if (elem->type != type) {
- continue;
- }
+ seq_cache_lock(scene);
- if (seq_cmp_render_data(&elem->context, context) != 0) {
- continue;
+ GHashIterator gh_iter;
+ BLI_ghashIterator_init(&gh_iter, cache->hash);
+ while (!BLI_ghashIterator_done(&gh_iter)) {
+ SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_ghashIterator_step(&gh_iter);
+
+ if (key->seq == seq) {
+ /* Relink keys, so we don't end up with orphaned keys */
+ if (key->link_next || key->link_prev) {
+ seq_cache_relink_keys(key->link_next, key->link_prev);
+ }
+
+ BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree);
}
+ }
+ cache->last_key = NULL;
+ seq_cache_unlock(scene);
+}
+
+struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context,
+ Sequence *seq,
+ float cfra,
+ int type)
+{
+ Scene *scene = context->scene;
- IMB_refImBuf(elem->ibuf);
- return elem->ibuf;
+ if (!scene->ed->cache) {
+ BKE_sequencer_cache_create(scene);
+ return NULL;
}
- return NULL;
+ seq_cache_lock(scene);
+ SeqCache *cache = seq_cache_get_from_scene(scene);
+ ImBuf *ibuf = NULL;
+
+ if (cache && seq) {
+ SeqCacheKey key;
+
+ key.seq = seq;
+ key.context = *context;
+ key.nfra = cfra - seq->start;
+ key.type = type;
+
+ ibuf = seq_cache_get(cache, &key);
+ }
+ seq_cache_unlock(scene);
+
+ return ibuf;
}
-void BKE_sequencer_preprocessed_cache_put(
- const SeqRenderData *context, Sequence *seq, float cfra, eSeqStripElemIBuf type, ImBuf *ibuf)
+bool BKE_sequencer_cache_put_if_possible(
+ const SeqRenderData *context, Sequence *seq, float cfra, int type, ImBuf *ibuf, float cost)
{
- SeqPreprocessCacheElem *elem;
+ Scene *scene = context->scene;
- if (!preprocess_cache) {
- preprocess_cache = MEM_callocN(sizeof(SeqPreprocessCache), "sequencer preprocessed cache");
+ if (seq_cache_recycle_item(scene)) {
+ BKE_sequencer_cache_put(context, seq, cfra, type, ibuf, cost);
+ return true;
}
else {
- if (preprocess_cache->cfra != cfra) {
- BKE_sequencer_preprocessed_cache_cleanup();
- }
+ seq_cache_set_temp_cache_linked(scene, scene->ed->cache->last_key);
+ scene->ed->cache->last_key = NULL;
+ return false;
}
+}
+
+void BKE_sequencer_cache_put(
+ const SeqRenderData *context, Sequence *seq, float cfra, int type, ImBuf *i, float cost)
+{
+ Scene *scene = context->scene;
+ short creator_id = 0;
- elem = MEM_callocN(sizeof(SeqPreprocessCacheElem), "sequencer preprocessed cache element");
+ if (i == NULL || context->skip_cache || context->is_proxy_render || !seq) {
+ return;
+ }
- elem->seq = seq;
- elem->type = type;
- elem->context = *context;
- elem->ibuf = ibuf;
+ /* Prevent reinserting, it breaks cache key linking */
+ ImBuf *test = BKE_sequencer_cache_get(context, seq, cfra, type);
+ if (test) {
+ IMB_freeImBuf(test);
+ return;
+ }
- preprocess_cache->cfra = cfra;
+ if (!scene->ed->cache) {
+ BKE_sequencer_cache_create(scene);
+ }
- IMB_refImBuf(ibuf);
+ seq_cache_lock(scene);
- BLI_addtail(&preprocess_cache->elems, elem);
+ SeqCache *cache = seq_cache_get_from_scene(scene);
+ int flag;
+
+ if (seq->cache_flag & SEQ_CACHE_OVERRIDE) {
+ flag = seq->cache_flag;
+ flag |= scene->ed->cache_flag & SEQ_CACHE_STORE_FINAL_OUT;
+ }
+ else {
+ flag = scene->ed->cache_flag;
+ }
+
+ if (cost > SEQ_CACHE_COST_MAX) {
+ cost = SEQ_CACHE_COST_MAX;
+ }
+
+ SeqCacheKey *key;
+ key = BLI_mempool_alloc(cache->keys_pool);
+ key->cache_owner = cache;
+ key->seq = seq;
+ key->context = *context;
+ key->cfra = cfra;
+ key->nfra = cfra - seq->start;
+ key->type = type;
+ key->cost = cost;
+ key->cache_owner = cache;
+ key->link_prev = NULL;
+ key->link_next = NULL;
+ key->is_temp_cache = true;
+ key->creator_id = creator_id;
+
+ /* Item stored for later use */
+ if (flag & type) {
+ key->is_temp_cache = false;
+ key->link_prev = cache->last_key;
+ }
+
+ SeqCacheKey *temp_last_key = cache->last_key;
+ seq_cache_put(cache, key, i);
+
+ /* Restore pointer to previous item as this one will be freed when stack is rendered */
+ if (key->is_temp_cache) {
+ cache->last_key = temp_last_key;
+ }
+
+ /* Set last_key's reference to this key so we can look up chain backwards
+ * Item is already put in cache, so cache->last_key points to current key;
+ */
+ if (flag & type && temp_last_key) {
+ temp_last_key->link_next = cache->last_key;
+ }
+
+ /* Reset linking */
+ if (key->type == SEQ_CACHE_STORE_FINAL_OUT) {
+ cache->last_key = NULL;
+ }
+
+ seq_cache_unlock(scene);
}
-void BKE_sequencer_preprocessed_cache_cleanup_sequence(Sequence *seq)
+void BKE_sequencer_cache_iterate(
+ struct Scene *scene,
+ void *userdata,
+ bool callback(void *userdata, struct Sequence *seq, int cfra, int cache_type, float cost))
{
- SeqPreprocessCacheElem *elem, *elem_next;
-
- if (!preprocess_cache) {
+ SeqCache *cache = seq_cache_get_from_scene(scene);
+ if (!cache) {
return;
}
- for (elem = preprocess_cache->elems.first; elem; elem = elem_next) {
- elem_next = elem->next;
+ seq_cache_lock(scene);
+ GHashIterator gh_iter;
+ BLI_ghashIterator_init(&gh_iter, cache->hash);
+ bool interrupt = false;
- if (elem->seq == seq) {
- IMB_freeImBuf(elem->ibuf);
+ while (!BLI_ghashIterator_done(&gh_iter) && !interrupt) {
+ SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_ghashIterator_step(&gh_iter);
- BLI_freelinkN(&preprocess_cache->elems, elem);
- }
+ interrupt = callback(userdata, key->seq, key->cfra, key->type, key->cost);
}
+
+ cache->last_key = NULL;
+ seq_cache_unlock(scene);
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 68c2869b5d2..2887f30532e 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -27,7 +27,7 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
-#include <math.h>
+#include <time.h>
#include "MEM_guardedalloc.h"
@@ -464,6 +464,11 @@ Editing *BKE_sequencer_editing_ensure(Scene *scene)
ed = scene->ed = MEM_callocN(sizeof(Editing), "addseq");
ed->seqbasep = &ed->seqbase;
+ ed->cache = NULL;
+ ed->cache_flag = SEQ_CACHE_STORE_FINAL_OUT;
+ ed->cache_flag |= SEQ_CACHE_VIEW_FINAL_OUT;
+ ed->cache_flag |= SEQ_CACHE_VIEW_ENABLE;
+ ed->recycle_max_cost = 10.0f;
}
return scene->ed;
@@ -478,8 +483,7 @@ void BKE_sequencer_editing_free(Scene *scene, const bool do_id_user)
return;
}
- /* this may not be the active scene!, could be smarter about this */
- BKE_sequencer_cache_cleanup();
+ BKE_sequencer_cache_destruct(scene);
SEQ_BEGIN (ed, seq) {
/* handle cache freeing above */
@@ -2639,7 +2643,7 @@ bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context,
{
float mul;
- if (context->is_proxy_render) {
+ if (context && context->is_proxy_render) {
return false;
}
@@ -2809,54 +2813,6 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
return ibuf;
}
-static ImBuf *copy_from_ibuf_still(const SeqRenderData *context, Sequence *seq, float nr)
-{
- ImBuf *rval = NULL;
- ImBuf *ibuf = NULL;
-
- if (nr == 0) {
- ibuf = BKE_sequencer_cache_get(context, seq, seq->start, SEQ_STRIPELEM_IBUF_STARTSTILL);
- }
- else if (nr == seq->len - 1) {
- ibuf = BKE_sequencer_cache_get(context, seq, seq->start, SEQ_STRIPELEM_IBUF_ENDSTILL);
- }
-
- if (ibuf) {
- rval = IMB_dupImBuf(ibuf);
- IMB_metadata_copy(rval, ibuf);
- IMB_freeImBuf(ibuf);
- }
-
- return rval;
-}
-
-static void copy_to_ibuf_still(const SeqRenderData *context, Sequence *seq, float nr, ImBuf *ibuf)
-{
- /* warning: ibuf may be NULL if the video fails to load */
- if (nr == 0 || nr == seq->len - 1) {
- /* we have to store a copy, since the passed ibuf
- * could be preprocessed afterwards (thereby silently
- * changing the cached image... */
- ImBuf *oibuf = ibuf;
- ibuf = IMB_dupImBuf(oibuf);
-
- if (ibuf) {
- IMB_metadata_copy(ibuf, oibuf);
- sequencer_imbuf_assign_spaces(context->scene, ibuf);
- }
-
- if (nr == 0) {
- BKE_sequencer_cache_put(context, seq, seq->start, SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf);
- }
-
- if (nr == seq->len - 1) {
- BKE_sequencer_cache_put(context, seq, seq->start, SEQ_STRIPELEM_IBUF_ENDSTILL, ibuf);
- }
-
- IMB_freeImBuf(ibuf);
- }
-}
-
/*********************** strip rendering functions *************************/
typedef struct RenderEffectInitData {
@@ -3062,7 +3018,7 @@ static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context,
static ImBuf *seq_render_image_strip(const SeqRenderData *context,
Sequence *seq,
- float nr,
+ float UNUSED(nr),
float cfra)
{
ImBuf *ibuf = NULL;
@@ -3138,8 +3094,8 @@ static ImBuf *seq_render_image_strip(const SeqRenderData *context,
BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibufs_arr[i], false);
if (i != context->view_id) {
- copy_to_ibuf_still(&localcontext, seq, nr, ibufs_arr[i]);
- BKE_sequencer_cache_put(&localcontext, seq, cfra, SEQ_STRIPELEM_IBUF, ibufs_arr[i]);
+ BKE_sequencer_cache_put(
+ &localcontext, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, ibufs_arr[i], 0);
}
}
}
@@ -3253,8 +3209,8 @@ static ImBuf *seq_render_movie_strip(const SeqRenderData *context,
BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf_arr[i], false);
}
if (i != context->view_id) {
- copy_to_ibuf_still(&localcontext, seq, nr, ibuf_arr[i]);
- BKE_sequencer_cache_put(&localcontext, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf_arr[i]);
+ BKE_sequencer_cache_put(
+ &localcontext, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, ibuf_arr[i], 0);
}
}
@@ -3656,8 +3612,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context,
}
if (i != context->view_id) {
- copy_to_ibuf_still(&localcontext, seq, nr, ibufs_arr[i]);
- BKE_sequencer_cache_put(&localcontext, seq, cfra, SEQ_STRIPELEM_IBUF, ibufs_arr[i]);
+ BKE_sequencer_cache_put(&localcontext, seq, cfra, SEQ_CACHE_STORE_RAW, ibufs_arr[i], 0);
}
RE_ReleaseResultImage(re);
@@ -3781,8 +3736,6 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context,
/* Scene strips update all animation, so we need to restore original state.*/
BKE_animsys_evaluate_all_animation(
context->bmain, context->depsgraph, context->scene, cfra);
-
- copy_to_ibuf_still(context, seq, nr, ibuf);
}
break;
}
@@ -3820,13 +3773,11 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context,
case SEQ_TYPE_IMAGE: {
ibuf = seq_render_image_strip(context, seq, nr, cfra);
- copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
case SEQ_TYPE_MOVIE: {
ibuf = seq_render_movie_strip(context, seq, nr, cfra);
- copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
@@ -3842,8 +3793,6 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context,
if (ibuf->rect_float) {
BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
}
-
- copy_to_ibuf_still(context, seq, nr, ibuf);
}
break;
@@ -3852,8 +3801,6 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context,
case SEQ_TYPE_MASK: {
/* ibuf is always new */
ibuf = seq_render_mask_strip(context, seq, nr);
-
- copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
}
@@ -3865,6 +3812,26 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context,
return ibuf;
}
+/* Estimate time spent by the program rendering the strip */
+static clock_t seq_estimate_render_cost_begin(void)
+{
+ return clock();
+}
+
+static float seq_estimate_render_cost_end(Scene *scene, clock_t begin)
+{
+ clock_t end = clock();
+ float time_spent = (float)(end - begin);
+ float time_max = (1.0f / scene->r.frs_sec) * CLOCKS_PER_SEC;
+
+ if (time_max != 0) {
+ return time_spent / time_max;
+ }
+ else {
+ return 1;
+ }
+}
+
static ImBuf *seq_render_strip(const SeqRenderData *context,
SeqRenderState *state,
Sequence *seq,
@@ -3873,37 +3840,32 @@ static ImBuf *seq_render_strip(const SeqRenderData *context,
ImBuf *ibuf = NULL;
bool use_preprocess = false;
bool is_proxy_image = false;
- float nr = give_stripelem_index(seq, cfra);
/* all effects are handled similarly with the exception of speed effect */
int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT :
seq->type;
bool is_preprocessed = !ELEM(
type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIECLIP);
- ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
+ clock_t begin = seq_estimate_render_cost_begin();
- if (ibuf == NULL) {
- ibuf = copy_from_ibuf_still(context, seq, nr);
+ ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED);
+ if (ibuf == NULL) {
+ ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_CACHE_STORE_RAW);
if (ibuf == NULL) {
- ibuf = BKE_sequencer_preprocessed_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
+ /* MOVIECLIPs have their own proxy management */
+ if (seq->type != SEQ_TYPE_MOVIECLIP) {
+ ibuf = seq_proxy_fetch(context, seq, cfra);
+ is_proxy_image = (ibuf != NULL);
+ }
if (ibuf == NULL) {
- /* MOVIECLIPs have their own proxy management */
- if (seq->type != SEQ_TYPE_MOVIECLIP) {
- ibuf = seq_proxy_fetch(context, seq, cfra);
- is_proxy_image = (ibuf != NULL);
- }
-
- if (ibuf == NULL) {
- ibuf = do_render_strip_uncached(context, state, seq, cfra);
- }
+ ibuf = do_render_strip_uncached(context, state, seq, cfra);
+ }
- if (ibuf) {
- if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP)) {
- is_proxy_image = (context->preview_render_size != 100);
- }
- BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
+ if (ibuf) {
+ if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP)) {
+ is_proxy_image = (context->preview_render_size != 100);
}
}
}
@@ -3911,30 +3873,29 @@ static ImBuf *seq_render_strip(const SeqRenderData *context,
if (ibuf) {
use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
}
- }
- else {
- /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
- * but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL
- * so, no need in check for preprocess here
- */
- }
- if (ibuf == NULL) {
- ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect);
- sequencer_imbuf_assign_spaces(context->scene, ibuf);
- }
+ if (ibuf == NULL) {
+ ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect);
+ sequencer_imbuf_assign_spaces(context->scene, ibuf);
+ }
- if (context->is_proxy_render == false &&
- (ibuf->x != context->rectx || ibuf->y != context->recty)) {
- use_preprocess = true;
- }
+ if (context->is_proxy_render == false &&
+ (ibuf->x != context->rectx || ibuf->y != context->recty)) {
+ use_preprocess = true;
+ }
- if (use_preprocess) {
- ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image, is_preprocessed);
- }
+ if (use_preprocess) {
+ float cost = seq_estimate_render_cost_end(context->scene, begin);
+ BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost);
- BKE_sequencer_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
+ /* reset timer so we can get partial render time */
+ begin = seq_estimate_render_cost_begin();
+ ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image, is_preprocessed);
+ }
+ float cost = seq_estimate_render_cost_end(context->scene, begin);
+ BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, ibuf, cost);
+ }
return ibuf;
}
@@ -4015,6 +3976,7 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
int count;
int i;
ImBuf *out = NULL;
+ clock_t begin;
count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
@@ -4022,73 +3984,11 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
return NULL;
}
-#if 0 /* commentind since this breaks keyframing, since it resets the value on draw */
- if (scene->r.cfra != cfra) {
- /* XXX for prefetch and overlay offset!..., very bad!!! */
- AnimData *adt = BKE_animdata_from_id(&scene->id);
- BKE_animsys_evaluate_animdata(scene, &scene->id, adt, cfra, ADT_RECALC_ANIM);
- }
-#endif
-
- out = BKE_sequencer_cache_get(context, seq_arr[count - 1], cfra, SEQ_STRIPELEM_IBUF_COMP);
-
- if (out) {
- return out;
- }
-
- if (count == 1) {
- Sequence *seq = seq_arr[0];
-
- /* Some of the blend modes are unclear how to apply with only single input,
- * or some of them will just produce an empty result..
- */
- if (ELEM(seq->blend_mode, SEQ_BLEND_REPLACE, SEQ_TYPE_CROSS, SEQ_TYPE_ALPHAOVER)) {
- int early_out;
- if (seq->blend_mode == SEQ_BLEND_REPLACE) {
- early_out = EARLY_NO_INPUT;
- }
- else {
- early_out = seq_get_early_out_for_blend_mode(seq);
- }
-
- if (ELEM(early_out, EARLY_NO_INPUT, EARLY_USE_INPUT_2)) {
- out = seq_render_strip(context, state, seq, cfra);
- }
- else if (early_out == EARLY_USE_INPUT_1) {
- out = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect);
- }
- else {
- out = seq_render_strip(context, state, seq, cfra);
-
- if (early_out == EARLY_DO_EFFECT) {
- ImBuf *ibuf1 = IMB_allocImBuf(
- context->rectx, context->recty, 32, out->rect_float ? IB_rectfloat : IB_rect);
- ImBuf *ibuf2 = out;
-
- out = seq_render_strip_stack_apply_effect(context, seq, cfra, ibuf1, ibuf2);
- if (out) {
- IMB_metadata_copy(out, ibuf2);
- }
-
- IMB_freeImBuf(ibuf1);
- IMB_freeImBuf(ibuf2);
- }
- }
- }
- else {
- out = seq_render_strip(context, state, seq, cfra);
- }
-
- BKE_sequencer_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF_COMP, out);
-
- return out;
- }
-
for (i = count - 1; i >= 0; i--) {
int early_out;
Sequence *seq = seq_arr[i];
- out = BKE_sequencer_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF_COMP);
+ out = BKE_sequencer_cache_get(context, seq, cfra, SEQ_CACHE_STORE_COMPOSITE);
if (out) {
break;
@@ -4112,15 +4012,19 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
break;
case EARLY_DO_EFFECT:
if (i == 0) {
+ begin = seq_estimate_render_cost_begin();
+
ImBuf *ibuf1 = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect);
ImBuf *ibuf2 = seq_render_strip(context, state, seq, cfra);
out = seq_render_strip_stack_apply_effect(context, seq, cfra, ibuf1, ibuf2);
+ float cost = seq_estimate_render_cost_end(context->scene, begin);
+ BKE_sequencer_cache_put(context, seq_arr[i], cfra, SEQ_CACHE_STORE_COMPOSITE, out, cost);
+
IMB_freeImBuf(ibuf1);
IMB_freeImBuf(ibuf2);
}
-
break;
}
if (out) {
@@ -4128,11 +4032,9 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
}
}
- BKE_sequencer_cache_put(context, seq_arr[i], cfra, SEQ_STRIPELEM_IBUF_COMP, out);
-
i++;
-
for (; i < count; i++) {
+ begin = seq_estimate_render_cost_begin();
Sequence *seq = seq_arr[i];
if (seq_get_early_out_for_blend_mode(seq) == EARLY_DO_EFFECT) {
@@ -4145,7 +4047,8 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
IMB_freeImBuf(ibuf2);
}
- BKE_sequencer_cache_put(context, seq_arr[i], cfra, SEQ_STRIPELEM_IBUF_COMP, out);
+ float cost = seq_estimate_render_cost_end(context->scene, begin);
+ BKE_sequencer_cache_put(context, seq_arr[i], cfra, SEQ_CACHE_STORE_COMPOSITE, out, cost);
}
return out;
@@ -4158,7 +4061,8 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int chanshown)
{
- Editing *ed = BKE_sequencer_editing_get(context->scene, false);
+ Scene *scene = context->scene;
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
ListBase *seqbasep;
if (ed == NULL) {
@@ -4176,8 +4080,29 @@ ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int cha
SeqRenderState state;
sequencer_state_init(&state);
+ ImBuf *out = NULL;
+ Sequence *seq_arr[MAXSEQ + 1];
+ int count;
- return seq_render_strip_stack(context, &state, seqbasep, cfra, chanshown);
+ count = get_shown_sequences(seqbasep, cfra, chanshown, seq_arr);
+
+ if (count) {
+ out = BKE_sequencer_cache_get(context, seq_arr[count - 1], cfra, SEQ_CACHE_STORE_FINAL_OUT);
+ }
+
+ BKE_sequencer_cache_free_temp_cache(context->scene, 0, cfra);
+
+ clock_t begin = seq_estimate_render_cost_begin();
+ float cost = 0;
+
+ if (count && !out) {
+ out = seq_render_strip_stack(context, &state, seqbasep, cfra, chanshown);
+ cost = seq_estimate_render_cost_end(context->scene, begin);
+ BKE_sequencer_cache_put_if_possible(
+ context, seq_arr[count - 1], cfra, SEQ_CACHE_STORE_FINAL_OUT, out, cost);
+ }
+
+ return out;
}
ImBuf *BKE_sequencer_give_ibuf_seqbase(const SeqRenderData *context,
@@ -4196,7 +4121,9 @@ ImBuf *BKE_sequencer_give_ibuf_direct(const SeqRenderData *context, float cfra,
SeqRenderState state;
sequencer_state_init(&state);
- return seq_render_strip(context, &state, seq, cfra);
+ ImBuf *ibuf = seq_render_strip(context, &state, seq, cfra);
+
+ return ibuf;
}
/* *********************** threading api ******************* */
@@ -4368,7 +4295,7 @@ bool BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
return true;
}
-static void sequence_do_invalidate_dependent(Sequence *seq, ListBase *seqbase)
+static void sequence_do_invalidate_dependent(Scene *scene, Sequence *seq, ListBase *seqbase)
{
Sequence *cur;
@@ -4378,12 +4305,11 @@ static void sequence_do_invalidate_dependent(Sequence *seq, ListBase *seqbase)
}
if (BKE_sequence_check_depend(seq, cur)) {
- BKE_sequencer_cache_cleanup_sequence(cur);
- BKE_sequencer_preprocessed_cache_cleanup_sequence(cur);
+ BKE_sequencer_cache_cleanup_sequence(scene, cur);
}
if (cur->seqbase.first) {
- sequence_do_invalidate_dependent(seq, &cur->seqbase);
+ sequence_do_invalidate_dependent(scene, seq, &cur->seqbase);
}
}
}
@@ -4391,7 +4317,7 @@ static void sequence_do_invalidate_dependent(Sequence *seq, ListBase *seqbase)
static void sequence_invalidate_cache(Scene *scene,
Sequence *seq,
bool invalidate_self,
- bool invalidate_preprocess)
+ bool UNUSED(invalidate_preprocess))
{
Editing *ed = scene->ed;
@@ -4402,7 +4328,7 @@ static void sequence_invalidate_cache(Scene *scene,
* re-open the animation.
*/
BKE_sequence_free_anim(seq);
- BKE_sequencer_cache_cleanup_sequence(seq);
+ BKE_sequencer_cache_cleanup_sequence(scene, seq);
}
/* if invalidation is invoked from sequence free routine, effectdata would be NULL here */
@@ -4410,16 +4336,12 @@ static void sequence_invalidate_cache(Scene *scene,
BKE_sequence_effect_speed_rebuild_map(scene, seq, true);
}
- if (invalidate_preprocess) {
- BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
- }
-
/* invalidate cache for all dependent sequences */
/* NOTE: can not use SEQ_BEGIN/SEQ_END here because that macro will change sequence's depth,
* which makes transformation routines work incorrect
*/
- sequence_do_invalidate_dependent(seq, &ed->seqbase);
+ sequence_do_invalidate_dependent(scene, seq, &ed->seqbase);
}
void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
@@ -4441,7 +4363,7 @@ void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, bool for_render)
{
Sequence *seq;
- BKE_sequencer_cache_cleanup();
+ BKE_sequencer_cache_cleanup(scene);
for (seq = seqbase->first; seq; seq = seq->next) {
if (for_render && CFRA >= seq->startdisp && CFRA <= seq->enddisp) {
@@ -5449,6 +5371,7 @@ Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine)
seq->scene_sound = NULL;
seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Sequence Stereo Format");
+ seq->cache_flag = SEQ_CACHE_ALL_TYPES;
return seq;
}
@@ -6080,7 +6003,6 @@ static void sequencer_all_free_anim_ibufs(ListBase *seqbase, int cfra)
void BKE_sequencer_all_free_anim_ibufs(Main *bmain, int cfra)
{
- BKE_sequencer_cache_cleanup();
for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed == NULL) {
@@ -6088,5 +6010,6 @@ void BKE_sequencer_all_free_anim_ibufs(Main *bmain, int cfra)
continue;
}
sequencer_all_free_anim_ibufs(&ed->seqbase, cfra);
+ BKE_sequencer_cache_cleanup(scene);
}
}