Author: boucman
Date: Sun Jun 22 20:39:10 2008
New Revision: 27415

URL: http://svn.gna.org/viewcvs/wesnoth?rev=27415&view=rev
Log:
made the image cache LRU with a size of 600 images.

Modified:
    trunk/changelog
    trunk/src/image.cpp
    trunk/src/image.hpp
    trunk/src/unit.cpp
    trunk/src/unit_frame.cpp

Modified: trunk/changelog
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/changelog?rev=27415&r1=27414&r2=27415&view=diff
==============================================================================
--- trunk/changelog (original)
+++ trunk/changelog Sun Jun 22 20:39:10 2008
@@ -179,6 +179,7 @@
    * fix a regression about missing default portrait in dialogs.
    * fix false move-cursor around enemies after some dialog events.
    * fix some unit decapitation when placed on a keep
+   * made the image cache LRU, with a high limit of 600 images per cache
 
 Version 1.5.0:
  * campaigns:

Modified: trunk/src/image.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/image.cpp?rev=27415&r1=27414&r2=27415&view=diff
==============================================================================
--- trunk/src/image.cpp (original)
+++ trunk/src/image.cpp Sun Jun 22 20:39:10 2008
@@ -66,38 +66,33 @@
 int zoom = image::tile_size;
 int cached_zoom = 0;
 
-// The "pointer to surfaces" vector is not cleared anymore
-// (the surface are still freed, of course).
-// I do not think it is a problem, as the number of different surfaces
-// the program may lookup has an upper limit, so its memory usage
-// won't grow indefinitely over time.
+} // end anon namespace
+
+namespace image {
+
 template<typename T>
-void reset_cache(std::vector<image::cache_item<T> >& cache)
-{
-       typename std::vector<image::cache_item<T> >::iterator beg = 
cache.begin();
-       typename std::vector<image::cache_item<T> >::iterator end = cache.end();
+void cache_type<T>::flush()
+{
+       typename std::vector<cache_item<T> >::iterator beg = content.begin();
+       typename std::vector<cache_item<T> >::iterator end = content.end();
 
        for(; beg != end; ++beg) {
                beg->loaded = false;
                beg->item = T();
        }
 }
-} // end anon namespace
-
-namespace image {
-
 mini_terrain_cache_map mini_terrain_cache;
 mini_terrain_cache_map mini_fogged_terrain_cache;
 
 void flush_cache()
 {
-       reset_cache(images_);
-       reset_cache(hexed_images_);
-       reset_cache(scaled_to_hex_images_);
-       reset_cache(scaled_to_zoom_);
-       reset_cache(unmasked_images_);
-       reset_cache(brightened_images_);
-       reset_cache(semi_brightened_images_);
+       images_.flush();
+       hexed_images_.flush();
+       scaled_to_hex_images_.flush();
+       scaled_to_zoom_.flush();
+       unmasked_images_.flush();
+       brightened_images_.flush();
+       semi_brightened_images_.flush();
        mini_terrain_cache.clear();
        mini_fogged_terrain_cache.clear();
        reversed_images_.clear();
@@ -115,13 +110,6 @@
                index_ = last_index_++;
                locator_finder.insert(locator_finder_pair(val_, index_));
 
-               images_.push_back(cache_item<surface>());
-               hexed_images_.push_back(cache_item<surface>());
-               scaled_to_hex_images_.push_back(cache_item<surface>());
-               scaled_to_zoom_.push_back(cache_item<surface>());
-               unmasked_images_.push_back(cache_item<surface>());
-               brightened_images_.push_back(cache_item<surface>());
-               semi_brightened_images_.push_back(cache_item<surface>());
 
        } else {
                index_ = i->second;
@@ -460,34 +448,6 @@
        }
 }
 
-#if 0
-template<typename T>
-bool locator::in_cache(const std::vector<cache_item<T> >& cache) const
-{
-       if(index_ == -1)
-               return false;
-
-       return cache[index_].loaded;
-}
-
-template<typename T>
-T locator::locate_in_cache(const std::vector<cache_item<T> >& cache) const
-{
-       if(index_ == -1)
-               return T();
-
-       return cache[index_].item;
-}
-
-template<typename T>
-void locator::add_to_cache(std::vector<cache_item<T> >& cache, const T& item) 
const
-{
-       if(index_ == -1)
-               return;
-
-       cache[index_] = cache_item<T>(item);
-}
-#endif
 
 manager::manager() {}
 
@@ -536,9 +496,9 @@
                red_adjust = r;
                green_adjust = g;
                blue_adjust = b;
-               reset_cache(scaled_to_hex_images_);
-               reset_cache(brightened_images_);
-               reset_cache(semi_brightened_images_);
+               scaled_to_hex_images_.flush();
+               brightened_images_.flush();
+               semi_brightened_images_.flush();
                reversed_images_.clear();
        }
 }
