[Bf-blender-cvs] [415b5a4] master: Fix T46646: Point Cloud Density crashes on real time rendering

Sergey Sharybin noreply at git.blender.org
Wed Nov 25 13:51:51 CET 2015


Commit: 415b5a43690b3b823506871335281df717309f72
Author: Sergey Sharybin
Date:   Wed Nov 25 17:38:12 2015 +0500
Branches: master
https://developer.blender.org/rB415b5a43690b3b823506871335281df717309f72

Fix T46646: Point Cloud Density crashes on real time rendering

The issue was caused by possible use of object->derivedFinal from the render
thread, The patch tries to eliminate (or at least minimize, huh) amount of
access to the derivedFinal of a source object. It's still possible that in
the case of particle source derived mesh will be still unsafely used, but
with the patch applied we can easily change runtime part of the code and
cache derived mesh on the preparation stage.

Some ideas for the future:

- Check whether cache() was called on the point density node when calling
  calc().

- Cache derivedMesh in the runtime part of point density node to avoid
  possible remained thread conflicts.

- NULL the runtime part of the node on .blend load

Reviewers: campbellbarton, plasmasolutions

Reviewed By: plasmasolutions

Differential Revision: https://developer.blender.org/D1614

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

M	intern/cycles/blender/blender_shader.cpp
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/render/extern/include/RE_render_ext.h
M	source/blender/render/intern/source/pointdensity.c

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

diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 5bbdeb6..3f4f1bb 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -184,6 +184,7 @@ static ShaderNode *add_node(Scene *scene,
                             BL::RenderEngine b_engine,
                             BL::BlendData b_data,
                             BL::Scene b_scene,
+                            const bool background,
                             ShaderGraph *graph,
                             BL::ShaderNodeTree b_ntree,
                             BL::ShaderNode b_node)
