[Bf-blender-cvs] [0374114aca6] soc-2021-vse-strip-thumbnails: Cache limit : Set a limit of 1000 thumbs that can be cached giving around 160MB of memory for thumbs. Once the limit is reached, all cached thumbs before and after the current view x limits are removed.

Aditya Y Jeppu noreply at git.blender.org
Thu Jun 24 20:28:15 CEST 2021


Commit: 0374114aca64580642819efbef7253b7c1dbfd59
Author: Aditya Y Jeppu
Date:   Thu Jun 24 23:56:16 2021 +0530
Branches: soc-2021-vse-strip-thumbnails
https://developer.blender.org/rB0374114aca64580642819efbef7253b7c1dbfd59

Cache limit : Set a limit of 1000 thumbs that can be cached giving around
160MB of memory for thumbs. Once the limit is reached, all cached thumbs
before and after the current view x limits are removed.

===================================================================

M	source/blender/editors/space_sequencer/sequencer_draw.c
M	source/blender/sequencer/SEQ_render.h
M	source/blender/sequencer/intern/image_cache.c
M	source/blender/sequencer/intern/image_cache.h
M	source/blender/sequencer/intern/render.c

===================================================================

diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 7baf98f64d9..d652acd02fc 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -1116,7 +1116,7 @@ static void draw_seq_strip_thumbnail(View2D *v2d,
   context.is_proxy_render = false;
   context.is_thumb = true;
 
-  ibuf = SEQ_render_thumbnail(&context, seq, seq->startdisp);
+  ibuf = SEQ_render_thumbnail(&context, seq, seq->startdisp, v2d);
 
   /*Calculate thumb dimensions */
   float thumb_h = (SEQ_STRIP_OFSTOP - SEQ_STRIP_OFSBOTTOM) - (20 * U.dpi_fac * pixely);
@@ -1166,7 +1166,7 @@ static void draw_seq_strip_thumbnail(View2D *v2d,
     }
 
     /* Get the image */
-    ibuf = SEQ_render_thumbnail(&context, seq, x1 + (int)(cut_off));
+    ibuf = SEQ_render_thumbnail(&context, seq, x1 + (int)(cut_off), v2d);
 
     if (ibuf) {
       ED_draw_imbuf_ctx_clipping(C, ibuf, x1, y1, true, x1 + cut_off, y1, x2, y2, zoom_x, zoom_y);
diff --git a/source/blender/sequencer/SEQ_render.h b/source/blender/sequencer/SEQ_render.h
index 20472650d20..e3346d35aa4 100644
--- a/source/blender/sequencer/SEQ_render.h
+++ b/source/blender/sequencer/SEQ_render.h
@@ -70,7 +70,8 @@ struct ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context,
                                           struct Sequence *seq);
 struct ImBuf *SEQ_render_thumbnail(SeqRenderData *context,
                                    struct Sequence *seq,
-                                   float timeline_frame);
+                                   float timeline_frame,
+                                   View2D *v2d);
 void SEQ_render_init_colorspace(struct Sequence *seq);
 void SEQ_render_new_render_data(struct Main *bmain,
                                 struct Depsgraph *depsgraph,
diff --git a/source/blender/sequencer/intern/image_cache.c b/source/blender/sequencer/intern/image_cache.c
index 3393b034dc0..06c081c1ba1 100644
--- a/source/blender/sequencer/intern/image_cache.c
+++ b/source/blender/sequencer/intern/image_cache.c
@@ -148,6 +148,7 @@ typedef struct SeqCache {
   struct BLI_mempool *items_pool;
   struct SeqCacheKey *last_key;
   SeqDiskCache *disk_cache;
+  int count;
 } SeqCache;
 
 typedef struct SeqCacheItem {
@@ -1151,6 +1152,7 @@ static void seq_cache_create(Main *bmain, Scene *scene)
     cache->hash = BLI_ghash_new(seq_cache_hashhash, seq_cache_hashcmp, "SeqCache hash");
     cache->last_key = NULL;
     cache->bmain = bmain;
+    cache->count = 0;
     BLI_mutex_init(&cache->iterator_mutex);
     scene->ed->cache = cache;
 
@@ -1268,6 +1270,7 @@ void SEQ_cache_cleanup(Scene *scene)
     BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree);
   }
   cache->last_key = NULL;
+  cache->count = 0;
   seq_cache_unlock(scene);
 }
 
@@ -1336,6 +1339,36 @@ void seq_cache_cleanup_sequence(Scene *scene,
   seq_cache_unlock(scene);
 }
 