@@ -560,10 +520,10 @@
 /*
        if(image_mask != image) {
                image_mask = image;
-               reset_cache(scaled_to_hex_images_);
-               reset_cache(scaled_to_zoom_);
-               reset_cache(brightened_images_);
-               reset_cache(semi_brightened_images_);
+               scaled_to_hex_images_.flush();
+               scaled_to_zoom_.flush();
+               brightened_images_.flush();
+               semi_brightened_images_.flush();
                reversed_images_.clear();
        }
 */
@@ -573,17 +533,17 @@
 {
        if(amount != zoom) {
                zoom = amount;
-               reset_cache(scaled_to_hex_images_);
-               reset_cache(brightened_images_);
-               reset_cache(semi_brightened_images_);
+               scaled_to_hex_images_.flush();
+               brightened_images_.flush();
+               semi_brightened_images_.flush();
                reversed_images_.clear();
 
                // We keep these caches if:
                // we use default zoom (it doesn't need those)
                // or if they are already at the wanted zoom.
                if (zoom != tile_size && zoom != cached_zoom) {
-                       reset_cache(scaled_to_zoom_);
-                       reset_cache(unmasked_images_);
+                       scaled_to_zoom_.flush();
+                       unmasked_images_.flush();
                        cached_zoom = zoom;
                }
        }
@@ -593,7 +553,7 @@
 {
        // w.e don't want to add it to the unscaled cache,
        // since we will normaly never need the non-hexed one.
-       surface image(get_image(i_locator, UNSCALED, false));
+       surface image(get_image(i_locator, UNSCALED));
        // Re-cut scaled tiles according to a mask.
        const surface hex(get_image(game_config::terrain_mask_image,
                                        UNSCALED));
@@ -659,7 +619,7 @@
        return surface(brighten_image(image, ftofxp(1.25)));
 }
 
-surface get_image(const image::locator& i_locator, TYPE type, bool 
add_to_cache )
+surface get_image(const image::locator& i_locator, TYPE type)
 {
        surface res(NULL);
        image_cache *imap;
@@ -716,7 +676,7 @@
                res = i_locator.load_from_disk();
 
                if(res == NULL) {
-                       if(add_to_cache) i_locator.add_to_cache(*imap, 
surface(NULL));
+                        i_locator.add_to_cache(*imap, surface(NULL));
                        return surface(NULL);
                }
        } else {
@@ -749,7 +709,7 @@
 
        // Optimizes surface before storing it
        res = create_optimized_surface(res);
-       if(add_to_cache) i_locator.add_to_cache(*imap, res);
+        i_locator.add_to_cache(*imap, res);
        return res;
 }
 
@@ -835,5 +795,37 @@
 }
 
 