@@ -763,6 +764,8 @@ static ShaderNode *add_node(Scene *scene,
 
 		/* TODO(sergey): Use more proper update flag. */
 		if(true) {
+			int settings = background ? 1 : 0;  /* 1 - render settings, 0 - vewport settings. */
+			b_point_density_node.cache_point_density(b_scene, settings);
 			scene->image_manager->tag_reload_image(
 			        point_density->filename,
 			        point_density->builtin_data,
@@ -852,6 +855,7 @@ static void add_nodes(Scene *scene,
                       BL::RenderEngine b_engine,
                       BL::BlendData b_data,
                       BL::Scene b_scene,
+                      const bool background,
                       ShaderGraph *graph,
                       BL::ShaderNodeTree b_ntree,
                       const ProxyMap &proxy_input_map,
@@ -937,6 +941,7 @@ static void add_nodes(Scene *scene,
 				          b_engine,
 				          b_data,
 				          b_scene,
+				          background,
 				          graph,
 				          b_group_ntree,
 				          group_proxy_input_map,
@@ -984,6 +989,7 @@ static void add_nodes(Scene *scene,
 				                b_engine,
 				                b_data,
 				                b_scene,
+				                background,
 				                graph,
 				                b_ntree,
 				                BL::ShaderNode(*b_node));
@@ -1046,6 +1052,7 @@ static void add_nodes(Scene *scene,
                       BL::RenderEngine b_engine,
                       BL::BlendData b_data,
                       BL::Scene b_scene,
+                      const bool background,
                       ShaderGraph *graph,
                       BL::ShaderNodeTree b_ntree)
 {
@@ -1054,6 +1061,7 @@ static void add_nodes(Scene *scene,
 	          b_engine,
 	          b_data,
 	          b_scene,
+	          background,
 	          graph,
 	          b_ntree,
 	          empty_proxy_map,
@@ -1083,7 +1091,7 @@ void BlenderSync::sync_materials(bool update_all)
 			if(b_mat->use_nodes() && b_mat->node_tree()) {
 				BL::ShaderNodeTree b_ntree(b_mat->node_tree());
 
-				add_nodes(scene, b_engine, b_data, b_scene, graph, b_ntree);
+				add_nodes(scene, b_engine, b_data, b_scene, !preview, graph, b_ntree);
 			}
 			else {
 				ShaderNode *closure, *out;
@@ -1126,7 +1134,7 @@ void BlenderSync::sync_world(bool update_all)
 		if(b_world && b_world.use_nodes() && b_world.node_tree()) {
 			BL::ShaderNodeTree b_ntree(b_world.node_tree());
 
-			add_nodes(scene, b_engine, b_data, b_scene, graph, b_ntree);
+			add_nodes(scene, b_engine, b_data, b_scene, !preview, graph, b_ntree);
 
 			/* volume */
 			PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
@@ -1217,7 +1225,7 @@ void BlenderSync::sync_lamps(bool update_all)
 
 				BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
 
-				add_nodes(scene, b_engine, b_data, b_scene, graph, b_ntree);
+				add_nodes(scene, b_engine, b_data, b_scene, !preview, graph, b_ntree);
 			}
 			else {
 				ShaderNode *closure, *out;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 6d282f4..86713d7 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -807,6 +807,7 @@ typedef struct NodeShaderTexPointDensity {
 	short interpolation;
 	short color_source;
 	short pad2;
+	PointDensity pd;
 } NodeShaderTexPointDensity;
 
 /* TEX_output */
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 2d412bf..e7e8f6d 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -3016,6 +3016,39 @@ static int point_density_color_source_from_shader(NodeShaderTexPointDensity *sha
 	}
 }
 
+void rna_ShaderNodePointDensity_density_cache(bNode *self,
+                                              Scene *scene,
+                                              int settings)
+{
+	NodeShaderTexPointDensity *shader_point_density = self->storage;
+	PointDensity *pd = &shader_point_density->pd;
+	if (scene == NULL) {
+		return;
+	}
+
+	/* Create PointDensity structure from node for sampling. */
+	memset(pd, 0, sizeof(*pd));
+	BKE_texture_pointdensity_init_data(pd);
+	pd->object = (Object *)self->id;
+	pd->radius = shader_point_density->radius;
+	if (shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_PSYS) {
+		pd->source = TEX_PD_PSYS;
+		pd->psys = shader_point_density->particle_system;
+		pd->psys_cache_space = TEX_PD_OBJECTSPACE;
+	}
+	else {
+		BLI_assert(shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_OBJECT);
+		pd->source = TEX_PD_OBJECT;
+		pd->ob_cache_space = TEX_PD_OBJECTSPACE;
+	}
+	pd->color_source = point_density_color_source_from_shader(shader_point_density);
+
+	/* Single-threaded sampling of the voxel domain. */
+	RE_cache_point_density(scene,
+	                       pd,
+	                       settings == 1);
+}
+
 void rna_ShaderNodePointDensity_density_calc(bNode *self,
                                              Scene *scene,
                                              int settings,
@@ -3023,7 +3056,7 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self,
                                              float **values)
 {
 	NodeShaderTexPointDensity *shader_point_density = self->storage;
-	PointDensity pd;
+	PointDensity *pd = &shader_point_density->pd;
 
 	if (scene == NULL) {
 		*length = 0;
@@ -3038,30 +3071,14 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self,
 		*values = MEM_mallocN(sizeof(float) * (*length), "point density dynamic array");
 	}
 
-	/* Create PointDensity structure from node for sampling. */
-	BKE_texture_pointdensity_init_data(&pd);
-	pd.object = (Object *)self->id;
-	pd.radius = shader_point_density->radius;
-	if (shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_PSYS) {
-		pd.source = TEX_PD_PSYS;
-		pd.psys = shader_point_density->particle_system;
-		pd.psys_cache_space = TEX_PD_OBJECTSPACE;
-	}
-	else {
-		BLI_assert(shader_point_density->point_source == SHD_POINTDENSITY_SOURCE_OBJECT);
-		pd.source = TEX_PD_OBJECT;
-		pd.ob_cache_space = TEX_PD_OBJECTSPACE;
-	}
-	pd.color_source = point_density_color_source_from_shader(shader_point_density);
-
 	/* Single-threaded sampling of the voxel domain. */
-	RE_sample_point_density(scene, &pd,
+	RE_sample_point_density(scene, pd,
 	                        shader_point_density->resolution,
 	                        settings == 1,
 	                        *values);
 
 	/* We're done, time to clean up. */
-	BKE_texture_pointdensity_free_data(&pd);
+	BKE_texture_pointdensity_free_data(pd);
 }
 
 #else
@@ -3993,6 +4010,11 @@ static void def_sh_tex_pointdensity(StructRNA *srna)
 	RNA_def_property_ui_text(prop, "Color Source", "Data to derive color results from");
 	RNA_def_property_update(prop, 0, "rna_Node_update");
 
+	func = RNA_def_function(srna, "cache_point_density", "rna_ShaderNodePointDensity_density_cache");
+	RNA_def_function_ui_description(func, "Cache point density data for later calculation");
+	RNA_def_pointer(func, "scene", "Scene", "", "");
+	RNA_def_enum(func, "settings", calc_mode_items, 1, "", "Calculate density for rendering");
+
 	func = RNA_def_function(srna, "calc_point_density", "rna_ShaderNodePointDensity_density_calc");
 	RNA_def_function_ui_description(func, "Calculate point density");
 	RNA_def_pointer(func, "scene", "Scene", "", "");
diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h
index 85a9dc9..81d1a00 100644
--- a/source/blender/render/extern/include/RE_render_ext.h
+++ b/source/blender/render/extern/include/RE_render_ext.h
@@ -63,6 +63,10 @@ void RE_sample_material_color(
 
 struct PointDensity;
 
+void RE_cache_point_density(struct Scene *scene,
+                            struct PointDensity *pd,
+                            const bool use_render_params);
+
 void RE_sample_point_density(struct Scene *scene,
                              struct PointDensity *pd,
                              const int resolution,
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index 9b58bde..4028d80 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -715,6 +715,21 @@ static void particle_system_minmax(Scene *scene,
 	}
 }
 
+void RE_cache_point_density(Scene *scene,
+                            PointDensity *pd,
+                            const bool use_render_params)
+{
+	float mat[4][4];
+	/* Same matricies/resolution as dupli_render_particle_set(). */
+	unit_m4(mat);
+	BLI_mutex_lock(&sample_mutex);
+	cache_pointdensity_ex(scene, pd, mat, mat, 1, 1, use_render_params);
+	BLI_mutex_unlock(&sample_mutex);
+}
+
+/* NOTE 1: Requires RE_cache_point_density() to be called first.
+ * NOTE 2: Frees point density structure after sampling.
+ */
 void RE_sample_point_density(Scene *scene,
                              PointDensity *pd,
                              const int resolution,
@@ -724,7 +739,11 @@ void RE_sample_point_density(Scene *scene,
 	const size_t resolution2 = resolution * resolution;
 	Object *object = pd->object;
 	size_t x, y, z;
-	float min[3], max[3], dim[3], mat[4][4];
+	float min[3], max[3], dim[3];
+
+	/* TODO(sergey): Implement some sort of assert() that point density
+	 * was cached already.
+	 */
 
 	if (object == NULL) {
 		sample_dummy_point_density(resolution, values);
@@ -766,11 +785,7 @@ void RE_sample_point_density(Scene *scene,
 		return;
 	}
 


@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list