1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup bke
22 */
23
24 #include <stddef.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "MEM_guardedalloc.h"
29
30 #include "DNA_anim_types.h"
31 #include "DNA_scene_types.h"
32 #include "DNA_screen_types.h"
33 #include "DNA_sequence_types.h"
34 #include "DNA_windowmanager_types.h"
35
36 #include "BLI_listbase.h"
37 #include "BLI_threads.h"
38
39 #include "IMB_imbuf.h"
40 #include "IMB_imbuf_types.h"
41
42 #include "BKE_anim_data.h"
43 #include "BKE_animsys.h"
44 #include "BKE_context.h"
45 #include "BKE_global.h"
46 #include "BKE_layer.h"
47 #include "BKE_lib_id.h"
48 #include "BKE_main.h"
49 #include "BKE_scene.h"
50 #include "BKE_sequencer.h"
51
52 #include "DEG_depsgraph.h"
53 #include "DEG_depsgraph_build.h"
54 #include "DEG_depsgraph_debug.h"
55 #include "DEG_depsgraph_query.h"
56
57 typedef struct PrefetchJob {
58 struct PrefetchJob *next, *prev;
59
60 struct Main *bmain;
61 struct Main *bmain_eval;
62 struct Scene *scene;
63 struct Scene *scene_eval;
64 struct Depsgraph *depsgraph;
65
66 ThreadMutex prefetch_suspend_mutex;
67 ThreadCondition prefetch_suspend_cond;
68
69 ListBase threads;
70
71 /* context */
72 struct SeqRenderData context;
73 struct SeqRenderData context_cpy;
74 struct ListBase *seqbasep;
75 struct ListBase *seqbasep_cpy;
76
77 /* prefetch area */
78 float cfra;
79 int num_frames_prefetched;
80
81 /* control */
82 bool running;
83 bool waiting;
84 bool stop;
85 } PrefetchJob;
86
seq_prefetch_is_playing(Main * bmain)87 static bool seq_prefetch_is_playing(Main *bmain)
88 {
89 for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
90 if (screen->animtimer) {
91 return true;
92 }
93 }
94 return false;
95 }
96
seq_prefetch_is_scrubbing(Main * bmain)97 static bool seq_prefetch_is_scrubbing(Main *bmain)
98 {
99
100 for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
101 if (screen->scrubbing) {
102 return true;
103 }
104 }
105 return false;
106 }
107
seq_prefetch_job_get(Scene * scene)108 static PrefetchJob *seq_prefetch_job_get(Scene *scene)
109 {
110 if (scene && scene->ed) {
111 return scene->ed->prefetch_job;
112 }
113 return NULL;
114 }
115
BKE_sequencer_prefetch_job_is_running(Scene * scene)116 bool BKE_sequencer_prefetch_job_is_running(Scene *scene)
117 {
118 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
119
120 if (!pfjob) {
121 return false;
122 }
123
124 return pfjob->running;
125 }
126
seq_prefetch_job_is_waiting(Scene * scene)127 static bool seq_prefetch_job_is_waiting(Scene *scene)
128 {
129 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
130
131 if (!pfjob) {
132 return false;
133 }
134
135 return pfjob->waiting;
136 }
137
sequencer_prefetch_get_original_sequence(Sequence * seq,ListBase * seqbase)138 static Sequence *sequencer_prefetch_get_original_sequence(Sequence *seq, ListBase *seqbase)
139 {
140 LISTBASE_FOREACH (Sequence *, seq_orig, seqbase) {
141 if (STREQ(seq->name, seq_orig->name)) {
142 return seq_orig;
143 }
144
145 if (seq_orig->type == SEQ_TYPE_META) {
146 Sequence *match = sequencer_prefetch_get_original_sequence(seq, &seq_orig->seqbase);
147 if (match != NULL) {
148 return match;
149 }
150 }
151 }
152
153 return NULL;
154 }
155
156 /* for cache context swapping */
BKE_sequencer_prefetch_get_original_sequence(Sequence * seq,Scene * scene)157 Sequence *BKE_sequencer_prefetch_get_original_sequence(Sequence *seq, Scene *scene)
158 {
159 Editing *ed = scene->ed;
160 return sequencer_prefetch_get_original_sequence(seq, &ed->seqbase);
161 }
162
163 /* for cache context swapping */
BKE_sequencer_prefetch_get_original_context(const SeqRenderData * context)164 SeqRenderData *BKE_sequencer_prefetch_get_original_context(const SeqRenderData *context)
165 {
166 PrefetchJob *pfjob = seq_prefetch_job_get(context->scene);
167
168 return &pfjob->context;
169 }
170
seq_prefetch_is_cache_full(Scene * scene)171 static bool seq_prefetch_is_cache_full(Scene *scene)
172 {
173 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
174
175 if (!BKE_sequencer_cache_is_full(pfjob->scene)) {
176 return false;
177 }
178
179 return BKE_sequencer_cache_recycle_item(pfjob->scene) == false;
180 }
181
seq_prefetch_cfra(PrefetchJob * pfjob)182 static float seq_prefetch_cfra(PrefetchJob *pfjob)
183 {
184 return pfjob->cfra + pfjob->num_frames_prefetched;
185 }
seq_prefetch_anim_eval_context(PrefetchJob * pfjob)186 static AnimationEvalContext seq_prefetch_anim_eval_context(PrefetchJob *pfjob)
187 {
188 return BKE_animsys_eval_context_construct(pfjob->depsgraph, seq_prefetch_cfra(pfjob));
189 }
190
BKE_sequencer_prefetch_get_time_range(Scene * scene,int * start,int * end)191 void BKE_sequencer_prefetch_get_time_range(Scene *scene, int *start, int *end)
192 {
193 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
194
195 *start = pfjob->cfra;
196 *end = seq_prefetch_cfra(pfjob);
197 }
198
seq_prefetch_free_depsgraph(PrefetchJob * pfjob)199 static void seq_prefetch_free_depsgraph(PrefetchJob *pfjob)
200 {
201 if (pfjob->depsgraph != NULL) {
202 DEG_graph_free(pfjob->depsgraph);
203 }
204 pfjob->depsgraph = NULL;
205 pfjob->scene_eval = NULL;
206 }
207
seq_prefetch_update_depsgraph(PrefetchJob * pfjob)208 static void seq_prefetch_update_depsgraph(PrefetchJob *pfjob)
209 {
210 DEG_evaluate_on_framechange(pfjob->depsgraph, seq_prefetch_cfra(pfjob));
211 }
212
seq_prefetch_init_depsgraph(PrefetchJob * pfjob)213 static void seq_prefetch_init_depsgraph(PrefetchJob *pfjob)
214 {
215 Main *bmain = pfjob->bmain_eval;
216 Scene *scene = pfjob->scene;
217 ViewLayer *view_layer = BKE_view_layer_default_render(scene);
218
219 pfjob->depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
220 DEG_debug_name_set(pfjob->depsgraph, "SEQUENCER PREFETCH");
221
222 /* Make sure there is a correct evaluated scene pointer. */
223 DEG_graph_build_for_render_pipeline(pfjob->depsgraph);
224
225 /* Update immediately so we have proper evaluated scene. */
226 seq_prefetch_update_depsgraph(pfjob);
227
228 pfjob->scene_eval = DEG_get_evaluated_scene(pfjob->depsgraph);
229 pfjob->scene_eval->ed->cache_flag = 0;
230 }
231
seq_prefetch_update_area(PrefetchJob * pfjob)232 static void seq_prefetch_update_area(PrefetchJob *pfjob)
233 {
234 int cfra = pfjob->scene->r.cfra;
235
236 /* rebase */
237 if (cfra > pfjob->cfra) {
238 int delta = cfra - pfjob->cfra;
239 pfjob->cfra = cfra;
240 pfjob->num_frames_prefetched -= delta;
241
242 if (pfjob->num_frames_prefetched <= 1) {
243 pfjob->num_frames_prefetched = 1;
244 }
245 }
246
247 /* reset */
248 if (cfra < pfjob->cfra) {
249 pfjob->cfra = cfra;
250 pfjob->num_frames_prefetched = 1;
251 }
252 }
253
BKE_sequencer_prefetch_stop_all(void)254 void BKE_sequencer_prefetch_stop_all(void)
255 {
256 /*TODO(Richard): Use wm_jobs for prefetch, or pass main. */
257 for (Scene *scene = G.main->scenes.first; scene; scene = scene->id.next) {
258 BKE_sequencer_prefetch_stop(scene);
259 }
260 }
261
262 /* Use also to update scene and context changes
263 * This function should almost always be called by cache invalidation, not directly.
264 */
BKE_sequencer_prefetch_stop(Scene * scene)265 void BKE_sequencer_prefetch_stop(Scene *scene)
266 {
267 PrefetchJob *pfjob;
268 pfjob = seq_prefetch_job_get(scene);
269
270 if (!pfjob) {
271 return;
272 }
273
274 pfjob->stop = true;
275
276 while (pfjob->running) {
277 BLI_condition_notify_one(&pfjob->prefetch_suspend_cond);
278 }
279 }
280
seq_prefetch_update_context(const SeqRenderData * context)281 static void seq_prefetch_update_context(const SeqRenderData *context)
282 {
283 PrefetchJob *pfjob;
284 pfjob = seq_prefetch_job_get(context->scene);
285
286 BKE_sequencer_new_render_data(pfjob->bmain_eval,
287 pfjob->depsgraph,
288 pfjob->scene_eval,
289 context->rectx,
290 context->recty,
291 context->preview_render_size,
292 false,
293 &pfjob->context_cpy);
294 pfjob->context_cpy.is_prefetch_render = true;
295 pfjob->context_cpy.task_id = SEQ_TASK_PREFETCH_RENDER;
296
297 BKE_sequencer_new_render_data(pfjob->bmain,
298 pfjob->depsgraph,
299 pfjob->scene,
300 context->rectx,
301 context->recty,
302 context->preview_render_size,
303 false,
304 &pfjob->context);
305 pfjob->context.is_prefetch_render = false;
306
307 /* Same ID as prefetch context, because context will be swapped, but we still
308 * want to assign this ID to cache entries created in this thread.
309 * This is to allow "temp cache" work correctly for both threads.
310 */
311 pfjob->context.task_id = SEQ_TASK_PREFETCH_RENDER;
312 }
313
seq_prefetch_update_scene(Scene * scene)314 static void seq_prefetch_update_scene(Scene *scene)
315 {
316 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
317
318 if (!pfjob) {
319 return;
320 }
321
322 pfjob->scene = scene;
323 seq_prefetch_free_depsgraph(pfjob);
324 seq_prefetch_init_depsgraph(pfjob);
325 }
326
seq_prefetch_resume(Scene * scene)327 static void seq_prefetch_resume(Scene *scene)
328 {
329 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
330
331 if (pfjob && pfjob->waiting) {
332 BLI_condition_notify_one(&pfjob->prefetch_suspend_cond);
333 }
334 }
335
BKE_sequencer_prefetch_free(Scene * scene)336 void BKE_sequencer_prefetch_free(Scene *scene)
337 {
338 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
339 if (!pfjob) {
340 return;
341 }
342
343 BKE_sequencer_prefetch_stop(scene);
344
345 BLI_threadpool_remove(&pfjob->threads, pfjob);
346 BLI_threadpool_end(&pfjob->threads);
347 BLI_mutex_end(&pfjob->prefetch_suspend_mutex);
348 BLI_condition_end(&pfjob->prefetch_suspend_cond);
349 seq_prefetch_free_depsgraph(pfjob);
350 BKE_main_free(pfjob->bmain_eval);
351 MEM_freeN(pfjob);
352 scene->ed->prefetch_job = NULL;
353 }
354
seq_prefetch_do_skip_frame(Scene * scene)355 static bool seq_prefetch_do_skip_frame(Scene *scene)
356 {
357 Editing *ed = scene->ed;
358 PrefetchJob *pfjob = seq_prefetch_job_get(scene);
359 float cfra = seq_prefetch_cfra(pfjob);
360 Sequence *seq_arr[MAXSEQ + 1];
361 int count = BKE_sequencer_get_shown_sequences(ed->seqbasep, cfra, 0, seq_arr);
362 SeqRenderData *ctx = &pfjob->context_cpy;
363 ImBuf *ibuf = NULL;
364
365 /* Disable prefetching 3D scene strips, but check for disk cache. */
366 for (int i = 0; i < count; i++) {
367 if (seq_arr[i]->type == SEQ_TYPE_SCENE && (seq_arr[i]->flag & SEQ_SCENE_STRIPS) == 0) {
368 int cached_types = 0;
369
370 ibuf = BKE_sequencer_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_FINAL_OUT, false);
371 if (ibuf != NULL) {
372 cached_types |= SEQ_CACHE_STORE_FINAL_OUT;
373 IMB_freeImBuf(ibuf);
374 ibuf = NULL;
375 }
376
377 ibuf = BKE_sequencer_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_FINAL_OUT, false);
378 if (ibuf != NULL) {
379 cached_types |= SEQ_CACHE_STORE_COMPOSITE;
380 IMB_freeImBuf(ibuf);
381 ibuf = NULL;
382 }
383
384 ibuf = BKE_sequencer_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_PREPROCESSED, false);
385 if (ibuf != NULL) {
386 cached_types |= SEQ_CACHE_STORE_PREPROCESSED;
387 IMB_freeImBuf(ibuf);
388 ibuf = NULL;
389 }
390
391 ibuf = BKE_sequencer_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_RAW, false);
392 if (ibuf != NULL) {
393 cached_types |= SEQ_CACHE_STORE_RAW;
394 IMB_freeImBuf(ibuf);
395 ibuf = NULL;
396 }
397
398 if ((cached_types & (SEQ_CACHE_STORE_RAW | SEQ_CACHE_STORE_PREPROCESSED)) != 0) {
399 continue;
400 }
401
402 /* It is only safe to use these cache types if strip is last in stack. */
403 if (i == count - 1 &&
404 (cached_types & (SEQ_CACHE_STORE_PREPROCESSED | SEQ_CACHE_STORE_RAW)) != 0) {
405 continue;
406 }
407
408 return true;
409 }
410 }
411
412 return false;
413 }
414
seq_prefetch_need_suspend(PrefetchJob * pfjob)415 static bool seq_prefetch_need_suspend(PrefetchJob *pfjob)
416 {
417 return seq_prefetch_is_cache_full(pfjob->scene) || seq_prefetch_is_scrubbing(pfjob->bmain) ||
418 (seq_prefetch_cfra(pfjob) >= pfjob->scene->r.efra);
419 }
420
seq_prefetch_do_suspend(PrefetchJob * pfjob)421 static void seq_prefetch_do_suspend(PrefetchJob *pfjob)
422 {
423 BLI_mutex_lock(&pfjob->prefetch_suspend_mutex);
424 while (seq_prefetch_need_suspend(pfjob) &&
425 (pfjob->scene->ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) && !pfjob->stop) {
426 pfjob->waiting = true;
427 BLI_condition_wait(&pfjob->prefetch_suspend_cond, &pfjob->prefetch_suspend_mutex);
428 seq_prefetch_update_area(pfjob);
429 }
430 pfjob->waiting = false;
431 BLI_mutex_unlock(&pfjob->prefetch_suspend_mutex);
432 }
433
seq_prefetch_frames(void * job)434 static void *seq_prefetch_frames(void *job)
435 {
436 PrefetchJob *pfjob = (PrefetchJob *)job;
437
438 while (seq_prefetch_cfra(pfjob) <= pfjob->scene->r.efra) {
439 pfjob->scene_eval->ed->prefetch_job = NULL;
440
441 seq_prefetch_update_depsgraph(pfjob);
442 AnimData *adt = BKE_animdata_from_id(&pfjob->context_cpy.scene->id);
443 AnimationEvalContext anim_eval_context = seq_prefetch_anim_eval_context(pfjob);
444 BKE_animsys_evaluate_animdata(
445 &pfjob->context_cpy.scene->id, adt, &anim_eval_context, ADT_RECALC_ALL, false);
446
447 /* This is quite hacky solution:
448 * We need cross-reference original scene with copy for cache.
449 * However depsgraph must not have this data, because it will try to kill this job.
450 * Scene copy don't reference original scene. Perhaps, this could be done by depsgraph.
451 * Set to NULL before return!
452 */
453 pfjob->scene_eval->ed->prefetch_job = pfjob;
454
455 if (seq_prefetch_do_skip_frame(pfjob->scene)) {
456 pfjob->num_frames_prefetched++;
457 continue;
458 }
459
460 ImBuf *ibuf = BKE_sequencer_give_ibuf(&pfjob->context_cpy, seq_prefetch_cfra(pfjob), 0);
461 BKE_sequencer_cache_free_temp_cache(
462 pfjob->scene, pfjob->context.task_id, seq_prefetch_cfra(pfjob));
463 IMB_freeImBuf(ibuf);
464
465 /* Suspend thread if there is nothing to be prefetched. */
466 seq_prefetch_do_suspend(pfjob);
467
468 /* Avoid "collision" with main thread, but make sure to fetch at least few frames */
469 if (pfjob->num_frames_prefetched > 5 &&
470 (seq_prefetch_cfra(pfjob) - pfjob->scene->r.cfra) < 2) {
471 break;
472 }
473
474 if (!(pfjob->scene->ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) || pfjob->stop) {
475 break;
476 }
477
478 seq_prefetch_update_area(pfjob);
479 pfjob->num_frames_prefetched++;
480 }
481
482 BKE_sequencer_cache_free_temp_cache(
483 pfjob->scene, pfjob->context.task_id, seq_prefetch_cfra(pfjob));
484 pfjob->running = false;
485 pfjob->scene_eval->ed->prefetch_job = NULL;
486
487 return NULL;
488 }
489
seq_prefetch_start(const SeqRenderData * context,float cfra)490 static PrefetchJob *seq_prefetch_start(const SeqRenderData *context, float cfra)
491 {
492 PrefetchJob *pfjob = seq_prefetch_job_get(context->scene);
493
494 if (!pfjob) {
495 if (context->scene->ed) {
496 pfjob = (PrefetchJob *)MEM_callocN(sizeof(PrefetchJob), "PrefetchJob");
497 context->scene->ed->prefetch_job = pfjob;
498
499 BLI_threadpool_init(&pfjob->threads, seq_prefetch_frames, 1);
500 BLI_mutex_init(&pfjob->prefetch_suspend_mutex);
501 BLI_condition_init(&pfjob->prefetch_suspend_cond);
502
503 pfjob->bmain_eval = BKE_main_new();
504 pfjob->scene = context->scene;
505 seq_prefetch_init_depsgraph(pfjob);
506 }
507 }
508 pfjob->bmain = context->bmain;
509
510 pfjob->cfra = cfra;
511 pfjob->num_frames_prefetched = 1;
512
513 pfjob->waiting = false;
514 pfjob->stop = false;
515 pfjob->running = true;
516
517 seq_prefetch_update_scene(context->scene);
518 seq_prefetch_update_context(context);
519
520 BLI_threadpool_remove(&pfjob->threads, pfjob);
521 BLI_threadpool_insert(&pfjob->threads, pfjob);
522
523 return pfjob;
524 }
525
526 /* Start or resume prefetching*/
BKE_sequencer_prefetch_start(const SeqRenderData * context,float cfra,float cost)527 void BKE_sequencer_prefetch_start(const SeqRenderData *context, float cfra, float cost)
528 {
529 Scene *scene = context->scene;
530 Editing *ed = scene->ed;
531 bool has_strips = (bool)ed->seqbasep->first;
532
533 if (!context->is_prefetch_render && !context->is_proxy_render) {
534 bool playing = seq_prefetch_is_playing(context->bmain);
535 bool scrubbing = seq_prefetch_is_scrubbing(context->bmain);
536 bool running = BKE_sequencer_prefetch_job_is_running(scene);
537 seq_prefetch_resume(scene);
538 /* conditions to start:
539 * prefetch enabled, prefetch not running, not scrubbing,
540 * not playing and rendering-expensive footage, cache storage enabled, has strips to render,
541 * not rendering, not doing modal transform - important, see D7820.
542 */
543 if ((ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) && !running && !scrubbing &&
544 !(playing && cost > 0.9) && ed->cache_flag & SEQ_CACHE_ALL_TYPES && has_strips &&
545 !G.is_rendering && !G.moving) {
546
547 seq_prefetch_start(context, cfra);
548 }
549 }
550 }
551
BKE_sequencer_prefetch_need_redraw(Main * bmain,Scene * scene)552 bool BKE_sequencer_prefetch_need_redraw(Main *bmain, Scene *scene)
553 {
554 bool playing = seq_prefetch_is_playing(bmain);
555 bool scrubbing = seq_prefetch_is_scrubbing(bmain);
556 bool running = BKE_sequencer_prefetch_job_is_running(scene);
557 bool suspended = seq_prefetch_job_is_waiting(scene);
558
559 /* force redraw, when prefetching and using cache view. */
560 if (running && !playing && !suspended && scene->ed->cache_flag & SEQ_CACHE_VIEW_ENABLE) {
561 return true;
562 }
563 /* Sometimes scrubbing flag is set when not scrubbing. In that case I want to catch "event" of
564 * stopping scrubbing */
565 if (scrubbing) {
566 return true;
567 }
568 return false;
569 }
570