+template<typename T>
+cache_item<T>& cache_type<T>::get_element(int index){
+       assert (index != -1);
+       while(index >= content.size()) {
+               content.push_back(cache_item<T>());
+       }
+       cache_item<T>& elt = content[index];
+       if(elt.loaded) {
+               assert(*elt.position == index);
+               lru_list.erase(elt.position);
+               lru_list.push_front(index);
+               elt.position = lru_list.begin();
+       }
+       return elt;
+}
+template<typename T>
+void cache_type<T>::on_load(int index){
+       if(index == -1) return ;
+       cache_item<T>& elt = content[index];
+       if(!elt.loaded) return ;
+       lru_list.push_front(index);
+       cache_size++;
+       elt.position = lru_list.begin();
+       while(cache_size > cache_max_size-100) {
+               cache_item<T>& elt = content[lru_list.back()];
+               elt.loaded=false;
+               elt.item = T();
+               lru_list.pop_back();
+               cache_size--;
+       }
+}
+
 } // end namespace image
 

Modified: trunk/src/image.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/image.hpp?rev=27415&r1=27414&r2=27415&view=diff
==============================================================================
--- trunk/src/image.hpp (original)
+++ trunk/src/image.hpp Sun Jun 22 20:39:10 2008
@@ -19,8 +19,10 @@
 #include "sdl_utils.hpp"
 
 #include "SDL.h"
+#include "cassert"
 #include <string>
 #include <vector>
+#include <list>
 
 ///this module manages the cache of images. With an image name, you can get
 ///the surface corresponding to that image.
@@ -46,6 +48,22 @@
 
                bool loaded;
                T item;
+               std::list<int>::iterator position;
+       };
+
+       template<typename T>
+       class cache_type 
+       {
+               public:
+               cache_type():cache_size(0),cache_max_size(600){}
+               cache_item<T>& get_element(int index);
+               void on_load(int index);
+               void flush();
+               private:
+               int cache_size ;
+               int cache_max_size ;
+               std::list<int> lru_list;
+               std::vector<cache_item<T> > content;
        };
 
        //a generic image locator. Abstracts the location of an image.
@@ -65,7 +83,7 @@
                        value(const char *filename);
                        value(const char *filename, const std::string& 
modifications);
                        value(const std::string& filename);
-                    value(const std::string& filename, const std::string& 
modifications);
+                       value(const std::string& filename, const std::string& 
modifications);
                        value(const std::string& filename, const 
gamemap::location& loc, const std::string& modifications);
                        value(const std::string& filename, const 
gamemap::location& loc, int center_x, int center_y, const std::string& 
modifications);
 
@@ -110,31 +128,19 @@
                // loads the image it is pointing to from the disk
                surface load_from_disk() const;
 
-#if 0
-               // returns true if the locator already was stored in the given
-               // cache
-               template<typename T>
-               bool in_cache(const std::vector<cache_item<T> >& cache) const;
-               // returns the image it is corresponding to in the given cache
-               template<typename T>
-               T locate_in_cache(const std::vector<cache_item<T> >& cache) 
const;
-               // adds the given image to the given cache, indexed with the
-               // current locator
-               template<typename T>
-               void add_to_cache(std::vector<cache_item<T> >& cache, const T 
&image) const;
-#endif
-               bool in_cache(const std::vector<cache_item<surface> >& cache) 
const
-                       { return index_ == -1 ? false : cache[index_].loaded; }
-               surface locate_in_cache(const std::vector<cache_item<surface> 
>& cache) const
-                       { return index_ == -1 ? surface() : cache[index_].item; 
}
-               void add_to_cache(std::vector<cache_item<surface> >& cache, 
const surface &image) const
-                       { if(index_ != -1 ) cache[index_] = 
cache_item<surface>(image); }
-               bool in_cache(const std::vector<cache_item<locator> >& cache) 
const
-                       { return index_ == -1 ? false : cache[index_].loaded; }
-               locator locate_in_cache(const std::vector<cache_item<locator> 
>& cache) const
-                       { return index_ == -1 ? locator() : cache[index_].item; 
}
-               void add_to_cache(std::vector<cache_item<locator> >& cache, 
const locator &image) const
-                       { if(index_ != -1) cache[index_] = 
cache_item<locator>(image); }
+               bool in_cache(cache_type<surface>& cache) const
+                       { return index_ == -1 ? false : 
cache.get_element(index_).loaded; }
+               surface locate_in_cache(cache_type<surface>& cache) const
+                       { return index_ == -1 ? surface() : 
cache.get_element(index_).item; }
+               void add_to_cache(cache_type<surface>& cache, const surface 
&image) const
+                       { if(index_ != -1 ) cache.get_element(index_) = 
cache_item<surface>(image); cache.on_load(index_); }
+
+               bool in_cache(cache_type<locator>& cache) const
+                       { return index_ == -1 ? false : 
cache.get_element(index_).loaded; cache.on_load(index_); }
+               locator locate_in_cache(cache_type<locator>& cache) const
+                       { return index_ == -1 ? locator() : 
cache.get_element(index_).item; }
+               void add_to_cache(cache_type<locator>& cache, const locator 
&image) const
+                       { if(index_ != -1) cache.get_element(index_) = 
cache_item<locator>(image); }
        protected:
                static int last_index_;
        private:
