Blender V5.0
prefetch.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <algorithm>
10#include <cstdlib>
11#include <cstring>
12#include <limits>
13
14#include "MEM_guardedalloc.h"
15
16#include "DNA_scene_types.h"
17#include "DNA_screen_types.h"
18#include "DNA_sequence_types.h"
19#include "DNA_space_types.h"
20
21#include "BLI_listbase.h"
22#include "BLI_threads.h"
23#include "BLI_vector_set.hh"
24
25#include "IMB_imbuf.hh"
26#include "IMB_imbuf_types.hh"
27
28#include "BKE_anim_data.hh"
29#include "BKE_animsys.h"
30#include "BKE_context.hh"
31#include "BKE_global.hh"
32#include "BKE_layer.hh"
33#include "BKE_main.hh"
34
35#include "DEG_depsgraph.hh"
39
40#include "SEQ_channels.hh"
41#include "SEQ_prefetch.hh"
42#include "SEQ_relations.hh"
43#include "SEQ_render.hh"
44#include "SEQ_sequencer.hh"
45
46#include "SEQ_time.hh"
49#include "prefetch.hh"
50#include "render.hh"
51
52namespace blender::seq {
53
55 PrefetchJob *next = nullptr;
56 PrefetchJob *prev = nullptr;
57
58 Main *bmain = nullptr;
59 Main *bmain_eval = nullptr;
60 Scene *scene = nullptr;
61 Scene *scene_eval = nullptr;
62 Depsgraph *depsgraph = nullptr;
63
66
68
69 /* context */
72
73 /* prefetch area */
74 int cfra = 0;
76 int timeline_end = 0;
79 int cache_flags = 0; /* Only used to detect cache flag changes. */
80
81 /* Control: */
82 /* Set by prefetch. */
83 bool running = false;
84 bool waiting = false;
85 bool stop = false;
86 /* Set from outside. */
87 bool is_scrubbing = false;
88};
89
91{
92 if (scene && scene->ed) {
93 return scene->ed->prefetch_job;
94 }
95 return nullptr;
96}
97
99{
100 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
101
102 if (!pfjob) {
103 return false;
104 }
105
106 return pfjob->running;
107}
108
109static void seq_prefetch_job_scrubbing_set(Scene *scene, bool is_scrubbing)
110{
111 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
112
113 if (!pfjob) {
114 return;
115 }
116
117 pfjob->is_scrubbing = is_scrubbing;
118}
119
121{
122 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
123
124 if (!pfjob) {
125 return false;
126 }
127
128 return pfjob->waiting;
129}
130
131static Strip *original_strip_get(const Strip *strip, ListBase *seqbase)
132{
133 LISTBASE_FOREACH (Strip *, strip_orig, seqbase) {
134 if (STREQ(strip->name, strip_orig->name)) {
135 return strip_orig;
136 }
137
138 if (strip_orig->type == STRIP_TYPE_META) {
139 Strip *match = original_strip_get(strip, &strip_orig->seqbase);
140 if (match != nullptr) {
141 return match;
142 }
143 }
144 }
145
146 return nullptr;
147}
148
149static Strip *original_strip_get(const Strip *strip, Scene *scene)
150{
151 Editing *ed = scene->ed;
152 return original_strip_get(strip, &ed->seqbase);
153}
154
156{
157 PrefetchJob *pfjob = seq_prefetch_job_get(context->scene);
158 return pfjob ? &pfjob->context : nullptr;
159}
160
162{
163 Scene *scene = context->scene;
164 if (context->is_prefetch_render) {
165 context = get_original_context(context);
166 if (context != nullptr) {
167 scene = context->scene;
168 }
169 }
170 return scene;
171}
172
174{
175 Scene *scene = context->scene;
176 if (context->is_prefetch_render) {
177 context = get_original_context(context);
178 if (context != nullptr) {
179 scene = context->scene;
180 strip = original_strip_get(strip, scene);
181 }
182 }
183 return scene;
184}
185
187{
188 return evict_caches_if_full(scene);
189}
190
192{
193 int new_frame = pfjob->cfra + pfjob->num_frames_prefetched;
194 Scene *scene = pfjob->scene; /* For the start/end frame macros. */
195 int timeline_start = PSFRA;
196 int timeline_end = PEFRA;
197 if (new_frame >= timeline_end) {
198 /* Wrap around to where we will jump when we reach the end frame. */
199 new_frame = timeline_start + new_frame - timeline_end;
200 }
201 return new_frame;
202}
203
208
209void seq_prefetch_get_time_range(Scene *scene, int *r_start, int *r_end)
210{
211 /* When there is no prefetch job, return "impossible" negative values. */
212 *r_start = std::numeric_limits<int>::min();
213 *r_end = std::numeric_limits<int>::min();
214
215 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
216 if (pfjob == nullptr) {
217 return;
218 }
219 if ((scene->ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) == 0 || !pfjob->running) {
220 return;
221 }
222
223 *r_start = pfjob->cfra;
224 *r_end = seq_prefetch_cfra(pfjob);
225}
226
228{
229 if (pfjob->depsgraph != nullptr) {
231 }
232 pfjob->depsgraph = nullptr;
233 pfjob->scene_eval = nullptr;
234}
235
237{
239 /* Prevent depsgraph from copying scene data to evaluated scene. It would reset updated frame. */
240 DEG_ids_clear_recalc(pfjob->depsgraph, false);
241}
242
244{
245 Main *bmain = pfjob->bmain_eval;
246 Scene *scene = pfjob->scene;
247 ViewLayer *view_layer = BKE_view_layer_default_render(scene);
248
249 pfjob->depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
250 DEG_debug_name_set(pfjob->depsgraph, "SEQUENCER PREFETCH");
251
252 /* Make sure there is a correct evaluated scene pointer. */
254
255 /* Update immediately so we have proper evaluated scene. */
257
259 pfjob->scene_eval->ed->cache_flag = 0;
260}
261
263{
264 int cfra = pfjob->scene->r.cfra;
265
266 /* rebase */
267 if (cfra > pfjob->cfra) {
268 int delta = cfra - pfjob->cfra;
269 pfjob->cfra = cfra;
270 pfjob->num_frames_prefetched -= delta;
271
272 pfjob->num_frames_prefetched = std::max(pfjob->num_frames_prefetched, 1);
273 }
274
275 /* reset */
276 if (cfra < pfjob->cfra) {
277 pfjob->cfra = cfra;
278 pfjob->num_frames_prefetched = 1;
279 }
280
281 /* timeline span changes */
282 Scene *scene = pfjob->scene; /* For the start/end frame macros. */
283 if (pfjob->timeline_start != PSFRA || pfjob->timeline_end != PEFRA) {
284 pfjob->timeline_start = PSFRA;
285 pfjob->timeline_end = PEFRA;
286 pfjob->timeline_length = PEFRA - PSFRA;
287 /* Reset the number of prefetched frames as we need to re-evaluate which
288 * frames to keep in the cache.
289 */
290 pfjob->num_frames_prefetched = 1;
291 }
292
293 /* cache flag changes */
294 if (pfjob->cache_flags != scene->ed->cache_flag) {
295 pfjob->cache_flags = scene->ed->cache_flag;
296 pfjob->num_frames_prefetched = 1;
297 }
298}
299
301{
302 /* TODO(Richard): Use wm_jobs for prefetch, or pass main. */
303 for (Scene *scene = static_cast<Scene *>(G.main->scenes.first); scene;
304 scene = static_cast<Scene *>(scene->id.next))
305 {
306 prefetch_stop(scene);
307 }
308}
309
311{
312 PrefetchJob *pfjob;
313 pfjob = seq_prefetch_job_get(scene);
314
315 if (!pfjob) {
316 return;
317 }
318
319 pfjob->stop = true;
320
321 while (pfjob->running) {
323 }
324}
325
326static void seq_prefetch_update_context(const RenderData *context)
327{
328 PrefetchJob *pfjob;
329 pfjob = seq_prefetch_job_get(context->scene);
330
332 pfjob->depsgraph,
333 pfjob->scene_eval,
334 context->rectx,
335 context->recty,
336 context->preview_render_size,
337 nullptr,
338 &pfjob->context_cpy);
339 pfjob->context_cpy.is_prefetch_render = true;
341
343 pfjob->depsgraph,
344 pfjob->scene,
345 context->rectx,
346 context->recty,
347 context->preview_render_size,
348 nullptr,
349 &pfjob->context);
350 pfjob->context.is_prefetch_render = false;
351
352 /* Same ID as prefetch context, because context will be swapped, but we still
353 * want to assign this ID to cache entries created in this thread.
354 * This is to allow "temp cache" work correctly for both threads.
355 */
357}
358
360{
361 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
362
363 if (!pfjob) {
364 return;
365 }
366
367 pfjob->scene = scene;
370}
371
373{
375 Editing *ed_eval = editing_get(pfjob->scene_eval);
376
377 if (ms_orig != nullptr) {
378 Strip *meta_eval = original_strip_get(ms_orig->parent_strip, pfjob->scene_eval);
379 ed_eval->current_meta_strip = meta_eval;
380 }
381 else {
382 ed_eval->current_meta_strip = nullptr;
383 }
384}
385
386static void seq_prefetch_resume(Scene *scene)
387{
388 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
389
390 if (pfjob && pfjob->waiting) {
392 }
393}
394
396{
397 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
398 if (!pfjob) {
399 return;
400 }
401
402 prefetch_stop(scene);
403
404 BLI_threadpool_remove(&pfjob->threads, pfjob);
410 scene->ed->prefetch_job = nullptr;
411 MEM_delete(pfjob);
412}
413
415{
418
419 VectorSet<Strip *> scene_strips;
420 for (VectorSet<Strip *> strips : strips_by_scene.values()) {
421 scene_strips.add_multiple(strips);
422 }
423 return scene_strips;
424}
425
427 ListBase *channels,
428 ListBase *seqbase,
429 blender::Span<Strip *> scene_strips,
430 int timeline_frame,
432{
434 scene, channels, seqbase, timeline_frame, 0);
435
436 /* Iterate over rendered strips. */
437 for (Strip *strip : rendered_strips) {
438 if (strip->type == STRIP_TYPE_META &&
440 scene, &strip->channels, &strip->seqbase, scene_strips, timeline_frame, state))
441 {
442 return true;
443 }
444
445 /* Recursive "sequencer-type" scene strip detected, no point in attempting to render it. */
446 if (state.strips_rendering_seqbase.contains(strip)) {
447 return true;
448 }
449
450 if (strip->type == STRIP_TYPE_SCENE && (strip->flag & SEQ_SCENE_STRIPS) != 0 &&
451 strip->scene != nullptr && editing_get(strip->scene))
452 {
453 state.strips_rendering_seqbase.add(strip);
454
455 const Scene *target_scene = strip->scene;
456 Editing *target_ed = editing_get(target_scene);
457 if (target_ed == nullptr) {
458 continue;
459 }
460
461 blender::VectorSet<Strip *> target_scene_strips = query_scene_strips(target_ed);
462 int target_timeline_frame = give_frame_index(scene, strip, timeline_frame) +
463 target_scene->r.sfra;
464
465 return seq_prefetch_scene_strip_is_rendered(target_scene,
466 target_ed->current_channels(),
467 target_ed->current_strips(),
468 target_scene_strips,
469 target_timeline_frame,
470 state);
471 }
472
473 /* Check if strip is effect of scene strip or uses it as modifier.
474 * This also checks if `strip == seq_scene`. */
475 for (Strip *seq_scene : scene_strips) {
476 if (relations_render_loop_check(strip, seq_scene)) {
477 return true;
478 }
479 }
480 }
481 return false;
482}
483
484/* Prefetch must avoid rendering scene strips, because rendering in background locks UI and can
485 * make it unresponsive for long time periods. */
486static bool seq_prefetch_must_skip_frame(PrefetchJob *pfjob, ListBase *channels, ListBase *seqbase)
487{
488 /* Pass in state to check for infinite recursion of "sequencer-type" scene strips. */
490
493 pfjob->scene_eval, channels, seqbase, scene_strips, seq_prefetch_cfra(pfjob), state);
494}
495
497{
498 return seq_prefetch_is_cache_full(pfjob->scene) || pfjob->is_scrubbing ||
499 (pfjob->num_frames_prefetched >= pfjob->timeline_length);
500}
501
503{
505 while (seq_prefetch_need_suspend(pfjob) &&
506 (pfjob->scene->ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) && !pfjob->stop)
507 {
508 pfjob->waiting = true;
511 }
512 pfjob->waiting = false;
514}
515
516static void *seq_prefetch_frames(void *job)
517{
518 PrefetchJob *pfjob = (PrefetchJob *)job;
519
520 while (true) {
521 if (pfjob->cfra < pfjob->timeline_start || pfjob->cfra > pfjob->timeline_end) {
522 /* Don't try to prefetch anything when we are outside of the timeline range. */
523 break;
524 }
525 pfjob->scene_eval->ed->prefetch_job = nullptr;
526
529 AnimationEvalContext anim_eval_context = seq_prefetch_anim_eval_context(pfjob);
531 &pfjob->context_cpy.scene->id, adt, &anim_eval_context, ADT_RECALC_ALL, false);
532
533 /* This is quite hacky solution:
534 * We need cross-reference original scene with copy for cache.
535 * However depsgraph must not have this data, because it will try to kill this job.
536 * Scene copy don't reference original scene. Perhaps, this could be done by depsgraph.
537 * Set to nullptr before return!
538 */
539 pfjob->scene_eval->ed->prefetch_job = pfjob;
540
543 if (seq_prefetch_must_skip_frame(pfjob, channels, seqbase)) {
544 pfjob->num_frames_prefetched++;
545 /* Break instead of keep looping if the job should be terminated. */
546 if (!(pfjob->scene->ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) ||
547 !(pfjob->scene->ed->cache_flag & SEQ_CACHE_ALL_TYPES) || pfjob->stop)
548 {
549 break;
550 }
551 continue;
552 }
553
554 ImBuf *ibuf = render_give_ibuf(&pfjob->context_cpy, seq_prefetch_cfra(pfjob), 0);
555 pfjob->num_frames_prefetched++;
556 IMB_freeImBuf(ibuf);
557
558 /* Suspend thread if there is nothing to be prefetched. */
560
561 if (!(pfjob->scene->ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) ||
562 !(pfjob->scene->ed->cache_flag & SEQ_CACHE_ALL_TYPES) || pfjob->stop)
563 {
564 break;
565 }
566
568 }
569
570 pfjob->running = false;
571 pfjob->scene_eval->ed->prefetch_job = nullptr;
572
573 return nullptr;
574}
575
576static PrefetchJob *seq_prefetch_start_ex(const RenderData *context, float cfra)
577{
578 PrefetchJob *pfjob = seq_prefetch_job_get(context->scene);
579
580 if (!pfjob) {
581 if (!context->scene->ed) {
582 return nullptr;
583 }
584 pfjob = MEM_new<PrefetchJob>("PrefetchJob");
585 context->scene->ed->prefetch_job = pfjob;
586
590
591 pfjob->bmain_eval = BKE_main_new();
592 pfjob->scene = context->scene;
594 }
595 pfjob->bmain = context->bmain;
596
597 Scene *scene = pfjob->scene; /* For the start/end frame macros. */
598 pfjob->cfra = cfra;
599 pfjob->timeline_start = PSFRA;
600 pfjob->timeline_end = PEFRA;
601 pfjob->timeline_length = PEFRA - PSFRA;
602 pfjob->num_frames_prefetched = 1;
603 pfjob->cache_flags = scene->ed->cache_flag;
604
605 pfjob->waiting = false;
606 pfjob->stop = false;
607 pfjob->running = true;
608
609 seq_prefetch_update_scene(context->scene);
612
613 BLI_threadpool_remove(&pfjob->threads, pfjob);
614 BLI_threadpool_insert(&pfjob->threads, pfjob);
615
616 return pfjob;
617}
618
619void seq_prefetch_start(const RenderData *context, float timeline_frame)
620{
621 Scene *scene = context->scene;
622 Editing *ed = scene->ed;
623 bool has_strips = bool(ed->current_strips()->first);
624
625 if (!context->is_prefetch_render && !context->is_proxy_render) {
626 bool playing = context->is_playing;
627 bool scrubbing = context->is_scrubbing;
628 bool running = seq_prefetch_job_is_running(scene);
629 seq_prefetch_job_scrubbing_set(scene, scrubbing);
630 seq_prefetch_resume(scene);
631
632 /* conditions to start:
633 * prefetch enabled, prefetch not running, not scrubbing, not playing,
634 * cache storage enabled, has strips to render, not rendering, not doing modal transform -
635 * important, see D7820. */
636 if ((ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) && !running && !scrubbing && !playing &&
637 (ed->cache_flag & SEQ_CACHE_ALL_TYPES) && has_strips && !G.is_rendering && !G.moving)
638 {
639 seq_prefetch_start_ex(context, timeline_frame);
640 }
641 }
642}
643
645{
646 bScreen *screen = CTX_wm_screen(C);
647 bool playing = screen->animtimer != nullptr;
648 bool scrubbing = screen->scrubbing;
649 bool running = seq_prefetch_job_is_running(scene);
650 bool suspended = seq_prefetch_job_is_waiting(scene);
651
652 SpaceSeq *sseq = CTX_wm_space_seq(C);
653 bool showing_cache = sseq->cache_overlay.flag & SEQ_CACHE_SHOW;
654
655 /* force redraw, when prefetching and using cache view. */
656 if (running && !playing && !suspended && showing_cache) {
657 return true;
658 }
659 /* Sometimes scrubbing flag is set when not scrubbing. In that case I want to catch "event" of
660 * stopping scrubbing */
661 if (scrubbing) {
662 return true;
663 }
664 return false;
665}
666
667} // namespace blender::seq
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:83
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time) ATTR_WARN_UNUSED_RESULT
Definition anim_sys.cc:738
@ ADT_RECALC_ALL
void BKE_animsys_evaluate_animdata(struct ID *id, struct AnimData *adt, const struct AnimationEvalContext *anim_eval_context, eAnimData_Recalc recalc, bool flush_to_original)
bScreen * CTX_wm_screen(const bContext *C)
SpaceSeq * CTX_wm_space_seq(const bContext *C)
ViewLayer * BKE_view_layer_default_render(const Scene *scene)
Main * BKE_main_new()
Definition main.cc:89
void BKE_main_free(Main *bmain)
Definition main.cc:192
#define LISTBASE_FOREACH(type, var, list)
void BLI_mutex_end(ThreadMutex *mutex)
Definition threads.cc:360
void BLI_threadpool_remove(struct ListBase *threadbase, void *callerdata)
Definition threads.cc:197
void BLI_condition_wait(ThreadCondition *cond, ThreadMutex *mutex)
Definition threads.cc:580
void BLI_threadpool_init(struct ListBase *threadbase, void *(*do_thread)(void *), int tot)
Definition threads.cc:121
void BLI_mutex_init(ThreadMutex *mutex)
Definition threads.cc:340
pthread_cond_t ThreadCondition
void BLI_condition_end(ThreadCondition *cond)
Definition threads.cc:600
void BLI_threadpool_end(struct ListBase *threadbase)
Definition threads.cc:234
void BLI_condition_notify_one(ThreadCondition *cond)
Definition threads.cc:590
void BLI_condition_init(ThreadCondition *cond)
Definition threads.cc:575
void BLI_mutex_lock(ThreadMutex *mutex)
Definition threads.cc:345
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition threads.cc:350
void BLI_threadpool_insert(struct ListBase *threadbase, void *callerdata)
Definition threads.cc:184
pthread_mutex_t ThreadMutex
Definition BLI_threads.h:79
#define STREQ(a, b)
void DEG_ids_clear_recalc(Depsgraph *depsgraph, bool backup)
@ DAG_EVAL_RENDER
Depsgraph * DEG_graph_new(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode)
Definition depsgraph.cc:278
void DEG_graph_free(Depsgraph *graph)
Definition depsgraph.cc:306
void DEG_evaluate_on_framechange(Depsgraph *graph, float frame, DepsgraphEvaluateSyncWriteback sync_writeback=DEG_EVALUATE_SYNC_WRITEBACK_NO)
void DEG_graph_build_for_render_pipeline(Depsgraph *graph)
void DEG_debug_name_set(Depsgraph *depsgraph, const char *name)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
#define PSFRA
#define PEFRA
@ SEQ_CACHE_ALL_TYPES
@ SEQ_CACHE_PREFETCH_ENABLE
@ STRIP_TYPE_SCENE
@ STRIP_TYPE_META
@ SEQ_SCENE_STRIPS
@ SEQ_CACHE_SHOW
void IMB_freeImBuf(ImBuf *ibuf)
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
ValueIterator values() const &
Definition BLI_map.hh:884
void add_multiple(Span< Key > keys)
static ulong state[N]
#define G(x, y, z)
static void seq_prefetch_update_active_seqbase(PrefetchJob *pfjob)
Definition prefetch.cc:372
void prefetch_stop(Scene *scene)
Definition prefetch.cc:310
blender::Map< const Scene *, VectorSet< Strip * > > & lookup_strips_by_scene_map_get(Editing *ed)
static PrefetchJob * seq_prefetch_job_get(Scene *scene)
Definition prefetch.cc:90
ImBuf * render_give_ibuf(const RenderData *context, float timeline_frame, int chanshown)
Definition render.cc:2028
bool seq_prefetch_job_is_running(Scene *scene)
Definition prefetch.cc:98
ListBase * channels_displayed_get(const Editing *ed)
Definition channels.cc:28
bool prefetch_need_redraw(const bContext *C, Scene *scene)
Definition prefetch.cc:644
bool relations_render_loop_check(Strip *strip_main, Strip *strip)
static void seq_prefetch_update_depsgraph(PrefetchJob *pfjob)
Definition prefetch.cc:236
static bool seq_prefetch_must_skip_frame(PrefetchJob *pfjob, ListBase *channels, ListBase *seqbase)
Definition prefetch.cc:486
static void seq_prefetch_init_depsgraph(PrefetchJob *pfjob)
Definition prefetch.cc:243
float give_frame_index(const Scene *scene, const Strip *strip, float timeline_frame)
Definition strip_time.cc:52
Editing * editing_get(const Scene *scene)
Definition sequencer.cc:286
void seq_prefetch_free(Scene *scene)
Definition prefetch.cc:395
static PrefetchJob * seq_prefetch_start_ex(const RenderData *context, float cfra)
Definition prefetch.cc:576
@ SEQ_TASK_PREFETCH_RENDER
Definition SEQ_render.hh:28
static void seq_prefetch_resume(Scene *scene)
Definition prefetch.cc:386
static RenderData * get_original_context(const RenderData *context)
Definition prefetch.cc:155
static int seq_prefetch_cfra(PrefetchJob *pfjob)
Definition prefetch.cc:191
void seq_prefetch_start(const RenderData *context, float timeline_frame)
Definition prefetch.cc:619
MetaStack * meta_stack_active_get(const Editing *ed)
Definition sequencer.cc:454
static bool seq_prefetch_need_suspend(PrefetchJob *pfjob)
Definition prefetch.cc:496
void prefetch_stop_all()
Definition prefetch.cc:300
void render_new_render_data(Main *bmain, Depsgraph *depsgraph, Scene *scene, int rectx, int recty, eSpaceSeq_Proxy_RenderSize preview_render_size, Render *render, RenderData *r_context)
Definition render.cc:210
static void seq_prefetch_update_area(PrefetchJob *pfjob)
Definition prefetch.cc:262
static AnimationEvalContext seq_prefetch_anim_eval_context(PrefetchJob *pfjob)
Definition prefetch.cc:204
static bool seq_prefetch_job_is_waiting(Scene *scene)
Definition prefetch.cc:120
Scene * prefetch_get_original_scene_and_strip(const RenderData *context, const Strip *&strip)
Definition prefetch.cc:173
static blender::VectorSet< Strip * > query_scene_strips(Editing *ed)
Definition prefetch.cc:414
static void * seq_prefetch_frames(void *job)
Definition prefetch.cc:516
static void seq_prefetch_do_suspend(PrefetchJob *pfjob)
Definition prefetch.cc:502
static Strip * original_strip_get(const Strip *strip, ListBase *seqbase)
Definition prefetch.cc:131
bool evict_caches_if_full(Scene *scene)
static void seq_prefetch_update_context(const RenderData *context)
Definition prefetch.cc:326
ListBase * active_seqbase_get(const Editing *ed)
Definition sequencer.cc:433
Vector< Strip * > seq_shown_strips_get(const Scene *scene, ListBase *channels, ListBase *seqbase, const int timeline_frame, const int chanshown)
Definition render.cc:258
static void seq_prefetch_update_scene(Scene *scene)
Definition prefetch.cc:359
static bool seq_prefetch_scene_strip_is_rendered(const Scene *scene, ListBase *channels, ListBase *seqbase, blender::Span< Strip * > scene_strips, int timeline_frame, SeqRenderState state)
Definition prefetch.cc:426
static void seq_prefetch_job_scrubbing_set(Scene *scene, bool is_scrubbing)
Definition prefetch.cc:109
Scene * prefetch_get_original_scene(const RenderData *context)
Definition prefetch.cc:161
static void seq_prefetch_free_depsgraph(PrefetchJob *pfjob)
Definition prefetch.cc:227
void seq_prefetch_get_time_range(Scene *scene, int *r_start, int *r_end)
Definition prefetch.cc:209
static bool seq_prefetch_is_cache_full(Scene *scene)
Definition prefetch.cc:186
PrefetchJob * prefetch_job
Strip * current_meta_strip
struct Editing * ed
struct RenderData r
struct SequencerCacheOverlay cache_overlay
ListBase seqbase
char name[64]
struct wmTimer * animtimer
ThreadMutex prefetch_suspend_mutex
Definition prefetch.cc:64
ThreadCondition prefetch_suspend_cond
Definition prefetch.cc:65