[Bf-blender-cvs] [f5f0b97564c] master: Fix T61763: Crash on selecting "Background Scene"

Sergey Sharybin noreply at git.blender.org
Tue Mar 5 10:24:06 CET 2019


Commit: f5f0b97564cdb21c334ef736923905887111ddcf
Author: Sergey Sharybin
Date:   Tue Mar 5 10:22:14 2019 +0100
Branches: master
https://developer.blender.org/rBf5f0b97564cdb21c334ef736923905887111ddcf

Fix T61763: Crash on selecting "Background Scene"

Memory optimization in dependency graph was using wrong view layer
for the scene which came via set.

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

M	source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
M	source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc

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

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;
 }



More information about the Bf-blender-cvs mailing list