Merge "Correctly compare strings in UTF-8 instead of UTF-16 Bug #3272858"
This commit is contained in:
@ -19,6 +19,7 @@
|
||||
|
||||
#include <utils/KeyedVector.h>
|
||||
|
||||
#include "utils/Compare.h"
|
||||
#include "Debug.h"
|
||||
#include "Patch.h"
|
||||
|
||||
|
@ -39,7 +39,8 @@
|
||||
enum DebugLevel {
|
||||
kDebugDisabled = 0,
|
||||
kDebugMemory = 1,
|
||||
kDebugCaches = 2
|
||||
kDebugCaches = 2,
|
||||
kDebugMoreCaches = 3
|
||||
};
|
||||
|
||||
// These properties are defined in mega-bytes
|
||||
|
@ -37,19 +37,24 @@ TextDropShadowCache::TextDropShadowCache():
|
||||
LOGD(" Using default drop shadow cache size of %.2fMB", DEFAULT_DROP_SHADOW_CACHE_SIZE);
|
||||
}
|
||||
|
||||
mCache.setOnEntryRemovedListener(this);
|
||||
init();
|
||||
}
|
||||
|
||||
TextDropShadowCache::TextDropShadowCache(uint32_t maxByteSize):
|
||||
mCache(GenerationCache<ShadowText, ShadowTexture*>::kUnlimitedCapacity),
|
||||
mSize(0), mMaxSize(maxByteSize) {
|
||||
mCache.setOnEntryRemovedListener(this);
|
||||
init();
|
||||
}
|
||||
|
||||
TextDropShadowCache::~TextDropShadowCache() {
|
||||
mCache.clear();
|
||||
}
|
||||
|
||||
void TextDropShadowCache::init() {
|
||||
mCache.setOnEntryRemovedListener(this);
|
||||
mDebugEnabled = readDebugLevel() & kDebugMoreCaches;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Size management
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -75,8 +80,11 @@ void TextDropShadowCache::setMaxSize(uint32_t maxSize) {
|
||||
|
||||
void TextDropShadowCache::operator()(ShadowText& text, ShadowTexture*& texture) {
|
||||
if (texture) {
|
||||
const uint32_t size = texture->width * texture->height;
|
||||
mSize -= size;
|
||||
mSize -= texture->bitmapSize;
|
||||
|
||||
if (mDebugEnabled) {
|
||||
LOGD("Shadow texture deleted, size = %d", texture->bitmapSize);
|
||||
}
|
||||
|
||||
glDeleteTextures(1, &texture->id);
|
||||
delete texture;
|
||||
@ -109,6 +117,8 @@ ShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32
|
||||
texture->blend = true;
|
||||
|
||||
const uint32_t size = shadow.width * shadow.height;
|
||||
texture->bitmapSize = size;
|
||||
|
||||
// Don't even try to cache a bitmap that's bigger than the cache
|
||||
if (size < mMaxSize) {
|
||||
while (mSize + size > mMaxSize) {
|
||||
@ -132,6 +142,9 @@ ShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
if (size < mMaxSize) {
|
||||
if (mDebugEnabled) {
|
||||
LOGD("Shadow texture created, size = %d", texture->bitmapSize);
|
||||
}
|
||||
mSize += size;
|
||||
mCache.put(entry, texture);
|
||||
} else {
|
||||
|
@ -21,6 +21,9 @@
|
||||
|
||||
#include <SkPaint.h>
|
||||
|
||||
#include <utils/String8.h>
|
||||
|
||||
#include "utils/Compare.h"
|
||||
#include "utils/GenerationCache.h"
|
||||
#include "FontRenderer.h"
|
||||
#include "Texture.h"
|
||||
@ -29,20 +32,20 @@ namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
struct ShadowText {
|
||||
ShadowText() {
|
||||
text = NULL;
|
||||
ShadowText(): radius(0), len(0), hash(0), textSize(0.0f), typeface(NULL) {
|
||||
}
|
||||
|
||||
ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText):
|
||||
radius(radius), len(len) {
|
||||
text = new char[len];
|
||||
memcpy(text, srcText, len);
|
||||
// The source text we receive is in UTF-16, convert to UTF-8
|
||||
str.setTo((const char16_t*) srcText, len >> 1);
|
||||
|
||||
textSize = paint->getTextSize();
|
||||
typeface = paint->getTypeface();
|
||||
|
||||
hash = 0;
|
||||
uint32_t multiplier = 1;
|
||||
const char* text = str.string();
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
hash += text[i] * multiplier;
|
||||
uint32_t shifted = multiplier << 5;
|
||||
@ -52,13 +55,10 @@ struct ShadowText {
|
||||
|
||||
ShadowText(const ShadowText& shadow):
|
||||
radius(shadow.radius), len(shadow.len), hash(shadow.hash),
|
||||
textSize(shadow.textSize), typeface(shadow.typeface) {
|
||||
text = new char[shadow.len];
|
||||
memcpy(text, shadow.text, shadow.len);
|
||||
textSize(shadow.textSize), typeface(shadow.typeface), str(shadow.str) {
|
||||
}
|
||||
|
||||
~ShadowText() {
|
||||
delete[] text;
|
||||
}
|
||||
|
||||
uint32_t radius;
|
||||
@ -66,20 +66,16 @@ struct ShadowText {
|
||||
uint32_t hash;
|
||||
float textSize;
|
||||
SkTypeface* typeface;
|
||||
char *text;
|
||||
String8 str;
|
||||
|
||||
bool operator<(const ShadowText& rhs) const {
|
||||
if (hash < rhs.hash) return true;
|
||||
else if (hash == rhs.hash) {
|
||||
if (len < rhs.len) return true;
|
||||
else if (len == rhs.len) {
|
||||
if (radius < rhs.radius) return true;
|
||||
else if (radius == rhs.radius) {
|
||||
if (textSize < rhs.textSize) return true;
|
||||
else if (textSize == rhs.textSize) {
|
||||
LTE_INT(hash) {
|
||||
LTE_INT(len) {
|
||||
LTE_INT(radius) {
|
||||
LTE_FLOAT(textSize) {
|
||||
if (typeface < rhs.typeface) return true;
|
||||
else if (typeface == rhs.typeface) {
|
||||
return strncmp(text, rhs.text, len) < 0;
|
||||
return str.compare(rhs.str) < 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,11 +134,14 @@ public:
|
||||
uint32_t getSize();
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
GenerationCache<ShadowText, ShadowTexture*> mCache;
|
||||
|
||||
uint32_t mSize;
|
||||
uint32_t mMaxSize;
|
||||
FontRenderer* mRenderer;
|
||||
bool mDebugEnabled;
|
||||
}; // class TextDropShadowCache
|
||||
|
||||
}; // namespace uirenderer
|
||||
|
Reference in New Issue
Block a user