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