Add a layer (FBO) cache.

The cache is used to draw layers so that a new
texture does not have to be recreated every time
a call to saveLayer() happens.

The FBO cache used a KeyedVector, which is a bad
idea. The cache should be able to store several
FBOs of the same size (this happens a lot during
scrolling with fading edges for instance.) This
will be changed in a future CL.

Change-Id: Ic316189e625f0dbcf0d273a71cc981a433d48726
diff --git a/libs/hwui/GenerationCache.h b/libs/hwui/GenerationCache.h
index 56693da..d92a0bb 100644
--- a/libs/hwui/GenerationCache.h
+++ b/libs/hwui/GenerationCache.h
@@ -27,7 +27,7 @@
 class OnEntryRemoved {
 public:
     virtual ~OnEntryRemoved() { };
-    virtual void operator()(EntryKey key, EntryValue value) = 0;
+    virtual void operator()(EntryKey& key, EntryValue& value) = 0;
 }; // class OnEntryRemoved
 
 template<typename K, typename V>
@@ -40,15 +40,15 @@
         kUnlimitedCapacity,
     };
 
-    void setOnEntryRemovedListener(OnEntryRemoved<K*, V*>* listener);
+    void setOnEntryRemovedListener(OnEntryRemoved<K, V>* listener);
 
     void clear();
 
-    bool contains(K* key) const;
-    V* get(K* key);
-    void put(K* key, V* value);
-    V* remove(K* key);
-    void removeOldest();
+    bool contains(K key) const;
+    V get(K key);
+    void put(K key, V value);
+    V remove(K key);
+    V removeOldest();
 
     uint32_t size() const;
 
@@ -68,18 +68,18 @@
         sp<Entry<EntryKey, EntryValue> > child;
     }; // struct Entry
 
-    void addToCache(sp<Entry<K*, V*> > entry, K* key, V* value);
-    void attachToCache(sp<Entry<K*, V*> > entry);
-    void detachFromCache(sp<Entry<K*, V*> > entry);
+    void addToCache(sp<Entry<K, V> > entry, K key, V value);
+    void attachToCache(sp<Entry<K, V> > entry);
+    void detachFromCache(sp<Entry<K, V> > entry);
 
     uint32_t mMaxCapacity;
 
-    OnEntryRemoved<K*, V*>* mListener;
+    OnEntryRemoved<K, V>* mListener;
 
-    KeyedVector<K*, sp<Entry<K*, V*> > > mCache;
+    KeyedVector<K, sp<Entry<K, V> > > mCache;
 
-    sp<Entry<K*, V*> > mOldest;
-    sp<Entry<K*, V*> > mYougest;
+    sp<Entry<K, V> > mOldest;
+    sp<Entry<K, V> > mYougest;
 }; // class GenerationCache
 
 template<typename K, typename V>
@@ -88,7 +88,7 @@
 }
 
 template<typename K, typename V>
-void GenerationCache<K, V>::setOnEntryRemovedListener(OnEntryRemoved<K*, V*>* listener) {
+void GenerationCache<K, V>::setOnEntryRemovedListener(OnEntryRemoved<K, V>* listener) {
     mListener = listener;
 }
 
@@ -106,15 +106,15 @@
 }
 
 template<typename K, typename V>
-bool GenerationCache<K, V>::contains(K* key) const {
+bool GenerationCache<K, V>::contains(K key) const {
     return mCache.indexOfKey(key) >= 0;
 }
 
 template<typename K, typename V>
-V* GenerationCache<K, V>::get(K* key) {
+V GenerationCache<K, V>::get(K key) {
     ssize_t index = mCache.indexOfKey(key);
     if (index >= 0) {
-        sp<Entry<K*, V*> > entry = mCache.valueAt(index);
+        sp<Entry<K, V> > entry = mCache.valueAt(index);
         if (entry.get()) {
             detachFromCache(entry);
             attachToCache(entry);
@@ -126,24 +126,24 @@
 }
 
 template<typename K, typename V>
-void GenerationCache<K, V>::put(K* key, V* value) {
+void GenerationCache<K, V>::put(K key, V value) {
     if (mMaxCapacity != kUnlimitedCapacity && mCache.size() >= mMaxCapacity) {
         removeOldest();
     }
 
     ssize_t index = mCache.indexOfKey(key);
     if (index >= 0) {
-        sp<Entry<K*, V*> > entry = mCache.valueAt(index);
+        sp<Entry<K, V> > entry = mCache.valueAt(index);
         detachFromCache(entry);
         addToCache(entry, key, value);
     } else {
-        sp<Entry<K*, V*> > entry = new Entry<K*, V*>;
+        sp<Entry<K, V> > entry = new Entry<K, V>;
         addToCache(entry, key, value);
     }
 }
 
 template<typename K, typename V>
-void GenerationCache<K, V>::addToCache(sp<Entry<K*, V*> > entry, K* key, V* value) {
+void GenerationCache<K, V>::addToCache(sp<Entry<K, V> > entry, K key, V value) {
     entry->key = key;
     entry->value = value;
     mCache.add(key, entry);
@@ -151,29 +151,33 @@
 }
 
 template<typename K, typename V>
-V* GenerationCache<K, V>::remove(K* key) {
+V GenerationCache<K, V>::remove(K key) {
     ssize_t index = mCache.indexOfKey(key);
     if (index >= 0) {
-        sp<Entry<K*, V*> > entry = mCache.valueAt(index);
+        sp<Entry<K, V> > entry = mCache.valueAt(index);
         if (mListener) {
             (*mListener)(entry->key, entry->value);
         }
         mCache.removeItemsAt(index, 1);
         detachFromCache(entry);
+
+        return entry->value;
     }
 
     return NULL;
 }
 
 template<typename K, typename V>
-void GenerationCache<K, V>::removeOldest() {
+V GenerationCache<K, V>::removeOldest() {
     if (mOldest.get()) {
-        remove(mOldest->key);
+        return remove(mOldest->key);
     }
+
+    return NULL;
 }
 
 template<typename K, typename V>
-void GenerationCache<K, V>::attachToCache(sp<Entry<K*, V*> > entry) {
+void GenerationCache<K, V>::attachToCache(sp<Entry<K, V> > entry) {
     if (!mYougest.get()) {
         mYougest = mOldest = entry;
     } else {
@@ -184,7 +188,7 @@
 }
 
 template<typename K, typename V>
-void GenerationCache<K, V>::detachFromCache(sp<Entry<K*, V*> > entry) {
+void GenerationCache<K, V>::detachFromCache(sp<Entry<K, V> > entry) {
     if (entry->parent.get()) {
         entry->parent->child = entry->child;
     }