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