[Bf-blender-cvs] [211afba] alembic: Alembic: Make group's write_sample() threaded

Sergey Sharybin noreply at git.blender.org
Mon Apr 27 15:00:53 CEST 2015


Commit: 211afbabc743b8beed4d56221b8078319f2c8173
Author: Sergey Sharybin
Date:   Mon Apr 27 17:58:13 2015 +0500
Branches: alembic
https://developer.blender.org/rB211afbabc743b8beed4d56221b8078319f2c8173

Alembic: Make group's write_sample() threaded

The idea is to evaluate derived meshes in multiple threads, which will
reduce overall write_sample() time. We can't make all routines threaded
in there because alembic's file IO can't be threaded.

In any case, this change gives 2x speedup of exporting render resolution
version of Franck here.

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

M	source/blender/pointcache/alembic/abc_group.cpp
M	source/blender/pointcache/alembic/abc_group.h
M	source/blender/pointcache/alembic/abc_object.cpp
M	source/blender/pointcache/alembic/abc_object.h

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

diff --git a/source/blender/pointcache/alembic/abc_group.cpp b/source/blender/pointcache/alembic/abc_group.cpp
index 361ffd6..27504b9 100644
--- a/source/blender/pointcache/alembic/abc_group.cpp
+++ b/source/blender/pointcache/alembic/abc_group.cpp
@@ -44,6 +44,8 @@ extern "C" {
 #include "BKE_strands.h"
 }
 
+#include "util_task.h"
+
 namespace PTC {
 
 using namespace Abc;
@@ -131,16 +133,22 @@ void AbcDupligroupWriter::init_abc()
 
 void AbcDupligroupWriter::write_sample_object(Object *ob)
 {
-	AbcWriter *ob_writer = find_id_writer((ID *)ob);
-	if (!ob_writer) {
-		bool do_mesh = (m_cachelib->data_types & CACHE_TYPE_DERIVED_MESH);
-		bool do_hair = (m_cachelib->data_types & CACHE_TYPE_HAIR);
-		
-		ob_writer = new AbcObjectWriter(ob->id.name, m_scene, ob, do_mesh, do_hair);
-		ob_writer->init(abc_archive());
-		m_id_writers.insert(IDWriterPair((ID *)ob, ob_writer));
+	AbcWriter *ob_writer;
+
+	/* TODO(sergey): Optimize this out using RW mutex. */
+	{
+		thread_scoped_lock lock(m_init_mutex);
+		ob_writer = find_id_writer((ID *)ob);
+		if (!ob_writer) {
+			bool do_mesh = (m_cachelib->data_types & CACHE_TYPE_DERIVED_MESH);
+			bool do_hair = (m_cachelib->data_types & CACHE_TYPE_HAIR);
+
+			ob_writer = new AbcObjectWriter(ob->id.name, m_scene, ob, do_mesh, do_hair);
+			ob_writer->init(abc_archive());
+			m_id_writers.insert(IDWriterPair((ID *)ob, ob_writer));
+		}
 	}
-	
+
 	ob_writer->write_sample();
 }
 
@@ -198,16 +206,19 @@ void AbcDupligroupWriter::write_sample()
 		if (dob->ob)
 			dob->ob->id.flag &= ~LIB_DOIT;
 	}
-	
+
+	UtilTaskPool pool;
 	/* write actual object data: duplicator itself + all instanced objects */
 	for (dob = (DupliObject *)duplilist->first; dob; dob = dob->next) {
 		if (dob->ob->id.flag & LIB_DOIT)
 			continue;
 		dob->ob->id.flag |= LIB_DOIT;
-		
-		write_sample_object(dob->ob);
+		pool.push(function_bind(&AbcDupligroupWriter::write_sample_object,
+		                        this, dob->ob));
 	}
-	
+
+	pool.wait_work();
+
 	/* write dupli instances */
 	for (dob = (DupliObject *)duplilist->first, i = 0; dob; dob = dob->next, ++i) {
 		write_sample_dupli(dob, i);
diff --git a/source/blender/pointcache/alembic/abc_group.h b/source/blender/pointcache/alembic/abc_group.h
index 6a26999..7ad6824 100644
--- a/source/blender/pointcache/alembic/abc_group.h
+++ b/source/blender/pointcache/alembic/abc_group.h
@@ -25,6 +25,8 @@
 #include "abc_schema.h"
 #include "abc_writer.h"
 
+#include "util_thread.h"
+
 struct CacheLibrary;
 struct DupliCache;
 struct DupliObject;
@@ -95,6 +97,7 @@ private:
 	ObjectWriterList m_object_writers;
 	PropertyWriterList m_property_writers;
 	IDWriterMap m_id_writers;
+	thread_mutex m_init_mutex;
 };
 
 class AbcDupliCacheWriter : public GroupWriter, public AbcWriter {
diff --git a/source/blender/pointcache/alembic/abc_object.cpp b/source/blender/pointcache/alembic/abc_object.cpp
index 0b2c1a8..a0d6849 100644
--- a/source/blender/pointcache/alembic/abc_object.cpp
+++ b/source/blender/pointcache/alembic/abc_object.cpp
@@ -33,6 +33,8 @@ namespace PTC {
 using namespace Abc;
 using namespace AbcGeom;
 
+thread_mutex AbcObjectWriter::m_sample_write_mutex;
+
 AbcObjectWriter::AbcObjectWriter(const std::string &name, Scene *scene, Object *ob, bool do_mesh, bool do_hair) :
     ObjectWriter(ob, name),
     m_scene(scene),
@@ -106,7 +108,10 @@ void AbcObjectWriter::write_sample()
 			m_final_dm = mesh_create_derived_render(m_scene, m_ob, CD_MASK_BAREMESH);
 			
 			if (m_final_dm) {
-				m_dm_writer->write_sample();
+				{
+					thread_scoped_lock lock(m_sample_write_mutex);
+					m_dm_writer->write_sample();
+				}
 				
 				m_final_dm->release(m_final_dm);
 			}
@@ -117,6 +122,7 @@ void AbcObjectWriter::write_sample()
 				m_final_dm = mesh_get_derived_final(m_scene, m_ob, CD_MASK_BAREMESH);
 			
 			if (m_final_dm) {
+				thread_scoped_lock lock(m_sample_write_mutex);
 				m_dm_writer->write_sample();
 			}
 		}
@@ -125,6 +131,7 @@ void AbcObjectWriter::write_sample()
 	for (int i = 0; i < m_hair_writers.size(); ++i) {
 		AbcHairWriter *hair_writer = m_hair_writers[i];
 		if (hair_writer) {
+			thread_scoped_lock lock(m_sample_write_mutex);
 			hair_writer->write_sample();
 		}
 	}
diff --git a/source/blender/pointcache/alembic/abc_object.h b/source/blender/pointcache/alembic/abc_object.h
index d0b88a9..cb845dc 100644
--- a/source/blender/pointcache/alembic/abc_object.h
+++ b/source/blender/pointcache/alembic/abc_object.h
@@ -32,6 +32,8 @@
 #include "abc_schema.h"
 #include "abc_writer.h"
 
+#include "util_thread.h"
+
 struct DerivedMesh;
 struct Object;
 struct Scene;
@@ -62,6 +64,7 @@ private:
 	Abc::OObject m_abc_object;
 	AbcDerivedMeshWriter *m_dm_writer;
 	HairWriters m_hair_writers;
+	static thread_mutex m_sample_write_mutex;
 };
 
 class AbcObjectReader : public ObjectReader, public AbcReader {




More information about the Bf-blender-cvs mailing list