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>2015-11-25 15:38:12 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-11-25 15:43:44 +0300
commit415b5a43690b3b823506871335281df717309f72 (patch)
treee3d063ad4a9071a0e44ab3d34423dee7ff66be4d /source/blender
parent328208a6a646448246f002a2aa144633c67197e7 (diff)
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
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/makesdna/DNA_node_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c60
-rw-r--r--source/blender/render/extern/include/RE_render_ext.h4
-rw-r--r--source/blender/render/intern/source/pointdensity.c25
4 files changed, 66 insertions, 24 deletions
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 6d282f4ece9..86713d7dcc8 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 2d412bf778b..e7e8f6d6121 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 85a9dc9fccd..81d1a00702d 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 9b58bde730a..4028d80fd86 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;
}
- /* 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);
for (z = 0; z < resolution; ++z) {
for (y = 0; y < resolution; ++y) {
for (x = 0; x < resolution; ++x) {