TextLayoutCache.h revision c2063a5b18bc2e54f000b411c82f43992a53854e
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef ANDROID_TEXT_LAYOUT_CACHE_H 18#define ANDROID_TEXT_LAYOUT_CACHE_H 19 20#include "RtlProperties.h" 21 22#include <stddef.h> 23#include <utils/threads.h> 24#include <utils/String16.h> 25#include <utils/GenerationCache.h> 26#include <utils/Compare.h> 27#include <utils/RefBase.h> 28 29#include <SkPaint.h> 30#include <SkTemplates.h> 31#include <SkUtils.h> 32#include <SkScalerContext.h> 33#include <SkAutoKern.h> 34 35#include <unicode/ubidi.h> 36#include <unicode/ushape.h> 37#include "HarfbuzzSkia.h" 38#include "harfbuzz-shaper.h" 39 40#include <android_runtime/AndroidRuntime.h> 41 42#define UNICODE_NOT_A_CHAR 0xffff 43#define UNICODE_ZWSP 0x200b 44#define UNICODE_FIRST_LOW_SURROGATE 0xdc00 45#define UNICODE_FIRST_HIGH_SURROGATE 0xd800 46#define UNICODE_FIRST_PRIVATE_USE 0xe000 47#define UNICODE_FIRST_RTL_CHAR 0x0590 48 49// Temporary buffer size 50#define CHAR_BUFFER_SIZE 80 51 52// Converts a number of mega-bytes into bytes 53#define MB(s) s * 1024 * 1024 54 55// Define the default cache size in Mb 56#define DEFAULT_TEXT_LAYOUT_CACHE_SIZE_IN_MB 0.250f 57 58// Define the interval in number of cache hits between two statistics dump 59#define DEFAULT_DUMP_STATS_CACHE_HIT_INTERVAL 100 60 61namespace android { 62 63/** 64 * TextLayoutCacheKey is the Cache key 65 */ 66class TextLayoutCacheKey { 67public: 68 TextLayoutCacheKey(); 69 70 TextLayoutCacheKey(const SkPaint* paint, 71 const UChar* text, size_t start, size_t count, 72 size_t contextCount, int dirFlags); 73 74 bool operator<(const TextLayoutCacheKey& rhs) const; 75 76 /** 77 * We need to copy the text when we insert the key into the cache itself. 78 * We don't need to copy the text when we are only comparing keys. 79 */ 80 void internalTextCopy(); 81 82 /** 83 * Get the size of the Cache key. 84 */ 85 size_t getSize(); 86 87private: 88 const UChar* text; 89 String16 textCopy; 90 size_t start; 91 size_t count; 92 size_t contextCount; 93 int dirFlags; 94 SkTypeface* typeface; 95 SkScalar textSize; 96 SkScalar textSkewX; 97 SkScalar textScaleX; 98 uint32_t flags; 99 SkPaint::Hinting hinting; 100}; // TextLayoutCacheKey 101 102/* 103 * TextLayoutCacheValue is the Cache value 104 */ 105class TextLayoutCacheValue : public RefBase { 106protected: 107 ~TextLayoutCacheValue(); 108 109public: 110 TextLayoutCacheValue(); 111 112 void setElapsedTime(uint32_t time); 113 uint32_t getElapsedTime(); 114 115 void computeValues(SkPaint* paint, const UChar* chars, size_t start, size_t count, 116 size_t contextCount, int dirFlags); 117 118 inline const jfloat* getAdvances() const { return mAdvances; } 119 inline size_t getAdvancesCount() const { return mAdvancesCount; } 120 inline jfloat getTotalAdvance() const { return mTotalAdvance; } 121 inline const jchar* getGlyphs() const { return mGlyphs; } 122 inline size_t getGlyphsCount() const { return mGlyphsCount; } 123 124 /** 125 * Get the size of the Cache entry 126 */ 127 size_t getSize(); 128 129 static void setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData, 130 SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, 131 bool isRTL); 132 133 static void shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData, 134 SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, 135 bool isRTL); 136 137 static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start, 138 size_t count, size_t contextCount, int dirFlags, 139 jfloat* outAdvances, jfloat* outTotalAdvance, 140 jchar** outGlyphs, size_t* outGlyphsCount); 141 142 static void computeAdvancesWithICU(SkPaint* paint, const UChar* chars, size_t start, 143 size_t count, size_t contextCount, int dirFlags, 144 jfloat* outAdvances, jfloat* outTotalAdvance); 145 146private: 147 /** 148 * Advances array 149 */ 150 jfloat* mAdvances; 151 152 /** 153 * Total number of advances 154 */ 155 jfloat mTotalAdvance; 156 157 /** 158 * Allocated size for advances array 159 */ 160 size_t mAdvancesCount; 161 162 /** 163 * Glyphs array 164 */ 165 jchar* mGlyphs; 166 167 /** 168 * Total number of glyphs 169 */ 170 size_t mGlyphsCount; 171 172 /** 173 * Time for computing the values (in milliseconds) 174 */ 175 uint32_t mElapsedTime; 176 177 static void deleteGlyphArrays(HB_ShaperItem* shaperItem); 178 static void createGlyphArrays(HB_ShaperItem* shaperItem, int size); 179 static void resetGlyphArrays(HB_ShaperItem* shaperItem); 180 181 static void computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start, 182 size_t count, size_t contextCount, bool isRTL, 183 jfloat* outAdvances, jfloat* outTotalAdvance, 184 jchar** outGlyphs, size_t* outGlyphsCount); 185}; // TextLayoutCacheValue 186 187/** 188 * Cache of text layout information. 189 */ 190class TextLayoutCache : public OnEntryRemoved<TextLayoutCacheKey, sp<TextLayoutCacheValue> > 191{ 192public: 193 TextLayoutCache(); 194 TextLayoutCache(uint32_t maxByteSize); 195 196 virtual ~TextLayoutCache(); 197 198 bool isInitialized() { 199 return mInitialized; 200 } 201 202 /** 203 * Used as a callback when an entry is removed from the cache 204 * Do not invoke directly 205 */ 206 void operator()(TextLayoutCacheKey& text, sp<TextLayoutCacheValue>& desc); 207 208 sp<TextLayoutCacheValue> getValue(SkPaint* paint, 209 const jchar* text, jint start, jint count, jint contextCount, jint dirFlags); 210 211 /** 212 * Clear the cache 213 */ 214 void clear(); 215 216 /** 217 * Sets the maximum size of the cache in bytes 218 */ 219 void setMaxSize(uint32_t maxSize); 220 221 /** 222 * Returns the maximum size of the cache in bytes 223 */ 224 uint32_t getMaxSize(); 225 226 /** 227 * Returns the current size of the cache in bytes 228 */ 229 uint32_t getSize(); 230 231private: 232 Mutex mLock; 233 bool mInitialized; 234 235 GenerationCache<TextLayoutCacheKey, sp<TextLayoutCacheValue> > mCache; 236 237 uint32_t mSize; 238 uint32_t mMaxSize; 239 240 uint32_t mCacheHitCount; 241 uint64_t mNanosecondsSaved; 242 243 uint64_t mCacheStartTime; 244 245 RtlDebugLevel mDebugLevel; 246 bool mDebugEnabled; 247 248 /* 249 * Class initialization 250 */ 251 void init(); 252 253 /** 254 * Remove oldest entries until we are having enough space 255 */ 256 void removeOldests(); 257 258 /** 259 * Dump Cache statistics 260 */ 261 void dumpCacheStats(); 262}; // TextLayoutCache 263 264} // namespace android 265#endif /* ANDROID_TEXT_LAYOUT_CACHE_H */ 266 267