aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkGlyphCache.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/SkGlyphCache.h')
-rw-r--r--src/core/SkGlyphCache.h65
1 files changed, 49 insertions, 16 deletions
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h
index 4eb6b5bc60..cf64527b49 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 {