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:
Raph Levien
2012-10-25 23:17:33 -07:00
parent 7d747cdf20
commit d98efca738
2 changed files with 36 additions and 8 deletions

View File

@@ -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
*/

View File

@@ -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;