From ac9eefacbf567631d7f6f4d52d4a98f2dd771d95 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Tue, 21 May 2013 11:48:10 -1000 Subject: [PATCH] Same PNG file no longer decoded multiple times for tiled images, see bug 967 --- src/video/texture_manager.cpp | 61 +++++++++++++++++++++++++------------------ src/video/texture_manager.hpp | 4 +++ 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/video/texture_manager.cpp b/src/video/texture_manager.cpp index 7343a45f3..0c77a5add 100644 --- a/src/video/texture_manager.cpp +++ b/src/video/texture_manager.cpp @@ -36,6 +36,7 @@ TextureManager::TextureManager() : image_textures() + ,surfaces() #ifdef HAVE_OPENGL ,textures(), saved_textures() @@ -75,8 +76,9 @@ TextureManager::get(const std::string& _filename) } TexturePtr -TextureManager::get(const std::string& filename, const Rect& rect) +TextureManager::get(const std::string& _filename, const Rect& rect) { + std::string filename = FileSystem::normalize(_filename); // FIXME: implement caching return create_image_texture(filename, rect); } @@ -121,40 +123,47 @@ TextureManager::create_image_texture(const std::string& filename, const Rect& re TexturePtr TextureManager::create_image_texture_raw(const std::string& filename, const Rect& rect) { - SDLSurfacePtr image(IMG_Load_RW(get_physfs_SDLRWops(filename), 1)); + SDL_Surface *image = NULL; + + Surfaces::iterator i = surfaces.find(filename); + if (i != surfaces.end()) + image = i->second; + + if (!image) { + image = IMG_Load_RW(get_physfs_SDLRWops(filename), 1); + } + if (!image) { std::ostringstream msg; msg << "Couldn't load image '" << filename << "' :" << SDL_GetError(); throw std::runtime_error(msg.str()); } - else + + surfaces[filename] = image; + + SDLSurfacePtr subimage(SDL_CreateRGBSurfaceFrom(static_cast(image->pixels) + + rect.top * image->pitch + + rect.left * image->format->BytesPerPixel, + + rect.get_width(), rect.get_height(), + image->format->BitsPerPixel, + image->pitch, + image->format->Rmask, + image->format->Gmask, + image->format->Bmask, + image->format->Amask)); + if (!subimage) { - SDLSurfacePtr subimage(SDL_CreateRGBSurfaceFrom(static_cast(image->pixels) + - rect.top * image->pitch + - rect.left * image->format->BytesPerPixel, - - rect.get_width(), rect.get_height(), - image->format->BitsPerPixel, - image->pitch, - image->format->Rmask, - image->format->Gmask, - image->format->Bmask, - image->format->Amask)); - if (!subimage) - { - throw std::runtime_error("SDL_CreateRGBSurfaceFrom() call failed"); - } - else - { - if (image->format->palette) - { // copy the image palette to subimage if present - SDL_SetColors(subimage.get(), image->format->palette->colors, 0, image->format->palette->ncolors); - } + throw std::runtime_error("SDL_CreateRGBSurfaceFrom() call failed"); + } - return VideoSystem::new_texture(subimage.get()); - } + if (image->format->palette) + { // copy the image palette to subimage if present + SDL_SetColors(subimage.get(), image->format->palette->colors, 0, image->format->palette->ncolors); } + + return VideoSystem::new_texture(subimage.get()); } TexturePtr diff --git a/src/video/texture_manager.hpp b/src/video/texture_manager.hpp index 61350fb16..a78037e4d 100644 --- a/src/video/texture_manager.hpp +++ b/src/video/texture_manager.hpp @@ -17,6 +17,8 @@ #ifndef HEADER_SUPERTUX_VIDEO_TEXTURE_MANAGER_HPP #define HEADER_SUPERTUX_VIDEO_TEXTURE_MANAGER_HPP +#include + #include #include @@ -55,6 +57,8 @@ private: typedef std::map > ImageTextures; ImageTextures image_textures; + typedef std::map Surfaces; + Surfaces surfaces; TexturePtr create_image_texture(const std::string& filename, const Rect& rect); -- 2.11.0