SDL: use hash table for color cache
authorTim Goya <tuxdev103@gmail.com>
Fri, 17 Aug 2007 00:18:17 +0000 (00:18 +0000)
committerTim Goya <tuxdev103@gmail.com>
Fri, 17 Aug 2007 00:18:17 +0000 (00:18 +0000)
SVN-Revision: 5140

src/video/sdl_texture.cpp
src/video/sdl_texture.hpp

index d5a9d9c..917a4df 100644 (file)
@@ -401,9 +401,9 @@ namespace SDL
   Texture::Texture(SDL_Surface* image)
   {
     texture = SDL_DisplayFormatAlpha(image);
-    //image->refcount++;
-    //texture = image;
-
+    //width = texture->w;
+    //height = texture->h;
+    int numerator, denominator;
     float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
     float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
     if(xfactor < yfactor)
@@ -416,7 +416,7 @@ namespace SDL
       numerator = config->screenheight;
       denominator = SCREEN_HEIGHT;
     }
-    cache[white][NO_EFFECT] = scale(texture, numerator, denominator);
+    cache[NO_EFFECT][white] = scale(texture, numerator, denominator);
   }
 
   Texture::~Texture()
@@ -426,26 +426,25 @@ namespace SDL
 
   SDL_Surface *Texture::get_transform(const Color &color, DrawingEffect effect)
   {
-    if(cache.find(color) == cache.end())
-    {
-      cache[color][NO_EFFECT] = colorize(cache[white][NO_EFFECT], color);
+    if(cache[NO_EFFECT][color] == 0) {
+      assert(cache[NO_EFFECT][white]);
+      cache[NO_EFFECT][color] = colorize(cache[NO_EFFECT][white], color);
     }
-    if(cache[color][effect] == 0) {
-      assert(cache[color][NO_EFFECT]);
+    if(cache[effect][color] == 0) {
+      assert(cache[NO_EFFECT][color]);
       switch(effect) {
         case NO_EFFECT:
           break;
         case HORIZONTAL_FLIP:
-          cache[color][HORIZONTAL_FLIP] = horz_flip(cache[color][NO_EFFECT]);
+          cache[HORIZONTAL_FLIP][color] = horz_flip(cache[NO_EFFECT][color]);
           break;
         case VERTICAL_FLIP:
-          cache[color][VERTICAL_FLIP] = vert_flip(cache[color][NO_EFFECT]);
+          cache[VERTICAL_FLIP][color] = vert_flip(cache[NO_EFFECT][color]);
           break;
         default:
-          std::cerr << "Warning: transformation unknown" << std::endl;
           return 0;
       }
     }
-    return cache[color][effect];
+    return cache[effect][color];
   }
 }
index 0a8045f..34479db 100644 (file)
@@ -25,8 +25,7 @@
 #include <SDL.h>
 
 #include "texture.hpp"
-
-class Color;
+#include "color.hpp"
 
 namespace SDL
 {
@@ -34,11 +33,14 @@ namespace SDL
   {
   protected:
     SDL_Surface *texture;
-    int numerator;
-    int denominator;
+    //unsigned int width;
+    //unsigned int height;
 
-    struct Cache
+    struct ColorCache
     {
+      static const int HASHED_BITS = 3;
+      static const int CACHE_SIZE = 1 << (HASHED_BITS * 3);
+
       static void ref(SDL_Surface *surface)
       {
         if(surface)
@@ -47,31 +49,40 @@ namespace SDL
         }
       }
 
-      SDL_Surface *data[NUM_EFFECTS];
+      static int hash(const Color &color)
+      {
+        return
+      ((int) (color.red * ((1 << HASHED_BITS) - 1)) << (HASHED_BITS - 1) * 2) |
+      ((int) (color.green * ((1 << HASHED_BITS) - 1)) << (HASHED_BITS - 1)) |
+      ((int) (color.blue * ((1 << HASHED_BITS) - 1)) << 0);
+      }
+
+      SDL_Surface *data[CACHE_SIZE];
 
-      Cache()
+      ColorCache()
       {
-        memset(data, 0, NUM_EFFECTS * sizeof(SDL_Surface *));
+        memset(data, 0, CACHE_SIZE * sizeof(SDL_Surface *));
       }
 
-      ~Cache()
+      ~ColorCache()
       {
-        std::for_each(data, data + NUM_EFFECTS, SDL_FreeSurface);
+        std::for_each(data, data + CACHE_SIZE, SDL_FreeSurface);
       }
 
-      void operator = (const Cache &other)
+      void operator = (const ColorCache &other)
       {
-        std::for_each(other.data, other.data + NUM_EFFECTS, ref);
-        std::for_each(data, data + NUM_EFFECTS, SDL_FreeSurface);
-        memcpy(data, other.data, sizeof(Cache));
+        std::for_each(other.data, other.data + CACHE_SIZE, ref);
+        std::for_each(data, data + CACHE_SIZE, SDL_FreeSurface);
+        memcpy(data, other.data, CACHE_SIZE * sizeof(SDL_Surface *));
       }
 
-      SDL_Surface *&operator [] (DrawingEffect effect)
+      SDL_Surface *&operator [] (const Color &color)
       {
-        return data[effect];
+        return data[hash(color)];
       }
     };
-    mutable std::map<Color, Cache> cache; /**< Cache for processed surfaces */
+    //typedef std::map<Color, SDL_Surface *> ColorCache;
+    ColorCache cache[NUM_EFFECTS];
 
   public:
     Texture(SDL_Surface* sdlsurface);
@@ -103,6 +114,26 @@ namespace SDL
     {
       return texture->h;
     }
+
+    /*unsigned int get_texture_width() const
+    {
+      return width;
+    }
+
+    unsigned int get_texture_height() const
+    {
+      return height;
+    }
+
+    unsigned int get_image_width() const
+    {
+      return width;
+    }
+
+    unsigned int get_image_height() const
+    {
+      return height;
+    }*/
   };
 }