[Spice-devel] [PATCH v2 9/9] server: split spice_image_cache from red_worker

Alon Levy alevy at redhat.com
Mon Aug 12 08:32:27 PDT 2013


---
 server/Makefile.am         |   2 +
 server/red_worker.c        | 158 +--------------------------------------------
 server/spice_image_cache.c | 135 ++++++++++++++++++++++++++++++++++++++
 server/spice_image_cache.h |  39 +++++++++++
 4 files changed, 177 insertions(+), 157 deletions(-)
 create mode 100644 server/spice_image_cache.c
 create mode 100644 server/spice_image_cache.h

diff --git a/server/Makefile.am b/server/Makefile.am
index feee2f1..815f65e 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -100,6 +100,8 @@ libspice_server_la_SOURCES =			\
 	spice_bitmap_utils.h		\
 	spice_bitmap_utils.c		\
 	spice_server_utils.h		\
+	spice_image_cache.h			\
+	spice_image_cache.c			\
 	$(NULL)
 
 if SUPPORT_TUNNEL
diff --git a/server/red_worker.c b/server/red_worker.c
index b0dd471..a201315 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -85,6 +85,7 @@
 #include "spice_server_utils.h"
 #include "red_time.h"
 #include "spice_bitmap_utils.h"
+#include "spice_image_cache.h"
 
 //#define COMPRESS_STAT
 //#define DUMP_BITMAP
@@ -757,29 +758,6 @@ typedef struct CursorChannel {
 #endif
 } CursorChannel;
 
-typedef struct ImageCacheItem {
-    RingItem lru_link;
-    uint64_t id;
-#ifdef IMAGE_CACHE_AGE
-    uint32_t age;
-#endif
-    struct ImageCacheItem *next;
-    pixman_image_t *image;
-} ImageCacheItem;
-
-#define IMAGE_CACHE_HASH_SIZE 1024
-
-typedef struct ImageCache {
-    SpiceImageCache base;
-    ImageCacheItem *hash_table[IMAGE_CACHE_HASH_SIZE];
-    Ring lru;
-#ifdef IMAGE_CACHE_AGE
-    uint32_t age;
-#else
-    uint32_t num_items;
-#endif
-} ImageCache;
-
 enum {
     TREE_ITEM_TYPE_DRAWABLE,
     TREE_ITEM_TYPE_CONTAINER,
@@ -4310,140 +4288,6 @@ static void image_surface_init(RedWorker *worker)
     worker->image_surfaces.ops = &image_surfaces_ops;
 }
 
