summaryrefslogtreecommitdiffstats
path: root/client/shared_cache.hpp
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2010-06-01 10:30:51 +0300
committerAlexander Larsson <alexl@redhat.com>2010-06-09 11:41:01 +0200
commit5d2ae66f5022187e0028a1d7ccf67fe48fdaa94b (patch)
tree0458ad257a08447d5edc21c6391225ac8b738717 /client/shared_cache.hpp
parent263646a1f7e705766f7d46017679812d4b1406b8 (diff)
downloadspice-5d2ae66f5022187e0028a1d7ccf67fe48fdaa94b.tar.gz
spice-5d2ae66f5022187e0028a1d7ccf67fe48fdaa94b.tar.xz
spice-5d2ae66f5022187e0028a1d7ccf67fe48fdaa94b.zip
support for lossy images in the pixmap cache and fill bits
1) add an option to determine if a bitmap can be sent lossy to the client 2) when required, replacing lossy cache items with their correspending lossless bitmaps
Diffstat (limited to 'client/shared_cache.hpp')
-rw-r--r--client/shared_cache.hpp80
1 files changed, 76 insertions, 4 deletions
diff --git a/client/shared_cache.hpp b/client/shared_cache.hpp
index 88360251..a8308545 100644
--- a/client/shared_cache.hpp
+++ b/client/shared_cache.hpp
@@ -41,7 +41,7 @@ public:
clear();
}
- void add(uint64_t id, T* data)
+ void add(uint64_t id, T* data, bool is_lossy = FALSE)
{
Lock lock(_lock);
Item** item = &_hash[key(id)];
@@ -53,7 +53,7 @@ public:
}
item = &(*item)->next;
}
- *item = new Item(id, data);
+ *item = new Item(id, data, is_lossy);
_new_item_cond.notify_all();
}
@@ -81,6 +81,68 @@ public:
}
}
+ T* get_lossless(uint64_t id)
+ {
+ Lock lock(_lock);
+ Item* item = _hash[key(id)];
+
+ for (;;) {
+ if (!item) {
+ if (_aborting) {
+ THROW("%s aborting", Treat::name());
+ }
+ _new_item_cond.wait(lock);
+ item = _hash[key(id)];
+ continue;
+ }
+
+ if (item->id != id) {
+ item = item->next;
+ continue;
+ }
+ break;
+ }
+
+ // item has been retreived. Now checking if lossless
+ for (;;) {
+ if (item->lossy) {
+ if (_aborting) {
+ THROW("%s aborting", Treat::name());
+ }
+ _replace_data_cond.wait(lock);
+ continue;
+ }
+
+ return Treat::get(item->data);
+ }
+ }
+
+ void replace(uint64_t id, T* data, bool is_lossy = FALSE)
+ {
+ Lock lock(_lock);
+ Item* item = _hash[key(id)];
+
+ for (;;) {
+ if (!item) {
+ if (_aborting) {
+ THROW("%s aborting", Treat::name());
+ }
+ _new_item_cond.wait(lock);
+ item = _hash[key(id)];
+ continue;
+ }
+
+ if (item->id != id) {
+ item = item->next;
+ continue;
+ }
+
+ item->replace(data, is_lossy);
+ break;
+ }
+ _replace_data_cond.notify_all();
+ }
+
void remove(uint64_t id)
{
Lock lock(_lock);
@@ -125,26 +187,36 @@ private:
private:
class Item {
public:
- Item(uint64_t in_id, T* data)
+ Item(uint64_t in_id, T* data, bool is_lossy = FALSE)
: id (in_id)
, refs (1)
, next (NULL)
- , data (Treat::get(data)) {}
+ , data (Treat::get(data))
+ , lossy (is_lossy) {}
~Item()
{
Treat::release(data);
}
+ void replace(T* new_data, bool is_lossy = FALSE)
+ {
+ Treat::release(data);
+ data = Treat::get(new_data);
+ lossy = is_lossy;
+ }
+
uint64_t id;
int refs;
Item* next;
T* data;
+ bool lossy;
};
Item* _hash[HASH_SIZE];
Mutex _lock;
Condition _new_item_cond;
+ Condition _replace_data_cond;
bool _aborting;
};