Loading libs/hwui/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ LOCAL_SRC_FILES:= \ Matrix.cpp \ OpenGLRenderer.cpp \ Program.cpp \ SortedList.cpp \ TextureCache.cpp LOCAL_C_INCLUDES += \ Loading libs/hwui/GenerationCache.h +153 −48 Original line number Diff line number Diff line Loading @@ -20,9 +20,68 @@ #include <utils/KeyedVector.h> #include <utils/RefBase.h> #include "SortedList.h" namespace android { namespace uirenderer { template<typename K, typename V> class GenerationCacheStorage { public: virtual ~GenerationCacheStorage(); virtual size_t size() const = 0; virtual void clear() = 0; virtual ssize_t add(const K& key, const V& item) = 0; virtual ssize_t indexOfKey(const K& key) const = 0; virtual const V& valueAt(size_t index) const = 0; virtual ssize_t removeItemsAt(size_t index, size_t count) = 0; }; // GenerationCacheStorage template<typename K, typename V> GenerationCacheStorage<K, V>::~GenerationCacheStorage() { } template<typename K, typename V> class KeyedVectorStorage: public GenerationCacheStorage<K, V> { public: KeyedVectorStorage() { } ~KeyedVectorStorage() { } inline size_t size() const { return mStorage.size(); } inline void clear() { mStorage.clear(); } inline ssize_t add(const K& key, const V& value) { return mStorage.add(key, value); } inline ssize_t indexOfKey(const K& key) const { return mStorage.indexOfKey(key); } inline const V& valueAt(size_t index) const { return mStorage.valueAt(index); } inline ssize_t removeItemsAt(size_t index, size_t count) { return mStorage.removeItemsAt(index, count); } private: KeyedVector<K, V> mStorage; }; // class KeyedVectorStorage template<typename K, typename V> class SortedListStorage: public GenerationCacheStorage<K, V> { public: SortedListStorage() { } ~SortedListStorage() { } inline size_t size() const { return mStorage.size(); } inline void clear() { mStorage.clear(); } inline ssize_t add(const K& key, const V& value) { return mStorage.add(key_value_pair_t<K, V>(key, value)); } inline ssize_t indexOfKey(const K& key) const { return mStorage.indexOf(key_value_pair_t<K, V>(key)); } inline const V& valueAt(size_t index) const { return mStorage.itemAt(index).value; } inline ssize_t removeItemsAt(size_t index, size_t count) { return mStorage.removeItemsAt(index, count); } private: SortedList<key_value_pair_t<K, V> > mStorage; }; // class SortedListStorage template<typename EntryKey, typename EntryValue> class OnEntryRemoved { public: Loading @@ -30,11 +89,27 @@ public: virtual void operator()(EntryKey& key, EntryValue& value) = 0; }; // class OnEntryRemoved template<typename EntryKey, typename EntryValue> struct Entry: public LightRefBase<Entry<EntryKey, EntryValue> > { Entry() { } Entry(const Entry<EntryKey, EntryValue>& e): key(e.key), value(e.value), index(e.index), parent(e.parent), child(e.child) { } Entry(sp<Entry<EntryKey, EntryValue> > e): key(e->key), value(e->value), index(e->index), parent(e->parent), child(e->child) { } EntryKey key; EntryValue value; ssize_t index; sp<Entry<EntryKey, EntryValue> > parent; sp<Entry<EntryKey, EntryValue> > child; }; // struct Entry template<typename K, typename V> class GenerationCache { public: GenerationCache(uint32_t maxCapacity): mMaxCapacity(maxCapacity), mListener(NULL) { }; ~GenerationCache() { clear(); }; GenerationCache(uint32_t maxCapacity); virtual ~GenerationCache(); enum Capacity { kUnlimitedCapacity, Loading @@ -52,39 +127,64 @@ public: uint32_t size() const; private: template<typename EntryKey, typename EntryValue> struct Entry: public LightRefBase<Entry<EntryKey, EntryValue> > { Entry() { } Entry(const Entry<EntryKey, EntryValue>& e): key(e.key), value(e.value), parent(e.parent), child(e.child) { } Entry(sp<Entry<EntryKey, EntryValue> > e): key(e->key), value(e->value), parent(e->parent), child(e->child) { } EntryKey key; EntryValue value; sp<Entry<EntryKey, EntryValue> > parent; sp<Entry<EntryKey, EntryValue> > child; }; // struct Entry protected: virtual GenerationCacheStorage<K, sp<Entry<K, V> > >* createStorage() = 0; GenerationCacheStorage<K, sp<Entry<K, V> > >* mCache; private: 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); V removeAt(ssize_t index); uint32_t mMaxCapacity; OnEntryRemoved<K, V>* mListener; KeyedVector<K, sp<Entry<K, V> > > mCache; sp<Entry<K, V> > mOldest; sp<Entry<K, V> > mYougest; sp<Entry<K, V> > mYoungest; }; // class GenerationCache template<typename K, typename V> class GenerationSingleCache: public GenerationCache<K, V> { public: GenerationSingleCache(uint32_t maxCapacity): GenerationCache<K, V>(maxCapacity) { GenerationCache<K, V>::mCache = createStorage(); }; ~GenerationSingleCache() { } protected: GenerationCacheStorage<K, sp<Entry<K, V> > >* createStorage() { return new KeyedVectorStorage<K, sp<Entry<K, V> > >; } }; // GenerationSingleCache template<typename K, typename V> class GenerationMultiCache: public GenerationCache<K, V> { public: GenerationMultiCache(uint32_t maxCapacity): GenerationCache<K, V>(maxCapacity) { GenerationCache<K, V>::mCache = createStorage(); }; ~GenerationMultiCache() { } protected: GenerationCacheStorage<K, sp<Entry<K, V> > >* createStorage() { return new SortedListStorage<K, sp<Entry<K, V> > >; } }; // GenerationMultiCache template<typename K, typename V> GenerationCache<K, V>::GenerationCache(uint32_t maxCapacity): mMaxCapacity(maxCapacity), mListener(NULL) { }; template<typename K, typename V> GenerationCache<K, V>::~GenerationCache() { clear(); delete mCache; }; template<typename K, typename V> uint32_t GenerationCache<K, V>::size() const { return mCache.size(); return mCache->size(); } template<typename K, typename V> Loading @@ -95,26 +195,26 @@ void GenerationCache<K, V>::setOnEntryRemovedListener(OnEntryRemoved<K, V>* list template<typename K, typename V> void GenerationCache<K, V>::clear() { if (mListener) { while (mCache.size() > 0) { while (mCache->size() > 0) { removeOldest(); } } else { mCache.clear(); mCache->clear(); } mYougest.clear(); mYoungest.clear(); mOldest.clear(); } template<typename K, typename V> bool GenerationCache<K, V>::contains(K key) const { return mCache.indexOfKey(key) >= 0; return mCache->indexOfKey(key) >= 0; } template<typename K, typename V> V GenerationCache<K, V>::get(K key) { ssize_t index = mCache.indexOfKey(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); Loading @@ -127,13 +227,13 @@ V GenerationCache<K, V>::get(K key) { template<typename K, typename V> void GenerationCache<K, V>::put(K key, V value) { if (mMaxCapacity != kUnlimitedCapacity && mCache.size() >= mMaxCapacity) { if (mMaxCapacity != kUnlimitedCapacity && mCache->size() >= mMaxCapacity) { removeOldest(); } ssize_t index = mCache.indexOfKey(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); detachFromCache(entry); addToCache(entry, key, value); } else { Loading @@ -146,31 +246,36 @@ template<typename K, typename V> void GenerationCache<K, V>::addToCache(sp<Entry<K, V> > entry, K key, V value) { entry->key = key; entry->value = value; mCache.add(key, entry); entry->index = mCache->add(key, entry); attachToCache(entry); } template<typename K, typename V> V GenerationCache<K, V>::remove(K key) { ssize_t index = mCache.indexOfKey(key); ssize_t index = mCache->indexOfKey(key); if (index >= 0) { sp<Entry<K, V> > entry = mCache.valueAt(index); return removeAt(index); } return NULL; } template<typename K, typename V> V GenerationCache<K, V>::removeAt(ssize_t index) { sp<Entry<K, V> > entry = mCache->valueAt(index); if (mListener) { (*mListener)(entry->key, entry->value); } mCache.removeItemsAt(index, 1); mCache->removeItemsAt(index, 1); detachFromCache(entry); return entry->value; } return NULL; } template<typename K, typename V> V GenerationCache<K, V>::removeOldest() { if (mOldest.get()) { return remove(mOldest->key); return removeAt(mOldest->index); } return NULL; Loading @@ -178,12 +283,12 @@ V GenerationCache<K, V>::removeOldest() { template<typename K, typename V> void GenerationCache<K, V>::attachToCache(sp<Entry<K, V> > entry) { if (!mYougest.get()) { mYougest = mOldest = entry; if (!mYoungest.get()) { mYoungest = mOldest = entry; } else { entry->parent = mYougest; mYougest->child = entry; mYougest = entry; entry->parent = mYoungest; mYoungest->child = entry; mYoungest = entry; } } Loading @@ -201,8 +306,8 @@ void GenerationCache<K, V>::detachFromCache(sp<Entry<K, V> > entry) { mOldest = entry->child; } if (mYougest == entry) { mYougest = entry->parent; if (mYoungest == entry) { mYoungest = entry->parent; } entry->parent.clear(); Loading libs/hwui/LayerCache.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -28,13 +28,12 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// LayerCache::LayerCache(uint32_t maxByteSize): mCache(GenerationCache<LayerSize, Layer*>::kUnlimitedCapacity), mCache(GenerationMultiCache<LayerSize, Layer*>::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { } LayerCache::~LayerCache() { mCache.setOnEntryRemovedListener(this); mCache.clear(); clear(); } /////////////////////////////////////////////////////////////////////////////// Loading libs/hwui/LayerCache.h +1 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ public: private: void deleteLayer(Layer* layer); GenerationCache<LayerSize, Layer*> mCache; GenerationMultiCache<LayerSize, Layer*> mCache; uint32_t mSize; uint32_t mMaxSize; Loading libs/hwui/OpenGLRenderer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ namespace uirenderer { #define FV(x, y, u, v) { { x, y }, { u, v } } // Debug #ifdef DEBUG_LAYERS #if DEBUG_LAYERS #define LAYER_LOGD(...) LOGD(__VA_ARGS__) #else #define LAYER_LOGD(...) Loading Loading
libs/hwui/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ LOCAL_SRC_FILES:= \ Matrix.cpp \ OpenGLRenderer.cpp \ Program.cpp \ SortedList.cpp \ TextureCache.cpp LOCAL_C_INCLUDES += \ Loading
libs/hwui/GenerationCache.h +153 −48 Original line number Diff line number Diff line Loading @@ -20,9 +20,68 @@ #include <utils/KeyedVector.h> #include <utils/RefBase.h> #include "SortedList.h" namespace android { namespace uirenderer { template<typename K, typename V> class GenerationCacheStorage { public: virtual ~GenerationCacheStorage(); virtual size_t size() const = 0; virtual void clear() = 0; virtual ssize_t add(const K& key, const V& item) = 0; virtual ssize_t indexOfKey(const K& key) const = 0; virtual const V& valueAt(size_t index) const = 0; virtual ssize_t removeItemsAt(size_t index, size_t count) = 0; }; // GenerationCacheStorage template<typename K, typename V> GenerationCacheStorage<K, V>::~GenerationCacheStorage() { } template<typename K, typename V> class KeyedVectorStorage: public GenerationCacheStorage<K, V> { public: KeyedVectorStorage() { } ~KeyedVectorStorage() { } inline size_t size() const { return mStorage.size(); } inline void clear() { mStorage.clear(); } inline ssize_t add(const K& key, const V& value) { return mStorage.add(key, value); } inline ssize_t indexOfKey(const K& key) const { return mStorage.indexOfKey(key); } inline const V& valueAt(size_t index) const { return mStorage.valueAt(index); } inline ssize_t removeItemsAt(size_t index, size_t count) { return mStorage.removeItemsAt(index, count); } private: KeyedVector<K, V> mStorage; }; // class KeyedVectorStorage template<typename K, typename V> class SortedListStorage: public GenerationCacheStorage<K, V> { public: SortedListStorage() { } ~SortedListStorage() { } inline size_t size() const { return mStorage.size(); } inline void clear() { mStorage.clear(); } inline ssize_t add(const K& key, const V& value) { return mStorage.add(key_value_pair_t<K, V>(key, value)); } inline ssize_t indexOfKey(const K& key) const { return mStorage.indexOf(key_value_pair_t<K, V>(key)); } inline const V& valueAt(size_t index) const { return mStorage.itemAt(index).value; } inline ssize_t removeItemsAt(size_t index, size_t count) { return mStorage.removeItemsAt(index, count); } private: SortedList<key_value_pair_t<K, V> > mStorage; }; // class SortedListStorage template<typename EntryKey, typename EntryValue> class OnEntryRemoved { public: Loading @@ -30,11 +89,27 @@ public: virtual void operator()(EntryKey& key, EntryValue& value) = 0; }; // class OnEntryRemoved template<typename EntryKey, typename EntryValue> struct Entry: public LightRefBase<Entry<EntryKey, EntryValue> > { Entry() { } Entry(const Entry<EntryKey, EntryValue>& e): key(e.key), value(e.value), index(e.index), parent(e.parent), child(e.child) { } Entry(sp<Entry<EntryKey, EntryValue> > e): key(e->key), value(e->value), index(e->index), parent(e->parent), child(e->child) { } EntryKey key; EntryValue value; ssize_t index; sp<Entry<EntryKey, EntryValue> > parent; sp<Entry<EntryKey, EntryValue> > child; }; // struct Entry template<typename K, typename V> class GenerationCache { public: GenerationCache(uint32_t maxCapacity): mMaxCapacity(maxCapacity), mListener(NULL) { }; ~GenerationCache() { clear(); }; GenerationCache(uint32_t maxCapacity); virtual ~GenerationCache(); enum Capacity { kUnlimitedCapacity, Loading @@ -52,39 +127,64 @@ public: uint32_t size() const; private: template<typename EntryKey, typename EntryValue> struct Entry: public LightRefBase<Entry<EntryKey, EntryValue> > { Entry() { } Entry(const Entry<EntryKey, EntryValue>& e): key(e.key), value(e.value), parent(e.parent), child(e.child) { } Entry(sp<Entry<EntryKey, EntryValue> > e): key(e->key), value(e->value), parent(e->parent), child(e->child) { } EntryKey key; EntryValue value; sp<Entry<EntryKey, EntryValue> > parent; sp<Entry<EntryKey, EntryValue> > child; }; // struct Entry protected: virtual GenerationCacheStorage<K, sp<Entry<K, V> > >* createStorage() = 0; GenerationCacheStorage<K, sp<Entry<K, V> > >* mCache; private: 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); V removeAt(ssize_t index); uint32_t mMaxCapacity; OnEntryRemoved<K, V>* mListener; KeyedVector<K, sp<Entry<K, V> > > mCache; sp<Entry<K, V> > mOldest; sp<Entry<K, V> > mYougest; sp<Entry<K, V> > mYoungest; }; // class GenerationCache template<typename K, typename V> class GenerationSingleCache: public GenerationCache<K, V> { public: GenerationSingleCache(uint32_t maxCapacity): GenerationCache<K, V>(maxCapacity) { GenerationCache<K, V>::mCache = createStorage(); }; ~GenerationSingleCache() { } protected: GenerationCacheStorage<K, sp<Entry<K, V> > >* createStorage() { return new KeyedVectorStorage<K, sp<Entry<K, V> > >; } }; // GenerationSingleCache template<typename K, typename V> class GenerationMultiCache: public GenerationCache<K, V> { public: GenerationMultiCache(uint32_t maxCapacity): GenerationCache<K, V>(maxCapacity) { GenerationCache<K, V>::mCache = createStorage(); }; ~GenerationMultiCache() { } protected: GenerationCacheStorage<K, sp<Entry<K, V> > >* createStorage() { return new SortedListStorage<K, sp<Entry<K, V> > >; } }; // GenerationMultiCache template<typename K, typename V> GenerationCache<K, V>::GenerationCache(uint32_t maxCapacity): mMaxCapacity(maxCapacity), mListener(NULL) { }; template<typename K, typename V> GenerationCache<K, V>::~GenerationCache() { clear(); delete mCache; }; template<typename K, typename V> uint32_t GenerationCache<K, V>::size() const { return mCache.size(); return mCache->size(); } template<typename K, typename V> Loading @@ -95,26 +195,26 @@ void GenerationCache<K, V>::setOnEntryRemovedListener(OnEntryRemoved<K, V>* list template<typename K, typename V> void GenerationCache<K, V>::clear() { if (mListener) { while (mCache.size() > 0) { while (mCache->size() > 0) { removeOldest(); } } else { mCache.clear(); mCache->clear(); } mYougest.clear(); mYoungest.clear(); mOldest.clear(); } template<typename K, typename V> bool GenerationCache<K, V>::contains(K key) const { return mCache.indexOfKey(key) >= 0; return mCache->indexOfKey(key) >= 0; } template<typename K, typename V> V GenerationCache<K, V>::get(K key) { ssize_t index = mCache.indexOfKey(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); Loading @@ -127,13 +227,13 @@ V GenerationCache<K, V>::get(K key) { template<typename K, typename V> void GenerationCache<K, V>::put(K key, V value) { if (mMaxCapacity != kUnlimitedCapacity && mCache.size() >= mMaxCapacity) { if (mMaxCapacity != kUnlimitedCapacity && mCache->size() >= mMaxCapacity) { removeOldest(); } ssize_t index = mCache.indexOfKey(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); detachFromCache(entry); addToCache(entry, key, value); } else { Loading @@ -146,31 +246,36 @@ template<typename K, typename V> void GenerationCache<K, V>::addToCache(sp<Entry<K, V> > entry, K key, V value) { entry->key = key; entry->value = value; mCache.add(key, entry); entry->index = mCache->add(key, entry); attachToCache(entry); } template<typename K, typename V> V GenerationCache<K, V>::remove(K key) { ssize_t index = mCache.indexOfKey(key); ssize_t index = mCache->indexOfKey(key); if (index >= 0) { sp<Entry<K, V> > entry = mCache.valueAt(index); return removeAt(index); } return NULL; } template<typename K, typename V> V GenerationCache<K, V>::removeAt(ssize_t index) { sp<Entry<K, V> > entry = mCache->valueAt(index); if (mListener) { (*mListener)(entry->key, entry->value); } mCache.removeItemsAt(index, 1); mCache->removeItemsAt(index, 1); detachFromCache(entry); return entry->value; } return NULL; } template<typename K, typename V> V GenerationCache<K, V>::removeOldest() { if (mOldest.get()) { return remove(mOldest->key); return removeAt(mOldest->index); } return NULL; Loading @@ -178,12 +283,12 @@ V GenerationCache<K, V>::removeOldest() { template<typename K, typename V> void GenerationCache<K, V>::attachToCache(sp<Entry<K, V> > entry) { if (!mYougest.get()) { mYougest = mOldest = entry; if (!mYoungest.get()) { mYoungest = mOldest = entry; } else { entry->parent = mYougest; mYougest->child = entry; mYougest = entry; entry->parent = mYoungest; mYoungest->child = entry; mYoungest = entry; } } Loading @@ -201,8 +306,8 @@ void GenerationCache<K, V>::detachFromCache(sp<Entry<K, V> > entry) { mOldest = entry->child; } if (mYougest == entry) { mYougest = entry->parent; if (mYoungest == entry) { mYoungest = entry->parent; } entry->parent.clear(); Loading
libs/hwui/LayerCache.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -28,13 +28,12 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// LayerCache::LayerCache(uint32_t maxByteSize): mCache(GenerationCache<LayerSize, Layer*>::kUnlimitedCapacity), mCache(GenerationMultiCache<LayerSize, Layer*>::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { } LayerCache::~LayerCache() { mCache.setOnEntryRemovedListener(this); mCache.clear(); clear(); } /////////////////////////////////////////////////////////////////////////////// Loading
libs/hwui/LayerCache.h +1 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ public: private: void deleteLayer(Layer* layer); GenerationCache<LayerSize, Layer*> mCache; GenerationMultiCache<LayerSize, Layer*> mCache; uint32_t mSize; uint32_t mMaxSize; Loading
libs/hwui/OpenGLRenderer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ namespace uirenderer { #define FV(x, y, u, v) { { x, y }, { u, v } } // Debug #ifdef DEBUG_LAYERS #if DEBUG_LAYERS #define LAYER_LOGD(...) LOGD(__VA_ARGS__) #else #define LAYER_LOGD(...) Loading