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