Chromium Code Reviews| 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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 kJustAdvance_MetricsType, | 170 kJustAdvance_MetricsType, |
| 175 kFull_MetricsType | 171 kFull_MetricsType |
| 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 |
| 180 typedef uint32_t PackedGlyphID; // glyph-index + subpixel-pos | |
| 181 typedef uint32_t PackedUnicharID; // unichar + subpixel-pos | |
| 182 | |
| 184 struct CharGlyphRec { | 183 struct CharGlyphRec { |
| 185 uint32_t fID; // unichar + subpixel | 184 PackedUnicharID fPackedUnicharID; |
| 186 uint16_t fGlyphIndex; | 185 PackedGlyphID fPackedGlyphID; |
| 187 }; | 186 }; |
| 188 | 187 |
| 189 struct AuxProcRec { | 188 struct AuxProcRec { |
| 190 AuxProcRec* fNext; | 189 AuxProcRec* fNext; |
| 191 void (*fProc)(void*); | 190 void (*fProc)(void*); |
| 192 void* fData; | 191 void* fData; |
| 193 }; | 192 }; |
| 194 | 193 |
| 195 // SkGlyphCache takes ownership of the scalercontext. | 194 // SkGlyphCache takes ownership of the scalercontext. |
| 196 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*); | 195 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*); |
| 197 ~SkGlyphCache(); | 196 ~SkGlyphCache(); |
| 198 | 197 |
| 199 // Return the SkGlyph* associated with MakeID. The id parameter is the | 198 // 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 | 199 // 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. | 200 // then x and y are assumed to be zero. |
| 202 SkGlyph* lookupByCombinedID(uint32_t id, MetricsType type); | 201 SkGlyph* lookupByPackedGlyphID(PackedGlyphID packedGlyphID, MetricsType type ); |
| 203 | 202 |
| 204 // Return a SkGlyph* associated with unicode id and position x and y. | 203 // 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); | 204 SkGlyph* lookupByChar(SkUnichar id, MetricsType type, SkFixed x = 0, SkFixed y = 0); |
| 206 | 205 |
| 207 // Return the index of id in the fGlyphArray. If it does not exist, | 206 // Return a new SkGlyph for the glyph ID and subpixel position id. Limit the amount |
| 208 // create a new one using MetricsType. | 207 // of work |
| 209 uint16_t lookupMetrics(uint32_t id, MetricsType type); | 208 // using type. |
| 209 SkGlyph* allocateNewGlyph(PackedGlyphID packedGlyphID, MetricsType type); | |
| 210 | |
| 210 static bool DetachProc(const SkGlyphCache*, void*) { return true; } | 211 static bool DetachProc(const SkGlyphCache*, void*) { return true; } |
| 211 | 212 |
| 212 // The id arg is a combined id generated by MakeID. | 213 // The id arg is a combined id generated by MakeID. |
| 213 CharGlyphRec* getCharGlyphRec(uint32_t id); | 214 CharGlyphRec* getCharGlyphRec(PackedUnicharID id); |
| 214 void adjustCaches(int insertion_index); | |
| 215 | |
| 216 static inline unsigned ID2HashIndex(uint32_t h) { | |
| 217 return SkChecksum::CheapMix(h) & kHashMask; | |
| 218 } | |
| 219 | 215 |
| 220 void invokeAndRemoveAuxProcs(); | 216 void invokeAndRemoveAuxProcs(); |
| 221 | 217 |
| 222 inline static SkGlyphCache* FindTail(SkGlyphCache* head); | 218 inline static SkGlyphCache* FindTail(SkGlyphCache* head); |
| 223 | 219 |
| 224 SkGlyphCache* fNext, *fPrev; | 220 SkGlyphCache *fNext, *fPrev; |
|
mtklein
2015/07/21 19:35:52
I think I'd generally prefer
SkGlyphCache* fNext;
herb_g
2015/07/21 22:27:34
T * const is nicer in multithreaded cases, and it
| |
| 225 SkDescriptor* fDesc; | 221 SkDescriptor * const fDesc; |
| 226 SkScalerContext* fScalerContext; | 222 SkScalerContext * const fScalerContext; |
| 227 SkPaint::FontMetrics fFontMetrics; | 223 SkPaint::FontMetrics fFontMetrics; |
| 228 | 224 |
| 229 // A quick lookup to avoid the binary search looking for glyphs in fGlyphArr ay. | 225 // Map from a combined GlyphID and sub-pixel position to a SkGlyph. |
| 230 uint16_t fGlyphHash[kHashCount]; | 226 SkTHashTable<SkGlyph, PackedGlyphID, SkGlyph::GlyphHashTraits> fGlyphMap; |
| 231 | 227 |
| 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; | 228 SkChunkAlloc fGlyphAlloc; |
| 238 | 229 |
| 239 // no reason to use the same kHashCount as fGlyphHash, but we do for now | 230 SkAutoTArray<CharGlyphRec> fPackedUnicharIDToPackedGlyphID; |
| 240 // Dynamically allocated when chars are encountered. | |
| 241 SkAutoTArray<CharGlyphRec> fCharToGlyphHash; | |
| 242 | 231 |
| 243 // used to track (approx) how much ram is tied-up in this cache | 232 // used to track (approx) how much ram is tied-up in this cache |
| 244 size_t fMemoryUsed; | 233 size_t fMemoryUsed; |
| 245 | 234 |
| 246 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | 235 AuxProcRec* fAuxProcList; |
| 247 int fHashHitCount; | |
| 248 int fHashMissCount; | |
| 249 #endif | |
| 250 | |
| 251 AuxProcRec* fAuxProcList; | |
| 252 }; | 236 }; |
| 253 | 237 |
| 254 class SkAutoGlyphCacheBase { | 238 class SkAutoGlyphCacheBase { |
| 255 public: | 239 public: |
| 256 SkGlyphCache* getCache() const { return fCache; } | 240 SkGlyphCache* getCache() const { return fCache; } |
| 257 | 241 |
| 258 void release() { | 242 void release() { |
| 259 if (fCache) { | 243 if (fCache) { |
| 260 SkGlyphCache::AttachCache(fCache); | 244 SkGlyphCache::AttachCache(fCache); |
| 261 fCache = NULL; | 245 fCache = NULL; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 315 const SkMatrix* matrix) { | 299 const SkMatrix* matrix) { |
| 316 fCache = paint.detachCache(surfaceProps, matrix, true); | 300 fCache = paint.detachCache(surfaceProps, matrix, true); |
| 317 } | 301 } |
| 318 | 302 |
| 319 private: | 303 private: |
| 320 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} | 304 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} |
| 321 }; | 305 }; |
| 322 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm a) | 306 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm a) |
| 323 | 307 |
| 324 #endif | 308 #endif |
| OLD | NEW |