[Bf-blender-cvs] [2b29bf25fca] master: Fix T69924: Prefetch stops when moving playhead Fix T70194: Prefetch freezes Blender in some cases

Richard Antalik noreply at git.blender.org
Wed Oct 2 22:53:44 CEST 2019


Commit: 2b29bf25fcaa22812a4656c2f4243c037b6b2bb2
Author: Richard Antalik
Date:   Wed Oct 2 13:04:48 2019 -0700
Branches: master
https://developer.blender.org/rB2b29bf25fcaa22812a4656c2f4243c037b6b2bb2

Fix T69924: Prefetch stops when moving playhead
Fix T70194: Prefetch freezes Blender in some cases

- Initialize depsgraph in isolated bmain struct.
- Fix prefetching range (forgot in initial prefetch commit).
- Fix crash - Add check if prefetch job is initialized and running.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D5899

===================================================================

M	source/blender/blenkernel/BKE_sequencer.h
M	source/blender/blenkernel/intern/seqcache.c
M	source/blender/blenkernel/intern/seqprefetch.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 16f766ae8bb..a5b223a73f2 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -351,6 +351,7 @@ void BKE_sequencer_prefetch_start(const SeqRenderData *context, float cfra, floa
 void BKE_sequencer_prefetch_stop(struct Scene *scene);
 void BKE_sequencer_prefetch_free(struct Scene *scene);
 bool BKE_sequencer_prefetch_need_redraw(struct Main *bmain, struct Scene *scene);
+bool BKE_sequencer_prefetch_job_is_running(struct Scene *scene);
 void BKE_sequencer_prefetch_get_time_range(struct Scene *scene, int *start, int *end);
 SeqRenderData *BKE_sequencer_prefetch_get_original_context(const SeqRenderData *context);
 struct Sequence *BKE_sequencer_prefetch_get_original_sequence(struct Sequence *seq,
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index d12710690df..ccb1869ee21 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -244,7 +244,8 @@ static SeqCacheKey *seq_cache_choose_key(Scene *scene, SeqCacheKey *lkey, SeqCac
    * We could use temp cache as a shield and later make it a non-temporary entry,
    * but it is not worth of increasing system complexity.
    */
-  if (scene->ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE) {
+  if (scene->ed->cache_flag & SEQ_CACHE_PREFETCH_ENABLE &&
+      BKE_sequencer_prefetch_job_is_running(scene)) {
     int pfjob_start, pfjob_end;
     BKE_sequencer_prefetch_get_time_range(scene, &pfjob_start, &pfjob_end);
 
diff --git a/source/blender/blenkernel/intern/seqprefetch.c b/source/blender/blenkernel/intern/seqprefetch.c
index c1109347e76..6dd1c47407f 100644
--- a/source/blender/blenkernel/intern/seqprefetch.c
+++ b/source/blender/blenkernel/intern/seqprefetch.c
@@ -31,6 +31,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_windowmanager_types.h"
+#include "DNA_anim_types.h"
 
 #include "BLI_listbase.h"
 #include "BLI_threads.h"
@@ -55,6 +56,7 @@ typedef struct PrefetchJob {
   struct PrefetchJob *next, *prev;
 
   struct Main *bmain;
+  struct Main *bmain_eval;
   struct Scene *scene;
   struct Scene *scene_eval;
   struct Depsgraph *depsgraph;
@@ -109,7 +111,7 @@ static PrefetchJob *seq_prefetch_job_get(Scene *scene)
   return NULL;
 }
 
-static bool seq_prefetch_job_is_running(Scene *scene)
+bool BKE_sequencer_prefetch_job_is_running(Scene *scene)
 {
   PrefetchJob *pfjob = seq_prefetch_job_get(scene);
 
@@ -185,12 +187,12 @@ static void seq_prefetch_free_depsgraph(PrefetchJob *pfjob)
 static void seq_prefetch_update_depsgraph(PrefetchJob *pfjob)
 {
   DEG_evaluate_on_framechange(
-      pfjob->bmain, pfjob->depsgraph, pfjob->cfra + pfjob->num_frames_prefetched);
+      pfjob->bmain_eval, pfjob->depsgraph, pfjob->cfra + pfjob->num_frames_prefetched);
 }
 
 static void seq_prefetch_init_depsgraph(PrefetchJob *pfjob)
 {
-  Main *bmain = pfjob->bmain;
+  Main *bmain = pfjob->bmain_eval;
   Scene *scene = pfjob->scene;
   ViewLayer *view_layer = BKE_view_layer_default_render(scene);
 
@@ -198,7 +200,7 @@ static void seq_prefetch_init_depsgraph(PrefetchJob *pfjob)
   DEG_debug_name_set(pfjob->depsgraph, "SEQUENCER PREFETCH");
 
   /* Make sure there is a correct evaluated scene pointer. */
-  DEG_graph_build_for_render_pipeline(pfjob->depsgraph, pfjob->bmain, scene, view_layer);
+  DEG_graph_build_for_render_pipeline(pfjob->depsgraph, bmain, scene, view_layer);
 
   /* Update immediately so we have proper evaluated scene. */
   seq_prefetch_update_depsgraph(pfjob);
@@ -229,7 +231,9 @@ static void seq_prefetch_update_area(PrefetchJob *pfjob)
   }
 }
 
-/* Use also to update scene and context changes */
+/* Use also to update scene and context changes
+ * This function should almost always be called by cache invalidation, not directly.
+ */
 void BKE_sequencer_prefetch_stop(Scene *scene)
 {
   PrefetchJob *pfjob;
@@ -251,7 +255,7 @@ static void seq_prefetch_update_context(const SeqRenderData *context)
   PrefetchJob *pfjob;
   pfjob = seq_prefetch_job_get(context->scene);
 
-  BKE_sequencer_new_render_data(pfjob->bmain,
+  BKE_sequencer_new_render_data(pfjob->bmain_eval,
                                 pfjob->depsgraph,
                                 pfjob->scene_eval,
                                 context->rectx,
@@ -314,6 +318,7 @@ void BKE_sequencer_prefetch_free(Scene *scene)
   BLI_mutex_end(&pfjob->prefetch_suspend_mutex);
   BLI_condition_end(&pfjob->prefetch_suspend_cond);
   seq_prefetch_free_depsgraph(pfjob);
+  BKE_main_free(pfjob->bmain_eval);
   MEM_freeN(pfjob);
   scene->ed->prefetch_job = NULL;
 }
@@ -322,16 +327,26 @@ static void *seq_prefetch_frames(void *job)
 {
   PrefetchJob *pfjob = (PrefetchJob *)job;
 
-  /* set to NULL before return! */
-  pfjob->scene_eval->ed->prefetch_job = pfjob;
+  while (pfjob->cfra + pfjob->num_frames_prefetched <= pfjob->scene->r.efra) {
+    pfjob->scene_eval->ed->prefetch_job = NULL;
 
-  while (pfjob->cfra + pfjob->num_frames_prefetched < pfjob->scene->r.efra) {
-    BKE_animsys_evaluate_all_animation(pfjob->context_cpy.bmain,
-                                       pfjob->context_cpy.depsgraph,
-                                       pfjob->context_cpy.scene,
-                                       pfjob->cfra + pfjob->num_frames_prefetched);
+    AnimData *adt = BKE_animdata_from_id(&pfjob->context_cpy.scene->id);
+    BKE_animsys_evaluate_animdata(pfjob->context_cpy.scene,
+                                  &pfjob->context_cpy.scene->id,
+                                  adt,
+                                  pfjob->cfra + pfjob->num_frames_prefetched,
+                                  ADT_RECALC_ALL,
+                                  false);
     seq_prefetch_update_depsgraph(pfjob);
 
+    /* This is quite hacky solution:
+     * 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.
+     * Scene copy don't reference original scene. Perhaps, this could be done by depsgraph.
+     * Set to NULL before return!
+     */
+    pfjob->scene_eval->ed->prefetch_job = pfjob;
+
     ImBuf *ibuf = BKE_sequencer_give_ibuf(
         &pfjob->context_cpy, pfjob->cfra + pfjob->num_frames_prefetched, 0);
     BKE_sequencer_cache_free_temp_cache(
@@ -373,8 +388,7 @@ static void *seq_prefetch_frames(void *job)
 
 static PrefetchJob *seq_prefetch_start(const SeqRenderData *context, float cfra)
 {
-  PrefetchJob *pfjob;
-  pfjob = seq_prefetch_job_get(context->scene);
+  PrefetchJob *pfjob = seq_prefetch_job_get(context->scene);
 
   if (!pfjob) {
     if (context->scene->ed) {
@@ -386,6 +400,7 @@ static PrefetchJob *seq_prefetch_start(const SeqRenderData *context, float cfra)
       BLI_condition_init(&pfjob->prefetch_suspend_cond);
 
       pfjob->bmain = context->bmain;
+      pfjob->bmain_eval = BKE_main_new();
 
       pfjob->scene = context->scene;
       seq_prefetch_init_depsgraph(pfjob);
@@ -419,7 +434,7 @@ void BKE_sequencer_prefetch_start(const SeqRenderData *context, float cfra, floa
   if (!context->is_prefetch_render && !context->is_proxy_render) {
     bool playing = seq_prefetch_is_playing(context->bmain);
     bool scrubbing = seq_prefetch_is_scrubbing(context->bmain);
-    bool running = seq_prefetch_job_is_running(scene);
+    bool running = BKE_sequencer_prefetch_job_is_running(scene);
     seq_prefetch_resume(scene);
     /* conditions to start:
      * prefetch enabled, prefetch not running, not scrubbing,
@@ -437,7 +452,7 @@ bool BKE_sequencer_prefetch_need_redraw(Main *bmain, Scene *scene)
 {
   bool playing = seq_prefetch_is_playing(bmain);
   bool scrubbing = seq_prefetch_is_scrubbing(bmain);
-  bool running = seq_prefetch_job_is_running(scene);
+  bool running = BKE_sequencer_prefetch_job_is_running(scene);
   bool suspended = seq_prefetch_job_is_waiting(scene);
 
   /* force redraw, when prefetching and using cache view. */



More information about the Bf-blender-cvs mailing list