Fixed more texture memory leaks.

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@8498 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2011-05-01 22:38:23 +00:00
parent 92123f8681
commit c216d2b35e
6 changed files with 74 additions and 10 deletions

View File

@@ -868,6 +868,54 @@ video::ITexture *IrrDriver::getTexture(const std::string &filename,
return out;
} // getTexture
// ----------------------------------------------------------------------------
/** Appends a pointer to each texture used in this mesh to the vector.
* \param mesh The mesh from which the textures are being determined.
* \param texture_list The list to which to attach the pointer to.
*/
void IrrDriver::grabAllTextures(const scene::IMesh *mesh)
{
const unsigned int n = mesh->getMeshBufferCount();
for(unsigned int i=0; i<n; i++)
{
scene::IMeshBuffer *b = mesh->getMeshBuffer(i);
video::SMaterial &m = b->getMaterial();
for(unsigned int j=0; j<video::MATERIAL_MAX_TEXTURES; j++)
{
video::ITexture *t = m.getTexture(j);
if(t)
t->grab();
} // for j < MATERIAL_MAX_TEXTURE
} // for i <getMeshBufferCount
} // grabAllTextures
// ----------------------------------------------------------------------------
/** Appends a pointer to each texture used in this mesh to the vector.
* \param mesh The mesh from which the textures are being determined.
* \param texture_list The list to which to attach the pointer to.
*/
void IrrDriver::dropAllTextures(const scene::IMesh *mesh)
{
const unsigned int n = mesh->getMeshBufferCount();
for(unsigned int i=0; i<n; i++)
{
scene::IMeshBuffer *b = mesh->getMeshBuffer(i);
video::SMaterial &m = b->getMaterial();
for(unsigned int j=0; j<video::MATERIAL_MAX_TEXTURES; j++)
{
video::ITexture *t = m.getTexture(j);
if(t)
{
t->drop();
if(t->getReferenceCount()==1)
removeTexture(t);
} // if t
} // for j < MATERIAL_MAX_TEXTURE
} // for i <getMeshBufferCount
} // dropAllTextures
// ----------------------------------------------------------------------------
ITexture* IrrDriver::applyMask(video::ITexture* texture,
const std::string& mask_path)

View File

@@ -120,6 +120,8 @@ public:
video::ITexture *getTexture(const std::string &filename,
bool is_premul=false,
bool is_prediv=false);
void grabAllTextures(const scene::IMesh *mesh);
void dropAllTextures(const scene::IMesh *mesh);
scene::IMesh *createQuadMesh(const video::SMaterial *material=NULL,
bool create_one_quad=false);
scene::IMesh *createTexturedQuadMesh(const video::SMaterial *material,

View File

@@ -264,12 +264,14 @@ void Material::install(bool is_full_path)
if (tex) m_texture = tex;
else fprintf(stderr, "Applying mask failed for '%s'!\n", m_texname.c_str());
}
m_texture->grab();
} // install
//-----------------------------------------------------------------------------
Material::~Material()
{
if(m_texture)
assert(m_texture);
m_texture->drop();
if(m_texture->getReferenceCount()==1)
irr_driver->removeTexture(m_texture);
// If a special sfx is installed (that isn't part of stk itself), the
// entry needs to be removed from the sfx_manager's mapping, since other

View File

@@ -217,11 +217,11 @@ void Track::cleanup()
{
video::ITexture *t = vd->getTextureByIndex(i);
std::vector<video::ITexture*>::iterator p;
p = std::find(m_all_used_textures.begin(), m_all_used_textures.end(),
p = std::find(m_old_textures.begin(), m_old_textures.end(),
t);
if(p!=m_all_used_textures.end())
if(p!=m_old_textures.end())
{
m_all_used_textures.erase(p);
m_old_textures.erase(p);
}
else
{
@@ -1008,12 +1008,12 @@ void Track::loadTrackModel(World* parent, unsigned int mode_id)
m_old_mesh_buffers.push_back(name.getInternalName().c_str());
}
m_all_used_textures.clear();
m_old_textures.clear();
video::IVideoDriver *vd = irr_driver->getVideoDriver();
for(unsigned int i=0; i<vd->getTextureCount(); i++)
{
video::ITexture *t=vd->getTextureByIndex(i);
m_all_used_textures.push_back(t);
m_old_textures.push_back(t);
}
#endif
}

View File

@@ -76,17 +76,27 @@ private:
std::string m_designer;
/** The full filename of the config (xml) file. */
std::string m_filename;
/** The base dir of all files of this track. */
std::string m_root;
std::vector<std::string> m_groups;
std::vector<scene::ISceneNode*> m_all_nodes;
/** The list of all meshes that are loaded from disk, which means
* that those meshes are being cached by irrlicht, and need to be freed. */
std::vector<scene::IMesh*> m_all_cached_meshes;
/** A list of textures to help in removing unused textures from irrlicht's
* texture cache after cleanup. */
std::vector<video::ITexture*> m_all_used_textures;
/** A list of all textures loaded by the track, so that they can
* be removed from the cache at cleanup time. */
std::vector<video::ITexture*> m_all_cached_textures;
#ifdef DEBUG
/** A list of textures that were cached before the track is loaded.
* After cleanup of ta track it can be tested which new textures
* are still in the cache, and print a report of leaked textures
* (in debug mode only). */
std::vector<video::ITexture*> m_old_textures;
/** Used to store all buffers in irrlicht's memory cache before a track
* is loaded. After cleanup of a track we can test which meshes are
* still in the cache, and print a report of leaked meshes (of course in

View File

@@ -77,6 +77,7 @@ TrackObject::TrackObject(const XMLNode &xml_node)
}
m_mesh->grab();
irr_driver->grabAllTextures(m_mesh);
scene::IAnimatedMeshSceneNode *node=irr_driver->addAnimatedMesh(m_mesh);
m_node = node;
#ifdef DEBUG
@@ -104,6 +105,7 @@ TrackObject::~TrackObject()
{
if(m_node)
irr_driver->removeNode(m_node);
irr_driver->dropAllTextures(m_mesh);
if(m_mesh)
{
m_mesh->drop();