Modify TextLayoutCache to use new LRU cache
This patch modifies TextLayoutCache to use the new hash-based LRU caching mechanism, which should be significantly faster than the old GenerationCache implementation. Change-Id: I6170462ad93a56156a731a2927680164d62b5cfc
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
#define LOG_TAG "TextLayoutCache"
|
||||
|
||||
#include <utils/JenkinsHash.h>
|
||||
|
||||
#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<TextLayoutCacheKey, sp<TextLayoutValue> >::kUnlimitedCapacity),
|
||||
mCache(LruCache<TextLayoutCacheKey, sp<TextLayoutValue> >::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
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <stddef.h>
|
||||
#include <utils/threads.h>
|
||||
#include <utils/String16.h>
|
||||
#include <utils/GenerationCache.h>
|
||||
#include <utils/LruCache.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/Compare.h>
|
||||
#include <utils/RefBase.h>
|
||||
@@ -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<TextLayoutCacheKey, sp<TextLayoutValue> > mCache;
|
||||
LruCache<TextLayoutCacheKey, sp<TextLayoutValue> > mCache;
|
||||
|
||||
uint32_t mSize;
|
||||
uint32_t mMaxSize;
|
||||
|
||||
Reference in New Issue
Block a user