[Bf-blender-cvs] [2c5f878] openvdb: Cycles: create per-thread utils before the actual rendering starts.

Kévin Dietrich noreply at git.blender.org
Sun Jan 17 17:18:57 CET 2016


Commit: 2c5f878ba18ff606f090dc9bcf172b1aa0b2f191
Author: Kévin Dietrich
Date:   Sun Jan 17 16:27:21 2016 +0100
Branches: openvdb
https://developer.blender.org/rB2c5f878ba18ff606f090dc9bcf172b1aa0b2f191

Cycles: create per-thread utils before the actual rendering starts.

Previously, those were created on the fly as needed, but wasn't thread
safe at all, since multiple threads could write to the maps at the same
time.

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

M	intern/cycles/render/volume.cpp
M	intern/cycles/util/util_task.cpp
M	intern/cycles/util/util_task.h
M	intern/cycles/util/util_thread.h
M	intern/cycles/util/util_volume.h

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

diff --git a/intern/cycles/render/volume.cpp b/intern/cycles/render/volume.cpp
index fd8a66d..71aba3c 100644
--- a/intern/cycles/render/volume.cpp
+++ b/intern/cycles/render/volume.cpp
@@ -18,6 +18,7 @@
 #include "scene.h"
 #include "util_logging.h"
 #include "util_progress.h"
+#include "util_task.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -194,6 +195,7 @@ size_t VolumeManager::add_openvdb_volume(const std::string& filename, const std:
 		FloatGrid::Ptr fgrid = gridPtrCast<FloatGrid>(grid);
 
 		vdb_float_volume *sampler = new vdb_float_volume(fgrid);
+		sampler->create_threads_utils(TaskScheduler::thread_ids());
 		float_volumes.insert(float_volumes.begin() + slot, sampler);
 		scalar_grids.push_back(fgrid);
 	}
@@ -205,6 +207,7 @@ size_t VolumeManager::add_openvdb_volume(const std::string& filename, const std:
 		Vec3SGrid::Ptr vgrid = gridPtrCast<Vec3SGrid>(grid);
 
 		vdb_float3_volume *sampler = new vdb_float3_volume(vgrid);
+		sampler->create_threads_utils(TaskScheduler::thread_ids());
 		float3_volumes.insert(float3_volumes.begin() + slot, sampler);
 		vector_grids.push_back(vgrid);
 	}
diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp
index d56553d..2186c7c 100644
--- a/intern/cycles/util/util_task.cpp
+++ b/intern/cycles/util/util_task.cpp
@@ -298,6 +298,18 @@ void TaskScheduler::clear(TaskPool *pool)
 	pool->num_decrease(done);
 }
 
+vector<pthread_t> TaskScheduler::thread_ids()
+{
+	thread_scoped_lock lock(mutex);
+
+	vector<pthread_t> ids;
+	foreach(thread *t, threads) {
+		ids.push_back(t->id());
+	}
+
+	return ids;
+}
+
 /* Dedicated Task Pool */
 
 DedicatedTaskPool::DedicatedTaskPool()
diff --git a/intern/cycles/util/util_task.h b/intern/cycles/util/util_task.h
index debcff3..e0e1f90 100644
--- a/intern/cycles/util/util_task.h
+++ b/intern/cycles/util/util_task.h
@@ -95,6 +95,9 @@ public:
 	/* number of threads that can work on task */
 	static int num_threads() { return threads.size(); }
 
+	/* ids of all threads managed by the scheduler */
+	static vector<pthread_t> thread_ids();
+
 	/* test if any session is using the scheduler */
 	static bool active() { return users != 0; }
 
diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h
index 9c19235..027eca4 100644
--- a/intern/cycles/util/util_thread.h
+++ b/intern/cycles/util/util_thread.h
@@ -75,6 +75,11 @@ public:
 		return pthread_join(pthread_id, NULL) == 0;
 	}
 
+	pthread_t id() const
+	{
+		return pthread_id;
+	}
+
 protected:
 	function<void(void)> run_cb;
 	pthread_t pthread_id;
diff --git a/intern/cycles/util/util_volume.h b/intern/cycles/util/util_volume.h
index bcd1318..1bc10a0 100644
--- a/intern/cycles/util/util_volume.h
+++ b/intern/cycles/util/util_volume.h
@@ -54,6 +54,7 @@ CCL_NAMESPACE_END
 #endif
 
 #include "util_map.h"
+#include "util_vector.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -63,6 +64,52 @@ using std::isfinite;
 using boost::math::isfinite;
 #endif
 
