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 |