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