Fix #139501: VSE: Build separate dependency graph for scene strip previews
Currently, the scene strip preview uses the existing dependency graph built for that scene. This was not a big issue before the sequencer scene was introduced, because the user would have to create two main Blender windows to run into problems. Now with the sequencer scene, it's possible to look at the scene of a scene strip within the same window. When the user is editing the scene (e.g. moving an animated object) any open sequencer preview will cause the edits to be flushed. This can e.g. result in visual jumping of animated objects, and more. This PR attempts to fix the issue in a straightforward way: Use a separate dependency graph for rendering the sequencer preview. While this fixes the immediate issues, there are some consequences: * The memory usage of the scene dependency graph _can_ roughly double (since there are now likely two instances of the same dependency graph). Because of implicit sharing, unmodified data will not be copied. But for example modifiers on meshes would currently create two copies of the evaluated data in the two dependency graphs. * Creating the dependency graph can be costly, which will cause the first frame that the scene has to render to be slower. Note: The current code changes some properties of the original scene like the frame, subframe etc. before rendering and then restores the original state. In theory, this part of the code can be removed, but may be a bit too risky for just a fix. This should be improved at a later stage. Also resolves #146769, #139501. Pull Request: https://projects.blender.org/blender/blender/pulls/147457
This commit is contained in:
@@ -34,9 +34,19 @@ class CompositorRuntime {
|
||||
~CompositorRuntime();
|
||||
};
|
||||
|
||||
/* Runtime data specific to the sequencer, e.g. when using scene strips. */
|
||||
class SequencerRuntime {
|
||||
public:
|
||||
Depsgraph *depsgraph = nullptr;
|
||||
|
||||
~SequencerRuntime();
|
||||
};
|
||||
|
||||
class SceneRuntime : NonCopyable, NonMovable {
|
||||
public:
|
||||
CompositorRuntime compositor;
|
||||
|
||||
SequencerRuntime sequencer;
|
||||
};
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
@@ -114,6 +114,7 @@
|
||||
|
||||
using blender::bke::CompositorRuntime;
|
||||
using blender::bke::SceneRuntime;
|
||||
using blender::bke::SequencerRuntime;
|
||||
|
||||
CompositorRuntime::~CompositorRuntime()
|
||||
{
|
||||
@@ -122,6 +123,11 @@ CompositorRuntime::~CompositorRuntime()
|
||||
}
|
||||
}
|
||||
|
||||
SequencerRuntime::~SequencerRuntime()
|
||||
{
|
||||
DEG_graph_free(depsgraph);
|
||||
}
|
||||
|
||||
CurveMapping *BKE_sculpt_default_cavity_curve()
|
||||
|
||||
{
|
||||
|
||||
@@ -38,8 +38,11 @@
|
||||
#include "BKE_mask.h"
|
||||
#include "BKE_movieclip.h"
|
||||
#include "BKE_scene.hh"
|
||||
#include "BKE_scene_runtime.hh"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
#include "DEG_depsgraph_build.hh"
|
||||
#include "DEG_depsgraph_debug.hh"
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
|
||||
#include "IMB_colormanagement.hh"
|
||||
@@ -1384,6 +1387,26 @@ static ImBuf *seq_render_mask_strip(const RenderData *context, Strip *strip, flo
|
||||
context->depsgraph, context->rectx, context->recty, strip->mask, frame_index, make_float);
|
||||
}
|
||||
|
||||
static Depsgraph *get_depsgraph_for_scene_strip(Main *bmain, Scene *scene, ViewLayer *view_layer)
|
||||
{
|
||||
Depsgraph *depsgraph = scene->runtime->sequencer.depsgraph;
|
||||
if (!depsgraph) {
|
||||
/* Create a new depsgraph for the sequencer preview. Use viewport evaluation, because this
|
||||
* depsgraph is not used during final render. */
|
||||
scene->runtime->sequencer.depsgraph = DEG_graph_new(
|
||||
bmain, scene, view_layer, DAG_EVAL_VIEWPORT);
|
||||
depsgraph = scene->runtime->sequencer.depsgraph;
|
||||
DEG_debug_name_set(depsgraph, "SEQ_SCENE_STRIP");
|
||||
}
|
||||
|
||||
if (DEG_get_input_view_layer(depsgraph) != view_layer) {
|
||||
DEG_graph_replace_owners(depsgraph, bmain, scene, view_layer);
|
||||
DEG_graph_tag_relations_update(depsgraph);
|
||||
}
|
||||
|
||||
return depsgraph;
|
||||
}
|
||||
|
||||
static ImBuf *seq_render_scene_strip_ex(const RenderData *context,
|
||||
Strip *strip,
|
||||
float frame_index,
|
||||
@@ -1441,10 +1464,8 @@ static ImBuf *seq_render_scene_strip_ex(const RenderData *context,
|
||||
#endif
|
||||
const bool have_comp = (scene->r.scemode & R_DOCOMP) && scene->compositing_node_group;
|
||||
|
||||
/* Get view layer for the strip. */
|
||||
ViewLayer *view_layer = BKE_view_layer_default_render(scene);
|
||||
/* Depsgraph will be nullptr when doing rendering. */
|
||||
Depsgraph *depsgraph = nullptr;
|
||||
Depsgraph *depsgraph = get_depsgraph_for_scene_strip(context->bmain, scene, view_layer);
|
||||
|
||||
BKE_scene_frame_set(scene, frame);
|
||||
|
||||
@@ -1485,7 +1506,6 @@ static ImBuf *seq_render_scene_strip_ex(const RenderData *context,
|
||||
}
|
||||
|
||||
/* opengl offscreen render */
|
||||
depsgraph = BKE_scene_ensure_depsgraph(context->bmain, scene, view_layer);
|
||||
BKE_scene_graph_update_for_newframe(depsgraph);
|
||||
Object *camera_eval = DEG_get_evaluated(depsgraph, camera);
|
||||
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
|
||||
|
||||
Reference in New Issue
Block a user