+void seq_cache_thumbnail_cleanup(Scene *scene, Sequence *seq, Sequence *seq_changed)
+{
+  SeqCache *cache = seq_cache_get_from_scene(scene);
+  if (!cache) {
+    return;
+  }
+
+  int range_start = seq_changed->startdisp;
+  int range_end = seq_changed->enddisp;
+
+  int invalidate_composite = SEQ_CACHE_STORE_THUMBNAIL;
+
+  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->type & invalidate_composite) && key->timeline_frame >= range_start &&
+        key->timeline_frame <= range_end) {
+      if (key->link_next || key->link_prev) {
+        seq_cache_relink_keys(key->link_next, key->link_prev);
+      }
+      cache->count--;
+      BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree);
+    }
+  }
+  cache->last_key = NULL;
+}
+
 struct ImBuf *seq_cache_get(const SeqRenderData *context,
                             Sequence *seq,
                             float timeline_frame,
@@ -1427,6 +1460,65 @@ bool seq_cache_put_if_possible(
   return false;
 }
 
+void seq_cache_thumbnail_put(const SeqRenderData *context,
+                             Sequence *seq,
+                             float timeline_frame,
+                             int type,
+                             ImBuf *i,
+                             View2D *v2d)
+{
+  if (i == NULL || context->skip_cache || context->is_proxy_render || !seq) {
+    return;
+  }
+
+  Scene *scene = context->scene;
+
+  if (context->is_prefetch_render) {
+    context = seq_prefetch_get_original_context(context);
+    scene = context->scene;
+    seq = seq_prefetch_get_original_sequence(seq, scene);
+    BLI_assert(seq != NULL);
+  }
+
+  /* Prevent reinserting, it breaks cache key linking. */
+  ImBuf *test = seq_cache_get(context, seq, timeline_frame, type);
+  if (test) {
+    IMB_freeImBuf(test);
+    return;
+  }
+
+  if (!scene->ed->cache) {
+    seq_cache_create(context->bmain, scene);
+  }
+
+  seq_cache_lock(scene);
+  SeqCache *cache = seq_cache_get_from_scene(scene);
+  SeqCacheKey *key = seq_cache_allocate_key(cache, context, seq, timeline_frame, type);
+
+  /* Limit cache to 1000 images stored. */
+  if (cache->count >= 1000) {
+    float safe_ofs = 20;
+    Sequence cut = *seq;
+
+    /* Frames to the left */
+    cut.startdisp = (int)v2d->tot.xmin;
+    cut.enddisp = (int)v2d->cur.xmin - (int)safe_ofs;
+    if (cut.startdisp < cut.enddisp) {
+      seq_cache_thumbnail_cleanup(scene, seq, &cut);
+    }
+    /* Frames to the right */
+    cut.startdisp = v2d->cur.xmax + safe_ofs;
+    cut.enddisp = v2d->tot.xmax;
+    if (cut.startdisp < cut.enddisp) {
+      seq_cache_thumbnail_cleanup(scene, seq, &cut);
+    }
+  }
+
+  seq_cache_put_ex(scene, key, i);
+  cache->count++;
+  seq_cache_unlock(scene);
+}
+
 void seq_cache_put(
     const SeqRenderData *context, Sequence *seq, float timeline_frame, int type, ImBuf *i)
 {
diff --git a/source/blender/sequencer/intern/image_cache.h b/source/blender/sequencer/intern/image_cache.h
index 63c559caee9..fbe47f3edd0 100644
--- a/source/blender/sequencer/intern/image_cache.h
+++ b/source/blender/sequencer/intern/image_cache.h
@@ -46,6 +46,12 @@ void seq_cache_put(const struct SeqRenderData *context,
                    float timeline_frame,
                    int type,
                    struct ImBuf *i);
+void seq_cache_thumbnail_put(const struct SeqRenderData *context,
+                             struct Sequence *seq,
+                             float timeline_frame,
+                             int type,
+                             struct ImBuf *i,
+                             struct View2D *v2d);
 bool seq_cache_put_if_possible(const struct SeqRenderData *context,
                                struct Sequence *seq,
                                float timeline_frame,
@@ -60,6 +66,7 @@ void seq_cache_cleanup_sequence(struct Scene *scene,
                                 struct Sequence *seq_changed,
                                 int invalidate_types,
                                 bool force_seq_changed_range);
+void seq_cache_thumbnail_cleanup(Scene *scene, Sequence *seq, Sequence *seq_changed);
 bool seq_cache_is_full(void);
 
 #ifdef __cplusplus
diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c
index c4307984adb..21897d0685a 100644
--- a/source/blender/sequencer/intern/render.c
+++ b/source/blender/sequencer/intern/render.c
@@ -2028,7 +2028,10 @@ ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context,
   return ibuf;
 }
 
-ImBuf *SEQ_render_thumbnail(SeqRenderData *context, Sequence *seq, float timeline_frame)
+ImBuf *SEQ_render_thumbnail(SeqRenderData *context,
+                            Sequence *seq,
+                            float timeline_frame,
+                            View2D *v2d)
 {
   SeqRenderState state;
   seq_render_state_init(&state);
@@ -2065,7 +2068,8 @@ ImBuf *SEQ_render_thumbnail(SeqRenderData *context, Sequence *seq, float timelin
   }
 
   if (scaled_ibuf)
-    seq_cache_put(context, seq, timeline_frame, SEQ_CACHE_STORE_THUMBNAIL, scaled_ibuf);
+    seq_cache_thumbnail_put(
+        context, seq, timeline_frame, SEQ_CACHE_STORE_THUMBNAIL, scaled_ibuf, v2d);
 
   if (scaled_ibuf == NULL) {
     ibuf = IMB_allocImBuf(rectx, recty, 32, IB_rect);



More information about the Bf-blender-cvs mailing list