OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #ifndef SkGlyphCache_DEFINED | 10 #ifndef SkGlyphCache_DEFINED |
11 #define SkGlyphCache_DEFINED | 11 #define SkGlyphCache_DEFINED |
12 | 12 |
13 #include "SkBitmap.h" | 13 #include "SkBitmap.h" |
14 #include "SkChunkAlloc.h" | 14 #include "SkChunkAlloc.h" |
15 #include "SkDescriptor.h" | 15 #include "SkDescriptor.h" |
16 #include "SkGlyph.h" | 16 #include "SkGlyph.h" |
17 #include "SkScalerContext.h" | 17 #include "SkScalerContext.h" |
18 #include "SkTemplates.h" | 18 #include "SkTemplates.h" |
19 #include "SkTDArray.h" | 19 #include "SkTDArray.h" |
20 | 20 |
21 struct SkDeviceProperties; | 21 struct SkDeviceProperties; |
22 class SkPaint; | 22 class SkPaint; |
23 | 23 |
24 class SkGlyphCache_Globals; | 24 class SkGlyphCache_Globals; |
25 | 25 |
26 // Enable this locally to add stats for hash-table hit rates. It also extends th e dump() | |
27 // output to show those stats. | |
28 //#define SK_GLYPHCACHE_TRACK_HASH_STATS | |
29 | |
26 /** \class SkGlyphCache | 30 /** \class SkGlyphCache |
27 | 31 |
28 This class represents a strike: a specific combination of typeface, size, | 32 This class represents a strike: a specific combination of typeface, size, |
29 matrix, etc., and holds the glyphs for that strike. Calling any of the | 33 matrix, etc., and holds the glyphs for that strike. Calling any of the |
30 getUnichar.../getGlyphID... methods will return the requested glyph, | 34 getUnichar.../getGlyphID... methods will return the requested glyph, |
31 either instantly if it is already cached, or by first generating it and then | 35 either instantly if it is already cached, or by first generating it and then |
32 adding it to the strike. | 36 adding it to the strike. |
33 | 37 |
34 The strikes are held in a global list, available to all threads. To interact | 38 The strikes are held in a global list, available to all threads. To interact |
35 with one, call either VisitCache() or DetachCache(). | 39 with one, call either VisitCache() or DetachCache(). |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
94 const SkDescriptor& getDescriptor() const { return *fDesc; } | 98 const SkDescriptor& getDescriptor() const { return *fDesc; } |
95 | 99 |
96 SkMask::Format getMaskFormat() const { | 100 SkMask::Format getMaskFormat() const { |
97 return fScalerContext->getMaskFormat(); | 101 return fScalerContext->getMaskFormat(); |
98 } | 102 } |
99 | 103 |
100 bool isSubpixel() const { | 104 bool isSubpixel() const { |
101 return fScalerContext->isSubpixel(); | 105 return fScalerContext->isSubpixel(); |
102 } | 106 } |
103 | 107 |
108 void dump() const; | |
109 | |
104 /* AuxProc/Data allow a client to associate data with this cache entry. | 110 /* AuxProc/Data allow a client to associate data with this cache entry. |
105 Multiple clients can use this, as their data is keyed with a function | 111 Multiple clients can use this, as their data is keyed with a function |
106 pointer. In addition to serving as a key, the function pointer is called | 112 pointer. In addition to serving as a key, the function pointer is called |
107 with the data when the glyphcache object is deleted, so the client can | 113 with the data when the glyphcache object is deleted, so the client can |
108 cleanup their data as well. NOTE: the auxProc must not try to access | 114 cleanup their data as well. NOTE: the auxProc must not try to access |
109 this glyphcache in any way, since it may be in the process of being | 115 this glyphcache in any way, since it may be in the process of being |
110 deleted. | 116 deleted. |
111 */ | 117 */ |
112 | 118 |
113 //! If the proc is found, return true and set *dataPtr to its data | 119 //! If the proc is found, return true and set *dataPtr to its data |
(...skipping 24 matching lines...) Expand all Loading... | |
138 a different strike will be generated. This is fine. It does mean we | 144 a different strike will be generated. This is fine. It does mean we |
139 can have more than 1 strike for the same descriptor, but that will | 145 can have more than 1 strike for the same descriptor, but that will |
140 eventually get purged, and the win is that different thread will never | 146 eventually get purged, and the win is that different thread will never |
141 block each other while a strike is being used. | 147 block each other while a strike is being used. |
142 */ | 148 */ |
143 static SkGlyphCache* DetachCache(SkTypeface* typeface, | 149 static SkGlyphCache* DetachCache(SkTypeface* typeface, |
144 const SkDescriptor* desc) { | 150 const SkDescriptor* desc) { |
145 return VisitCache(typeface, desc, DetachProc, NULL); | 151 return VisitCache(typeface, desc, DetachProc, NULL); |
146 } | 152 } |
147 | 153 |
154 static void Dump(); | |
155 | |
148 #ifdef SK_DEBUG | 156 #ifdef SK_DEBUG |
149 void validate() const; | 157 void validate() const; |
150 #else | 158 #else |
151 void validate() const {} | 159 void validate() const {} |
152 #endif | 160 #endif |
153 | 161 |
154 class AutoValidate : SkNoncopyable { | 162 class AutoValidate : SkNoncopyable { |
155 public: | 163 public: |
156 AutoValidate(const SkGlyphCache* cache) : fCache(cache) { | 164 AutoValidate(const SkGlyphCache* cache) : fCache(cache) { |
157 if (fCache) { | 165 if (fCache) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 SkTDArray<SkGlyph*> fGlyphArray; | 205 SkTDArray<SkGlyph*> fGlyphArray; |
198 SkChunkAlloc fGlyphAlloc; | 206 SkChunkAlloc fGlyphAlloc; |
199 | 207 |
200 struct CharGlyphRec { | 208 struct CharGlyphRec { |
201 uint32_t fID; // unichar + subpixel | 209 uint32_t fID; // unichar + subpixel |
202 SkGlyph* fGlyph; | 210 SkGlyph* fGlyph; |
203 }; | 211 }; |
204 // no reason to use the same kHashCount as fGlyphHash, but we do for now | 212 // no reason to use the same kHashCount as fGlyphHash, but we do for now |
205 CharGlyphRec fCharToGlyphHash[kHashCount]; | 213 CharGlyphRec fCharToGlyphHash[kHashCount]; |
206 | 214 |
207 static inline unsigned ID2HashIndex(uint32_t id) { | 215 static inline unsigned ID2HashIndex(uint32_t h) { |
mtklein
2015/01/27 22:28:22
SkChecksum::MixLess?
reed1
2015/01/28 21:22:39
Done.
| |
208 id ^= id >> 16; | 216 // apply (partial) Murmur3 finisher |
209 id ^= id >> 8; | 217 h ^= h >> 16; |
210 return id & kHashMask; | 218 h *= 0x85ebca6b; |
219 #if 0 | |
220 // This part of the Murmur3 finisher does not seems necessary, i.e. it d oes not seem | |
221 // to measurably improve our hash-hit efficiency, so we leave it out. | |
222 h ^= h >> 13; | |
223 h *= 0xc2b2ae35; | |
224 #endif | |
225 h ^= h >> 16; | |
226 return h & kHashMask; | |
211 } | 227 } |
212 | 228 |
213 // used to track (approx) how much ram is tied-up in this cache | 229 // used to track (approx) how much ram is tied-up in this cache |
214 size_t fMemoryUsed; | 230 size_t fMemoryUsed; |
215 | 231 |
232 | |
233 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
234 int fHashHitCount; | |
235 int fHashMissCount; | |
236 #endif | |
237 | |
216 struct AuxProcRec { | 238 struct AuxProcRec { |
217 AuxProcRec* fNext; | 239 AuxProcRec* fNext; |
218 void (*fProc)(void*); | 240 void (*fProc)(void*); |
219 void* fData; | 241 void* fData; |
220 }; | 242 }; |
221 AuxProcRec* fAuxProcList; | 243 AuxProcRec* fAuxProcList; |
222 void invokeAndRemoveAuxProcs(); | 244 void invokeAndRemoveAuxProcs(); |
223 | 245 |
224 inline static SkGlyphCache* FindTail(SkGlyphCache* head); | 246 inline static SkGlyphCache* FindTail(SkGlyphCache* head); |
225 | 247 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
290 const SkMatrix* matrix) { | 312 const SkMatrix* matrix) { |
291 fCache = paint.detachCache(deviceProperties, matrix, true); | 313 fCache = paint.detachCache(deviceProperties, matrix, true); |
292 } | 314 } |
293 | 315 |
294 private: | 316 private: |
295 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} | 317 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} |
296 }; | 318 }; |
297 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm a) | 319 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm a) |
298 | 320 |
299 #endif | 321 #endif |
OLD | NEW |