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 "SkChunkAlloc.h" | 11 #include "SkChunkAlloc.h" |
12 #include "SkDescriptor.h" | 12 #include "SkDescriptor.h" |
13 #include "SkGlyph.h" | 13 #include "SkGlyph.h" |
14 #include "SkMutex.h" | |
14 #include "SkTHash.h" | 15 #include "SkTHash.h" |
15 #include "SkScalerContext.h" | 16 #include "SkScalerContext.h" |
17 #include "SkSharedMutex.h" | |
18 #include "SkSpinlock.h" | |
16 #include "SkTemplates.h" | 19 #include "SkTemplates.h" |
17 #include "SkTDArray.h" | 20 #include "SkTDArray.h" |
18 | 21 |
19 class SkPaint; | 22 class SkPaint; |
20 class SkTraceMemoryDump; | 23 class SkTraceMemoryDump; |
21 | 24 |
22 class SkGlyphCache_Globals; | 25 class SkGlyphCache_Globals; |
23 | 26 |
24 /** \class SkGlyphCache | 27 /** \class SkGlyphCache |
25 | 28 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 */ | 115 */ |
113 | 116 |
114 //! If the proc is found, return true and set *dataPtr to its data | 117 //! If the proc is found, return true and set *dataPtr to its data |
115 bool getAuxProcData(void (*auxProc)(void*), void** dataPtr) const; | 118 bool getAuxProcData(void (*auxProc)(void*), void** dataPtr) const; |
116 | 119 |
117 //! Add a proc/data pair to the glyphcache. proc should be non-null | 120 //! Add a proc/data pair to the glyphcache. proc should be non-null |
118 void setAuxProc(void (*auxProc)(void*), void* auxData); | 121 void setAuxProc(void (*auxProc)(void*), void* auxData); |
119 | 122 |
120 SkScalerContext* getScalerContext() const { return fScalerContext; } | 123 SkScalerContext* getScalerContext() const { return fScalerContext; } |
121 | 124 |
125 struct GlyphAndCache { | |
126 SkGlyphCache* cache; | |
127 const SkGlyph* glyph; | |
128 }; | |
129 | |
130 static void onceFillInMetrics(GlyphAndCache); | |
mtklein_C
2015/09/03 21:16:08
These static members are NamedLikeThis: OnceFillIn
herb_g
2015/09/04 17:26:12
Done.
| |
131 | |
132 static void onceFillInImage(GlyphAndCache gc); | |
133 | |
134 static void onceFillInPath(GlyphAndCache gc); | |
135 | |
136 typedef bool (*VisitProc)(const SkGlyphCache*, void*); | |
137 | |
122 /** Find a matching cache entry, and call proc() with it. If none is found c reate a new one. | 138 /** Find a matching cache entry, and call proc() with it. If none is found c reate a new one. |
123 If the proc() returns true, detach the cache and return it, otherwise le ave it and return | 139 If the proc() returns true, detach the cache and return it, otherwise le ave it and return |
124 nullptr. | 140 nullptr. |
125 */ | 141 */ |
126 static SkGlyphCache* VisitCache(SkTypeface*, const SkDescriptor* desc, | 142 static SkGlyphCache* VisitCache(SkTypeface*, const SkDescriptor* desc, |
127 bool (*proc)(const SkGlyphCache*, void*), | 143 VisitProc proc, |
128 void* context); | 144 void* context); |
129 | 145 |
130 /** Given a strike that was returned by either VisitCache() or DetachCache() add it back into | 146 /** Given a strike that was returned by either VisitCache() or DetachCache() add it back into |
131 the global cache list (after which the caller should not reference it an ymore. | 147 the global cache list (after which the caller should not reference it an ymore. |
132 */ | 148 */ |
133 static void AttachCache(SkGlyphCache*); | 149 static void AttachCache(SkGlyphCache*); |
134 | 150 |
135 /** Detach a strike from the global cache matching the specified descriptor. Once detached, | 151 /** Detach a strike from the global cache matching the specified descriptor. Once detached, |
136 it can be queried/modified by the current thread, and when finished, be reattached to the | 152 it can be queried/modified by the current thread, and when finished, be reattached to the |
137 global cache with AttachCache(). While detached, if another request is m ade with the same | 153 global cache with AttachCache(). While detached, if another request is m ade with the same |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
174 void forget() { | 190 void forget() { |
175 fCache = nullptr; | 191 fCache = nullptr; |
176 } | 192 } |
177 private: | 193 private: |
178 const SkGlyphCache* fCache; | 194 const SkGlyphCache* fCache; |
179 }; | 195 }; |
180 | 196 |
181 private: | 197 private: |
182 friend class SkGlyphCache_Globals; | 198 friend class SkGlyphCache_Globals; |
183 | 199 |
184 enum { | |
185 kHashBits = 8, | |
186 kHashCount = 1 << kHashBits, | |
187 kHashMask = kHashCount - 1 | |
188 }; | |
189 | |
190 typedef uint32_t PackedGlyphID; // glyph-index + subpixel-pos | 200 typedef uint32_t PackedGlyphID; // glyph-index + subpixel-pos |
191 typedef uint32_t PackedUnicharID; // unichar + subpixel-pos | 201 typedef uint32_t PackedUnicharID; // unichar + subpixel-pos |
192 | 202 |
193 struct CharGlyphRec { | 203 struct CharGlyphRec { |
194 PackedUnicharID fPackedUnicharID; | 204 class HashTraits { |
195 PackedGlyphID fPackedGlyphID; | 205 public: |
206 static PackedUnicharID GetKey(const CharGlyphRec& rec) { | |
207 return rec.fPackedUnicharID; | |
208 } | |
209 static uint32_t Hash(PackedUnicharID unicharID) { | |
210 return SkChecksum::CheapMix(unicharID); | |
211 } | |
212 }; | |
213 PackedUnicharID fPackedUnicharID; | |
214 PackedGlyphID fPackedGlyphID; | |
196 }; | 215 }; |
197 | 216 |
198 struct AuxProcRec { | 217 struct AuxProcRec { |
199 AuxProcRec* fNext; | 218 AuxProcRec* fNext; |
200 void (*fProc)(void*); | 219 void (*fProc)(void*); |
201 void* fData; | 220 void* fData; |
202 }; | 221 }; |
203 | 222 |
204 // SkGlyphCache takes ownership of the scalercontext. | 223 // SkGlyphCache takes ownership of the scalercontext. |
205 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*); | 224 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*); |
206 ~SkGlyphCache(); | 225 ~SkGlyphCache(); |
207 | 226 |
227 // Increase the memory used keeping the cache and the global size in sync. | |
228 void increaseMemoryUsed(size_t used); | |
229 | |
208 // Return the SkGlyph* associated with MakeID. The id parameter is the | 230 // Return the SkGlyph* associated with MakeID. The id parameter is the |
209 // combined glyph/x/y id generated by MakeID. If it is just a glyph id | 231 // combined glyph/x/y id generated by MakeID. If it is just a glyph id |
210 // then x and y are assumed to be zero. | 232 // then x and y are assumed to be zero. |
211 SkGlyph* lookupByPackedGlyphID(PackedGlyphID packedGlyphID); | 233 SkGlyph* lookupByPackedGlyphID(PackedGlyphID packedGlyphID); |
212 | 234 |
213 // Return a SkGlyph* associated with unicode id and position x and y. | 235 // Return a SkGlyph* associated with unicode id and position x and y. |
214 SkGlyph* lookupByChar(SkUnichar id, SkFixed x = 0, SkFixed y = 0); | 236 SkGlyph* lookupByChar(SkUnichar id, SkFixed x = 0, SkFixed y = 0); |
215 | 237 |
216 // Return a new SkGlyph for the glyph ID and subpixel position id. | 238 // Return a new SkGlyph for the glyph ID and subpixel position id. Limit the amount |
mtklein_C
2015/09/03 21:16:08
Kill "limit the amount of work using type" :)
herb_g
2015/09/04 17:26:12
Done.
| |
239 // of work using type. | |
217 SkGlyph* allocateNewGlyph(PackedGlyphID packedGlyphID); | 240 SkGlyph* allocateNewGlyph(PackedGlyphID packedGlyphID); |
218 | 241 |
242 // Add the full metrics to an existing glyph. | |
243 void addFullMetrics(SkGlyph* glyph); | |
244 | |
219 static bool DetachProc(const SkGlyphCache*, void*) { return true; } | 245 static bool DetachProc(const SkGlyphCache*, void*) { return true; } |
220 | 246 |
247 CharGlyphRec PackedUnicharIDtoCharGlyphRec(PackedUnicharID packedUnicharID); | |
248 | |
249 | |
221 // The id arg is a combined id generated by MakeID. | 250 // The id arg is a combined id generated by MakeID. |
222 CharGlyphRec* getCharGlyphRec(PackedUnicharID id); | 251 CharGlyphRec* getCharGlyphRec(PackedUnicharID id); |
223 | 252 |
224 void invokeAndRemoveAuxProcs(); | |
225 | |
226 inline static SkGlyphCache* FindTail(SkGlyphCache* head); | 253 inline static SkGlyphCache* FindTail(SkGlyphCache* head); |
227 | 254 |
255 // The following are protected by the SkGlyphCache_Globals fLock mutex. | |
256 // Note: the following fields are protected by a mutex in a different class. | |
228 SkGlyphCache* fNext; | 257 SkGlyphCache* fNext; |
229 SkGlyphCache* fPrev; | 258 SkGlyphCache* fPrev; |
230 SkDescriptor* const fDesc; | 259 SkDescriptor* const fDesc; |
231 SkScalerContext* const fScalerContext; | |
232 SkPaint::FontMetrics fFontMetrics; | 260 SkPaint::FontMetrics fFontMetrics; |
261 int fRefCount; | |
233 | 262 |
263 // The following fields are protected by fMapMutex. | |
264 mutable SkSharedMutex fMapMutex; | |
234 // Map from a combined GlyphID and sub-pixel position to a SkGlyph. | 265 // Map from a combined GlyphID and sub-pixel position to a SkGlyph. |
235 SkTHashTable<SkGlyph, PackedGlyphID, SkGlyph::HashTraits> fGlyphMap; | 266 SkTHashTable<SkGlyph, PackedGlyphID, SkGlyph::HashTraits> fGlyphMap; |
236 | |
237 SkChunkAlloc fGlyphAlloc; | 267 SkChunkAlloc fGlyphAlloc; |
238 | 268 typedef SkTHashTable<CharGlyphRec, PackedUnicharID, CharGlyphRec::HashTraits > |
239 SkAutoTArray<CharGlyphRec> fPackedUnicharIDToPackedGlyphID; | 269 PackedUnicharIDToPackedGlyphIDMap; |
240 | 270 SkAutoTDelete<PackedUnicharIDToPackedGlyphIDMap> fPackedUnicharIDToPackedGly phID; |
241 // used to track (approx) how much ram is tied-up in this cache | 271 // used to track (approx) how much ram is tied-up in this cache |
242 size_t fMemoryUsed; | 272 size_t fMemoryUsed; |
243 | 273 |
274 // The FScalerMutex protects the following fields. It is mainly used to ensu re single-threaded | |
275 // access to the font scaler, but it also protects the fAuxProcList. | |
276 mutable SkMutex fScalerMutex; | |
277 SkScalerContext* const fScalerContext; | |
244 AuxProcRec* fAuxProcList; | 278 AuxProcRec* fAuxProcList; |
279 | |
280 // BEWARE: Mutex ordering | |
281 // If you need to hold both fMapMutex and fScalerMutex then fMapMutex must b e held first. | |
245 }; | 282 }; |
246 | 283 |
247 class SkAutoGlyphCacheBase { | 284 class SkAutoGlyphCacheBase { |
248 public: | 285 public: |
249 SkGlyphCache* getCache() const { return fCache; } | 286 SkGlyphCache* getCache() const { return fCache; } |
250 | 287 |
251 void release() { | 288 void release() { |
252 if (fCache) { | 289 if (fCache) { |
253 SkGlyphCache::AttachCache(fCache); | 290 SkGlyphCache::AttachCache(fCache); |
254 fCache = nullptr; | 291 fCache = nullptr; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 const SkMatrix* matrix) { | 345 const SkMatrix* matrix) { |
309 fCache = paint.detachCache(surfaceProps, matrix, true); | 346 fCache = paint.detachCache(surfaceProps, matrix, true); |
310 } | 347 } |
311 | 348 |
312 private: | 349 private: |
313 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} | 350 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} |
314 }; | 351 }; |
315 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm a) | 352 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm a) |
316 | 353 |
317 #endif | 354 #endif |
OLD | NEW |