From 985e82049fb16ff154816d266e2dfe385aa266e1 Mon Sep 17 00:00:00 2001 From: Daniel Emminizer Date: Tue, 31 Jul 2018 11:45:33 -0400 Subject: [PATCH] OpenFlight: Replace internal caches with osgDB::ObjectCache use. Fixes unbounded memory growth when using readNode(std::istream&, ...) method. --- src/osgPlugins/OpenFlight/PaletteRecords.cpp | 6 ++-- src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp | 11 ++----- src/osgPlugins/OpenFlight/Registry.h | 31 ++++--------------- 3 files changed, 11 insertions(+), 37 deletions(-) diff --git a/src/osgPlugins/OpenFlight/PaletteRecords.cpp b/src/osgPlugins/OpenFlight/PaletteRecords.cpp index cdffe75af..0abc5a81b 100644 --- a/src/osgPlugins/OpenFlight/PaletteRecords.cpp +++ b/src/osgPlugins/OpenFlight/PaletteRecords.cpp @@ -495,15 +495,15 @@ protected: } // Is texture in local cache? - osg::StateSet* stateset = flt::Registry::instance()->getTextureFromLocalCache(pathname); + osg::ref_ptr stateset = flt::Registry::instance()->getTextureFromLocalCache(pathname); // Read file if not in cache. - if (!stateset) + if (!stateset.valid()) { stateset = readTexture(pathname,document); // Add to texture cache. - flt::Registry::instance()->addTextureToLocalCache(pathname,stateset); + flt::Registry::instance()->addTextureToLocalCache(pathname,stateset.get()); } // Add to texture pool. diff --git a/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp b/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp index 1308bd578..e964921a7 100644 --- a/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp +++ b/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp @@ -276,8 +276,8 @@ class FLTReaderWriter : public ReaderWriter // in local cache? { - osg::Node* node = flt::Registry::instance()->getExternalFromLocalCache(fileName); - if (node) + osg::ref_ptr node = flt::Registry::instance()->getExternalFromLocalCache(fileName); + if (node.valid()) return ReadResult(node, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE); } @@ -299,7 +299,6 @@ class FLTReaderWriter : public ReaderWriter } } - static int nestedExternalsLevel = 0; if (rr.success()) { // add to local cache. @@ -316,10 +315,8 @@ class FLTReaderWriter : public ReaderWriter // read externals. if (rr.getNode()) { - nestedExternalsLevel++; ReadExternalsVisitor visitor(local_opt.get()); rr.getNode()->accept(visitor); - nestedExternalsLevel--; } } else @@ -334,10 +331,6 @@ class FLTReaderWriter : public ReaderWriter rr.getNode()->accept(cbov); } - // clear local cache. - if (nestedExternalsLevel==0) - flt::Registry::instance()->clearLocalCache(); - return rr; } diff --git a/src/osgPlugins/OpenFlight/Registry.h b/src/osgPlugins/OpenFlight/Registry.h index b94c6eb5a..a786f06b8 100644 --- a/src/osgPlugins/OpenFlight/Registry.h +++ b/src/osgPlugins/OpenFlight/Registry.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "Opcodes.h" #include "Record.h" @@ -51,7 +53,6 @@ class Registry : public osg::Referenced osg::Node* getExternalFromLocalCache(const std::string& filename); void addTextureToLocalCache(const std::string& filename, osg::StateSet* stateset); osg::StateSet* getTextureFromLocalCache(const std::string& filename); - void clearLocalCache(); protected: @@ -61,14 +62,6 @@ class Registry : public osg::Referenced RecordProtoMap _recordProtoMap; ExternalQueue _externalReadQueue; - - // External cache - typedef std::map > ExternalCacheMap; - ExternalCacheMap _externalCacheMap; - - // Texture cache - typedef std::map > TextureCacheMap; - TextureCacheMap _textureCacheMap; }; inline void Registry::addToExternalReadQueue(const std::string& filename, osg::Group* parent) @@ -78,34 +71,22 @@ inline void Registry::addToExternalReadQueue(const std::string& filename, osg::G inline void Registry::addExternalToLocalCache(const std::string& filename, osg::Node* node) { - _externalCacheMap[filename] = node; + osgDB::Registry::instance()->addEntryToObjectCache(filename, node); } inline osg::Node* Registry::getExternalFromLocalCache(const std::string& filename) { - ExternalCacheMap::iterator itr = _externalCacheMap.find(filename); - if (itr != _externalCacheMap.end()) - return (*itr).second.get(); - return NULL; + return dynamic_cast(osgDB::Registry::instance()->getFromObjectCache(filename)); } inline void Registry::addTextureToLocalCache(const std::string& filename, osg::StateSet* stateset) { - _textureCacheMap[filename] = stateset; + osgDB::Registry::instance()->addEntryToObjectCache(filename, stateset); } inline osg::StateSet* Registry::getTextureFromLocalCache(const std::string& filename) { - TextureCacheMap::iterator itr = _textureCacheMap.find(filename); - if (itr != _textureCacheMap.end()) - return (*itr).second.get(); - return NULL; -} - -inline void Registry::clearLocalCache() -{ - _externalCacheMap.clear(); - _textureCacheMap.clear(); + return dynamic_cast(osgDB::Registry::instance()->getFromObjectCache(filename)); } /** Proxy class for automatic registration of reader/writers with the Registry.*/