[Bf-blender-cvs] [fac1892e110] blender2.8: Depsgraph: Bind base by it's index

Sergey Sharybin noreply at git.blender.org
Thu Apr 12 11:43:30 CEST 2018


Commit: fac1892e110956c7ed285ef2d7b097d632bcc25e
Author: Sergey Sharybin
Date:   Wed Apr 11 12:39:36 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBfac1892e110956c7ed285ef2d7b097d632bcc25e

Depsgraph: Bind base by it's index

For the performance we convert object bases list to an array
during view layer evaluation. This makes it possible to have
very cheap index-based base lookup.

The goal of this change is to get rid of base used for function
binding, and avoid scene datablock expansion at the depsgraph
construction time.

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

M	source/blender/blenkernel/BKE_object.h
M	source/blender/blenkernel/intern/layer.c
M	source/blender/blenkernel/intern/object_update.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.h
M	source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
M	source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
M	source/blender/makesdna/DNA_layer_types.h

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

diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index c5eefedcfad..ff05ffc8df7 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -247,7 +247,7 @@ void BKE_object_data_select_update(
 
 void BKE_object_eval_flush_base_flags(
         const struct EvaluationContext *eval_ctx,
-        struct Object *object, struct Base *base,
+        struct Object *object, int base_index,
         const bool is_from_set);
 
 void BKE_object_handle_data_update(
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 4d3b4e43043..50c7dc0c02f 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -216,6 +216,8 @@ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user)
 		MEM_freeN(view_layer->id_properties);
 	}
 
+	MEM_SAFE_FREE(view_layer->object_bases_array);
+
 	MEM_freeN(view_layer);
 }
 
@@ -503,6 +505,8 @@ void BKE_view_layer_copy_data(
 			view_layer_dst->basact = base_dst;
 		}
 	}
+
+	view_layer_dst->object_bases_array = NULL;
 }
 
 /**
@@ -2358,11 +2362,19 @@ static void layer_eval_layer_collection(const EvaluationContext *eval_ctx,
 static void layer_eval_layer_collection_post(ViewLayer *view_layer)
 {
 	DEG_debug_print_eval(__func__, view_layer->name, view_layer);
-	/* if base is not selectabled, clear select */
+	/* Create array of bases, for fast index-based lookup. */
+	const int num_object_bases = BLI_listbase_count(&view_layer->object_bases);
+	MEM_SAFE_FREE(view_layer->object_bases_array);
+	view_layer->object_bases_array = MEM_malloc_arrayN(
+	        num_object_bases, sizeof(Base *), "view_layer->object_bases_array");
+	int base_index = 0;
 	for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+		/* if base is not selectabled, clear select. */
 		if ((base->flag & BASE_SELECTABLED) == 0) {
 			base->flag &= ~BASE_SELECTED;
 		}
+		/* Store base in the array. */
+		view_layer->object_bases_array[base_index++] = base;
 	}
 }
 
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index de2002624c0..7904e479933 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -433,9 +433,16 @@ void BKE_object_data_select_update(const EvaluationContext *UNUSED(eval_ctx),
 	}
 }
 
-void BKE_object_eval_flush_base_flags(const EvaluationContext *UNUSED(eval_ctx),
-                                      Object *object, Base *base, bool is_from_set)
+void BKE_object_eval_flush_base_flags(const EvaluationContext *eval_ctx,
+                                      Object *object, int base_index, bool is_from_set)
 {
+	ViewLayer *view_layer = eval_ctx->view_layer;
+	BLI_assert(view_layer->object_bases_array != NULL);
+	BLI_assert(base_index >= 0);
+	BLI_assert(base_index < MEM_allocN_len(view_layer->object_bases_array) / sizeof(Base *));
+	Base *base = view_layer->object_bases_array[base_index];
+	BLI_assert(base->object == object);
+
 	DEG_debug_print_eval(__func__, object->id.name, object);
 
 	/* Make sure we have the base collection settings is already populated.
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 7ae8f0410c5..a76350b23c9 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6217,6 +6217,7 @@ static void direct_link_view_layer(FileData *fd, ViewLayer *view_layer)
 	view_layer->properties_evaluated = NULL;
 
 	BLI_listbase_clear(&view_layer->drawdata);
+	view_layer->object_bases_array = NULL;
 }
 
 /**
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 338d1bc7572..bdc8d7cb572 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -136,6 +136,7 @@ DepsgraphNodeBuilder::DepsgraphNodeBuilder(Main *bmain, Depsgraph *graph)
     : bmain_(bmain),
       graph_(graph),
       scene_(NULL),
+      view_layer_(NULL),
       cow_id_hash_(NULL)
 {
 }
@@ -399,7 +400,7 @@ void DepsgraphNodeBuilder::build_group(Group *group)
 	}
 	/* Build group objects. */
 	LISTBASE_FOREACH (Base *, base, &group->view_layer->object_bases) {
-		build_object(NULL, base->object, DEG_ID_LINKED_INDIRECTLY);
+		build_object(-1, base->object, DEG_ID_LINKED_INDIRECTLY);
 	}
 	/* Operation to evaluate the whole view layer.
 	 *
@@ -417,7 +418,7 @@ void DepsgraphNodeBuilder::build_group(Group *group)
 	                   DEG_OPCODE_VIEW_LAYER_EVAL);
 }
 
-void DepsgraphNodeBuilder::build_object(Base *base,
+void DepsgraphNodeBuilder::build_object(int base_index,
                                         Object *object,
                                         eDepsNode_LinkedState_Type linked_state)
 {
@@ -429,7 +430,7 @@ void DepsgraphNodeBuilder::build_object(Base *base,
 		 * directly.
 		 */
 		if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) {
-			build_object_flags(base, object, linked_state);
+			build_object_flags(base_index, object, linked_state);
 		}
 		id_node->linked_state = max(id_node->linked_state, linked_state);
 		return;
