Fix #141282: VSE cache issues when rendering at reduced resolution scale

If render settings resolution scale had lowered resolution, cached
images from render image/animation session could "stay around"
and be incorrectly used in the VSE preview area. Two cases I found are
fixed here:
- Intra-frame cache was not flushed upon actual final resolution
  change,
- "Source images" for effect/scene strips were not removed when
  requested resolution no longer matches their rendered resolution.

Pull Request: https://projects.blender.org/blender/blender/pulls/141297
This commit is contained in:
Aras Pranckevicius
2025-07-02 09:58:11 +02:00
committed by Aras Pranckevicius
parent 0596c7f119
commit 21870da9e2
4 changed files with 27 additions and 5 deletions

View File

@@ -30,6 +30,8 @@ struct IntraFrameCache {
StripImageMap composite;
float timeline_frame = -1.0f;
int view_id = -1;
int width = -1;
int height = -1;
~IntraFrameCache()
{
@@ -54,6 +56,8 @@ void intra_frame_cache_invalidate(Scene *scene)
cache->composite.clear();
cache->timeline_frame = -1.0f;
cache->view_id = -1;
cache->width = -1;
cache->height = -1;
}
}
@@ -162,13 +166,17 @@ void intra_frame_cache_destroy(Scene *scene)
}
}
void intra_frame_cache_set_cur_frame(Scene *scene, float frame, int view_id)
void intra_frame_cache_set_cur_frame(Scene *scene, float frame, int view_id, int width, int height)
{
IntraFrameCache *cache = query_intra_frame_cache(scene);
if (cache != nullptr) {
if (cache->timeline_frame != frame || cache->view_id != view_id) {
if (cache->timeline_frame != frame || cache->view_id != view_id || cache->width != width ||
cache->height != height)
{
cache->timeline_frame = frame;
cache->view_id = view_id;
cache->width = width;
cache->height = height;
cache->preprocessed.clear();
cache->composite.clear();
}

View File

@@ -35,6 +35,7 @@ void intra_frame_cache_destroy(Scene *scene);
void intra_frame_cache_invalidate(Scene *scene, const Strip *strip);
void intra_frame_cache_invalidate(Scene *scene);
void intra_frame_cache_set_cur_frame(Scene *scene, float frame, int view_id);
void intra_frame_cache_set_cur_frame(
Scene *scene, float frame, int view_id, int width, int height);
} // namespace blender::seq

View File

@@ -122,6 +122,17 @@ ImBuf *source_image_cache_get(const RenderData *context, const Strip *strip, flo
if (frame != nullptr) {
res = frame->image;
}
/* For effect and scene strips, check if the cached result matches our current
* render resolution. If it does not, remove stale source entries for this strip. */
if (res != nullptr &&
((strip->type & STRIP_TYPE_EFFECT) != 0 || strip->type == STRIP_TYPE_SCENE))
{
if (res->x != context->rectx || res->y != context->recty) {
cache->remove_entry(strip);
return nullptr;
}
}
}
if (res) {

View File

@@ -1629,7 +1629,8 @@ static ImBuf *do_render_strip_seqbase(const RenderData *context,
BKE_animsys_evaluate_all_animation(context->bmain, context->depsgraph, frame_index);
}
intra_frame_cache_set_cur_frame(context->scene, frame_index, context->view_id);
intra_frame_cache_set_cur_frame(
context->scene, frame_index, context->view_id, context->rectx, context->recty);
ibuf = seq_render_strip_stack(context,
state,
channels,
@@ -2019,7 +2020,8 @@ ImBuf *render_give_ibuf(const RenderData *context, float timeline_frame, int cha
channels = ed->displayed_channels;
}
intra_frame_cache_set_cur_frame(scene, timeline_frame, context->view_id);
intra_frame_cache_set_cur_frame(
scene, timeline_frame, context->view_id, context->rectx, context->recty);
Scene *orig_scene = prefetch_get_original_scene(context);
ImBuf *out = nullptr;