diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp index 4669c378365b8..dce48a3ab8992 100644 --- a/core/jni/android/graphics/TextLayoutCache.cpp +++ b/core/jni/android/graphics/TextLayoutCache.cpp @@ -16,6 +16,8 @@ #define LOG_TAG "TextLayoutCache" +#include + #include "TextLayoutCache.h" #include "TextLayout.h" #include "SkFontHost.h" @@ -38,7 +40,7 @@ ANDROID_SINGLETON_STATIC_INSTANCE(TextLayoutEngine); TextLayoutCache::TextLayoutCache(TextLayoutShaper* shaper) : mShaper(shaper), - mCache(GenerationCache >::kUnlimitedCapacity), + mCache(LruCache >::kUnlimitedCapacity), mSize(0), mMaxSize(MB(DEFAULT_TEXT_LAYOUT_CACHE_SIZE_IN_MB)), mCacheHitCount(0), mNanosecondsSaved(0) { init(); @@ -199,11 +201,7 @@ void TextLayoutCache::dumpCacheStats() { float remainingPercent = 100 * ((mMaxSize - mSize) / ((float)mMaxSize)); float timeRunningInSec = (systemTime(SYSTEM_TIME_MONOTONIC) - mCacheStartTime) / 1000000000; - size_t bytes = 0; size_t cacheSize = mCache.size(); - for (size_t i = 0; i < cacheSize; i++) { - bytes += mCache.getKeyAt(i).getSize() + mCache.getValueAt(i)->getSize(); - } ALOGD("------------------------------------------------"); ALOGD("Cache stats"); @@ -212,7 +210,7 @@ void TextLayoutCache::dumpCacheStats() { ALOGD("running : %.0f seconds", timeRunningInSec); ALOGD("entries : %d", cacheSize); ALOGD("max size : %d bytes", mMaxSize); - ALOGD("used : %d bytes according to mSize, %d bytes actual", mSize, bytes); + ALOGD("used : %d bytes according to mSize", mSize); ALOGD("remaining : %d bytes or %2.2f percent", mMaxSize - mSize, remainingPercent); ALOGD("hits : %d", mCacheHitCount); ALOGD("saved : %0.6f ms", mNanosecondsSaved * 0.000001f); @@ -302,6 +300,23 @@ size_t TextLayoutCacheKey::getSize() const { return sizeof(TextLayoutCacheKey) + sizeof(UChar) * contextCount; } +hash_t TextLayoutCacheKey::hash() const { + uint32_t hash = JenkinsHashMix(0, start); + hash = JenkinsHashMix(hash, count); + /* contextCount not needed because it's included in text, below */ + hash = JenkinsHashMix(hash, hash_type(typeface)); + hash = JenkinsHashMix(hash, hash_type(textSize)); + hash = JenkinsHashMix(hash, hash_type(textSkewX)); + hash = JenkinsHashMix(hash, hash_type(textScaleX)); + hash = JenkinsHashMix(hash, flags); + hash = JenkinsHashMix(hash, hinting); + hash = JenkinsHashMix(hash, variant); + // Note: leaving out language is not problematic, as equality comparisons + // are still valid - the only bad thing that could happen is collisions. + hash = JenkinsHashMixShorts(hash, getText(), contextCount); + return JenkinsHashWhiten(hash); +} + /** * TextLayoutCacheValue */ diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h index 9994393a091ee..22de523270132 100644 --- a/core/jni/android/graphics/TextLayoutCache.h +++ b/core/jni/android/graphics/TextLayoutCache.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -85,6 +85,15 @@ public: inline const UChar* getText() const { return textCopy.string(); } + bool operator==(const TextLayoutCacheKey& other) const { + return compare(*this, other) == 0; + } + + bool operator!=(const TextLayoutCacheKey& other) const { + return compare(*this, other) != 0; + } + + hash_t hash() const; private: String16 textCopy; size_t start; @@ -110,6 +119,10 @@ inline int compare_type(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& return TextLayoutCacheKey::compare(lhs, rhs); } +inline hash_t hash_type(const TextLayoutCacheKey& key) { + return key.hash(); +} + /* * TextLayoutValue is the Cache value */ @@ -276,7 +289,7 @@ private: Mutex mLock; bool mInitialized; - GenerationCache > mCache; + LruCache > mCache; uint32_t mSize; uint32_t mMaxSize;