Index: src/core/SkGlyphCache.h |
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h |
index 4eb6b5bc60a82ad8b2b2fce8ccdd50fcb5043a02..cf64527b492c10a3a09e2fbf611ddd7660736db7 100644 |
--- a/src/core/SkGlyphCache.h |
+++ b/src/core/SkGlyphCache.h |
@@ -11,8 +11,11 @@ |
#include "SkChunkAlloc.h" |
#include "SkDescriptor.h" |
#include "SkGlyph.h" |
+#include "SkMutex.h" |
#include "SkTHash.h" |
#include "SkScalerContext.h" |
+#include "SkSharedMutex.h" |
+#include "SkSpinlock.h" |
#include "SkTemplates.h" |
#include "SkTDArray.h" |
@@ -119,12 +122,23 @@ public: |
SkScalerContext* getScalerContext() const { return fScalerContext; } |
+ struct GlyphAndCache { |
+ SkGlyphCache* cache; |
+ const SkGlyph* glyph; |
+ }; |
+ |
+ static void OnceFillInImage(GlyphAndCache gc); |
+ |
+ static void OnceFillInPath(GlyphAndCache gc); |
+ |
+ typedef bool (*VisitProc)(const SkGlyphCache*, void*); |
+ |
/** Find a matching cache entry, and call proc() with it. If none is found create a new one. |
If the proc() returns true, detach the cache and return it, otherwise leave it and return |
nullptr. |
*/ |
static SkGlyphCache* VisitCache(SkTypeface*, const SkDescriptor* desc, |
- bool (*proc)(const SkGlyphCache*, void*), |
+ VisitProc proc, |
void* context); |
/** Given a strike that was returned by either VisitCache() or DetachCache() add it back into |
@@ -181,18 +195,21 @@ public: |
private: |
friend class SkGlyphCache_Globals; |
- enum { |
- kHashBits = 8, |
- kHashCount = 1 << kHashBits, |
- kHashMask = kHashCount - 1 |
- }; |
- |
typedef uint32_t PackedGlyphID; // glyph-index + subpixel-pos |
typedef uint32_t PackedUnicharID; // unichar + subpixel-pos |
struct CharGlyphRec { |
- PackedUnicharID fPackedUnicharID; |
- PackedGlyphID fPackedGlyphID; |
+ class HashTraits { |
+ public: |
+ static PackedUnicharID GetKey(const CharGlyphRec& rec) { |
+ return rec.fPackedUnicharID; |
+ } |
+ static uint32_t Hash(PackedUnicharID unicharID) { |
+ return SkChecksum::CheapMix(unicharID); |
+ } |
+ }; |
+ PackedUnicharID fPackedUnicharID; |
+ PackedGlyphID fPackedGlyphID; |
}; |
struct AuxProcRec { |
@@ -205,6 +222,9 @@ private: |
SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*); |
~SkGlyphCache(); |
+ // Increase the memory used keeping the cache and the global size in sync. |
+ void increaseMemoryUsed(size_t used); |
+ |
// Return the SkGlyph* associated with MakeID. The id parameter is the |
// combined glyph/x/y id generated by MakeID. If it is just a glyph id |
// then x and y are assumed to be zero. |
@@ -216,32 +236,45 @@ private: |
// Return a new SkGlyph for the glyph ID and subpixel position id. |
SkGlyph* allocateNewGlyph(PackedGlyphID packedGlyphID); |
+ // Add the full metrics to an existing glyph. |
+ void addFullMetrics(SkGlyph* glyph); |
+ |
static bool DetachProc(const SkGlyphCache*, void*) { return true; } |
+ CharGlyphRec PackedUnicharIDtoCharGlyphRec(PackedUnicharID packedUnicharID); |
+ |
// The id arg is a combined id generated by MakeID. |
CharGlyphRec* getCharGlyphRec(PackedUnicharID id); |
- void invokeAndRemoveAuxProcs(); |
- |
inline static SkGlyphCache* FindTail(SkGlyphCache* head); |
+ // The following are protected by the SkGlyphCache_Globals fLock mutex. |
+ // Note: the following fields are protected by a mutex in a different class. |
SkGlyphCache* fNext; |
SkGlyphCache* fPrev; |
SkDescriptor* const fDesc; |
- SkScalerContext* const fScalerContext; |
SkPaint::FontMetrics fFontMetrics; |
+ int fRefCount; |
+ // The following fields are protected by fMapMutex. |
+ mutable SkSharedMutex fMapMutex; |
// Map from a combined GlyphID and sub-pixel position to a SkGlyph. |
SkTHashTable<SkGlyph, PackedGlyphID, SkGlyph::HashTraits> fGlyphMap; |
- |
SkChunkAlloc fGlyphAlloc; |
- |
- SkAutoTArray<CharGlyphRec> fPackedUnicharIDToPackedGlyphID; |
- |
+ typedef SkTHashTable<CharGlyphRec, PackedUnicharID, CharGlyphRec::HashTraits> |
+ PackedUnicharIDToPackedGlyphIDMap; |
+ SkAutoTDelete<PackedUnicharIDToPackedGlyphIDMap> fPackedUnicharIDToPackedGlyphID; |
// used to track (approx) how much ram is tied-up in this cache |
size_t fMemoryUsed; |
+ // The FScalerMutex protects the following fields. It is mainly used to ensure single-threaded |
+ // access to the font scaler, but it also protects the fAuxProcList. |
+ mutable SkMutex fScalerMutex; |
+ SkScalerContext* const fScalerContext; |
AuxProcRec* fAuxProcList; |
+ |
+ // BEWARE: Mutex ordering |
+ // If you need to hold both fMapMutex and fScalerMutex then fMapMutex must be held first. |
}; |
class SkAutoGlyphCacheBase { |