@@ -147,8 +153,8 @@
        };
 
 
-       typedef std::vector<cache_item<surface> > image_cache;
-       typedef std::vector<cache_item<locator> > locator_cache;
+       typedef cache_type<surface> image_cache;
+       typedef cache_type<locator> locator_cache;
        typedef std::map<t_translation::t_terrain, surface> 
mini_terrain_cache_map;
        extern mini_terrain_cache_map mini_terrain_cache;
        extern mini_terrain_cache_map mini_fogged_terrain_cache;
@@ -201,7 +207,7 @@
        ///function to get the surface corresponding to an image.
        ///note that this surface must be freed by the user by calling
        ///SDL_FreeSurface()
-       surface get_image(const locator& i_locator, TYPE type=UNSCALED, bool 
add_to_cache = true);
+       surface get_image(const locator& i_locator, TYPE type=UNSCALED);
 
        ///function to reverse an image. The image MUST have originally been 
returned from
        ///an image:: function. Returned images have the same semantics as for 
get_image()

Modified: trunk/src/unit.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/unit.cpp?rev=27415&r1=27414&r2=27415&view=diff
==============================================================================
--- trunk/src/unit.cpp (original)
+++ trunk/src/unit.cpp Sun Jun 22 20:39:10 2008
@@ -1719,7 +1719,7 @@
 
        // The caching used to be disabled for the lowmem case but that actually
        // resulted in a higher memory usage see bug ##11022.
-       surface image(image::get_image(image_loc, image::SCALED_TO_ZOOM, true));
+       surface image(image::get_image(image_loc, image::SCALED_TO_ZOOM));
 
        if(image == NULL) {
                image = still_image(true);

Modified: trunk/src/unit_frame.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/unit_frame.cpp?rev=27415&r1=27414&r2=27415&view=diff
==============================================================================
--- trunk/src/unit_frame.cpp (original)
+++ trunk/src/unit_frame.cpp Sun Jun 22 20:39:10 2008
@@ -351,8 +351,7 @@
        surface image;
        if(!image_loc.is_void() && image_loc.get_filename() != "") { // invalid 
diag image, or not diagonal
                image=image::get_image(image_loc,
-                               image::SCALED_TO_ZOOM,
-                               primary
+                               image::SCALED_TO_ZOOM
                                );
        }
        const int x = static_cast<int>(tmp_offset * xdst + (1.0-tmp_offset) * 
xsrc) + d2;
@@ -433,8 +432,7 @@
                 * should cache it here and release it (if needed) after redrawn
                 */
                image=image::get_image(image_loc,
-                               image::SCALED_TO_ZOOM,
-                               primary
+                               image::SCALED_TO_ZOOM
                                );
        }
        const int x = static_cast<int>(tmp_offset * xdst + (1.0-tmp_offset) * 
xsrc)+current_data.x;


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to