From 6c81893c626499e58c8eeb20d6c35ec4e1ce808b Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Wed, 7 Jul 2010 15:15:32 -0700 Subject: [PATCH] Simpler way to deal with the FBO multi-cache. This change removes the need for the SortedList and instead just add a generated id to each FBO stored in the cache. This is an artificial way to store several FBOs with the same dimensions. Change-Id: I9638364e9bdc0f2391261937a0c86096f20505bf --- libs/hwui/Android.mk | 3 +- libs/hwui/GenerationCache.h | 118 ++-------------- libs/hwui/Layer.h | 13 +- libs/hwui/LayerCache.cpp | 5 +- libs/hwui/LayerCache.h | 3 +- libs/hwui/OpenGLRenderer.cpp | 2 +- libs/hwui/SortedList.cpp | 126 ----------------- libs/hwui/SortedList.h | 255 ----------------------------------- libs/hwui/TextureCache.cpp | 2 +- libs/hwui/TextureCache.h | 2 +- 10 files changed, 33 insertions(+), 496 deletions(-) delete mode 100644 libs/hwui/SortedList.cpp delete mode 100644 libs/hwui/SortedList.h diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index cbdbc3c409ce2..9146ba67969f4 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -6,7 +6,6 @@ LOCAL_SRC_FILES:= \ Matrix.cpp \ OpenGLRenderer.cpp \ Program.cpp \ - SortedList.cpp \ TextureCache.cpp LOCAL_C_INCLUDES += \ @@ -20,7 +19,7 @@ LOCAL_C_INCLUDES += \ LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2 libskia -LOCAL_MODULE:= libhwui +LOCAL_MODULE := libhwui LOCAL_PRELINK_MODULE := false include $(BUILD_SHARED_LIBRARY) diff --git a/libs/hwui/GenerationCache.h b/libs/hwui/GenerationCache.h index 5f64a353658bb..5c1b5e142c0d7 100644 --- a/libs/hwui/GenerationCache.h +++ b/libs/hwui/GenerationCache.h @@ -20,68 +20,9 @@ #include #include -#include "SortedList.h" - namespace android { namespace uirenderer { -template -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 -GenerationCacheStorage::~GenerationCacheStorage() { -} - -template -class KeyedVectorStorage: public GenerationCacheStorage { -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 mStorage; -}; // class KeyedVectorStorage - -template -class SortedListStorage: public GenerationCacheStorage { -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(key, value)); - } - inline ssize_t indexOfKey(const K& key) const { - return mStorage.indexOf(key_value_pair_t(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 > mStorage; -}; // class SortedListStorage - template class OnEntryRemoved { public: @@ -127,17 +68,13 @@ public: uint32_t size() const; -protected: - virtual GenerationCacheStorage > >* createStorage() = 0; - GenerationCacheStorage > >* mCache; - -private: void addToCache(sp > entry, K key, V value); void attachToCache(sp > entry); void detachFromCache(sp > entry); V removeAt(ssize_t index); + KeyedVector > > mCache; uint32_t mMaxCapacity; OnEntryRemoved* mListener; @@ -146,32 +83,6 @@ private: sp > mYoungest; }; // class GenerationCache -template -class GenerationSingleCache: public GenerationCache { -public: - GenerationSingleCache(uint32_t maxCapacity): GenerationCache(maxCapacity) { - GenerationCache::mCache = createStorage(); - }; - ~GenerationSingleCache() { } -protected: - GenerationCacheStorage > >* createStorage() { - return new KeyedVectorStorage > >; - } -}; // GenerationSingleCache - -template -class GenerationMultiCache: public GenerationCache { -public: - GenerationMultiCache(uint32_t maxCapacity): GenerationCache(maxCapacity) { - GenerationCache::mCache = createStorage(); - }; - ~GenerationMultiCache() { } -protected: - GenerationCacheStorage > >* createStorage() { - return new SortedListStorage > >; - } -}; // GenerationMultiCache - template GenerationCache::GenerationCache(uint32_t maxCapacity): mMaxCapacity(maxCapacity), mListener(NULL) { }; @@ -179,12 +90,11 @@ GenerationCache::GenerationCache(uint32_t maxCapacity): mMaxCapacity(maxCa template GenerationCache::~GenerationCache() { clear(); - delete mCache; }; template uint32_t GenerationCache::size() const { - return mCache->size(); + return mCache.size(); } template @@ -195,11 +105,11 @@ void GenerationCache::setOnEntryRemovedListener(OnEntryRemoved* list template void GenerationCache::clear() { if (mListener) { - while (mCache->size() > 0) { + while (mCache.size() > 0) { removeOldest(); } } else { - mCache->clear(); + mCache.clear(); } mYoungest.clear(); mOldest.clear(); @@ -207,14 +117,14 @@ void GenerationCache::clear() { template bool GenerationCache::contains(K key) const { - return mCache->indexOfKey(key) >= 0; + return mCache.indexOfKey(key) >= 0; } template V GenerationCache::get(K key) { - ssize_t index = mCache->indexOfKey(key); + ssize_t index = mCache.indexOfKey(key); if (index >= 0) { - sp > entry = mCache->valueAt(index); + sp > entry = mCache.valueAt(index); if (entry.get()) { detachFromCache(entry); attachToCache(entry); @@ -227,13 +137,13 @@ V GenerationCache::get(K key) { template void GenerationCache::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 = mCache->valueAt(index); + sp > entry = mCache.valueAt(index); detachFromCache(entry); addToCache(entry, key, value); } else { @@ -246,13 +156,13 @@ template void GenerationCache::addToCache(sp > entry, K key, V value) { entry->key = key; entry->value = value; - entry->index = mCache->add(key, entry); + entry->index = mCache.add(key, entry); attachToCache(entry); } template V GenerationCache::remove(K key) { - ssize_t index = mCache->indexOfKey(key); + ssize_t index = mCache.indexOfKey(key); if (index >= 0) { return removeAt(index); } @@ -262,11 +172,11 @@ V GenerationCache::remove(K key) { template V GenerationCache::removeAt(ssize_t index) { - sp > entry = mCache->valueAt(index); + sp > entry = mCache.valueAt(index); if (mListener) { (*mListener)(entry->key, entry->value); } - mCache->removeItemsAt(index, 1); + mCache.removeItemsAt(index, 1); detachFromCache(entry); return entry->value; diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 70d64ca4b9140..586a05e77e253 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -30,14 +30,21 @@ namespace uirenderer { * Dimensions of a layer. */ struct LayerSize { - LayerSize(): width(0), height(0) { } - LayerSize(const uint32_t width, const uint32_t height): width(width), height(height) { } - LayerSize(const LayerSize& size): width(size.width), height(size.height) { } + LayerSize(): width(0), height(0), id(0) { } + LayerSize(const uint32_t width, const uint32_t height): width(width), height(height), id(0) { } + LayerSize(const LayerSize& size): width(size.width), height(size.height), id(size.id) { } uint32_t width; uint32_t height; + // Incremental id used by the layer cache to store multiple + // LayerSize with the same dimensions + uint32_t id; + bool operator<(const LayerSize& rhs) const { + if (id != 0 && rhs.id != 0) { + return id < rhs.id; + } if (width == rhs.width) { return height < rhs.height; } diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp index 7d85e7b37c8c5..882ad8388b9a7 100644 --- a/libs/hwui/LayerCache.cpp +++ b/libs/hwui/LayerCache.cpp @@ -28,8 +28,8 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// LayerCache::LayerCache(uint32_t maxByteSize): - mCache(GenerationMultiCache::kUnlimitedCapacity), - mSize(0), mMaxSize(maxByteSize) { + mCache(GenerationCache::kUnlimitedCapacity), + mIdGenerator(1), mSize(0), mMaxSize(maxByteSize) { } LayerCache::~LayerCache() { @@ -101,6 +101,7 @@ bool LayerCache::put(LayerSize& layerSize, Layer* layer) { deleteLayer(oldest); } + layerSize.id = mIdGenerator++; mCache.put(layerSize, layer); mSize += size; diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h index 2d339fab6b6d2..519552de274c1 100644 --- a/libs/hwui/LayerCache.h +++ b/libs/hwui/LayerCache.h @@ -66,7 +66,8 @@ public: private: void deleteLayer(Layer* layer); - GenerationMultiCache mCache; + GenerationCache mCache; + uint32_t mIdGenerator; uint32_t mSize; uint32_t mMaxSize; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 0ade173a60a3d..304af2eeeecd5 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -35,7 +35,7 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// // Debug -#define DEBUG_LAYERS 0 +#define DEBUG_LAYERS 1 // These properties are defined in mega-bytes #define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size" diff --git a/libs/hwui/SortedList.cpp b/libs/hwui/SortedList.cpp deleted file mode 100644 index 05adff5b80300..0000000000000 --- a/libs/hwui/SortedList.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "SortedList.h" - -namespace android { -namespace uirenderer { - -SortedListImpl::SortedListImpl(size_t itemSize, uint32_t flags) : - VectorImpl(itemSize, flags) { -} - -SortedListImpl::SortedListImpl(const VectorImpl& rhs) : - VectorImpl(rhs) { -} - -SortedListImpl::~SortedListImpl() { -} - -SortedListImpl& SortedListImpl::operator =(const SortedListImpl& rhs) { - return static_cast (VectorImpl::operator =( - static_cast (rhs))); -} - -ssize_t SortedListImpl::indexOf(const void* item) const { - return _indexOrderOf(item); -} - -size_t SortedListImpl::orderOf(const void* item) const { - size_t o; - _indexOrderOf(item, &o); - return o; -} - -ssize_t SortedListImpl::_indexOrderOf(const void* item, size_t* order) const { - // binary search - ssize_t err = NAME_NOT_FOUND; - ssize_t l = 0; - ssize_t h = size() - 1; - ssize_t mid; - const void* a = arrayImpl(); - const size_t s = itemSize(); - while (l <= h) { - mid = l + (h - l) / 2; - const void* const curr = reinterpret_cast (a) + (mid * s); - const int c = do_compare(curr, item); - if (c == 0) { - err = l = mid; - break; - } else if (c < 0) { - l = mid + 1; - } else { - h = mid - 1; - } - } - if (order) - *order = l; - return err; -} - -ssize_t SortedListImpl::add(const void* item) { - size_t order; - ssize_t index = _indexOrderOf(item, &order); - index = VectorImpl::insertAt(item, order, 1); - return index; -} - -ssize_t SortedListImpl::merge(const VectorImpl& vector) { - // naive merge... - if (!vector.isEmpty()) { - const void* buffer = vector.arrayImpl(); - const size_t is = itemSize(); - size_t s = vector.size(); - for (size_t i = 0; i < s; i++) { - ssize_t err = add(reinterpret_cast (buffer) + i * is); - if (err < 0) { - return err; - } - } - } - return NO_ERROR; -} - -ssize_t SortedListImpl::merge(const SortedListImpl& vector) { - // we've merging a sorted vector... nice! - ssize_t err = NO_ERROR; - if (!vector.isEmpty()) { - // first take care of the case where the vectors are sorted together - if (do_compare(vector.itemLocation(vector.size() - 1), arrayImpl()) <= 0) { - err = VectorImpl::insertVectorAt(static_cast (vector), 0); - } else if (do_compare(vector.arrayImpl(), itemLocation(size() - 1)) >= 0) { - err = VectorImpl::appendVector(static_cast (vector)); - } else { - // this could be made a little better - err = merge(static_cast (vector)); - } - } - return err; -} - -ssize_t SortedListImpl::remove(const void* item) { - ssize_t i = indexOf(item); - if (i >= 0) { - VectorImpl::removeItemsAt(i, 1); - } - return i; -} - -} -; // namespace uirenderer -} -; // namespace android - diff --git a/libs/hwui/SortedList.h b/libs/hwui/SortedList.h deleted file mode 100644 index 13cb64dc55cc2..0000000000000 --- a/libs/hwui/SortedList.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_UI_SORTED_LIST_H -#define ANDROID_UI_SORTED_LIST_H - -#include -#include - -namespace android { -namespace uirenderer { - -class SortedListImpl: public VectorImpl { -public: - SortedListImpl(size_t itemSize, uint32_t flags); - SortedListImpl(const VectorImpl& rhs); - virtual ~SortedListImpl(); - - SortedListImpl& operator =(const SortedListImpl& rhs); - - ssize_t indexOf(const void* item) const; - size_t orderOf(const void* item) const; - ssize_t add(const void* item); - ssize_t merge(const VectorImpl& vector); - ssize_t merge(const SortedListImpl& vector); - ssize_t remove(const void* item); - -protected: - virtual int do_compare(const void* lhs, const void* rhs) const = 0; - -private: - ssize_t _indexOrderOf(const void* item, size_t* order = 0) const; - - // these are made private, because they can't be used on a SortedList - // (they don't have an implementation either) - ssize_t add(); - void pop(); - void push(); - void push(const void* item); - ssize_t insertVectorAt(const VectorImpl& vector, size_t index); - ssize_t appendVector(const VectorImpl& vector); - ssize_t insertArrayAt(const void* array, size_t index, size_t length); - ssize_t appendArray(const void* array, size_t length); - ssize_t insertAt(size_t where, size_t numItems = 1); - ssize_t insertAt(const void* item, size_t where, size_t numItems = 1); - ssize_t replaceAt(size_t index); - ssize_t replaceAt(const void* item, size_t index); -}; // class SortedListImpl - -template -class SortedList: private SortedListImpl { -public: - typedef TYPE value_type; - - SortedList(); - SortedList(const SortedList& rhs); - virtual ~SortedList(); - - const SortedList& operator =(const SortedList& rhs) const; - SortedList& operator =(const SortedList& rhs); - - inline void clear() { - VectorImpl::clear(); - } - - inline size_t size() const { - return VectorImpl::size(); - } - - inline bool isEmpty() const { - return VectorImpl::isEmpty(); - } - - inline size_t capacity() const { - return VectorImpl::capacity(); - } - - inline ssize_t setCapacity(size_t size) { - return VectorImpl::setCapacity(size); - } - - inline const TYPE* array() const; - - TYPE* editArray(); - - ssize_t indexOf(const TYPE& item) const; - - size_t orderOf(const TYPE& item) const; - - inline const TYPE& operator [](size_t index) const; - inline const TYPE& itemAt(size_t index) const; - const TYPE& top() const; - const TYPE& mirrorItemAt(ssize_t index) const; - - ssize_t add(const TYPE& item); - - TYPE& editItemAt(size_t index) { - return *(static_cast (VectorImpl::editItemLocation(index))); - } - - ssize_t merge(const Vector& vector); - ssize_t merge(const SortedList& vector); - - ssize_t remove(const TYPE&); - - inline ssize_t removeItemsAt(size_t index, size_t count = 1); - inline ssize_t removeAt(size_t index) { - return removeItemsAt(index); - } - -protected: - virtual void do_construct(void* storage, size_t num) const; - virtual void do_destroy(void* storage, size_t num) const; - virtual void do_copy(void* dest, const void* from, size_t num) const; - virtual void do_splat(void* dest, const void* item, size_t num) const; - virtual void do_move_forward(void* dest, const void* from, size_t num) const; - virtual void - do_move_backward(void* dest, const void* from, size_t num) const; - virtual int do_compare(const void* lhs, const void* rhs) const; -}; - -template inline SortedList::SortedList() : - SortedListImpl(sizeof(TYPE), ((traits::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) - | (traits::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) - | (traits::has_trivial_copy ? HAS_TRIVIAL_COPY : 0))) { -} - -template inline SortedList::SortedList(const SortedList& rhs) : - SortedListImpl(rhs) { -} - -template inline SortedList::~SortedList() { - finish_vector(); -} - -template inline SortedList& SortedList::operator =( - const SortedList& rhs) { - SortedListImpl::operator =(rhs); - return *this; -} - -template inline const SortedList& SortedList::operator =(const SortedList< - TYPE>& rhs) const { - SortedListImpl::operator =(rhs); - return *this; -} - -template inline const TYPE* SortedList::array() const { - return static_cast (arrayImpl()); -} - -template inline TYPE* SortedList::editArray() { - return static_cast (editArrayImpl()); -} - -template inline const TYPE& SortedList::operator[](size_t index) const { - assert( index inline const TYPE& SortedList::itemAt(size_t index) const { - return operator[](index); -} - -template inline const TYPE& SortedList::mirrorItemAt(ssize_t index) const { - assert( (index>0 ? index : -index) inline const TYPE& SortedList::top() const { - return *(array() + size() - 1); -} - -template inline ssize_t SortedList::add(const TYPE& item) { - return SortedListImpl::add(&item); -} - -template inline ssize_t SortedList::indexOf(const TYPE& item) const { - return SortedListImpl::indexOf(&item); -} - -template inline size_t SortedList::orderOf(const TYPE& item) const { - return SortedListImpl::orderOf(&item); -} - -template inline ssize_t SortedList::merge(const Vector& vector) { - return SortedListImpl::merge(reinterpret_cast (vector)); -} - -template inline ssize_t SortedList::merge(const SortedList& vector) { - return SortedListImpl::merge(reinterpret_cast (vector)); -} - -template inline ssize_t SortedList::remove(const TYPE& item) { - return SortedListImpl::remove(&item); -} - -template inline ssize_t SortedList::removeItemsAt(size_t index, size_t count) { - return VectorImpl::removeItemsAt(index, count); -} - -template -void SortedList::do_construct(void* storage, size_t num) const { - construct_type(reinterpret_cast (storage), num); -} - -template -void SortedList::do_destroy(void* storage, size_t num) const { - destroy_type(reinterpret_cast (storage), num); -} - -template -void SortedList::do_copy(void* dest, const void* from, size_t num) const { - copy_type(reinterpret_cast (dest), reinterpret_cast (from), num); -} - -template -void SortedList::do_splat(void* dest, const void* item, size_t num) const { - splat_type(reinterpret_cast (dest), reinterpret_cast (item), num); -} - -template -void SortedList::do_move_forward(void* dest, const void* from, size_t num) const { - move_forward_type(reinterpret_cast (dest), reinterpret_cast (from), num); -} - -template -void SortedList::do_move_backward(void* dest, const void* from, size_t num) const { - move_backward_type(reinterpret_cast (dest), reinterpret_cast (from), num); -} - -template -int SortedList::do_compare(const void* lhs, const void* rhs) const { - return compare_type(*reinterpret_cast (lhs), *reinterpret_cast (rhs)); -} - -} -; // namespace uirenderer -} -; // namespace android - -#endif // ANDROID_UI_SORTED_LIST_H diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 460284e8fb78d..612f04e5570ef 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -28,7 +28,7 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// TextureCache::TextureCache(uint32_t maxByteSize): - mCache(GenerationSingleCache::kUnlimitedCapacity), + mCache(GenerationCache::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { mCache.setOnEntryRemovedListener(this); } diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index a6208765be4fd..bed11915c5811 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -78,7 +78,7 @@ private: */ void generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate = false); - GenerationSingleCache mCache; + GenerationCache mCache; uint32_t mSize; uint32_t mMaxSize;