summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2012-10-03 17:04:56 +0300
committerAndrei Karas <akaras@inbox.ru>2012-10-03 17:51:24 +0300
commit4dc93e343e0fb4990320e1056bca666e8ce8c3d9 (patch)
treed2a9220f19605f450942a0a38a18512916a3e500
parent42411c8963eec06448a5dbf565add0540d6987f1 (diff)
downloadmv-4dc93e343e0fb4990320e1056bca666e8ce8c3d9.tar.gz
mv-4dc93e343e0fb4990320e1056bca666e8ce8c3d9.tar.bz2
mv-4dc93e343e0fb4990320e1056bca666e8ce8c3d9.tar.xz
mv-4dc93e343e0fb4990320e1056bca666e8ce8c3d9.zip
fix memory problems with atlases.
-rw-r--r--src/resources/atlasmanager.cpp25
-rw-r--r--src/resources/resourcemanager.cpp19
-rw-r--r--src/resources/resourcemanager.h2
3 files changed, 41 insertions, 5 deletions
diff --git a/src/resources/atlasmanager.cpp b/src/resources/atlasmanager.cpp
index cd3d1d9db..c36d23254 100644
--- a/src/resources/atlasmanager.cpp
+++ b/src/resources/atlasmanager.cpp
@@ -261,6 +261,11 @@ void AtlasManager::convertAtlas(TextureAtlas *atlas)
// convert surface to OpemGL image
atlas->atlasImage = imageHelper->load(atlas->surface);
Image *const image = atlas->atlasImage;
+ if (image)
+ {
+ image->mIdPath = atlas->name;
+ image->incRef();
+ }
for (std::vector<AtlasItem*>::iterator it = atlas->items.begin(),
it_end = atlas->items.end();
@@ -272,6 +277,12 @@ void AtlasManager::convertAtlas(TextureAtlas *atlas)
// store OpenGL image
item->image = image->getSubImage(item->x, item->y,
item->width, item->height);
+ Image *const image2 = item->image;
+ if (image2)
+ {
+ image2->mIdPath = item->name;
+ image2->incRef();
+ }
}
}
@@ -285,7 +296,9 @@ void AtlasManager::injectToResources(AtlasResource *resource)
TextureAtlas *const atlas = *it;
if (atlas)
{
- resman->addResource(atlas->name, atlas->atlasImage);
+ Image *const image = atlas->atlasImage;
+ if (image)
+ resman->addResource(atlas->name, image);
for (std::vector<AtlasItem*>::iterator it2 = atlas->items.begin(),
it2_end = atlas->items.end();
it2 != it2_end; ++ it2)
@@ -349,11 +362,21 @@ AtlasResource::~AtlasResource()
{
AtlasItem *const item = *it2;
if (item)
+ {
+ Image *const image2 = item->image;
+ if (image2)
+ image2->decRef();
delete item;
+ }
}
+ Image *const image = atlas->atlasImage;
+ if (image)
+ image->decRef();
delete atlas;
}
}
+ ResourceManager *const resman = ResourceManager::getInstance();
+ resman->clearDeleted(false);
}
void AtlasResource::incRef()
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index b6befb491..ba23e4ac2 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -258,7 +258,7 @@ void ResourceManager::logResource(const Resource *const res)
#endif
}
-void ResourceManager::clearDeleted()
+void ResourceManager::clearDeleted(bool full)
{
bool status(true);
logger->log("clear deleted");
@@ -280,7 +280,7 @@ void ResourceManager::clearDeleted()
++ resDelIter;
}
}
- if (!mDeletedResources.empty())
+ if (full && !mDeletedResources.empty())
{
logger->log("leaks in deleted");
std::set<Resource*>::iterator resDelIter = mDeletedResources.begin();
@@ -783,8 +783,21 @@ void ResourceManager::release(Resource *const res)
ResourceIterator resIter = mResources.find(res->mIdPath);
+ if (resIter == mResources.end())
+ {
+ logger->log("no resource in cache: " + res->mIdPath);
+ delete res;
+ return;
+ }
+ if (resIter->second != res)
+ {
+ logger->log("in cache other image: " + res->mIdPath);
+ delete res;
+ return;
+ }
+
// The resource has to exist
- assert(resIter != mResources.end() && resIter->second == res);
+// assert(resIter != mResources.end() && resIter->second == res);
timeval tv;
gettimeofday(&tv, nullptr);
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index 432d404b6..6f8b386f0 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -225,7 +225,7 @@ class ResourceManager final
*/
void release(Resource *const res);
- void clearDeleted();
+ void clearDeleted(bool full = true);
static void logResource(const Resource *const res);