Don't leak cube-map textures

- use observer_ptr so cube-map textures are released without the
builder holing a ref.
This commit is contained in:
James Turner 2014-03-13 22:16:58 +00:00
parent 966789de90
commit c925b7b601

View File

@ -534,8 +534,8 @@ public:
Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*, Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*,
const SGReaderWriterOptions* options); const SGReaderWriterOptions* options);
protected: protected:
typedef map<CubeMapTuple, ref_ptr<TextureCubeMap> > CubeMap; typedef map<CubeMapTuple, observer_ptr<TextureCubeMap> > CubeMap;
typedef map<string, ref_ptr<TextureCubeMap> > CrossCubeMap; typedef map<string, observer_ptr<TextureCubeMap> > CrossCubeMap;
CubeMap _cubemaps; CubeMap _cubemaps;
CrossCubeMap _crossmaps; CrossCubeMap _crossmaps;
}; };
@ -570,10 +570,12 @@ Texture* CubeMapBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode*
CubeMapTuple _tuple = makeCubeMapTuple(effect, texturesProp); CubeMapTuple _tuple = makeCubeMapTuple(effect, texturesProp);
CubeMap::iterator itr = _cubemaps.find(_tuple); CubeMap::iterator itr = _cubemaps.find(_tuple);
if (itr != _cubemaps.end()) ref_ptr<TextureCubeMap> cubeTexture;
return itr->second.get();
TextureCubeMap* cubeTexture = new osg::TextureCubeMap; if (itr != _cubemaps.end() && itr->second.lock(cubeTexture))
return cubeTexture.release();
cubeTexture = new osg::TextureCubeMap;
// TODO: Read these from effect file? Maybe these are sane for all cuebmaps? // TODO: Read these from effect file? Maybe these are sane for all cuebmaps?
cubeTexture->setFilter(osg::Texture3D::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR); cubeTexture->setFilter(osg::Texture3D::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
@ -614,20 +616,22 @@ Texture* CubeMapBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode*
cubeTexture->setImage(TextureCubeMap::NEGATIVE_Z, image); cubeTexture->setImage(TextureCubeMap::NEGATIVE_Z, image);
} }
if (itr == _cubemaps.end())
_cubemaps[_tuple] = cubeTexture; _cubemaps[_tuple] = cubeTexture;
else
return cubeTexture; itr->second = cubeTexture; // update existing
return cubeTexture.release();
} }
// Using 1 cross image // Using 1 cross image
else if(crossProp) { else if(crossProp) {
std::string texname = crossProp->getStringValue(); std::string texname = crossProp->getStringValue();
// Try to find existing cube map // Try to find existing cube map
ref_ptr<TextureCubeMap> cubeTexture;
CrossCubeMap::iterator itr = _crossmaps.find(texname); CrossCubeMap::iterator itr = _crossmaps.find(texname);
if (itr != _crossmaps.end()) if ((itr != _crossmaps.end()) && itr->second.lock(cubeTexture))
return itr->second.get(); return cubeTexture.release();
osgDB::ReaderWriter::ReadResult result; osgDB::ReaderWriter::ReadResult result;
result = osgDB::readImageFile(texname, options); result = osgDB::readImageFile(texname, options);
@ -642,7 +646,7 @@ Texture* CubeMapBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode*
int height = image->t() / 4; int height = image->t() / 4;
int depth = image->r(); int depth = image->r();
TextureCubeMap* cubeTexture = new osg::TextureCubeMap; cubeTexture = new osg::TextureCubeMap;
// Copy the 6 sub-images and push them // Copy the 6 sub-images and push them
for(int n=0; n<6; n++) { for(int n=0; n<6; n++) {
@ -700,9 +704,11 @@ Texture* CubeMapBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode*
} }
if (itr == _crossmaps.end())
_crossmaps[texname] = cubeTexture; _crossmaps[texname] = cubeTexture;
else
return cubeTexture; itr->second = cubeTexture; // update existing
return cubeTexture.release();
} else { } else {
throw BuilderException("Could not load cube cross"); throw BuilderException("Could not load cube cross");