From 32996cee607c52ecef9be4638df554dd89b39c24 Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Wed, 8 Feb 2012 22:09:07 +0100 Subject: 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 --- src/gui/widgets/desktop.cpp | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) (limited to 'src/gui/widgets') diff --git a/src/gui/widgets/desktop.cpp b/src/gui/widgets/desktop.cpp index bf833898..baf3e951 100644 --- a/src/gui/widgets/desktop.cpp +++ b/src/gui/widgets/desktop.cpp @@ -105,30 +105,39 @@ void Desktop::draw(gcn::Graphics *graphics) void Desktop::setBestFittingWallpaper() { - const std::string wallpaperName = - Wallpaper::getWallpaper(getWidth(), getHeight()); + const int width = getWidth(); + const int height = getHeight(); - Image *nWallPaper = ResourceManager::getInstance()->getImage(wallpaperName); + if (width == 0 || height == 0) + return; - if (nWallPaper) + const std::string wallpaperName = Wallpaper::getWallpaper(width, height); + + if (wallpaperName.empty()) + return; + + ResourceManager *resman = ResourceManager::getInstance(); + Image *wallpaper = resman->getImage(wallpaperName); + + if (wallpaper) { if (mWallpaper) - mWallpaper->decRef(); + mWallpaper->decRef(Resource::DeleteImmediately); + + mWallpaper = wallpaper; - if (!nWallPaper->useOpenGL() && (nWallPaper->getWidth() != getWidth() - || nWallPaper->getHeight() != getHeight())) + // In software mode we try to prescale the image for performance + if (!wallpaper->useOpenGL() && + (wallpaper->getWidth() != width || + wallpaper->getHeight() != height)) { - // We rescale to obtain a fullscreen wallpaper... - Image *newRsclWlPpr = nWallPaper->SDLgetScaledImage(getWidth(), getHeight()); - std::string idPath = nWallPaper->getIdPath(); - - // We replace the resource in the resource manager - nWallPaper->decRef(); - ResourceManager::getInstance()->addResource(idPath, newRsclWlPpr); - mWallpaper = newRsclWlPpr; + if (Image *prescaled = wallpaper->SDLgetScaledImage(width, height)) + { + // Make sure the original can be freed + wallpaper->decRef(); + mWallpaper = prescaled; + } } - else - mWallpaper = nWallPaper; } else { -- cgit v1.2.3-60-g2f50