-static ImageCacheItem *image_cache_find(ImageCache *cache, uint64_t id)
-{
-    ImageCacheItem *item = cache->hash_table[id % IMAGE_CACHE_HASH_SIZE];
-
-    while (item) {
-        if (item->id == id) {
-            return item;
-        }
-        item = item->next;
-    }
-    return NULL;
-}
-
-static int image_cache_hit(ImageCache *cache, uint64_t id)
-{
-    ImageCacheItem *item;
-    if (!(item = image_cache_find(cache, id))) {
-        return FALSE;
-    }
-#ifdef IMAGE_CACHE_AGE
-    item->age = cache->age;
-#endif
-    ring_remove(&item->lru_link);
-    ring_add(&cache->lru, &item->lru_link);
-    return TRUE;
-}
-
-static void image_cache_remove(ImageCache *cache, ImageCacheItem *item)
-{
-    ImageCacheItem **now;
-
-    now = &cache->hash_table[item->id % IMAGE_CACHE_HASH_SIZE];
-    for (;;) {
-        spice_assert(*now);
-        if (*now == item) {
-            *now = item->next;
-            break;
-        }
-        now = &(*now)->next;
-    }
-    ring_remove(&item->lru_link);
-    pixman_image_unref(item->image);
-    free(item);
-#ifndef IMAGE_CACHE_AGE
-    cache->num_items--;
-#endif
-}
-
-#define IMAGE_CACHE_MAX_ITEMS 2
-
-static void image_cache_put(SpiceImageCache *spice_cache, uint64_t id, pixman_image_t *image)
-{
-    ImageCache *cache = (ImageCache *)spice_cache;
-    ImageCacheItem *item;
-
-#ifndef IMAGE_CACHE_AGE
-    if (cache->num_items == IMAGE_CACHE_MAX_ITEMS) {
-        ImageCacheItem *tail = (ImageCacheItem *)ring_get_tail(&cache->lru);
-        spice_assert(tail);
-        image_cache_remove(cache, tail);
-    }
-#endif
-
-    item = spice_new(ImageCacheItem, 1);
-    item->id = id;
-#ifdef IMAGE_CACHE_AGE
-    item->age = cache->age;
-#else
-    cache->num_items++;
-#endif
-    item->image = pixman_image_ref(image);
-    ring_item_init(&item->lru_link);
-
-    item->next = cache->hash_table[item->id % IMAGE_CACHE_HASH_SIZE];
-    cache->hash_table[item->id % IMAGE_CACHE_HASH_SIZE] = item;
-
-    ring_add(&cache->lru, &item->lru_link);
-}
-
-static pixman_image_t *image_cache_get(SpiceImageCache *spice_cache, uint64_t id)
-{
-    ImageCache *cache = (ImageCache *)spice_cache;
-
-    ImageCacheItem *item = image_cache_find(cache, id);
-    if (!item) {
-        spice_error("not found");
-    }
-    return pixman_image_ref(item->image);
-}
-
-static void image_cache_init(ImageCache *cache)
-{
-    static SpiceImageCacheOps image_cache_ops = {
-        image_cache_put,
-        image_cache_get,
-    };
-
-    cache->base.ops = &image_cache_ops;
-    memset(cache->hash_table, 0, sizeof(cache->hash_table));
-    ring_init(&cache->lru);
-#ifdef IMAGE_CACHE_AGE
-    cache->age = 0;
-#else
-    cache->num_items = 0;
-#endif
-}
-
-static void image_cache_reset(ImageCache *cache)
-{
-    ImageCacheItem *item;
-
-    while ((item = (ImageCacheItem *)ring_get_head(&cache->lru))) {
-        image_cache_remove(cache, item);
-    }
-#ifdef IMAGE_CACHE_AGE
-    cache->age = 0;
-#endif
-}
-
-#define IMAGE_CACHE_DEPTH 4
-
-static void image_cache_aging(ImageCache *cache)
-{
-#ifdef IMAGE_CACHE_AGE
-    ImageCacheItem *item;
-
-    cache->age++;
-    while ((item = (ImageCacheItem *)ring_get_tail(&cache->lru)) &&
-           cache->age - item->age > IMAGE_CACHE_DEPTH) {
-        image_cache_remove(cache, item);
-    }
-#endif
-}
-
 static void localize_bitmap(RedWorker *worker, SpiceImage **image_ptr, SpiceImage *image_store,
                             Drawable *drawable)
 {
diff --git a/server/spice_image_cache.c b/server/spice_image_cache.c
new file mode 100644
index 0000000..291094c
--- /dev/null
+++ b/server/spice_image_cache.c
@@ -0,0 +1,135 @@
+#include "spice_image_cache.h"
+
+static ImageCacheItem *image_cache_find(ImageCache *cache, uint64_t id)
+{
+    ImageCacheItem *item = cache->hash_table[id % IMAGE_CACHE_HASH_SIZE];
+
+    while (item) {
+        if (item->id == id) {
+            return item;
+        }
+        item = item->next;
+    }
+    return NULL;
+}
+
+int image_cache_hit(ImageCache *cache, uint64_t id)
+{
+    ImageCacheItem *item;
+    if (!(item = image_cache_find(cache, id))) {
+        return FALSE;
+    }
+#ifdef IMAGE_CACHE_AGE
+    item->age = cache->age;
+#endif
+    ring_remove(&item->lru_link);
+    ring_add(&cache->lru, &item->lru_link);
+    return TRUE;
+}
+
+static void image_cache_remove(ImageCache *cache, ImageCacheItem *item)
+{
+    ImageCacheItem **now;
+
+    now = &cache->hash_table[item->id % IMAGE_CACHE_HASH_SIZE];
+    for (;;) {
+        spice_assert(*now);
+        if (*now == item) {
+            *now = item->next;
+            break;
+        }
+        now = &(*now)->next;
+    }
+    ring_remove(&item->lru_link);
+    pixman_image_unref(item->image);
+    free(item);
+#ifndef IMAGE_CACHE_AGE
+    cache->num_items--;
+#endif
+}
+
+#define IMAGE_CACHE_MAX_ITEMS 2
+
+static void image_cache_put(SpiceImageCache *spice_cache, uint64_t id, pixman_image_t *image)
+{
+    ImageCache *cache = (ImageCache *)spice_cache;
+    ImageCacheItem *item;
+
+#ifndef IMAGE_CACHE_AGE
+    if (cache->num_items == IMAGE_CACHE_MAX_ITEMS) {
+        ImageCacheItem *tail = (ImageCacheItem *)ring_get_tail(&cache->lru);
+        spice_assert(tail);
+        image_cache_remove(cache, tail);
+    }
+#endif
+
+    item = spice_new(ImageCacheItem, 1);
+    item->id = id;
+#ifdef IMAGE_CACHE_AGE
+    item->age = cache->age;
+#else
+    cache->num_items++;
+#endif
+    item->image = pixman_image_ref(image);
+    ring_item_init(&item->lru_link);
+
+    item->next = cache->hash_table[item->id % IMAGE_CACHE_HASH_SIZE];
+    cache->hash_table[item->id % IMAGE_CACHE_HASH_SIZE] = item;
+
+    ring_add(&cache->lru, &item->lru_link);
+}
+
+static pixman_image_t *image_cache_get(SpiceImageCache *spice_cache, uint64_t id)
+{
+    ImageCache *cache = (ImageCache *)spice_cache;
+
+    ImageCacheItem *item = image_cache_find(cache, id);
+    if (!item) {
+        spice_error("not found");
+    }
+    return pixman_image_ref(item->image);
+}
+
+void image_cache_init(ImageCache *cache)
+{
+    static SpiceImageCacheOps image_cache_ops = {
+        image_cache_put,
+        image_cache_get,
+    };
+
+    cache->base.ops = &image_cache_ops;
+    memset(cache->hash_table, 0, sizeof(cache->hash_table));
+    ring_init(&cache->lru);
+#ifdef IMAGE_CACHE_AGE
+    cache->age = 0;
+#else
+    cache->num_items = 0;
+#endif
+}
+
+void image_cache_reset(ImageCache *cache)
+{
+    ImageCacheItem *item;
+
+    while ((item = (ImageCacheItem *)ring_get_head(&cache->lru))) {
+        image_cache_remove(cache, item);
+    }
+#ifdef IMAGE_CACHE_AGE
+    cache->age = 0;
+#endif
+}
+
+#define IMAGE_CACHE_DEPTH 4
+
+void image_cache_aging(ImageCache *cache)
+{
+#ifdef IMAGE_CACHE_AGE
+    ImageCacheItem *item;
+
+    cache->age++;
+    while ((item = (ImageCacheItem *)ring_get_tail(&cache->lru)) &&
+           cache->age - item->age > IMAGE_CACHE_DEPTH) {
+        image_cache_remove(cache, item);
+    }
+#endif
+}
diff --git a/server/spice_image_cache.h b/server/spice_image_cache.h
new file mode 100644
index 0000000..f11cebc
--- /dev/null
+++ b/server/spice_image_cache.h
@@ -0,0 +1,39 @@
+#ifndef H_SPICE_IMAGE_CACHE
+#define H_SPICE_IMAGE_CACHE
+
+#include <inttypes.h>
+
+#include "common/pixman_utils.h"
+#include "common/canvas_base.h"
+
+#include "common/ring.h"
+
+typedef struct ImageCacheItem {
+    RingItem lru_link;
+    uint64_t id;
+#ifdef IMAGE_CACHE_AGE
+    uint32_t age;
+#endif
+    struct ImageCacheItem *next;
+    pixman_image_t *image;
+} ImageCacheItem;
+
+#define IMAGE_CACHE_HASH_SIZE 1024
+
+typedef struct ImageCache {
+    SpiceImageCache base;
+    ImageCacheItem *hash_table[IMAGE_CACHE_HASH_SIZE];
+    Ring lru;
+#ifdef IMAGE_CACHE_AGE
+    uint32_t age;
+#else
+    uint32_t num_items;
+#endif
+} ImageCache;
+
+int image_cache_hit(ImageCache *cache, uint64_t id);
+void image_cache_init(ImageCache *cache);
+void image_cache_reset(ImageCache *cache);
+void image_cache_aging(ImageCache *cache);
+
+#endif
-- 
1.8.3.1



More information about the Spice-devel mailing list