diff options
author | Thorbjørn Lindeijer <thorbjorn@lindeijer.nl> | 2012-02-08 22:09:07 +0100 |
---|---|---|
committer | Thorbjørn Lindeijer <thorbjorn@lindeijer.nl> | 2012-02-09 23:47:51 +0100 |
commit | 32996cee607c52ecef9be4638df554dd89b39c24 (patch) | |
tree | b3c9987ea39b52e46e5969f938c3aa9002a4bd4c /src/resources/image.cpp | |
parent | 8aeb42b16430c85e4bc4052d881b8335d4a2ff36 (diff) | |
download | mana-32996cee607c52ecef9be4638df554dd89b39c24.tar.gz mana-32996cee607c52ecef9be4638df554dd89b39c24.tar.bz2 mana-32996cee607c52ecef9be4638df554dd89b39c24.tar.xz mana-32996cee607c52ecef9be4638df554dd89b39c24.zip |
Fixed wallpaper prescaling issues
Image::SDLgetScaledImage was changed so that it tries to find an existing
scaled version of the image first, and generates it when none exists.
When it needs to generate one, this resource is added to the resource
manager, partly to avoid duplicating the work later but mainly to keep
memory management straightforward.
This function also used to leak the scaled SDL_Surface since it wrongly
assumed that Image::load would free it.
To avoid filling up the memory with scaled wallpapers that are waiting
30 seconds until they will be deleted, the Resource::decRef function was
extended with a parameter that allows telling it what to do with orphans.
Calling decRef with Resource::DeleteImmediately will delete the resource
immediately in case the resource is orphaned.
Reviewed-by: Yohann Ferreira
Diffstat (limited to 'src/resources/image.cpp')
-rw-r--r-- | src/resources/image.cpp | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 3a6f7236..975bd647 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -326,31 +326,52 @@ void Image::setAlpha(float alpha) } } -Image* Image::SDLgetScaledImage(int width, int height) +Image *Image::SDLgetScaledImage(int width, int height) { - // No scaling on incorrect new values. if (width == 0 || height == 0) - return NULL; + return 0; - // No scaling when there is ... no different given size ... + // Increase our reference count and return ourselves in case of same size if (width == getWidth() && height == getHeight()) - return NULL; + { + incRef(); + return this; + } - Image* scaledImage = NULL; - SDL_Surface* scaledSurface = NULL; + if (!mSDLSurface) + return 0; - if (mSDLSurface) + ResourceManager *resman = ResourceManager::getInstance(); + + // Generate a unique ID path for storing the scaled version in the + // resource manager. + std::string idPath = getIdPath(); + idPath += ":scaled:"; + idPath += toString(width); + idPath += "x"; + idPath += toString(height); + + // Try whether a scaled version is already available + Image *scaledImage = static_cast<Image*>(resman->get(idPath)); + + if (!scaledImage) { - scaledSurface = zoomSurface(mSDLSurface, - (double) width / getWidth(), - (double) height / getHeight(), - 1); + // No scaled version with this size exists already, so create one + SDL_Surface *scaledSurface = zoomSurface(mSDLSurface, + (double) width / getWidth(), + (double) height / getHeight(), + 1); - // The load function takes care of the SDL<->OpenGL implementation - // and about freeing the given SDL_surface*. if (scaledSurface) + { scaledImage = load(scaledSurface); + SDL_FreeSurface(scaledSurface); + + // Place the scaled image in the resource manager + resman->addResource(idPath, scaledImage); + } } + return scaledImage; } |