Chromium Code Reviews| Index: src/core/SkGlyphCache.h |
| diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h |
| index 4eb6b5bc60a82ad8b2b2fce8ccdd50fcb5043a02..38453be4b9a4ddae0f24b24aa09b85af7d741640 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,25 @@ public: |
| SkScalerContext* getScalerContext() const { return fScalerContext; } |
| + struct GlyphAndCache { |
| + SkGlyphCache* cache; |
| + const SkGlyph* glyph; |
| + }; |
| + |
| + static void onceFillInMetrics(GlyphAndCache); |
|
mtklein_C
2015/09/03 21:16:08
These static members are NamedLikeThis: OnceFillIn
herb_g
2015/09/04 17:26:12
Done.
|
| + |
| + 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 +197,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 +224,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. |
| @@ -213,35 +235,50 @@ private: |
| // Return a SkGlyph* associated with unicode id and position x and y. |
| SkGlyph* lookupByChar(SkUnichar id, SkFixed x = 0, SkFixed y = 0); |
| - // Return a new SkGlyph for the glyph ID and subpixel position id. |
| + // Return a new SkGlyph for the glyph ID and subpixel position id. Limit the amount |
|
mtklein_C
2015/09/03 21:16:08
Kill "limit the amount of work using type" :)
herb_g
2015/09/04 17:26:12
Done.
|
| + // of work using type. |
| 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 { |