@@ -439,12 +440,12 @@ void DepsgraphNodeBuilder::build_object(Base *base,
 	id_node->linked_state = linked_state;
 	object->customdata_mask = 0;
 	/* Various flags, flushing from bases/collections. */
-	build_object_flags(base, object, linked_state);
+	build_object_flags(base_index, object, linked_state);
 	/* Transform. */
 	build_object_transform(object);
 	/* Parent. */
 	if (object->parent != NULL) {
-		build_object(NULL, object->parent, DEG_ID_LINKED_INDIRECTLY);
+		build_object(-1, object->parent, DEG_ID_LINKED_INDIRECTLY);
 	}
 	/* Modifiers. */
 	if (object->modifiers.first != NULL) {
@@ -483,7 +484,7 @@ void DepsgraphNodeBuilder::build_object(Base *base,
 	/* Object that this is a proxy for. */
 	if (object->proxy) {
 		object->proxy->proxy_from = object;
-		build_object(NULL, object->proxy, DEG_ID_LINKED_INDIRECTLY);
+		build_object(-1, object->proxy, DEG_ID_LINKED_INDIRECTLY);
 	}
 	/* Object dupligroup. */
 	if (object->dup_group != NULL) {
@@ -492,11 +493,11 @@ void DepsgraphNodeBuilder::build_object(Base *base,
 }
 
 void DepsgraphNodeBuilder::build_object_flags(
-        Base *base,
+        int base_index,
         Object *object,
         eDepsNode_LinkedState_Type linked_state)
 {
-	if (base == NULL) {
+	if (base_index == -1) {
 		return;
 	}
 	/* TODO(sergey): Is this really best component to be used? */
@@ -505,7 +506,9 @@ void DepsgraphNodeBuilder::build_object_flags(
 	add_operation_node(&object->id,
 	                   DEG_NODE_TYPE_LAYER_COLLECTIONS,
 	                   function_bind(BKE_object_eval_flush_base_flags,
-	                                 _1, object_cow, base, is_from_set),
+	                                 _1,
+	                                 object_cow, base_index,
+	                                 is_from_set),
 	                   DEG_OPCODE_OBJECT_BASE_FLAGS);
 }
 
@@ -877,7 +880,7 @@ void DepsgraphNodeBuilder::build_particles(Object *object)
 		switch (part->ren_as) {
 			case PART_DRAW_OB:
 				if (part->dup_ob != NULL) {
-					build_object(NULL,
+					build_object(-1,
 					             part->dup_ob,
 					             DEG_ID_LINKED_INDIRECTLY);
 				}
@@ -1083,13 +1086,13 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object)
 			 */
 			Curve *cu = (Curve *)obdata;
 			if (cu->bevobj != NULL) {
-				build_object(NULL, cu->bevobj, DEG_ID_LINKED_INDIRECTLY);
+				build_object(-1, cu->bevobj, DEG_ID_LINKED_INDIRECTLY);
 			}
 			if (cu->taperobj != NULL) {
-				build_object(NULL, cu->taperobj, DEG_ID_LINKED_INDIRECTLY);
+				build_object(-1, cu->taperobj, DEG_ID_LINKED_INDIRECTLY);
 			}
 			if (object->type == OB_FONT && cu->textoncurve != NULL) {
-				build_object(NULL, cu->textoncurve, DEG_ID_LINKED_INDIRECTLY);
+				build_object(-1, cu->textoncurve, DEG_ID_LINKED_INDIRECTLY);
 			}
 			break;
 		}
@@ -1208,7 +1211,7 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
 			build_image((Image *)id);
 		}
 		else if (id_type == ID_OB) {
-			build_object(NULL, (Object *)id, DEG_ID_LINKED_INDIRECTLY);
+			build_object(-1, (Object *)id, DEG_ID_LINKED_INDIRECTLY);
 		}
 		else if (id_type == ID_SCE) {
 			/* Scenes are used by compositor trees, and handled by render
@@ -1405,7 +1408,7 @@ void DepsgraphNodeBuilder::modifier_walk(void *user_data,
 	}
 	switch (GS(id->name)) {
 		case ID_OB:
-			data->builder->build_object(NULL,
+			data->builder->build_object(-1,
 			                            (Object *)id,
 			                            DEG_ID_LINKED_INDIRECTLY);
 			break;
@@ -1430,7 +1433,7 @@ void DepsgraphNodeBuilder::constraint_walk(bConstraint * /*con*/,
 	}
 	switch (GS(id->name)) {
 		case ID_OB:
-			data->builder->build_object(NULL,
+			data->builder->build_object(-1,
 			                            (Object *)id,
 			                            DEG_ID_LINKED_INDIRECTLY);
 			break;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 8c2885614fb..c2aa811c8e6 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -171,10 +171,10 @@ struct DepsgraphNodeBuilder {
 	                       ViewLayer *view_layer,
 	                       eDepsNode_LinkedState_Type linked_state);
 	void build_group(Group *group);
-	void build_object(Base *base,
+	void build_object(int base_index,
 	                  Object *object,
 	                  eDepsNode_LinkedState_Type linked_state);
-	void build_object_flags(Base *base,
+	void build_object_flags(int base_index,
 	                        Object *object,
 	                        eDepsNode_LinkedState_Type linked_state);
 	void build_object_data(Object *object);
@@ -242,6 +242,7 @@ protected:
 
 	/* State which demotes currently built entities. */
 	Scene *scene_;
+	ViewLayer *view_layer_;
 
 	GHash *cow_id_hash_;
 	BuilderMap 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list