OpenFlight: Replace internal caches with osgDB::ObjectCache use. Fixes unbounded memory growth when using readNode(std::istream&, ...) method.

This commit is contained in:
Daniel Emminizer 2018-07-31 11:45:33 -04:00
parent 11e4a995c4
commit 2e0e78144f
3 changed files with 11 additions and 37 deletions

View File

@ -495,15 +495,15 @@ protected:
} }
// Is texture in local cache? // Is texture in local cache?
osg::StateSet* stateset = flt::Registry::instance()->getTextureFromLocalCache(pathname); osg::ref_ptr<osg::StateSet> stateset = flt::Registry::instance()->getTextureFromLocalCache(pathname);
// Read file if not in cache. // Read file if not in cache.
if (!stateset) if (!stateset.valid())
{ {
stateset = readTexture(pathname,document); stateset = readTexture(pathname,document);
// Add to texture cache. // Add to texture cache.
flt::Registry::instance()->addTextureToLocalCache(pathname,stateset); flt::Registry::instance()->addTextureToLocalCache(pathname,stateset.get());
} }
// Add to texture pool. // Add to texture pool.

View File

@ -276,8 +276,8 @@ class FLTReaderWriter : public ReaderWriter
// in local cache? // in local cache?
{ {
osg::Node* node = flt::Registry::instance()->getExternalFromLocalCache(fileName); osg::ref_ptr<osg::Node> node = flt::Registry::instance()->getExternalFromLocalCache(fileName);
if (node) if (node.valid())
return ReadResult(node, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE); return ReadResult(node, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
} }
@ -299,7 +299,6 @@ class FLTReaderWriter : public ReaderWriter
} }
} }
static int nestedExternalsLevel = 0;
if (rr.success()) if (rr.success())
{ {
// add to local cache. // add to local cache.
@ -316,10 +315,8 @@ class FLTReaderWriter : public ReaderWriter
// read externals. // read externals.
if (rr.getNode()) if (rr.getNode())
{ {
nestedExternalsLevel++;
ReadExternalsVisitor visitor(local_opt.get()); ReadExternalsVisitor visitor(local_opt.get());
rr.getNode()->accept(visitor); rr.getNode()->accept(visitor);
nestedExternalsLevel--;
} }
} }
else else
@ -334,10 +331,6 @@ class FLTReaderWriter : public ReaderWriter
rr.getNode()->accept(cbov); rr.getNode()->accept(cbov);
} }
// clear local cache.
if (nestedExternalsLevel==0)
flt::Registry::instance()->clearLocalCache();
return rr; return rr;
} }

View File

@ -23,6 +23,8 @@
#include <queue> #include <queue>
#include <map> #include <map>
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <osgDB/ObjectCache>
#include <osgDB/Registry>
#include "Opcodes.h" #include "Opcodes.h"
#include "Record.h" #include "Record.h"
@ -51,7 +53,6 @@ class Registry : public osg::Referenced
osg::Node* getExternalFromLocalCache(const std::string& filename); osg::Node* getExternalFromLocalCache(const std::string& filename);
void addTextureToLocalCache(const std::string& filename, osg::StateSet* stateset); void addTextureToLocalCache(const std::string& filename, osg::StateSet* stateset);
osg::StateSet* getTextureFromLocalCache(const std::string& filename); osg::StateSet* getTextureFromLocalCache(const std::string& filename);
void clearLocalCache();
protected: protected:
@ -61,14 +62,6 @@ class Registry : public osg::Referenced
RecordProtoMap _recordProtoMap; RecordProtoMap _recordProtoMap;
ExternalQueue _externalReadQueue; ExternalQueue _externalReadQueue;
// External cache
typedef std::map<std::string, osg::ref_ptr<osg::Node> > ExternalCacheMap;
ExternalCacheMap _externalCacheMap;
// Texture cache
typedef std::map<std::string, osg::ref_ptr<osg::StateSet> > TextureCacheMap;
TextureCacheMap _textureCacheMap;
}; };
inline void Registry::addToExternalReadQueue(const std::string& filename, osg::Group* parent) 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) 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) inline osg::Node* Registry::getExternalFromLocalCache(const std::string& filename)
{ {
ExternalCacheMap::iterator itr = _externalCacheMap.find(filename); return dynamic_cast<osg::Node*>(osgDB::Registry::instance()->getFromObjectCache(filename));
if (itr != _externalCacheMap.end())
return (*itr).second.get();
return NULL;
} }
inline void Registry::addTextureToLocalCache(const std::string& filename, osg::StateSet* stateset) 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) inline osg::StateSet* Registry::getTextureFromLocalCache(const std::string& filename)
{ {
TextureCacheMap::iterator itr = _textureCacheMap.find(filename); return dynamic_cast<osg::StateSet*>(osgDB::Registry::instance()->getFromObjectCache(filename));
if (itr != _textureCacheMap.end())
return (*itr).second.get();
return NULL;
}
inline void Registry::clearLocalCache()
{
_externalCacheMap.clear();
_textureCacheMap.clear();
} }
/** Proxy class for automatic registration of reader/writers with the Registry.*/ /** Proxy class for automatic registration of reader/writers with the Registry.*/