diff options
author | Yonit Halperin <yhalperi@redhat.com> | 2010-06-01 10:30:51 +0300 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2010-06-09 11:41:01 +0200 |
commit | 5d2ae66f5022187e0028a1d7ccf67fe48fdaa94b (patch) | |
tree | 0458ad257a08447d5edc21c6391225ac8b738717 /client/shared_cache.hpp | |
parent | 263646a1f7e705766f7d46017679812d4b1406b8 (diff) |
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.hpp | 80 |
1 files changed, 76 insertions, 4 deletions
diff --git a/client/shared_cache.hpp b/client/shared_cache.hpp index 8836025..a830854 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; }; |