add a bunch of comments for images and image caches. and make the number of resized...
authorDana Jansens <danakj@orodu.net>
Wed, 13 Feb 2008 13:43:57 +0000 (08:43 -0500)
committerMikael Magnusson <mikachu@comhem.se>
Thu, 14 Feb 2008 10:44:51 +0000 (11:44 +0100)
openbox/openbox.c
render/image.c
render/imagecache.c
render/imagecache.h
render/render.h

index ec6cc44..f7d820e 100644 (file)
@@ -168,7 +168,11 @@ gint main(gint argc, gchar **argv)
     ob_rr_inst = RrInstanceNew(obt_display, ob_screen);
     if (ob_rr_inst == NULL)
         ob_exit_with_error(_("Failed to initialize the obrender library."));
-    ob_rr_icons = RrImageCacheNew();
+    /* Saving 3 resizes of an RrImage makes a lot of sense for icons, as there
+       are generally 3 icon sizes needed: the titlebar icon, the menu icon,
+       and the alt-tab icon
+    */
+    ob_rr_icons = RrImageCacheNew(3);
 
     XSynchronize(obt_display, xsync);
 
index 8ce3a57..a618f78 100644 (file)
@@ -28,6 +28,9 @@
 #define FLOOR(i)        ((i) & (~0UL << FRACTION))
 #define AVERAGE(a, b)   (((((a) ^ (b)) & 0xfefefefeL) >> 1) + ((a) & (b)))
 
+/*! Add a picture to an Image, that is, add another copy of the image at
+  another size.  This may add it to the "originals" list or to the
+  "resized" list. */
 static void AddPicture(RrImage *self, RrImagePic ***list, gint *len,
                        RrImagePic *pic)
 {
@@ -58,6 +61,8 @@ static void AddPicture(RrImage *self, RrImagePic ***list, gint *len,
 #endif
 }
 
+/*! Remove a picture from an Image.  This may remove it from the "originals"
+  list or the "resized" list. */
 static void RemovePicture(RrImage *self, RrImagePic ***list,
                           gint i, gint *len)
 {
@@ -84,9 +89,14 @@ static void RemovePicture(RrImage *self, RrImagePic ***list,
     *list = g_renew(RrImagePic*, *list, --*len);
 }
 
+/*! Given a picture in RGBA format, of a specified size, resize it to the new
+  requested size (but keep its aspect ratio).  If the image does not need to
+  be resized (it is already the right size) then this returns NULL.  Otherwise
+  it returns a newly allocated RrImagePic with the resized picture inside it
+*/
 static RrImagePic* ResizeImage(RrPixel32 *src,
-                                       gulong srcW, gulong srcH,
-                                       gulong dstW, gulong dstH)
+                               gulong srcW, gulong srcH,
+                               gulong dstW, gulong dstH)
 {
     RrPixel32 *dst;
     RrImagePic *pic;
@@ -199,6 +209,8 @@ void DrawRGBA(RrPixel32 *target, gint target_w, gint target_h,
     gint dw, dh;
 
     g_assert(source_w <= area->width && source_h <= area->height);
+    g_assert(area->x + area->width <= target_w);
+    g_assert(area->y + area->height <= target_h);
 
     /* keep the aspect ratio */
     dw = area->width;
@@ -246,6 +258,7 @@ void DrawRGBA(RrPixel32 *target, gint target_w, gint target_h,
     }
 }
 
+/*! Draw an RGBA texture into a target pixel buffer. */
 void RrImageDrawRGBA(RrPixel32 *target, RrTextureRGBA *rgba,
                      gint target_w, gint target_h,
                      RrRect *area)
@@ -270,10 +283,13 @@ void RrImageDrawRGBA(RrPixel32 *target, RrTextureRGBA *rgba,
                  rgba->alpha, area);
 }
 
+/*! Create a new RrImage, which is linked to an image cache */
 RrImage* RrImageNew(RrImageCache *cache)
 {
     RrImage *self;
 
+    g_assert(cache != NULL);
+
     self = g_new0(RrImage, 1);
     self->ref = 1;
     self->cache = cache;
@@ -300,6 +316,9 @@ void RrImageUnref(RrImage *self)
     }
 }
 
+/*! Add a new picture with the given RGBA pixel data and dimensions into the
+  RrImage.  This adds an "original" picture to the image.
+*/
 void RrImageAddPicture(RrImage *self, RrPixel32 *data, gint w, gint h)
 {
     gint i;
@@ -330,6 +349,9 @@ void RrImageAddPicture(RrImage *self, RrPixel32 *data, gint w, gint h)
     AddPicture(self, &self->original, &self->n_original, pic);
 }
 
+/*! Remove the picture from the RrImage which has the given dimensions. This
+ removes an "original" picture from the image.
+*/
 void RrImageRemovePicture(RrImage *self, gint w, gint h)
 {
     gint i;
@@ -342,6 +364,11 @@ void RrImageRemovePicture(RrImage *self, gint w, gint h)
         }
 }
 
+/*! Draw an RrImage texture into a target pixel buffer.  If the RrImage does
+  not contain a picture of the appropriate size, then one of its "original"
+  pictures will be resized and used (and stored in the RrImage as a "resized"
+  picture).
+ */
 void RrImageDrawImage(RrPixel32 *target, RrTextureImage *img,
                       gint target_w, gint target_h,
                       RrRect *area)
