Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2019-03-05 12:22:14 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2019-03-05 12:22:14 +0300
commitf5f0b97564cdb21c334ef736923905887111ddcf (patch)
treed57e41b0e01571e50d4a4b08a837857eea89df0e /source/blender/depsgraph
parentcaacedd861fea49086d6ec531acbaf79a775c62b (diff)
Fix T61763: Crash on selecting "Background Scene"
Memory optimization in dependency graph was using wrong view layer for the scene which came via set.
Diffstat (limited to 'source/blender/depsgraph')
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc3
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc56
2 files changed, 44 insertions, 15 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index beb67af8bf6..4e5f18198ba 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -83,7 +83,8 @@ void DepsgraphNodeBuilder::build_view_layer(
* only one view layer in there. */
view_layer_index_ = 0;
/* Scene ID block. */
- add_id_node(&scene->id);
+ IDNode *id_node = add_id_node(&scene->id);
+ id_node->linked_state = linked_state;
/* Time source. */
add_time_source();
/* Setup currently building context. */
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index a4948941b73..27c5bb89ba9 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -332,11 +332,35 @@ bool scene_copy_inplace_no_main(const Scene *scene, Scene *new_scene)
return result;
}
+/* For the given scene get view layer which corresponds to an original for the
+ * scene's evaluated one. This depends on how the scene is pulled into the
+ * dependency graph. */
+ViewLayer *get_original_view_layer(const Depsgraph *depsgraph,
+ const IDNode *id_node)
+{
+ if (id_node->linked_state == DEG_ID_LINKED_DIRECTLY) {
+ return depsgraph->view_layer;
+ }
+ else if (id_node->linked_state == DEG_ID_LINKED_VIA_SET) {
+ Scene *scene_orig = reinterpret_cast<Scene *>(id_node->id_orig);
+ return BKE_view_layer_default_render(scene_orig);
+ }
+ /* Is possible to have scene linked indirectly (i.e. via the driver) which
+ * we need to support. Currently there aer issues somewhere else, which
+ * makes testing hard. This is a reported problem, so will eventually be
+ * properly fixed.
+ *
+ * TODO(sergey): Support indirectly linked scene. */
+ return NULL;
+}
+
/* Remove all view layers but the one which corresponds to an input one. */
void scene_remove_unused_view_layers(const Depsgraph *depsgraph,
+ const IDNode *id_node,
Scene *scene_cow)
{
- ViewLayer *view_layer_input = depsgraph->view_layer;
+ const ViewLayer *view_layer_input = get_original_view_layer(
+ depsgraph, id_node);
ViewLayer *view_layer_eval = NULL;
/* Find evaluated view layer. At the same time we free memory used by
* all other of the view layers. */
@@ -378,8 +402,7 @@ void view_layer_remove_disabled_bases(const Depsgraph *depsgraph,
* NOTE: We are using original base since the object which evaluated base
* points to is not yet copied. This is dangerous access from evaluated
* domain to original one, but this is how the entire copy-on-write works:
- * it does need to access original for an initial copy.
- * */
+ * it does need to access original for an initial copy. */
const bool is_object_enabled =
deg_check_base_available_for_build(depsgraph, base->base_orig);
if (is_object_enabled) {
@@ -395,7 +418,7 @@ void view_layer_remove_disabled_bases(const Depsgraph *depsgraph,
view_layer->object_bases = enabled_bases;
}
-void view_layer_update_orig_base_pointers(ViewLayer *view_layer_orig,
+void view_layer_update_orig_base_pointers(const ViewLayer *view_layer_orig,
ViewLayer *view_layer_eval)
{
Base *base_orig =
@@ -407,22 +430,25 @@ void view_layer_update_orig_base_pointers(ViewLayer *view_layer_orig,
}
void scene_setup_view_layers_before_remap(const Depsgraph *depsgraph,
+ const IDNode *id_node,
Scene *scene_cow)
{
- scene_remove_unused_view_layers(depsgraph, scene_cow);
- /* TODO(sergey): Remove objects from collections as well.
- * Not a HUGE deal for now, nobody is looking into those CURRENTLY.
- * Still not an excuse to have those. */
+ scene_remove_unused_view_layers(depsgraph, id_node, scene_cow);
}
void scene_setup_view_layers_after_remap(const Depsgraph *depsgraph,
- Scene *scene_cow)
+ const IDNode *id_node,
+ Scene *scene_cow)
{
- ViewLayer *view_layer_orig = depsgraph->view_layer;
+ const ViewLayer *view_layer_orig = get_original_view_layer(
+ depsgraph, id_node);
ViewLayer *view_layer_eval =
reinterpret_cast<ViewLayer *>(scene_cow->view_layers.first);
view_layer_update_orig_base_pointers(view_layer_orig, view_layer_eval);
view_layer_remove_disabled_bases(depsgraph, view_layer_eval);
+ /* TODO(sergey): Remove objects from collections as well.
+ * Not a HUGE deal for now, nobody is looking into those CURRENTLY.
+ * Still not an excuse to have those. */
}
/* Check whether given ID is expanded or still a shallow copy. */
@@ -537,7 +563,7 @@ void update_mball_edit_mode_pointers(const Depsgraph * /*depsgraph*/,
}
void update_lattice_edit_mode_pointers(const Depsgraph * /*depsgraph*/,
- const ID *id_orig, ID *id_cow)
+ const ID *id_orig, ID *id_cow)
{
const Lattice *lt_orig = (const Lattice *)id_orig;
Lattice *lt_cow = (Lattice *)id_cow;
@@ -636,6 +662,7 @@ void update_pose_orig_pointers(const bPose *pose_orig, bPose *pose_cow)
* Only use for the newly created CoW datablocks.
*/
void update_id_after_copy(const Depsgraph *depsgraph,
+ const IDNode *id_node,
const ID *id_orig, ID *id_cow)
{
const ID_Type type = GS(id_orig->name);
@@ -670,7 +697,8 @@ void update_id_after_copy(const Depsgraph *depsgraph,
const Scene *scene_orig = (const Scene *)id_orig;
scene_cow->toolsettings = scene_orig->toolsettings;
scene_cow->eevee.light_cache = scene_orig->eevee.light_cache;
- scene_setup_view_layers_after_remap(depsgraph, (Scene *)id_cow);
+ scene_setup_view_layers_after_remap(
+ depsgraph, id_node, reinterpret_cast<Scene *>(id_cow));
break;
}
default:
@@ -750,7 +778,7 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
/* NOTE: This is important to do before remap, because this
* function will make it so less IDs are to be remapped. */
scene_setup_view_layers_before_remap(
- depsgraph, (Scene *)id_cow);
+ depsgraph, id_node, (Scene *)id_cow);
}
break;
}
@@ -791,7 +819,7 @@ ID *deg_expand_copy_on_write_datablock(const Depsgraph *depsgraph,
IDWALK_NOP);
/* Correct or tweak some pointers which are not taken care by foreach
* from above. */
- update_id_after_copy(depsgraph, id_orig, id_cow);
+ update_id_after_copy(depsgraph, id_node, id_orig, id_cow);
id_cow->recalc = id_orig->recalc | id_cow_recalc;
return id_cow;
}