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