@@ -431,13 +458,13 @@ void RrImageDrawImage(RrPixel32 *target, RrTextureImage *img,
 
         /* add the resized image to the image, as the first in the resized
            list */
-        if (self->n_resized >= MAX_CACHE_RESIZED) {
+        if (self->n_resized >= self->cache->max_resized_saved)
             /* remove the last one (last used one) */
             RemovePicture(self, &self->resized, self->n_resized - 1,
                           &self->n_resized);
-        }
-        /* add it to the top of the resized list */
-        AddPicture(self, &self->resized, &self->n_resized, pic);
+        if (self->cache->max_resized_saved)
+            /* add it to the top of the resized list */
+            AddPicture(self, &self->resized, &self->n_resized, pic);
     }
 
     g_assert(pic != NULL);
index ec2ff4d..9ebaec1 100644 (file)
 static gboolean RrImagePicEqual(const RrImagePic *p1,
                                 const RrImagePic *p2);
 
-RrImageCache* RrImageCacheNew()
+RrImageCache* RrImageCacheNew(gint max_resized_saved)
 {
     RrImageCache *self;
 
+    g_assert(max_resized_saved >= 0);
+
     self = g_new(RrImageCache, 1);
     self->ref = 1;
+    self->max_resized_saved = max_resized_saved;
     self->table = g_hash_table_new((GHashFunc)RrImagePicHash,
                                    (GEqualFunc)RrImagePicEqual);
     return self;
@@ -59,9 +62,6 @@ RrImage* RrImageCacheFind(RrImageCache *self,
     return g_hash_table_lookup(self->table, &pic);
 }
 
-/* This is a fast, reversable hash function called "lookup3", found here:
-   http://burtleburtle.net/bob/c/lookup3.c
-*/
 #define hashsize(n) ((RrPixel32)1<<(n))
 #define hashmask(n) (hashsize(n)-1)
 #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
@@ -87,6 +87,13 @@ RrImage* RrImageCacheFind(RrImageCache *self,
   c ^= b; c -= rot(b,24); \
 }
 
+/* This is a fast, reversable hash function called "lookup3", found here:
+   http://burtleburtle.net/bob/c/lookup3.c, by Bob Jenkins
+
+   This hashing algorithm is "reversible", that is, not cryptographically
+   secure at all.  But we don't care about that, we just want something to
+   tell when images are the same or different relatively quickly.
+*/
 guint32 hashword(const guint32 *key, gint length, guint32 initval)
 {
     guint32 a,b,c;
@@ -119,6 +126,9 @@ guint32 hashword(const guint32 *key, gint length, guint32 initval)
     return c;
 }
 
+/*! This is some arbitrary initial value for the hashing function.  It's
+  constant so that you get the same result from the same data each time.
+*/
 #define HASH_INITVAL 0xf00d
 
 guint RrImagePicHash(const RrImagePic *p)
index 8c96caf..4ad2dea 100644 (file)
 
 #include <glib.h>
 
-/* the number of resized pictures to cache for an image */
-#define MAX_CACHE_RESIZED 3
-
 struct _RrImagePic;
 
 guint RrImagePicHash(const struct _RrImagePic *p);
 
+/*! Create a new image cache.  An image cache is basically a hash table to look
+  up RrImages.  Each RrImage in the cache may contain one or more Pictures,
+  that is one or more actual copies of image data at various sizes.  For eg,
+  for a window, all of its various icons are loaded into the same RrImage.
+  When an RrImage is drawn and a picture inside it needs to be resized, that
+  is also saved within the RrImage.
+
+  For each picture that an RrImage has, the picture is hashed and that is used
+  as a key to find the RrImage.  So, given any picture in any RrImage in the
+  cache, if you hash it, you will find the RrImage.
+*/
 struct _RrImageCache {
     gint ref;
+    /*! When an original picture is resized for an RrImage, the resized picture
+      is saved in the RrImage.  This specifies how many pictures should be
+      saved at a time.  When this is exceeded, the least recently used
+      "resized" picture is deleted.
+    */
+    gint max_resized_saved;
 
     GHashTable *table;
 };
index 5d1d155..5f14508 100644 (file)
@@ -234,11 +234,18 @@ struct _RrImagePic {
   pictures */
 struct _RrImage {
     gint ref;
-    struct _RrImageCache *cache;
+    RrImageCache *cache;
 
-    struct _RrImagePic **original;
+    /*! An array of "originals", that is of RrPictures that have been added
+      to the image in various sizes, and that have not been resized.  These
+      are explicitly added to the RrImage. */
+    RrImagePic **original;
     gint n_original;
-    struct _RrImagePic **resized;
+    /*! An array of "resized" pictures.  When an "original" RrPicture
+      needs to be resized for drawing, it is saved in here so that it doesn't
+      need to be resized again.  These are automatically added to the
+      RrImage. */
+    RrImagePic **resized;
     gint n_resized;
 };
 
@@ -317,7 +324,10 @@ gboolean RrPixmapToRGBA(const RrInstance *inst,
                         Pixmap pmap, Pixmap mask,
                         gint *w, gint *h, RrPixel32 **data);
 
-RrImageCache* RrImageCacheNew();
+/*! Create a new image cache for RrImages.
+  @param max_resized_saved The number of resized copies of an image to save
+*/
+RrImageCache* RrImageCacheNew(gint max_resized_saved);
 void          RrImageCacheRef(RrImageCache *self);
 void          RrImageCacheUnref(RrImageCache *self);