| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be found
in the LICENSE file. | 4 * Use of this source code is governed by a BSD-style license that can be found
in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #ifndef SkGlyphCache_DEFINED | 7 #ifndef SkGlyphCache_DEFINED |
| 8 #define SkGlyphCache_DEFINED | 8 #define SkGlyphCache_DEFINED |
| 9 | 9 |
| 10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
| 11 #include "SkChecksum.h" | |
| 12 #include "SkChunkAlloc.h" | 11 #include "SkChunkAlloc.h" |
| 13 #include "SkDescriptor.h" | 12 #include "SkDescriptor.h" |
| 14 #include "SkGlyph.h" | 13 #include "SkGlyph.h" |
| 14 #include "SkTHash.h" |
| 15 #include "SkScalerContext.h" | 15 #include "SkScalerContext.h" |
| 16 #include "SkTemplates.h" | 16 #include "SkTemplates.h" |
| 17 #include "SkTDArray.h" | 17 #include "SkTDArray.h" |
| 18 | 18 |
| 19 class SkPaint; | 19 class SkPaint; |
| 20 | 20 |
| 21 class SkGlyphCache_Globals; | 21 class SkGlyphCache_Globals; |
| 22 | 22 |
| 23 // Enable this locally to add stats for hash-table hit rates. It also extends th
e dump() output | |
| 24 // to show those stats. | |
| 25 //#define SK_GLYPHCACHE_TRACK_HASH_STATS | |
| 26 | |
| 27 /** \class SkGlyphCache | 23 /** \class SkGlyphCache |
| 28 | 24 |
| 29 This class represents a strike: a specific combination of typeface, size, ma
trix, etc., and | 25 This class represents a strike: a specific combination of typeface, size, ma
trix, etc., and |
| 30 holds the glyphs for that strike. Calling any of the getUnichar.../getGlyphI
D... methods will | 26 holds the glyphs for that strike. Calling any of the getUnichar.../getGlyphI
D... methods will |
| 31 return the requested glyph, either instantly if it is already cached, or by
first generating | 27 return the requested glyph, either instantly if it is already cached, or by
first generating |
| 32 it and then adding it to the strike. | 28 it and then adding it to the strike. |
| 33 | 29 |
| 34 The strikes are held in a global list, available to all threads. To interact
with one, call | 30 The strikes are held in a global list, available to all threads. To interact
with one, call |
| 35 either VisitCache() or DetachCache(). | 31 either VisitCache() or DetachCache(). |
| 36 */ | 32 */ |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 }; | 172 }; |
| 177 | 173 |
| 178 enum { | 174 enum { |
| 179 kHashBits = 8, | 175 kHashBits = 8, |
| 180 kHashCount = 1 << kHashBits, | 176 kHashCount = 1 << kHashBits, |
| 181 kHashMask = kHashCount - 1 | 177 kHashMask = kHashCount - 1 |
| 182 }; | 178 }; |
| 183 | 179 |
| 184 struct CharGlyphRec { | 180 struct CharGlyphRec { |
| 185 uint32_t fID; // unichar + subpixel | 181 uint32_t fID; // unichar + subpixel |
| 186 uint16_t fGlyphIndex; | 182 uint32_t fGlyphAndPositionID; |
| 187 }; | 183 }; |
| 188 | 184 |
| 189 struct AuxProcRec { | 185 struct AuxProcRec { |
| 190 AuxProcRec* fNext; | 186 AuxProcRec* fNext; |
| 191 void (*fProc)(void*); | 187 void (*fProc)(void*); |
| 192 void* fData; | 188 void* fData; |
| 193 }; | 189 }; |
| 194 | 190 |
| 195 // SkGlyphCache takes ownership of the scalercontext. | 191 // SkGlyphCache takes ownership of the scalercontext. |
| 196 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*); | 192 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*); |
| 197 ~SkGlyphCache(); | 193 ~SkGlyphCache(); |
| 198 | 194 |
| 199 // Return the SkGlyph* associated with MakeID. The id parameter is the | 195 // Return the SkGlyph* associated with MakeID. The id parameter is the |
| 200 // combined glyph/x/y id generated by MakeID. If it is just a glyph id | 196 // combined glyph/x/y id generated by MakeID. If it is just a glyph id |
| 201 // then x and y are assumed to be zero. | 197 // then x and y are assumed to be zero. |
| 202 SkGlyph* lookupByCombinedID(uint32_t id, MetricsType type); | 198 SkGlyph* lookupByGlyphAndPositionID(uint32_t glyphAndPositionID, MetricsType
type); |
| 203 | 199 |
| 204 // Return a SkGlyph* associated with unicode id and position x and y. | 200 // Return a SkGlyph* associated with unicode id and position x and y. |
| 205 SkGlyph* lookupByChar(SkUnichar id, MetricsType type, SkFixed x = 0, SkFixed
y = 0); | 201 SkGlyph* lookupByChar(SkUnichar id, MetricsType type, SkFixed x = 0, SkFixed
y = 0); |
| 206 | 202 |
| 207 // Return the index of id in the fGlyphArray. If it does not exist, | 203 // Return a new SkGlyph for the glyph ID and subpixel position id. Limit the
amount |
| 208 // create a new one using MetricsType. | 204 // of work |
| 209 uint16_t lookupMetrics(uint32_t id, MetricsType type); | 205 // using type. |
| 206 SkGlyph* allocateNewGlyph(uint32_t glyphAndPositionID, MetricsType type); |
| 210 static bool DetachProc(const SkGlyphCache*, void*) { return true; } | 207 static bool DetachProc(const SkGlyphCache*, void*) { return true; } |
| 211 | 208 |
| 212 // The id arg is a combined id generated by MakeID. | 209 // The id arg is a combined id generated by MakeID. |
| 213 CharGlyphRec* getCharGlyphRec(uint32_t id); | 210 CharGlyphRec* getCharGlyphRec(uint32_t id); |
| 214 void adjustCaches(int insertion_index); | |
| 215 | |
| 216 static inline unsigned ID2HashIndex(uint32_t h) { | |
| 217 return SkChecksum::CheapMix(h) & kHashMask; | |
| 218 } | |
| 219 | 211 |
| 220 void invokeAndRemoveAuxProcs(); | 212 void invokeAndRemoveAuxProcs(); |
| 221 | 213 |
| 222 inline static SkGlyphCache* FindTail(SkGlyphCache* head); | 214 inline static SkGlyphCache* FindTail(SkGlyphCache* head); |
| 223 | 215 |
| 224 SkGlyphCache* fNext, *fPrev; | 216 SkGlyphCache* fNext, *fPrev; |
| 225 SkDescriptor* fDesc; | 217 SkDescriptor* fDesc; |
| 226 SkScalerContext* fScalerContext; | 218 SkScalerContext* fScalerContext; |
| 227 SkPaint::FontMetrics fFontMetrics; | 219 SkPaint::FontMetrics fFontMetrics; |
| 228 | 220 |
| 229 // A quick lookup to avoid the binary search looking for glyphs in fGlyphArr
ay. | 221 // Map from a combined GlyphID and sub-pixel position to a SkGlyph. |
| 230 uint16_t fGlyphHash[kHashCount]; | 222 SkTHashTable<SkGlyph, uint32_t, SkGlyph::GlyphHashTraits> fGlyphMap; |
| 231 | 223 |
| 232 // Contains the SkGlyphs that are used by fGlyphHash and fCharToGlyphHash. T
he ~0 element is | |
| 233 // reserved for a sentinel SkGlyph that reduces the logic to check for colli
sions in the hash | |
| 234 // arrays. The ~0 element has an fID of SkGlyph::kImpossibleID which never m
atches any | |
| 235 // combined id generated for a char or a glyph. | |
| 236 SkTDArray<SkGlyph> fGlyphArray; | |
| 237 SkChunkAlloc fGlyphAlloc; | 224 SkChunkAlloc fGlyphAlloc; |
| 238 | 225 |
| 239 // no reason to use the same kHashCount as fGlyphHash, but we do for now | 226 SkAutoTArray<CharGlyphRec> fCharToGlyphAndPositionIDHash; |
| 240 // Dynamically allocated when chars are encountered. | |
| 241 SkAutoTArray<CharGlyphRec> fCharToGlyphHash; | |
| 242 | 227 |
| 243 // used to track (approx) how much ram is tied-up in this cache | 228 // used to track (approx) how much ram is tied-up in this cache |
| 244 size_t fMemoryUsed; | 229 size_t fMemoryUsed; |
| 245 | 230 |
| 246 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
| 247 int fHashHitCount; | |
| 248 int fHashMissCount; | |
| 249 #endif | |
| 250 | |
| 251 AuxProcRec* fAuxProcList; | 231 AuxProcRec* fAuxProcList; |
| 252 }; | 232 }; |
| 253 | 233 |
| 254 class SkAutoGlyphCacheBase { | 234 class SkAutoGlyphCacheBase { |
| 255 public: | 235 public: |
| 256 SkGlyphCache* getCache() const { return fCache; } | 236 SkGlyphCache* getCache() const { return fCache; } |
| 257 | 237 |
| 258 void release() { | 238 void release() { |
| 259 if (fCache) { | 239 if (fCache) { |
| 260 SkGlyphCache::AttachCache(fCache); | 240 SkGlyphCache::AttachCache(fCache); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 const SkMatrix* matrix) { | 295 const SkMatrix* matrix) { |
| 316 fCache = paint.detachCache(surfaceProps, matrix, true); | 296 fCache = paint.detachCache(surfaceProps, matrix, true); |
| 317 } | 297 } |
| 318 | 298 |
| 319 private: | 299 private: |
| 320 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} | 300 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} |
| 321 }; | 301 }; |
| 322 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm
a) | 302 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm
a) |
| 323 | 303 |
| 324 #endif | 304 #endif |
| OLD | NEW |