From fb436be8f1b47220ed7c8921c641869cdee5cb22 Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 29 Jul 2021 17:50:14 +0100 Subject: [PATCH] MaterialLib: make it thread-safe --- simgear/scene/material/matlib.cxx | 53 +++++++++++++++++++++---------- simgear/scene/material/matlib.hxx | 2 ++ 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/simgear/scene/material/matlib.cxx b/simgear/scene/material/matlib.cxx index 9e6dd307..2d1a3f74 100644 --- a/simgear/scene/material/matlib.cxx +++ b/simgear/scene/material/matlib.cxx @@ -87,6 +87,8 @@ bool SGMaterialLib::load( const SGPath &fg_root, const SGPath& mpath, options->setObjectCacheHint(osgDB::Options::CACHE_ALL); options->setDatabasePath(fg_root.utf8Str()); + std::lock_guard g(d->mutex); + simgear::PropertyList blocks = materialblocks.getChildren("region"); simgear::PropertyList::const_iterator block_iter = blocks.begin(); @@ -174,14 +176,20 @@ bool SGMaterialLib::load( const SGPath &fg_root, const SGPath& mpath, // find a material record by material name and tile center SGMaterial *SGMaterialLib::find( const string& material, const SGVec2f center ) const +{ + std::lock_guard g(d->mutex); + return internalFind(material, center); +} + +SGMaterial* SGMaterialLib::internalFind(const string& material, const SGVec2f center) const { SGMaterial *result = NULL; const_material_map_iterator it = matlib.find( material ); - if ( it != end() ) { + if (it != end()) { // We now have a list of materials that match this // name. Find the first one that matches. - // We start at the end of the list, as the materials - // list is ordered with the smallest regions at the end. + // We start at the end of the list, as the materials + // list is ordered with the smallest regions at the end. material_list::const_reverse_iterator iter = it->second.rbegin(); while (iter != it->second.rend()) { result = *iter; @@ -197,12 +205,18 @@ SGMaterial *SGMaterialLib::find( const string& material, const SGVec2f center ) SGMaterial *SGMaterialLib::find( int lc, const SGVec2f center ) const { - const_landclass_map_iterator it = landclasslib.find( lc ); - if (it != landclasslib.end()) { - return find(it->second.first, center); - } else { - return NULL; + std::string materialName; + { + std::lock_guard g(d->mutex); + const_landclass_map_iterator it = landclasslib.find(lc); + if (it == landclasslib.end()) { + return nullptr; + } + + materialName = it->second.first; } + + return find(materialName, center); } // find a material record by material name and tile center @@ -215,28 +229,35 @@ SGMaterial *SGMaterialLib::find( const string& material, const SGGeod& center ) // find a material record by material name and tile center SGMaterial *SGMaterialLib::find( int lc, const SGGeod& center ) const { - const_landclass_map_iterator it = landclasslib.find( lc ); - if (it != landclasslib.end()) { - return find(it->second.first, center); - } else { - return NULL; + std::string materialName; + { + std::lock_guard g(d->mutex); + const_landclass_map_iterator it = landclasslib.find(lc); + if (it == landclasslib.end()) { + return nullptr; + } + + materialName = it->second.first; } + + return find(materialName, center); } SGMaterialCache *SGMaterialLib::generateMatCache(SGVec2f center, const simgear::SGReaderWriterOptions* options) { + std::lock_guard g(d->mutex); - SGMaterialCache* newCache = new SGMaterialCache(getMaterialTextureAtlas(center, options)); + SGMaterialCache* newCache = new SGMaterialCache(getMaterialTextureAtlas(center, options)); material_map::const_reverse_iterator it = matlib.rbegin(); for (; it != matlib.rend(); ++it) { - newCache->insert(it->first, find(it->first, center)); + newCache->insert(it->first, internalFind(it->first, center)); } // Collapse down the mapping from landclasses to materials. const_landclass_map_iterator lc_iter = landclasslib.begin(); for (; lc_iter != landclasslib.end(); ++lc_iter) { - newCache->insert(lc_iter->first, find(lc_iter->second.first, center)); + newCache->insert(lc_iter->first, internalFind(lc_iter->second.first, center)); } return newCache; diff --git a/simgear/scene/material/matlib.hxx b/simgear/scene/material/matlib.hxx index e0d15eb1..e1649c6e 100644 --- a/simgear/scene/material/matlib.hxx +++ b/simgear/scene/material/matlib.hxx @@ -120,6 +120,8 @@ private: // Get a (cached) texture atlas for this material cache SGMaterialCache::Atlas getMaterialTextureAtlas(SGVec2f center, const simgear::SGReaderWriterOptions* options); + SGMaterial* internalFind(const std::string& material, const SGVec2f center) const; + public: // Constructor