Changeset View
Changeset View
Standalone View
Standalone View
source/blender/sequencer/intern/prefetch.c
| Show First 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "DEG_depsgraph_build.h" | #include "DEG_depsgraph_build.h" | ||||
| #include "DEG_depsgraph_debug.h" | #include "DEG_depsgraph_debug.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| #include "SEQ_iterator.h" | |||||
| #include "SEQ_prefetch.h" | #include "SEQ_prefetch.h" | ||||
| #include "SEQ_relations.h" | |||||
| #include "SEQ_render.h" | #include "SEQ_render.h" | ||||
| #include "SEQ_sequencer.h" | #include "SEQ_sequencer.h" | ||||
| #include "image_cache.h" | #include "image_cache.h" | ||||
| #include "prefetch.h" | #include "prefetch.h" | ||||
| #include "render.h" | #include "render.h" | ||||
| typedef struct PrefetchJob { | typedef struct PrefetchJob { | ||||
| ▲ Show 20 Lines • Show All 289 Lines • ▼ Show 20 Lines | void seq_prefetch_free(Scene *scene) | ||||
| BLI_mutex_end(&pfjob->prefetch_suspend_mutex); | BLI_mutex_end(&pfjob->prefetch_suspend_mutex); | ||||
| BLI_condition_end(&pfjob->prefetch_suspend_cond); | BLI_condition_end(&pfjob->prefetch_suspend_cond); | ||||
| seq_prefetch_free_depsgraph(pfjob); | seq_prefetch_free_depsgraph(pfjob); | ||||
| BKE_main_free(pfjob->bmain_eval); | BKE_main_free(pfjob->bmain_eval); | ||||
| MEM_freeN(pfjob); | MEM_freeN(pfjob); | ||||
| scene->ed->prefetch_job = NULL; | scene->ed->prefetch_job = NULL; | ||||
| } | } | ||||
| /* Skip frame if we need to render 3D scene strip. Rendering 3D scene requires main lock or setting | static bool seq_prefetch_seq_has_disk_cache(PrefetchJob *pfjob, | ||||
| * up render job that doesn't have API to do openGL renders which can be used for sequencer. */ | Sequence *seq, | ||||
| static bool seq_prefetch_do_skip_frame(PrefetchJob *pfjob, ListBase *seqbase) | bool can_have_final_image) | ||||
| { | { | ||||
| float cfra = seq_prefetch_cfra(pfjob); | |||||
| Sequence *seq_arr[MAXSEQ + 1]; | |||||
| int count = seq_get_shown_sequences(seqbase, cfra, 0, seq_arr); | |||||
| SeqRenderData *ctx = &pfjob->context_cpy; | SeqRenderData *ctx = &pfjob->context_cpy; | ||||
| ImBuf *ibuf = NULL; | float cfra = seq_prefetch_cfra(pfjob); | ||||
| /* Disable prefetching 3D scene strips, but check for disk cache. */ | ImBuf *ibuf = seq_cache_get(ctx, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED); | ||||
| for (int i = 0; i < count; i++) { | if (ibuf != NULL) { | ||||
| if (seq_arr[i]->type == SEQ_TYPE_META && | IMB_freeImBuf(ibuf); | ||||
| seq_prefetch_do_skip_frame(pfjob, &seq_arr[i]->seqbase)) { | |||||
| return true; | return true; | ||||
| } | } | ||||
| if (seq_arr[i]->type == SEQ_TYPE_SCENE && (seq_arr[i]->flag & SEQ_SCENE_STRIPS) == 0) { | ibuf = seq_cache_get(ctx, seq, cfra, SEQ_CACHE_STORE_RAW); | ||||
| int cached_types = 0; | |||||
| ibuf = seq_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_FINAL_OUT); | |||||
| if (ibuf != NULL) { | if (ibuf != NULL) { | ||||
| cached_types |= SEQ_CACHE_STORE_FINAL_OUT; | |||||
| IMB_freeImBuf(ibuf); | IMB_freeImBuf(ibuf); | ||||
| ibuf = NULL; | return true; | ||||
| } | } | ||||
| ibuf = seq_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_COMPOSITE); | if (!can_have_final_image) { | ||||
| if (ibuf != NULL) { | return false; | ||||
| cached_types |= SEQ_CACHE_STORE_COMPOSITE; | |||||
| IMB_freeImBuf(ibuf); | |||||
| ibuf = NULL; | |||||
| } | } | ||||
| ibuf = seq_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_PREPROCESSED); | ibuf = seq_cache_get(ctx, seq, cfra, SEQ_CACHE_STORE_FINAL_OUT); | ||||
| if (ibuf != NULL) { | if (ibuf != NULL) { | ||||
| cached_types |= SEQ_CACHE_STORE_PREPROCESSED; | |||||
| IMB_freeImBuf(ibuf); | IMB_freeImBuf(ibuf); | ||||
| ibuf = NULL; | return true; | ||||
| } | } | ||||
| ibuf = seq_cache_get(ctx, seq_arr[i], cfra, SEQ_CACHE_STORE_RAW); | return false; | ||||
| if (ibuf != NULL) { | |||||
| cached_types |= SEQ_CACHE_STORE_RAW; | |||||
| IMB_freeImBuf(ibuf); | |||||
| ibuf = NULL; | |||||
| } | } | ||||
| if ((cached_types & (SEQ_CACHE_STORE_RAW | SEQ_CACHE_STORE_PREPROCESSED)) != 0) { | static bool seq_prefetch_scene_strip_is_rendered(PrefetchJob *pfjob, | ||||
| continue; | ListBase *seqbase, | ||||
| SeqCollection *scene_strips, | |||||
| bool is_recursive_check) | |||||
| { | |||||
| float cfra = seq_prefetch_cfra(pfjob); | |||||
| Sequence *seq_arr[MAXSEQ + 1]; | |||||
| int count = seq_get_shown_sequences(seqbase, cfra, 0, seq_arr); | |||||
| /* Iterate over rendered strips. */ | |||||
| for (int i = 0; i < count; i++) { | |||||
| Sequence *seq = seq_arr[i]; | |||||
| if (seq->type == SEQ_TYPE_META && | |||||
| seq_prefetch_scene_strip_is_rendered(pfjob, &seq->seqbase, scene_strips, true)) { | |||||
| return true; | |||||
| } | } | ||||
| /* It is only safe to use these cache types if strip is last in stack. */ | /* Disable prefetching 3D scene strips, but check for disk cache. */ | ||||
| if (i == count - 1 && (cached_types & SEQ_CACHE_STORE_FINAL_OUT) != 0) { | if (seq->type == SEQ_TYPE_SCENE && (seq->flag & SEQ_SCENE_STRIPS) == 0 && | ||||
| continue; | !seq_prefetch_seq_has_disk_cache(pfjob, seq, !is_recursive_check)) { | ||||
| return true; | |||||
| } | } | ||||
| /* Check if strip is effect of scene strip or uses it as modifier. This is recursive check. */ | |||||
| Sequence *seq_scene; | |||||
| SEQ_ITERATOR_FOREACH (seq_scene, scene_strips) { | |||||
| if (SEQ_relations_render_loop_check(seq, seq_scene)) { | |||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| return false; | |||||
| } | |||||
| static SeqCollection *query_scene_strips(ListBase *seqbase) | |||||
| { | |||||
| SeqCollection *collection = SEQ_query_all_strips_recursive(seqbase); | |||||
| LISTBASE_FOREACH (Sequence *, seq, seqbase) { | |||||
| if (seq->type != SEQ_TYPE_SCENE || (seq->flag & SEQ_SCENE_STRIPS) != 0) { | |||||
| SEQ_collection_remove_strip(seq, collection); | |||||
| } | |||||
| } | |||||
| return collection; | |||||
| } | |||||
| /* Prefetch must avoid rendering scene strips, because rendering in background locks UI and can | |||||
| * make it unresponsive for long time periods. */ | |||||
| static bool seq_prefetch_must_skip_frame(PrefetchJob *pfjob, ListBase *seqbase) | |||||
| { | |||||
| SeqCollection *scene_strips = query_scene_strips(seqbase); | |||||
| if (seq_prefetch_scene_strip_is_rendered(pfjob, seqbase, scene_strips, false)) { | |||||
| return true; | |||||
| } | |||||
| return false; | return false; | ||||
| } | } | ||||
| static bool seq_prefetch_need_suspend(PrefetchJob *pfjob) | static bool seq_prefetch_need_suspend(PrefetchJob *pfjob) | ||||
| { | { | ||||
| return seq_prefetch_is_cache_full(pfjob->scene) || seq_prefetch_is_scrubbing(pfjob->bmain) || | return seq_prefetch_is_cache_full(pfjob->scene) || seq_prefetch_is_scrubbing(pfjob->bmain) || | ||||
| (seq_prefetch_cfra(pfjob) >= pfjob->scene->r.efra); | (seq_prefetch_cfra(pfjob) >= pfjob->scene->r.efra); | ||||
| } | } | ||||
| Show All 28 Lines | while (seq_prefetch_cfra(pfjob) <= pfjob->scene->r.efra) { | ||||
| * We need cross-reference original scene with copy for cache. | * We need cross-reference original scene with copy for cache. | ||||
| * However depsgraph must not have this data, because it will try to kill this job. | * However depsgraph must not have this data, because it will try to kill this job. | ||||
| * Scene copy don't reference original scene. Perhaps, this could be done by depsgraph. | * Scene copy don't reference original scene. Perhaps, this could be done by depsgraph. | ||||
| * Set to NULL before return! | * Set to NULL before return! | ||||
| */ | */ | ||||
| pfjob->scene_eval->ed->prefetch_job = pfjob; | pfjob->scene_eval->ed->prefetch_job = pfjob; | ||||
| ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(pfjob->scene, false)); | ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(pfjob->scene, false)); | ||||
| if (seq_prefetch_do_skip_frame(pfjob, seqbase)) { | if (seq_prefetch_must_skip_frame(pfjob, seqbase)) { | ||||
| pfjob->num_frames_prefetched++; | pfjob->num_frames_prefetched++; | ||||
| continue; | continue; | ||||
| } | } | ||||
| ImBuf *ibuf = SEQ_render_give_ibuf(&pfjob->context_cpy, seq_prefetch_cfra(pfjob), 0); | ImBuf *ibuf = SEQ_render_give_ibuf(&pfjob->context_cpy, seq_prefetch_cfra(pfjob), 0); | ||||
| seq_cache_free_temp_cache(pfjob->scene, pfjob->context.task_id, seq_prefetch_cfra(pfjob)); | seq_cache_free_temp_cache(pfjob->scene, pfjob->context.task_id, seq_prefetch_cfra(pfjob)); | ||||
| IMB_freeImBuf(ibuf); | IMB_freeImBuf(ibuf); | ||||
| ▲ Show 20 Lines • Show All 103 Lines • Show Last 20 Lines | |||||