Convert GrStrikeCache to use SkTHashTable

Change-Id: I24179f1eafd0f39735415d1d4194a34d5478f8e3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/259432
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/gpu/text/GrStrikeCache.cpp b/src/gpu/text/GrStrikeCache.cpp
index 4a2cd29a..70b3594 100644
--- a/src/gpu/text/GrStrikeCache.cpp
+++ b/src/gpu/text/GrStrikeCache.cpp
@@ -15,6 +15,7 @@
 #include "src/core/SkAutoMalloc.h"
 #include "src/core/SkDistanceFieldGen.h"
 #include "src/core/SkStrikeSpec.h"
+#include "src/gpu/text/GrStrikeCache.h"
 
 GrStrikeCache::GrStrikeCache(const GrCaps* caps, size_t maxTextureBytes)
         : fPreserveStrike(nullptr)
@@ -22,40 +23,36 @@
                     GrMaskFormatBytesPerPixel(kA565_GrMaskFormat))) { }
 
 GrStrikeCache::~GrStrikeCache() {
-    StrikeHash::Iter iter(&fCache);
-    while (!iter.done()) {
-        (*iter).fIsAbandoned = true;
-        (*iter).unref();
-        ++iter;
-    }
+    fCache.foreach([](GrTextStrike** strike){
+        (*strike)->fIsAbandoned = true;
+        (*strike)->unref();
+    });
 }
 
 void GrStrikeCache::freeAll() {
-    StrikeHash::Iter iter(&fCache);
-    while (!iter.done()) {
-        (*iter).fIsAbandoned = true;
-        (*iter).unref();
-        ++iter;
-    }
-    fCache.rewind();
+    fCache.foreach([](GrTextStrike** strike){
+        (*strike)->fIsAbandoned = true;
+        (*strike)->unref();
+    });
+    fCache.reset();
 }
 
 void GrStrikeCache::HandleEviction(GrDrawOpAtlas::AtlasID id, void* ptr) {
     GrStrikeCache* grStrikeCache = reinterpret_cast<GrStrikeCache*>(ptr);
 
-    StrikeHash::Iter iter(&grStrikeCache->fCache);
-    for (; !iter.done(); ++iter) {
-        GrTextStrike* strike = &*iter;
+    grStrikeCache->fCache.mutate([grStrikeCache, id](GrTextStrike** strikePtrPtr){
+        GrTextStrike* strike = *strikePtrPtr;
         strike->removeID(id);
 
         // clear out any empty strikes.  We will preserve the strike whose call to addToAtlas
         // triggered the eviction
         if (strike != grStrikeCache->fPreserveStrike && 0 == strike->fAtlasedGlyphs) {
-            grStrikeCache->fCache.remove(GrTextStrike::GetKey(*strike));
             strike->fIsAbandoned = true;
             strike->unref();
+            return false;  // Remove this entry from the cache.
         }
-    }
+        return true;  // Keep this entry in the cache.
+    });
 }
 
 // expands each bit in a bitmask to 0 or ~0 of type INT_TYPE. Used to expand a BW glyph mask to
diff --git a/src/gpu/text/GrStrikeCache.h b/src/gpu/text/GrStrikeCache.h
index a0eaf7c..5616748 100644
--- a/src/gpu/text/GrStrikeCache.h
+++ b/src/gpu/text/GrStrikeCache.h
@@ -8,13 +8,13 @@
 #ifndef GrStrikeCache_DEFINED
 #define GrStrikeCache_DEFINED
 
+#include "include/private/SkTHash.h"
 #include "src/codec/SkMasks.h"
 #include "src/core/SkDescriptor.h"
 #include "src/core/SkTDynamicHash.h"
 #include "src/gpu/GrDrawOpAtlas.h"
 #include "src/gpu/GrGlyph.h"
 
-
 class GrAtlasManager;
 class GrGpu;
 class GrStrikeCache;
@@ -59,12 +59,6 @@
     // If a TextStrike is abandoned by the cache, then the caller must get a new strike
     bool isAbandoned() const { return fIsAbandoned; }
 
-    static const SkDescriptor& GetKey(const GrTextStrike& strike) {
-        return *strike.fFontScalerKey.getDesc();
-    }
-
-    static uint32_t Hash(const SkDescriptor& desc) { return desc.getChecksum(); }
-
 private:
     SkTDynamicHash<GrGlyph, SkPackedGlyphID> fCache;
     SkAutoDescriptor fFontScalerKey;
@@ -92,7 +86,7 @@
     // Therefore, the caller must check GrTextStrike::isAbandoned() if there are other
     // interactions with the cache since the strike was received.
     sk_sp<GrTextStrike> getStrike(const SkDescriptor& desc) {
-        sk_sp<GrTextStrike> strike = sk_ref_sp(fCache.find(desc));
+        sk_sp<GrTextStrike> strike = sk_ref_sp(fCache.findOrNull(desc));
         if (!strike) {
             strike = this->generateStrike(desc);
         }
@@ -109,11 +103,20 @@
     sk_sp<GrTextStrike> generateStrike(const SkDescriptor& desc) {
         // 'fCache' get the construction ref
         sk_sp<GrTextStrike> strike = sk_ref_sp(new GrTextStrike(desc));
-        fCache.add(strike.get());
+        fCache.set(strike.get());
         return strike;
     }
 
-    using StrikeHash = SkTDynamicHash<GrTextStrike, SkDescriptor>;
+    struct DescriptorHashTraits {
+        static const SkDescriptor& GetKey(const GrTextStrike* strike) {
+            return *strike->fFontScalerKey.getDesc();
+        }
+        static uint32_t Hash(const SkDescriptor& desc) { return desc.getChecksum(); }
+    };
+
+    // TODO - switch from GrTextStrike* to sk_sp<GrTextStrike>.
+    // TODO - can this become SkTHashMap?
+    using StrikeHash = SkTHashTable<GrTextStrike*, SkDescriptor, DescriptorHashTraits>;
 
     StrikeHash fCache;
     GrTextStrike* fPreserveStrike;