VSE: Make cache eviction a bit smarter when wrapping.
Also fix some minor cache and prefetch bugs that became more noticeable with these changes. Pull Request: https://projects.blender.org/blender/blender/pulls/139635
This commit is contained in:
@@ -200,17 +200,20 @@ bool final_image_cache_evict(Scene *scene)
|
||||
/* Only activate the prefetch guards if the cache is active. */
|
||||
seq_prefetch_get_time_range(scene, &cur_prefetch_start, &cur_prefetch_end);
|
||||
}
|
||||
bool prefetch_loops_around = cur_prefetch_start > cur_prefetch_end;
|
||||
const bool prefetch_loops_around = cur_prefetch_start > cur_prefetch_end;
|
||||
|
||||
const int timeline_start = PSFRA;
|
||||
const int timeline_end = PEFRA;
|
||||
/* If we wrap around, treat the timeline start as the playback head position.
|
||||
* This is to try to mitigate un-needed cache evictions. */
|
||||
const int cur_frame = prefetch_loops_around ? timeline_start : scene->r.cfra;
|
||||
|
||||
const int cur_frame = scene->r.cfra;
|
||||
std::pair<int, int> best_key = {};
|
||||
ImBuf *best_item = nullptr;
|
||||
int best_score = 0;
|
||||
for (const auto &item : cache->map_.items()) {
|
||||
const int item_frame = item.key.first;
|
||||
if (prefetch_loops_around) {
|
||||
int timeline_start = PSFRA;
|
||||
int timeline_end = PEFRA;
|
||||
if (item_frame >= timeline_start && item_frame <= cur_prefetch_end) {
|
||||
continue; /* Within active prefetch range, do not try to remove it. */
|
||||
}
|
||||
|
||||
@@ -268,9 +268,14 @@ bool source_image_cache_evict(Scene *scene)
|
||||
/* Only activate the prefetch guards if the cache is active. */
|
||||
seq_prefetch_get_time_range(scene, &cur_prefetch_start, &cur_prefetch_end);
|
||||
}
|
||||
bool prefetch_loops_around = cur_prefetch_start > cur_prefetch_end;
|
||||
const bool prefetch_loops_around = cur_prefetch_start > cur_prefetch_end;
|
||||
|
||||
const int timeline_start = PSFRA;
|
||||
const int timeline_end = PEFRA;
|
||||
/* If we wrap around, treat the timeline start as the playback head position.
|
||||
* This is to try to mitigate un-needed cache evictions. */
|
||||
const int cur_frame = prefetch_loops_around ? timeline_start : scene->r.cfra;
|
||||
|
||||
const int cur_frame = scene->r.cfra;
|
||||
SourceImageCache::StripEntry *best_strip = nullptr;
|
||||
std::pair<int, int> best_key = {};
|
||||
int best_score = 0;
|
||||
@@ -278,8 +283,6 @@ bool source_image_cache_evict(Scene *scene)
|
||||
for (const auto &entry : strip.value.frames.items()) {
|
||||
const int item_frame = int(strip.key->start + entry.value.strip_frame);
|
||||
if (prefetch_loops_around) {
|
||||
int timeline_start = PSFRA;
|
||||
int timeline_end = PEFRA;
|
||||
if (item_frame >= timeline_start && item_frame <= cur_prefetch_end) {
|
||||
continue; /* Within active prefetch range, do not try to remove it. */
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ struct PrefetchJob {
|
||||
int timeline_end = 0;
|
||||
int timeline_length = 0;
|
||||
int num_frames_prefetched = 0;
|
||||
int cache_flags = 0;
|
||||
int cache_flags = 0; /* Only used to detect cache flag changes. */
|
||||
|
||||
/* Control: */
|
||||
/* Set by prefetch. */
|
||||
@@ -544,6 +544,7 @@ static void *seq_prefetch_frames(void *job)
|
||||
}
|
||||
|
||||
ImBuf *ibuf = render_give_ibuf(&pfjob->context_cpy, seq_prefetch_cfra(pfjob), 0);
|
||||
pfjob->num_frames_prefetched++;
|
||||
IMB_freeImBuf(ibuf);
|
||||
|
||||
/* Suspend thread if there is nothing to be prefetched. */
|
||||
@@ -556,7 +557,6 @@ static void *seq_prefetch_frames(void *job)
|
||||
}
|
||||
|
||||
seq_prefetch_update_area(pfjob);
|
||||
pfjob->num_frames_prefetched++;
|
||||
}
|
||||
|
||||
pfjob->running = false;
|
||||
|
||||
@@ -2004,10 +2004,12 @@ ImBuf *render_give_ibuf(const RenderData *context, float timeline_frame, int cha
|
||||
|
||||
if (!strips.is_empty() && !out) {
|
||||
std::scoped_lock lock(seq_render_mutex);
|
||||
out = seq_render_strip_stack(context, &state, channels, seqbasep, timeline_frame, chanshown);
|
||||
|
||||
/* Try to make space before we add any new frames to the cache if it is full.
|
||||
* If we do this after we have added the new cache, we risk removing what we just added.*/
|
||||
evict_caches_if_full(orig_scene);
|
||||
|
||||
out = seq_render_strip_stack(context, &state, channels, seqbasep, timeline_frame, chanshown);
|
||||
|
||||
if (out && (orig_scene->ed->cache_flag & SEQ_CACHE_STORE_FINAL_OUT) && !context->skip_cache &&
|
||||
!context->is_proxy_render)
|
||||
{
|
||||
|
||||
@@ -94,11 +94,12 @@ bool evict_caches_if_full(Scene *scene)
|
||||
bool evicted_source = false;
|
||||
if (count_source != 0) {
|
||||
evicted_source = source_image_cache_evict(scene);
|
||||
/* Only try to enforce the final frame and raw cache ratio when the final cache is active. */
|
||||
if (evicted_source && scene->ed->cache_flag & SEQ_CACHE_STORE_FINAL_OUT) {
|
||||
/* Only try to enforce the final frame and raw cache ratio when the final cache is active. */
|
||||
const size_t source_per_final = divide_ceil_ul(count_source - 1,
|
||||
const size_t source_per_final = divide_ceil_ul(count_source,
|
||||
std::max<size_t>(count_final, 1));
|
||||
for (size_t i = 0; i < source_per_final; i++) {
|
||||
/* Start at "1" to make sure we only try to evict more frames if the ratio is above 1:1. */
|
||||
for (size_t i = 1; i < source_per_final; i++) {
|
||||
if (!source_image_cache_evict(scene)) {
|
||||
/* Can't evict any more frames, stop. */
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user