[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