From: sapier Date: Sun, 7 Apr 2013 20:19:53 +0000 (+0200) Subject: fix huge texture leak in tiledef X-Git-Url: http://81.2.79.47:8989/gitweb/?a=commitdiff_plain;h=5743ef4e6480897bc0a27d19b2dee0de93f6931c;p=zefram%2Fminetest%2Fminetest_engine.git fix huge texture leak in tiledef fix minor glitches too --- diff --git a/src/tile.cpp b/src/tile.cpp index c5e8a2a9..80db32ad 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -201,6 +201,13 @@ struct SourceAtlasPointer class SourceImageCache { public: + ~SourceImageCache() { + for(std::map::iterator iter = m_images.begin(); + iter != m_images.end(); iter++) { + iter->second->drop(); + } + m_images.clear(); + } void insert(const std::string &name, video::IImage *img, bool prefer_local, video::IVideoDriver *driver) { @@ -209,23 +216,28 @@ public: std::map::iterator n; n = m_images.find(name); if(n != m_images.end()){ - video::IImage *oldimg = n->second; - if(oldimg) - oldimg->drop(); + if(n->second) + n->second->drop(); } + + video::IImage* toadd = img; + bool need_to_grab = true; + // Try to use local texture instead if asked to if(prefer_local){ std::string path = getTexturePath(name.c_str()); if(path != ""){ video::IImage *img2 = driver->createImageFromFile(path.c_str()); if(img2){ - m_images[name] = img2; - return; + toadd = img2; + need_to_grab = false; } } } - img->grab(); - m_images[name] = img; + + if (need_to_grab) + toadd->grab(); + m_images[name] = toadd; } video::IImage* get(const std::string &name) { @@ -254,8 +266,7 @@ public: infostream<<"SourceImageCache::getOrLoad(): Loading path \""<createImageFromFile(path.c_str()); - // Even if could not be loaded, put as NULL - //m_images[name] = img; + if(img){ m_images[name] = img; img->grab(); // Grab for caller @@ -274,7 +285,7 @@ class TextureSource : public IWritableTextureSource { public: TextureSource(IrrlichtDevice *device); - ~TextureSource(); + virtual ~TextureSource(); /* Example case: @@ -454,6 +465,27 @@ TextureSource::TextureSource(IrrlichtDevice *device): TextureSource::~TextureSource() { + video::IVideoDriver* driver = m_device->getVideoDriver(); + + unsigned int textures_before = driver->getTextureCount(); + + for (std::vector::iterator iter = + m_atlaspointer_cache.begin(); iter != m_atlaspointer_cache.end(); + iter++) + { + video::ITexture *t = driver->getTexture(iter->name.c_str()); + + //cleanup texture + if (t) + driver->removeTexture(t); + + //cleanup source image + iter->atlas_img->drop(); + } + m_atlaspointer_cache.clear(); + + infostream << "~TextureSource() "<< textures_before << "/" + << driver->getTextureCount() << std::endl; } u32 TextureSource::getTextureId(const std::string &name) @@ -1205,7 +1237,6 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, core::dimension2d dim = image->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); image->copyTo(baseimg); - image->drop(); } // Else blit on base. else @@ -1224,9 +1255,9 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, video::SColor(255,255,255,255), NULL);*/ blit_with_alpha(image, baseimg, pos_from, pos_to, dim); - // Drop image - image->drop(); } + //cleanup + image->drop(); } else {