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