Fix #141768: VSE: Tabbing in/out of metastrips does not update strip cache

Regression caused by 9e4c26574a.

Add strip stack as a key to the final cache.

Use the pointer to the list of sequences, as it is the easiest one to
obtain in all places where it is needed. This is slightly different
from the code prior to the 9e4c26574a where strips.last() was used,
but it allows to use the same logic in the prefetch job.

Pull Request: https://projects.blender.org/blender/blender/pulls/141778
This commit is contained in:
Sergey Sharybin
2025-07-14 11:08:39 +02:00
committed by Sergey Sharybin
parent 62e0a9105a
commit 08ec4602a2
4 changed files with 37 additions and 16 deletions

View File

@@ -28,19 +28,20 @@ static Mutex final_image_cache_mutex;
struct FinalImageCache {
struct Key {
const ListBase *seqbasep;
int timeline_frame;
int view_id;
int display_channel;
const uint64_t hash() const
{
return blender::get_default_hash(timeline_frame, view_id, display_channel);
return get_default_hash(seqbasep, timeline_frame, view_id, display_channel);
}
bool operator==(const FinalImageCache::Key &other) const
bool operator==(const Key &other) const
{
return timeline_frame == other.timeline_frame && view_id == other.view_id &&
display_channel == other.display_channel;
return seqbasep == other.seqbasep && timeline_frame == other.timeline_frame &&
view_id == other.view_id && display_channel == other.display_channel;
}
};
Map<Key, ImBuf *> map_;
@@ -76,9 +77,14 @@ static FinalImageCache *query_final_image_cache(const Scene *scene)
return scene->ed->runtime.final_image_cache;
}
ImBuf *final_image_cache_get(Scene *scene, float timeline_frame, int view_id, int display_channel)
ImBuf *final_image_cache_get(Scene *scene,
const ListBase *seqbasep,
const float timeline_frame,
const int view_id,
const int display_channel)
{
const FinalImageCache::Key key = {int(math::round(timeline_frame)), view_id, display_channel};
const FinalImageCache::Key key = {
seqbasep, int(math::round(timeline_frame)), view_id, display_channel};
ImBuf *res = nullptr;
{
@@ -96,10 +102,15 @@ ImBuf *final_image_cache_get(Scene *scene, float timeline_frame, int view_id, in
return res;
}
void final_image_cache_put(
Scene *scene, float timeline_frame, int view_id, int display_channel, ImBuf *image)
void final_image_cache_put(Scene *scene,
const ListBase *seqbasep,
const float timeline_frame,
const int view_id,
const int display_channel,
ImBuf *image)
{
const FinalImageCache::Key key = {int(math::round(timeline_frame)), view_id, display_channel};
const FinalImageCache::Key key = {
seqbasep, int(math::round(timeline_frame)), view_id, display_channel};
IMB_refImBuf(image);

View File

@@ -22,10 +22,18 @@ struct Scene;
namespace blender::seq {
void final_image_cache_put(
Scene *scene, float timeline_frame, int view_id, int display_channel, ImBuf *image);
void final_image_cache_put(Scene *scene,
const ListBase *seqbasep,
float timeline_frame,
int view_id,
int display_channel,
ImBuf *image);
ImBuf *final_image_cache_get(Scene *scene, float timeline_frame, int view_id, int display_channel);
ImBuf *final_image_cache_get(Scene *scene,
const ListBase *seqbasep,
float timeline_frame,
int view_id,
int display_channel);
void final_image_cache_invalidate_frame_range(Scene *scene,
const float timeline_frame_start,

View File

@@ -69,7 +69,6 @@ struct PrefetchJob {
RenderData context = {};
RenderData context_cpy = {};
ListBase *seqbasep = nullptr;
ListBase *seqbasep_cpy = nullptr;
/* prefetch area */
float cfra = 0.0f;
@@ -396,7 +395,8 @@ static bool strip_is_cached(PrefetchJob *pfjob, Strip *strip, bool can_have_fina
}
if (can_have_final_image) {
ibuf = final_image_cache_get(pfjob->context.scene, cfra, pfjob->context.view_id, 0);
ibuf = final_image_cache_get(
pfjob->context.scene, pfjob->seqbasep, cfra, pfjob->context.view_id, 0);
if (ibuf != nullptr) {
IMB_freeImBuf(ibuf);
return true;
@@ -559,6 +559,7 @@ static PrefetchJob *seq_prefetch_start_ex(const RenderData *context, float cfra)
pfjob->bmain_eval = BKE_main_new();
pfjob->scene = context->scene;
pfjob->seqbasep = context->scene->ed->seqbasep;
seq_prefetch_init_depsgraph(pfjob);
}
pfjob->bmain = context->bmain;

View File

@@ -2026,7 +2026,7 @@ ImBuf *render_give_ibuf(const RenderData *context, float timeline_frame, int cha
Scene *orig_scene = prefetch_get_original_scene(context);
ImBuf *out = nullptr;
if (!context->skip_cache && !context->is_proxy_render) {
out = final_image_cache_get(orig_scene, timeline_frame, context->view_id, chanshown);
out = final_image_cache_get(orig_scene, seqbasep, timeline_frame, context->view_id, chanshown);
}
Vector<Strip *> strips = seq_shown_strips_get(
@@ -2046,7 +2046,8 @@ ImBuf *render_give_ibuf(const RenderData *context, float timeline_frame, int cha
if (out && (orig_scene->ed->cache_flag & SEQ_CACHE_STORE_FINAL_OUT) && !context->skip_cache &&
!context->is_proxy_render)
{
final_image_cache_put(orig_scene, timeline_frame, context->view_id, chanshown, out);
final_image_cache_put(
orig_scene, seqbasep, timeline_frame, context->view_id, chanshown, out);
}
}