+template <typename IsectorType>
+void create_isectors_threads(unordered_map<pthread_t, IsectorType *> &isect_map,
+                             const vector<pthread_t> &thread_ids,
+                             const IsectorType &main_isect)
+{
+	pthread_t my_thread = pthread_self();
+
+	for (size_t i = 0; i < thread_ids.size(); ++i) {
+		IsectorType *isect = new IsectorType(main_isect);
+		pair<pthread_t, IsectorType *> inter(thread_ids[i], isect);
+		isect_map.insert(inter);
+	}
+
+	if (isect_map.find(my_thread) == isect_map.end()) {
+		IsectorType *isect = new IsectorType(main_isect);
+		pair<pthread_t, IsectorType *> inter(my_thread, isect);
+		isect_map.insert(inter);
+	}
+}
+
+template <typename SamplerType, typename AccessorType>
+void create_samplers_threads(unordered_map<pthread_t, SamplerType *> &sampler_map,
+                             vector<AccessorType *> &accessors,
+                             const vector<pthread_t> &thread_ids,
+                             const openvdb::math::Transform *transform,
+                             const AccessorType &main_accessor)
+{
+	pthread_t my_thread = pthread_self();
+
+	for (size_t i = 0; i < thread_ids.size(); ++i) {
+		AccessorType *accessor = new AccessorType(main_accessor);
+		accessors.push_back(accessor);
+		SamplerType *sampler = new SamplerType(*accessor, *transform);
+		pair<pthread_t, SamplerType *> sampl(thread_ids[i], sampler);
+		sampler_map.insert(sampl);
+	}
+
+	if (sampler_map.find(my_thread) == sampler_map.end()) {
+		AccessorType *accessor = new AccessorType(main_accessor);
+		accessors.push_back(accessor);
+		SamplerType *sampler = new SamplerType(*accessor, *transform);
+		pair<pthread_t, SamplerType *> sampl(my_thread, sampler);
+		sampler_map.insert(sampl);
+	}
+}
+
 typedef openvdb::math::Ray<float> vdb_ray_t;
 
 class vdb_float_volume : public float_volume {
@@ -80,10 +127,10 @@ class vdb_float_volume : public float_volume {
 	point_map point_samplers;
 	box_map box_samplers;
 
-	std::vector<openvdb::FloatGrid::ConstAccessor *> accessors;
+	vector<openvdb::FloatGrid::ConstAccessor *> accessors;
 
 	openvdb::FloatGrid::ConstAccessor *accessor;
-	openvdb::math::Transform *transfrom;
+	openvdb::math::Transform *transform;
 
 	/* Main intersector, its purpose is to initialize the voxels' bounding box
 	 * so the ones for the various threads do not do this, rather they are
@@ -94,7 +141,7 @@ class vdb_float_volume : public float_volume {
 
 public:
 	vdb_float_volume(openvdb::FloatGrid::Ptr grid)
-	    : transfrom(&grid->transform())
+	    : transform(&grid->transform())
 	{
 		accessor = new openvdb::FloatGrid::ConstAccessor(grid->getConstAccessor());
 
@@ -144,41 +191,28 @@ public:
 		}
 	}
 
+	void create_threads_utils(const vector<pthread_t> &thread_ids)
+	{
+		create_isectors_threads(isectors, thread_ids, *main_isector);
+		create_samplers_threads(point_samplers, accessors, thread_ids, transform, *accessor);
+		create_samplers_threads(box_samplers, accessors, thread_ids, transform, *accessor);
+	}
+
 	ccl_always_inline float sample(float x, float y, float z, int sampling)
 	{
 		pthread_t thread = pthread_self();
 
 		if(sampling == OPENVDB_SAMPLE_POINT) {
 			point_map::iterator iter = point_samplers.find(thread);
-			point_sampler_t *sampler;
-
-			if(iter == point_samplers.end()) {
-				openvdb::FloatGrid::ConstAccessor *acc = new openvdb::FloatGrid::ConstAccessor(*accessor);
-				accessors.push_back(acc);
-				sampler = new point_sampler_t(*acc, *transfrom);
-				pair<pthread_t, point_sampler_t *> sampl(thread, sampler);
-				point_samplers.insert(sampl);
-			}
-			else {
-				sampler = iter->second;
-			}
+			assert(iter != point_samplers.end());
+			point_sampler_t *sampler = iter->second;
 
 			return sampler->wsSample(openvdb::Vec3d(x, y, z));
 		}
 		else {
 			box_map::iterator iter = box_samplers.find(thread);
-			box_sampler_t *sampler;
-
-			if(iter == box_samplers.end()) {
-				openvdb::FloatGrid::ConstAccessor *acc = new openvdb::FloatGrid::ConstAccessor(*accessor);
-				accessors.push_back(acc);
-				sampler = new box_sampler_t(*acc, *transfrom);
-				pair<pthread_t, box_sampler_t *> sampl(thread, sampler);
-				box_samplers.insert(sampl);
-			}
-			else {
-				sampler = iter->second;
-			}
+			assert(iter != box_samplers.end());
+			box_sampler_t *sampler = iter->second;
 
 			return sampler->wsSample(openvdb::Vec3d(x, y, z));
 		}
@@ -188,16 +222,8 @@ public:
 	{
 		pthread_t thread = pthread_self();
 		isect_map::iterator iter = isectors.find(thread);
-		isector_t *vdb_isect;
-
-		if(iter == isectors.end()) {
-			vdb_isect = new isector_t(*main_isector);
-			pair<pthread_t, isector_t *> inter(thread, vdb_isect);
-			isectors.insert(inter);
-		}
-		else {
-			vdb_isect = iter->second;
-		}
+		assert(iter != isectors.end());
+		isector_t *vdb_isect = iter->second;
 
 		vdb_ray_t::Vec3Type P(ray->P.x, ray->P.y, ray->P.z);
 		vdb_ray_t::Vec3Type D(ray->D.x, ray->D.y, ray->D.z);
@@ -268,10 +294,10 @@ class vdb_float3_volume : public float3_volume {
 	stag_point_map stag_point_samplers;
 	stag_box_map stag_box_samplers;
 
-	std::vector<openvdb::Vec3SGrid::ConstAccessor *> accessors;
+	vector<openvdb::Vec3SGrid::ConstAccessor *> accessors;
 
 	openvdb::Vec3SGrid::ConstAccessor *accessor;
-	openvdb::math::Transform *transfrom;
+	openvdb::math::Transform *transform;
 
 	/* Main intersector, its purpose is to initialize the voxels' bounding box
 	 * so the ones for the various threads do not do this, rather they are
@@ -282,7 +308,7 @@ class vdb_float3_volume : public float3_volume {
 
 public:
 	vdb_float3_volume(openvdb::Vec3SGrid::Ptr grid)
-	    : transfrom(&grid->transform())
+	    : transform(&grid->transform())
 	{
 		accessor = new openvdb::Vec3SGrid::ConstAccessor(grid->getConstAccessor());
 		staggered = (grid->getGridClass() == openvdb::GRID_STAGGERED);
@@ -347,6 +373,15 @@ public:
 		}
 	}
 
+	void create_threads_utils(const vector<pthread_t> &thread_ids)
+	{
+		create_isectors_threads(isectors, thread_ids, *main_isector);
+		create_samplers_threads(point_samplers, accessors, thread_ids, transform, *accessor);
+		create_samplers_threads(box_samplers, accessors, thread_ids, transform, *accessor);
+		create_samplers_threads(stag_point_samplers, accessors, thread_ids, transform, *accessor);
+		create_samplers_threads(stag_box_samplers, accessors, thread_ids, transform, *accessor);
+	}
+
 	ccl_always_inline float3 sample_staggered(float x, float y, float z, int sampling)
 	{
 		openvdb::Vec3s r;
@@ -354,35 +389,15 @@ public:
 
 		if(sampling == OPENVDB_SAMPLE_POINT) {
 			stag_point_map::iterator iter = stag_point_samplers.find(thread);
-			stag_point_sampler_t *sampler;
-
-			if(iter == stag_point_samplers.end()) {
-				openvdb::Vec3SGrid::ConstAccessor *acc = new openvdb::Vec3SGrid::ConstAccessor(*accessor);
-				accessors.push_back(acc);
-				sampler = new stag_point_sampler_t(*acc, *transfrom);
-				pair<pthread_t, stag_point_sampler_t *> sampl(thread, sampler);
-				stag_point_samplers.insert(sampl);
-			}
-			else {
-				sampler = iter->second;
-			}
+			assert(iter != stag_point_samplers.end());
+			stag_point_sampler_t *sampler = iter->second;
 
 			r = sampler->wsSample(openvdb::Vec3d(x, y, z));
 		}
 		else {
 			stag_box_map::iterator iter = stag_box_sample

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list