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; |
225 SkDescriptor* fDesc; | 221 SkGlyphCache* fPrev; |
226 SkScalerContext* fScalerContext; | 222 SkDescriptor* const fDesc; |
227 SkPaint::FontMetrics fFontMetrics; | 223 SkScalerContext* const fScalerContext; |
| 224 SkPaint::FontMetrics fFontMetrics; |
228 | 225 |
229 // A quick lookup to avoid the binary search looking for glyphs in fGlyphArr
ay. | 226 // Map from a combined GlyphID and sub-pixel position to a SkGlyph. |
230 uint16_t fGlyphHash[kHashCount]; | 227 SkTHashTable<SkGlyph, PackedGlyphID, SkGlyph::HashTraits> fGlyphMap; |
231 | 228 |
232 // Contains the SkGlyphs that are used by fGlyphHash and fCharToGlyphHash. T
he ~0 element is | 229 SkChunkAlloc fGlyphAlloc; |
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; | |
238 | 230 |
239 // no reason to use the same kHashCount as fGlyphHash, but we do for now | 231 SkAutoTArray<CharGlyphRec> fPackedUnicharIDToPackedGlyphID; |
240 // Dynamically allocated when chars are encountered. | |
241 SkAutoTArray<CharGlyphRec> fCharToGlyphHash; | |
242 | 232 |
243 // used to track (approx) how much ram is tied-up in this cache | 233 // used to track (approx) how much ram is tied-up in this cache |
244 size_t fMemoryUsed; | 234 size_t fMemoryUsed; |
245 | 235 |
246 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | 236 AuxProcRec* fAuxProcList; |
247 int fHashHitCount; | |
248 int fHashMissCount; | |
249 #endif | |
250 | |
251 AuxProcRec* fAuxProcList; | |
252 }; | 237 }; |
253 | 238 |
254 class SkAutoGlyphCacheBase { | 239 class SkAutoGlyphCacheBase { |
255 public: | 240 public: |
256 SkGlyphCache* getCache() const { return fCache; } | 241 SkGlyphCache* getCache() const { return fCache; } |
257 | 242 |
258 void release() { | 243 void release() { |
259 if (fCache) { | 244 if (fCache) { |
260 SkGlyphCache::AttachCache(fCache); | 245 SkGlyphCache::AttachCache(fCache); |
261 fCache = NULL; | 246 fCache = NULL; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 const SkMatrix* matrix) { | 300 const SkMatrix* matrix) { |
316 fCache = paint.detachCache(surfaceProps, matrix, true); | 301 fCache = paint.detachCache(surfaceProps, matrix, true); |
317 } | 302 } |
318 | 303 |
319 private: | 304 private: |
320 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} | 305 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} |
321 }; | 306 }; |
322 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm
a) | 307 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm
a) |
323 | 308 |
324 #endif | 309 #endif |
OLD | NEW |