Sequencer: initial support of refreshing only changed sequences
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 8 Aug 2012 16:46:40 +0000 (16:46 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 8 Aug 2012 16:46:40 +0000 (16:46 +0000)
Before this the the whole sequencer cache would be invalidated
when hanging sequence settings.

This was completely annoying because changing color balance
settings would re-load image file for which color balance
is happening on every change,

In fact it's still an issue if color balance is changing for
image strip itself, but if this strip has got effect and
color balance is changing for it file wouldn't be reloaded.

source/blender/blenkernel/BKE_sequencer.h
source/blender/blenkernel/intern/seqcache.c
source/blender/blenkernel/intern/sequencer.c
source/blender/makesrna/intern/rna_sequencer.c

index 1e4f7cf105c6d1bea4690adaac60e2e95dc860db..8a051e5de2deacf9dbf3af6f86f5c7319acf9885 100644 (file)
@@ -229,6 +229,8 @@ struct ImBuf *BKE_sequencer_cache_get(SeqRenderData context, struct Sequence *se
 
 void BKE_sequencer_cache_put(SeqRenderData context, struct Sequence *seq, float cfra, seq_stripelem_ibuf_t type, struct ImBuf *nval);
 
+void BKE_sequencer_cache_cleanup_sequence(struct Sequence *seq);
+
 /* **********************************************************************
  * seqeffects.c
  *
@@ -274,6 +276,8 @@ void BKE_sequencer_free_imbuf(struct Scene *scene, struct ListBase *seqbasep, in
 struct Sequence *BKE_sequence_dupli_recursive(struct Scene *scene, struct Scene *scene_to, struct Sequence *seq, int dupe_flag);
 int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str);
 
+void BKE_sequence_invalidate_cache(struct Scene *scene, struct Sequence *seq);
+
 void BKE_sequencer_update_sound_bounds_all(struct Scene *scene);
 void BKE_sequencer_update_sound_bounds(struct Scene *scene, struct Sequence *seq);
 void BKE_sequencer_update_muting(struct Editing *ed);
index 4f2eaba82a58359eebf7c12f02967c7f8bc691f6..a4ea5d1fb2634548e723a904d51d10f78ce9b1f0 100644 (file)
@@ -170,6 +170,19 @@ void BKE_sequencer_cache_cleanup(void)
        }
 }
 
+static int seqcache_key_check_seq(void *userkey, void *userdata)
+{
+       SeqCacheKey *key = (SeqCacheKey *) userkey;
+       Sequence *seq = (Sequence *) userdata;
+
+       return key->seq == seq;
+}
+
+void BKE_sequencer_cache_cleanup_sequence(Sequence *seq)
+{
+       IMB_moviecache_cleanup(moviecache, seqcache_key_check_seq, seq);
+}
+
 struct ImBuf *BKE_sequencer_cache_get(SeqRenderData context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type)
 {
        if (moviecache && seq) {
index d5a766ef97e93a24e4bb848f95f7c160f7b0525c..1488c1c2188528d2918b4223232a1462c96e7905 100644 (file)
@@ -2711,6 +2711,33 @@ static void free_anim_seq(Sequence *seq)
        }
 }
 
+void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
+{
+       Editing *ed = scene->ed;
+       Sequence *cur;
+       int left = seq->start, right = seq->start + seq->len;
+
+       /* invalidate cache for current sequence */
+       BKE_sequencer_cache_cleanup_sequence(seq);
+
+       /* invalidate cache for all dependent sequences */
+       SEQ_BEGIN (ed, cur)
+       {
+               int cur_left = cur->start, cur_right = cur->start + cur->len;
+
+               /* sequence is outside of changed one, shouldn't be invalidated */
+               if (cur_right < left || cur_left > right)
+                       continue;
+
+               /* sequence is below changed one, not dependent on it */
+               if (cur->machine < seq->machine)
+                       continue;
+
+               BKE_sequencer_cache_cleanup_sequence(cur);
+       }
+       SEQ_END
+}
+
 void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, int check_mem_usage, int keep_file_handles)
 {
        Sequence *seq;
index 070c0e8febe01b2d3b125e61157a2add9e0a1a89..d49ea264c81f1860ca830e361a681c2714734229 100644 (file)
@@ -59,6 +59,11 @@ typedef struct EffectInfo {
 
 #ifdef RNA_RUNTIME
 
+typedef struct SequenceSearchData {
+       Sequence *seq;
+       void *data;
+} SequenceSearchData;
+
 /* build a temp reference to the parent */
 static void meta_tmp_ref(Sequence *seq_par, Sequence *seq)
 {
@@ -292,28 +297,33 @@ static void rna_Sequence_use_crop_set(PointerRNA *ptr, int value)
 
 static int transform_seq_cmp_cb(Sequence *seq, void *arg_pt)
 {
-       struct { Sequence *seq; void *transform; } *data = arg_pt;
+       SequenceSearchData *data = arg_pt;
 
-       if (seq->strip && seq->strip->transform == data->transform) {
+       if (seq->strip && seq->strip->transform == data->data) {
                data->seq = seq;
                return -1; /* done so bail out */
        }
        return 1;
 }
 
-static char *rna_SequenceTransform_path(PointerRNA *ptr)
+static Sequence *sequence_get_by_transform(Editing *ed, StripTransform *transform)
 {
-       Scene *scene = ptr->id.data;
-       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
-       Sequence *seq;
+       SequenceSearchData data;
 
-       struct { Sequence *seq; void *transform; } data;
        data.seq = NULL;
-       data.transform = ptr->data;
+       data.data = transform;
 
        /* irritating we need to search for our sequence! */
        BKE_sequencer_base_recursive_apply(&ed->seqbase, transform_seq_cmp_cb, &data);
-       seq = data.seq;
+
+       return data.seq;
+}
+
+static char *rna_SequenceTransform_path(PointerRNA *ptr)
+{
+       Scene *scene = ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_transform(ed, ptr->data);
 
        if (seq && seq->name + 2)
                return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform", seq->name + 2);
@@ -321,30 +331,43 @@ static char *rna_SequenceTransform_path(PointerRNA *ptr)
                return BLI_strdup("");
 }
 
+static void rna_SequenceTransform_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+{
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_transform(ed, ptr->data);
+
+       BKE_sequence_invalidate_cache(scene, seq);
+}
+
 static int crop_seq_cmp_cb(Sequence *seq, void *arg_pt)
 {
-       struct { Sequence *seq; void *crop; } *data = arg_pt;
+       SequenceSearchData *data = arg_pt;
 
-       if (seq->strip && seq->strip->crop == data->crop) {
+       if (seq->strip && seq->strip->crop == data->data) {
                data->seq = seq;
                return -1; /* done so bail out */
        }
        return 1;
 }
 
-static char *rna_SequenceCrop_path(PointerRNA *ptr)
+static Sequence *sequence_get_by_crop(Editing *ed, StripCrop *crop)
 {
-       Scene *scene = ptr->id.data;
-       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
-       Sequence *seq;
+       SequenceSearchData data;
 
-       struct { Sequence *seq; void *crop; } data;
        data.seq = NULL;
-       data.crop = ptr->data;
+       data.data = crop;
 
        /* irritating we need to search for our sequence! */
        BKE_sequencer_base_recursive_apply(&ed->seqbase, crop_seq_cmp_cb, &data);
-       seq = data.seq;
+
+       return data.seq;
+}
+
+static char *rna_SequenceCrop_path(PointerRNA *ptr)
+{
+       Scene *scene = ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_crop(ed, ptr->data);
 
        if (seq && seq->name + 2)
                return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].crop", seq->name + 2);
@@ -352,6 +375,13 @@ static char *rna_SequenceCrop_path(PointerRNA *ptr)
                return BLI_strdup("");
 }
 
+static void rna_SequenceCrop_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+{
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_crop(ed, ptr->data);
+
+       BKE_sequence_invalidate_cache(scene, seq);
+}
 
 /* name functions that ignore the first two characters */
 static void rna_Sequence_name_get(PointerRNA *ptr, char *value)
@@ -575,12 +605,15 @@ static void rna_SequenceElement_filename_set(PointerRNA *ptr, const char *value)
 }
 #endif
 
-static void rna_Sequence_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+static void rna_Sequence_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
 {
        Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
 
-       if (ed)
-               BKE_sequencer_free_imbuf(scene, &ed->seqbase, FALSE, TRUE);
+       if (ed) {
+               Sequence *seq = (Sequence *) ptr->data;
+
+               BKE_sequence_invalidate_cache(scene, seq);
+       }
 }
 
 static void rna_Sequence_update_reopen_files(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
@@ -611,32 +644,43 @@ static void rna_Sequence_filepath_update(Main *bmain, Scene *scene, PointerRNA *
 
 static int seqproxy_seq_cmp_cb(Sequence *seq, void *arg_pt)
 {
-       struct { Sequence *seq; void *seq_proxy; } *data = arg_pt;
+       SequenceSearchData *data = arg_pt;
 
-       if (seq->strip && seq->strip->proxy == data->seq_proxy) {
+       if (seq->strip && seq->strip->proxy == data->data) {
                data->seq = seq;
                return -1; /* done so bail out */
        }
        return 1;
 }
 
-static void rna_Sequence_tcindex_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static Sequence *sequence_get_by_proxy(Editing *ed, StripProxy *proxy)
 {
-       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
-       Sequence *seq;
-
-       struct { Sequence *seq; void *seq_proxy; } data;
+       SequenceSearchData data;
 
        data.seq = NULL;
-       data.seq_proxy = ptr->data;
+       data.data = proxy;
 
        BKE_sequencer_base_recursive_apply(&ed->seqbase, seqproxy_seq_cmp_cb, &data);
-       seq = data.seq;
+       return data.seq;
+}
+
+static void rna_Sequence_tcindex_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_proxy(ed, ptr->data);
 
        BKE_sequence_reload_new_file(scene, seq, FALSE);
        rna_Sequence_frame_change_update(scene, seq);
 }
 
+static void rna_SequenceProxy_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+{
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_proxy(ed, ptr->data);
+
+       BKE_sequence_invalidate_cache(scene, seq);
+}
+
 /* do_versions? */
 static float rna_Sequence_opacity_get(PointerRNA *ptr)
 {
@@ -650,30 +694,35 @@ static void rna_Sequence_opacity_set(PointerRNA *ptr, float value)
        seq->blend_opacity = value * 100.0f;
 }
 
-
 static int colbalance_seq_cmp_cb(Sequence *seq, void *arg_pt)
 {
-       struct { Sequence *seq; void *color_balance; } *data = arg_pt;
+       SequenceSearchData *data = arg_pt;
 
-       if (seq->strip && seq->strip->color_balance == data->color_balance) {
+       if (seq->strip && seq->strip->color_balance == data->data) {
                data->seq = seq;
                return -1; /* done so bail out */
        }
        return 1;
 }
-static char *rna_SequenceColorBalance_path(PointerRNA *ptr)
+
+static Sequence *sequence_get_by_colorbalance(Editing *ed, StripColorBalance *cb)
 {
-       Scene *scene = ptr->id.data;
-       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
-       Sequence *seq;
+       SequenceSearchData data;
 
-       struct { Sequence *seq; void *color_balance; } data;
        data.seq = NULL;
-       data.color_balance = ptr->data;
+       data.data = cb;
 
        /* irritating we need to search for our sequence! */
        BKE_sequencer_base_recursive_apply(&ed->seqbase, colbalance_seq_cmp_cb, &data);
-       seq = data.seq;
+
+       return data.seq;
+}
+
+static char *rna_SequenceColorBalance_path(PointerRNA *ptr)
+{
+       Scene *scene = ptr->id.data;
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_colorbalance(ed, ptr->data);
 
        if (seq && seq->name + 2)
                return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].color_balance", seq->name + 2);
@@ -681,6 +730,14 @@ static char *rna_SequenceColorBalance_path(PointerRNA *ptr)
                return BLI_strdup("");
 }
 
+static void rna_SequenceColorBalance_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+{
+       Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+       Sequence *seq = sequence_get_by_colorbalance(ed, ptr->data);
+
+       BKE_sequence_invalidate_cache(scene, seq);
+}
+
 static void rna_SequenceEditor_overlay_lock_set(PointerRNA *ptr, int value)
 {
        Scene *scene = ptr->id.data;
@@ -787,25 +844,25 @@ static void rna_def_strip_crop(BlenderRNA *brna)
        RNA_def_property_int_sdna(prop, NULL, "top");
        RNA_def_property_ui_text(prop, "Top", "");
        RNA_def_property_ui_range(prop, 0, 4096, 1, 0);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
        
        prop = RNA_def_property(srna, "min_y", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "bottom");
        RNA_def_property_ui_text(prop, "Bottom", "");
        RNA_def_property_ui_range(prop, 0, 4096, 1, 0);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
        
        prop = RNA_def_property(srna, "min_x", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "left");
        RNA_def_property_ui_text(prop, "Left", "");
        RNA_def_property_ui_range(prop, 0, 4096, 1, 0);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
 
        prop = RNA_def_property(srna, "max_x", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "right");
        RNA_def_property_ui_text(prop, "Right", "");
        RNA_def_property_ui_range(prop, 0, 4096, 1, 0);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
 
        RNA_def_struct_path_func(srna, "rna_SequenceCrop_path");
 }
@@ -823,13 +880,13 @@ static void rna_def_strip_transform(BlenderRNA *brna)
        RNA_def_property_int_sdna(prop, NULL, "xofs");
        RNA_def_property_ui_text(prop, "Offset X", "");
        RNA_def_property_ui_range(prop, -4096, 4096, 1, 0);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
 
        prop = RNA_def_property(srna, "offset_y", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "yofs");
        RNA_def_property_ui_text(prop, "Offset Y", "");
        RNA_def_property_ui_range(prop, -4096, 4096, 1, 0);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
 
        RNA_def_struct_path_func(srna, "rna_SequenceTransform_path");
 
@@ -862,14 +919,14 @@ static void rna_def_strip_proxy(BlenderRNA *brna)
        prop = RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH);
        RNA_def_property_string_sdna(prop, NULL, "dir");
        RNA_def_property_ui_text(prop, "Directory", "Location to store the proxy files");
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceProxy_update");
        
        prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
        RNA_def_property_ui_text(prop, "Path", "Location of custom proxy file");
        RNA_def_property_string_funcs(prop, "rna_Sequence_proxy_filepath_get", "rna_Sequence_proxy_filepath_length",
                                      "rna_Sequence_proxy_filepath_set");
 
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceProxy_update");
 
        prop = RNA_def_property(srna, "build_25", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "build_size_flags", SEQ_PROXY_IMAGE_SIZE_25);
@@ -924,32 +981,32 @@ static void rna_def_strip_color_balance(BlenderRNA *brna)
        prop = RNA_def_property(srna, "lift", PROP_FLOAT, PROP_COLOR);
        RNA_def_property_ui_text(prop, "Lift", "Color balance lift (shadows)");
        RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
        
        prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_COLOR);
        RNA_def_property_ui_text(prop, "Gamma", "Color balance gamma (midtones)");
        RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
        
        prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_COLOR);
        RNA_def_property_ui_text(prop, "Gain", "Color balance gain (highlights)");
        RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
        
        prop = RNA_def_property(srna, "invert_gain", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAIN);
        RNA_def_property_ui_text(prop, "Inverse Gain", "");
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
 
        prop = RNA_def_property(srna, "invert_gamma", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAMMA);
        RNA_def_property_ui_text(prop, "Inverse Gamma", "");
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
 
        prop = RNA_def_property(srna, "invert_lift", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_LIFT);
        RNA_def_property_ui_text(prop, "Inverse Lift", "");
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
 
        RNA_def_struct_path_func(srna, "rna_SequenceColorBalance_path");
 
@@ -958,12 +1015,12 @@ static void rna_def_strip_color_balance(BlenderRNA *brna)
        prop = RNA_def_property(srna, "exposure", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, 0.0f, 1.0f);
        RNA_def_property_ui_text(prop, "Exposure", "");
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_ColorBabalnce_update");
        
        prop = RNA_def_property(srna, "saturation", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, 0.0f, 1.0f);
        RNA_def_property_ui_text(prop, "Saturation", "");
-       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+       RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_ColorBabalnce_update");
 #endif
 }