Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1228a01e authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Optimize FBO cache."

parents 17adbfb5 5f0c6a48
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ LOCAL_SRC_FILES:= \
	Matrix.cpp \
	OpenGLRenderer.cpp \
	Program.cpp \
	SortedList.cpp \
	TextureCache.cpp

LOCAL_C_INCLUDES += \
+153 −48
Original line number Diff line number Diff line
@@ -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:
@@ -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,
@@ -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>
@@ -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);
@@ -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 {
@@ -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;
@@ -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;
    }
}

@@ -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();
+2 −3
Original line number Diff line number Diff line
@@ -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();
}

///////////////////////////////////////////////////////////////////////////////
+1 −1
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ public:
private:
    void deleteLayer(Layer* layer);

    GenerationCache<LayerSize, Layer*> mCache;
    GenerationMultiCache<LayerSize, Layer*> mCache;

    uint32_t mSize;
    uint32_t mMaxSize;
+1 −1
Original line number Diff line number Diff line
@@ -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