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

Commit 059e12cc authored by Romain Guy's avatar Romain Guy
Browse files

Use LruCache instead of GenerationCache in libhwui

Change-Id: Ic26ddc7151eb5462bcd243b21daf7187ed6d3bec
parent c653df46
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -792,7 +792,9 @@ public:
    static void doTextBounds(JNIEnv* env, const jchar* text, int count,
                             jobject bounds, const SkPaint& paint)
    {
        SkRect  r{0,0,0,0};
        SkRect  r;
        r.set(0,0,0,0);

        SkIRect ir;

        sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
+30 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#define LOG_TAG "OpenGLRenderer"

#include <utils/JenkinsHash.h>
#include <utils/threads.h>

#include "Caches.h"
@@ -42,12 +43,39 @@ static inline T min(T a, T b) {
    return a < b ? a : b;
}

///////////////////////////////////////////////////////////////////////////////
// Cache entry
///////////////////////////////////////////////////////////////////////////////

hash_t GradientCacheEntry::hash() const {
    uint32_t hash = JenkinsHashMix(0, count);
    hash = JenkinsHashMix(hash, tileMode);
    for (uint32_t i = 0; i < count; i++) {
        hash = JenkinsHashMix(hash, android::hash_type(colors[i]));
        hash = JenkinsHashMix(hash, android::hash_type(positions[i]));
    }
    return JenkinsHashWhiten(hash);
}

int GradientCacheEntry::compare(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
    int deltaInt = int(lhs.count) - int(rhs.count);
    if (deltaInt != 0) return deltaInt;

    deltaInt = lhs.tileMode - rhs.tileMode;
    if (deltaInt != 0) return deltaInt;

    deltaInt = memcmp(lhs.colors, rhs.colors, lhs.count * sizeof(uint32_t));
    if (deltaInt != 0) return deltaInt;

    return memcmp(lhs.positions, rhs.positions, lhs.count * sizeof(float));
}

///////////////////////////////////////////////////////////////////////////////
// Constructors/destructor
///////////////////////////////////////////////////////////////////////////////

GradientCache::GradientCache():
        mCache(GenerationCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity),
        mCache(LruCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity),
        mSize(0), mMaxSize(MB(DEFAULT_GRADIENT_CACHE_SIZE)) {
    char property[PROPERTY_VALUE_MAX];
    if (property_get(PROPERTY_GRADIENT_CACHE_SIZE, property, NULL) > 0) {
@@ -63,7 +91,7 @@ GradientCache::GradientCache():
}

GradientCache::GradientCache(uint32_t maxByteSize):
        mCache(GenerationCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity),
        mCache(LruCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity),
        mSize(0), mMaxSize(maxByteSize) {
    mCache.setOnEntryRemovedListener(this);
}
+29 −17
Original line number Diff line number Diff line
@@ -21,12 +21,11 @@

#include <SkShader.h>

#include <utils/LruCache.h>
#include <utils/Mutex.h>
#include <utils/Vector.h>

#include "Texture.h"
#include "utils/Compare.h"
#include "utils/GenerationCache.h"

namespace android {
namespace uirenderer {
@@ -38,7 +37,7 @@ struct GradientCacheEntry {
        positions = NULL;
    }

    GradientCacheEntry(uint32_t* colors, float* positions, int count) {
    GradientCacheEntry(uint32_t* colors, float* positions, uint32_t count) {
        copy(colors, positions, count);
    }

@@ -62,27 +61,26 @@ struct GradientCacheEntry {
        return *this;
    }

    bool operator<(const GradientCacheEntry& r) const {
        const GradientCacheEntry& rhs = (const GradientCacheEntry&) r;
        LTE_INT(count) {
            int result = memcmp(colors, rhs.colors, count * sizeof(uint32_t));
            if (result< 0) return true;
            else if (result == 0) {
                result = memcmp(positions, rhs.positions, count * sizeof(float));
                if (result < 0) return true;
            }
    hash_t hash() const;

    static int compare(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs);

    bool operator==(const GradientCacheEntry& other) const {
        return compare(*this, other) == 0;
    }
        return false;

    bool operator!=(const GradientCacheEntry& other) const {
        return compare(*this, other) != 0;
    }

    uint32_t* colors;
    float* positions;
    int count;
    uint32_t count;
    SkShader::TileMode tileMode;

private:

    void copy(uint32_t* colors, float* positions, int count) {
    void copy(uint32_t* colors, float* positions, uint32_t count) {
        this->count = count;
        this->colors = new uint32_t[count];
        this->positions = new float[count];
@@ -93,6 +91,20 @@ private:

}; // GradientCacheEntry

// Caching support

inline int strictly_order_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
    return GradientCacheEntry::compare(lhs, rhs) < 0;
}

inline int compare_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
    return GradientCacheEntry::compare(lhs, rhs);
}

inline hash_t hash_type(const GradientCacheEntry& entry) {
    return entry.hash();
}

/**
 * A simple LRU gradient cache. The cache has a maximum size expressed in bytes.
 * Any texture added to the cache causing the cache to grow beyond the maximum
@@ -150,7 +162,7 @@ private:

    void getGradientInfo(const uint32_t* colors, const int count, GradientInfo& info);

    GenerationCache<GradientCacheEntry, Texture*> mCache;
    LruCache<GradientCacheEntry, Texture*> mCache;

    uint32_t mSize;
    uint32_t mMaxSize;
+8 −11
Original line number Diff line number Diff line
@@ -55,22 +55,19 @@ PathCache::PathCache(): ShapeCache<PathCacheEntry>("path",
}

void PathCache::remove(SkPath* path) {
    // TODO: Linear search...
    Vector<size_t> pathsToRemove;
    for (size_t i = 0; i < mCache.size(); i++) {
        if (mCache.getKeyAt(i).path == path) {
            pathsToRemove.push(i);
            removeTexture(mCache.getValueAt(i));
    Vector<PathCacheEntry> pathsToRemove;
    LruCache<PathCacheEntry, PathTexture*>::Iterator i(mCache);

    while (i.next()) {
        const PathCacheEntry& key = i.key();
        if (key.path == path) {
            pathsToRemove.push(key);
        }
    }

    mCache.setOnEntryRemovedListener(NULL);
    for (size_t i = 0; i < pathsToRemove.size(); i++) {
        // This will work because pathsToRemove is sorted
        // and because the cache is a sorted keyed vector
        mCache.removeAt(pathsToRemove.itemAt(i) - i);
        mCache.remove(pathsToRemove.itemAt(i));
    }
    mCache.setOnEntryRemovedListener(this);
}

void PathCache::removeDeferred(SkPath* path) {
+15 −7
Original line number Diff line number Diff line
@@ -22,8 +22,6 @@
#include "Debug.h"
#include "ShapeCache.h"

#include "utils/Compare.h"

namespace android {
namespace uirenderer {

@@ -41,18 +39,28 @@ struct PathCacheEntry: public ShapeCacheEntry {
        path = NULL;
    }

    bool lessThan(const ShapeCacheEntry& r) const {
        const PathCacheEntry& rhs = (const PathCacheEntry&) r;
        LTE_INT(path) {
            return false;
    hash_t hash() const {
        uint32_t hash = ShapeCacheEntry::hash();
        hash = JenkinsHashMix(hash, android::hash_type(path));
        return JenkinsHashWhiten(hash);
    }
        return false;

    int compare(const ShapeCacheEntry& r) const {
        int deltaInt = ShapeCacheEntry::compare(r);
        if (deltaInt != 0) return deltaInt;

        const PathCacheEntry& rhs = (const PathCacheEntry&) r;
        return path - rhs.path;
    }

    SkPath* path;

}; // PathCacheEntry

inline hash_t hash_type(const PathCacheEntry& entry) {
    return entry.hash();
}

/**
 * A simple LRU path cache. The cache has a maximum size expressed in bytes.
 * Any texture added to the cache causing the cache to grow beyond the maximum
Loading