From 35aedd87e78d44aa0a622d26261ecac7ece12925 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Feb 2022 21:32:50 +1100 Subject: Fix T66913: undo after frame-change doesn't refresh properly Use the ID.recalc flag to detect when updates after frame-change is needed. Since comparing the last calculated frame doesn't take undo into account (see code-comment for details). `ID_RECALC_AUDIO_SEEK` has been renamed to `ID_RECALC_FRAME_CHANGE` since this is not only related to audio however internally this flag is still categorized in `NodeType::AUDIO`. Reviewed By: sergey Ref D13942 --- source/blender/blenkernel/intern/scene.c | 2 +- source/blender/depsgraph/intern/depsgraph_eval.cc | 8 ++++++++ source/blender/depsgraph/intern/depsgraph_tag.cc | 6 +++--- source/blender/editors/animation/anim_ops.c | 2 +- source/blender/editors/screen/screen_edit.c | 2 +- source/blender/editors/screen/screen_ops.c | 12 ++++++------ source/blender/editors/space_clip/clip_ops.c | 2 +- source/blender/editors/space_clip/tracking_ops.c | 2 +- source/blender/editors/space_graph/graph_ops.c | 2 +- source/blender/editors/space_image/image_ops.c | 2 +- source/blender/editors/space_sequencer/sequencer_edit.c | 2 +- source/blender/makesdna/DNA_ID.h | 4 +++- source/blender/makesrna/intern/rna_scene.c | 2 +- source/blender/windowmanager/intern/wm_event_system.c | 2 +- 14 files changed, 30 insertions(+), 20 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 916a2786a98..ed9f10aaa91 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -2522,7 +2522,7 @@ void BKE_scene_update_sound(Depsgraph *depsgraph, Main *bmain) Scene *scene = DEG_get_evaluated_scene(depsgraph); const int recalc = scene->id.recalc; BKE_sound_ensure_scene(scene); - if (recalc & ID_RECALC_AUDIO_SEEK) { + if (recalc & ID_RECALC_FRAME_CHANGE) { BKE_sound_seek_scene(bmain, scene); } if (recalc & ID_RECALC_AUDIO_FPS) { diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index 7952f27507f..ae94fbcfdb8 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -72,6 +72,14 @@ void DEG_evaluate_on_refresh(Depsgraph *graph) deg_graph->frame = frame; deg_graph->ctime = ctime; } + else if (scene->id.recalc & ID_RECALC_FRAME_CHANGE) { + /* Comparing depsgraph & scene frame fails in the case of undo, + * since the undo state is stored before updates from the frame change have been applied. + * In this case reading back the undo state will behave as if no updates on frame change + * is needed as the #Depsgraph.ctime & frame will match the values in the input scene. + * Use #ID_RECALC_FRAME_CHANGE to detect that recalculation is necessary. see: T66913. */ + deg_graph->tag_time_source(); + } deg_flush_updates_and_refresh(deg_graph); } diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 6614509f860..11074b5bf72 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -211,7 +211,7 @@ void depsgraph_tag_to_component_opcode(const ID *id, case ID_RECALC_SEQUENCER_STRIPS: *component_type = NodeType::SEQUENCER; break; - case ID_RECALC_AUDIO_SEEK: + case ID_RECALC_FRAME_CHANGE: case ID_RECALC_AUDIO_FPS: case ID_RECALC_AUDIO_VOLUME: case ID_RECALC_AUDIO_MUTE: @@ -737,8 +737,8 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag) return "EDITORS"; case ID_RECALC_SEQUENCER_STRIPS: return "SEQUENCER_STRIPS"; - case ID_RECALC_AUDIO_SEEK: - return "AUDIO_SEEK"; + case ID_RECALC_FRAME_CHANGE: + return "FRAME_CHANGE"; case ID_RECALC_AUDIO_FPS: return "AUDIO_FPS"; case ID_RECALC_AUDIO_VOLUME: diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 1e60a129535..8c52480b89a 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -169,7 +169,7 @@ static void change_frame_apply(bContext *C, wmOperator *op) FRAMENUMBER_MIN_CLAMP(CFRA); /* do updates */ - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 5a2b53163b8..8dd4b940491 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1662,7 +1662,7 @@ void ED_screen_animation_timer(bContext *C, int redraws, int sync, int enable) } /* Seek audio to ensure playback in preview range with AV sync. */ - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); /* Notifier caught by top header, for button. */ WM_event_add_notifier(C, NC_SCREEN | ND_ANIMPLAY, NULL); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 6581bffb6bd..152a5c87c78 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2986,7 +2986,7 @@ static int frame_offset_exec(bContext *C, wmOperator *op) areas_do_frame_follow(C, false); - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); @@ -3047,7 +3047,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) areas_do_frame_follow(C, true); - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); } @@ -3161,7 +3161,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) areas_do_frame_follow(C, true); - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); @@ -3225,7 +3225,7 @@ static int marker_jump_exec(bContext *C, wmOperator *op) areas_do_frame_follow(C, true); - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); @@ -4626,7 +4626,7 @@ static int screen_animation_step_invoke(bContext *C, wmOperator *UNUSED(op), con if (scene_eval == NULL) { /* Happens when undo/redo system is used during playback, nothing meaningful we can do here. */ } - else if (scene_eval->id.recalc & ID_RECALC_AUDIO_SEEK) { + else if (scene_eval->id.recalc & ID_RECALC_FRAME_CHANGE) { /* Ignore seek here, the audio will be updated to the scene frame after jump during next * dependency graph update. */ } @@ -4741,7 +4741,7 @@ static int screen_animation_step_invoke(bContext *C, wmOperator *UNUSED(op), con } if (sad->flag & ANIMPLAY_FLAG_JUMPED) { - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); #ifdef PROFILE_AUDIO_SYNCH old_frame = CFRA; #endif diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 03b6d8c7381..b45eabdc7c3 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -1082,7 +1082,7 @@ static void change_frame_apply(bContext *C, wmOperator *op) SUBFRA = 0.0f; /* do updates */ - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); } diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index ee0406cde30..313887ec8fd 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1385,7 +1385,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) if (CFRA != sc->user.framenr) { CFRA = sc->user.framenr; - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); } diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 7606dcc60cf..0cebc6eb586 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -103,7 +103,7 @@ static void graphview_cursor_apply(bContext *C, wmOperator *op) } SUBFRA = 0.0f; - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); } /* set the cursor value */ diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 23d07c9b45b..b1ca8505b8a 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -3605,7 +3605,7 @@ static void change_frame_apply(bContext *C, wmOperator *op) SUBFRA = 0.0f; /* do updates */ - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 3b5e16d84a9..b2f13c612ac 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2213,7 +2213,7 @@ static int sequencer_strip_jump_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); return OPERATOR_FINISHED; diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index fad24f4326c..132121064c8 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -800,7 +800,9 @@ typedef enum IDRecalcFlag { * Use this tag with a scene ID which owns the sequences. */ ID_RECALC_SEQUENCER_STRIPS = (1 << 14), - ID_RECALC_AUDIO_SEEK = (1 << 15), + /* Runs on frame-change (used for seeking audio too). */ + ID_RECALC_FRAME_CHANGE = (1 << 15), + ID_RECALC_AUDIO_FPS = (1 << 16), ID_RECALC_AUDIO_VOLUME = (1 << 17), ID_RECALC_AUDIO_MUTE = (1 << 18), diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 064dc255811..201ea5469cc 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1028,7 +1028,7 @@ static void rna_Scene_frame_update(Main *UNUSED(bmain), PointerRNA *ptr) { Scene *scene = (Scene *)ptr->owner_id; - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); WM_main_add_notifier(NC_SCENE | ND_FRAME, scene); } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 9d2c97e151f..0cc2db661ec 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -3589,7 +3589,7 @@ void wm_event_do_handlers(bContext *C) if (scene_eval != NULL) { const int is_playing_sound = BKE_sound_scene_playing(scene_eval); - if (scene_eval->id.recalc & ID_RECALC_AUDIO_SEEK) { + if (scene_eval->id.recalc & ID_RECALC_FRAME_CHANGE) { /* Ignore seek here, the audio will be updated to the scene frame after jump during next * dependency graph update. */ } -- cgit v1.2.3