Chromium Code Reviews| Index: src/core/SkGlyphCache.h |
| diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h |
| index 1c985bf6715070bd1ff520535919aec3786429d2..029d598f8017a0904189b28505ac5a72b4e55248 100644 |
| --- a/src/core/SkGlyphCache.h |
| +++ b/src/core/SkGlyphCache.h |
| @@ -7,12 +7,16 @@ |
| #ifndef SkGlyphCache_DEFINED |
| #define SkGlyphCache_DEFINED |
| +#include <SkSpinlock.h> |
|
mtklein_C
2015/08/14 15:31:37
kill?
|
| #include "SkBitmap.h" |
| #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" |
| @@ -112,12 +116,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 |
| NULL. |
| */ |
| 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 |
| @@ -171,18 +186,21 @@ private: |
| kFull_MetricsType |
| }; |
| - 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 { |
| @@ -195,6 +213,9 @@ private: |
| SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*); |
| ~SkGlyphCache(); |
| + void increaseMemoryUsed(size_t used); |
| + size_t memoryUsed() const; |
| + |
| // 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. |
| @@ -204,12 +225,17 @@ private: |
| SkGlyph* lookupByChar(SkUnichar id, MetricsType type, SkFixed x = 0, SkFixed y = 0); |
| // Return a new SkGlyph for the glyph ID and subpixel position id. Limit the amount |
| - // of work |
| - // using type. |
| + // of work using type. |
| SkGlyph* allocateNewGlyph(PackedGlyphID packedGlyphID, MetricsType type); |
| + // 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); |
| @@ -217,23 +243,34 @@ private: |
| inline static SkGlyphCache* FindTail(SkGlyphCache* head); |
| + // The following are protected by the SkGlyphCache_Globals fLock mutex. |
| SkGlyphCache* fNext; |
| SkGlyphCache* fPrev; |
| SkDescriptor* const fDesc; |
| - SkScalerContext* const fScalerContext; |
| SkPaint::FontMetrics fFontMetrics; |
| + int refCount; |
| + // The following fields are protected by fMu. |
| + mutable SkSharedMutex fMu; |
| // 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 fMu and fScalerMutex then fMu must be held first. |
| + // fLock from SkGlyphCache_Globals should not be held when you need to hold either fMu |
| + // or fScalerMutex. |
| }; |
| class SkAutoGlyphCacheBase { |