From 4dc93e343e0fb4990320e1056bca666e8ce8c3d9 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 3 Oct 2012 17:04:56 +0300 Subject: fix memory problems with atlases. --- src/resources/atlasmanager.cpp | 25 ++++++++++++++++++++++++- src/resources/resourcemanager.cpp | 19 ++++++++++++++++--- src/resources/resourcemanager.h | 2 +- 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::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::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::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); -- cgit v1.2.3-60-g2f50