| 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 |