Expand ExclusiveStrikePtr with StrikeCache

Add an SkStrikeCache to ExclusiveStrikePtr to allow it to return
a glyph cache to one of multiple strike caches.

BUG=skia:8091

Change-Id: I5440a6451838e08f21677eb5d5b4ade6c6b75ca0
Reviewed-on: https://skia-review.googlesource.com/136617
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/core/SkStrikeCache.cpp b/src/core/SkStrikeCache.cpp
index 64146e2..817d00b 100644
--- a/src/core/SkStrikeCache.cpp
+++ b/src/core/SkStrikeCache.cpp
@@ -35,33 +35,52 @@
     std::unique_ptr<SkStrikePinner> fPinner;
 };
 
-SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr(SkStrikeCache::Node* node) : fNode{node} {}
-SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr() : fNode{nullptr} {}
+SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr(
+        SkStrikeCache::Node* node, SkStrikeCache* strikeCache)
+    : fNode{node}
+    , fStrikeCache{strikeCache} {}
+
+SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr()
+    : fNode{nullptr}
+    , fStrikeCache{nullptr} {}
+
 SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr(ExclusiveStrikePtr&& o)
-    : fNode{o.fNode} {
+    : fNode{o.fNode}
+    , fStrikeCache{o.fStrikeCache}{
     o.fNode = nullptr;
+    o.fStrikeCache = nullptr;
 }
 
 SkStrikeCache::ExclusiveStrikePtr&
 SkStrikeCache::ExclusiveStrikePtr::operator = (ExclusiveStrikePtr&& o) {
-    Attach(fNode);
+    if (fStrikeCache != nullptr) {
+        fStrikeCache->attachNode(fNode);
+    }
     fNode = o.fNode;
+    fStrikeCache = o.fStrikeCache;
     o.fNode = nullptr;
+    o.fStrikeCache = nullptr;
     return *this;
 }
 
 SkStrikeCache::ExclusiveStrikePtr::~ExclusiveStrikePtr() {
-    SkStrikeCache::Attach(fNode);
+    if (fStrikeCache != nullptr) {
+        fStrikeCache->attachNode(fNode);
+    }
 }
+
 SkGlyphCache* SkStrikeCache::ExclusiveStrikePtr::get() const {
     return &fNode->fCache;
 }
+
 SkGlyphCache* SkStrikeCache::ExclusiveStrikePtr::operator -> () const {
     return this->get();
 }
+
 SkGlyphCache& SkStrikeCache::ExclusiveStrikePtr::operator *  () const {
     return *this->get();
 }
+
 SkStrikeCache::ExclusiveStrikePtr::operator bool () const {
     return fNode != nullptr;
 }
@@ -70,9 +89,11 @@
                   const SkStrikeCache::ExclusiveStrikePtr& rhs) {
     return lhs.fNode == rhs.fNode;
 }
+
 bool operator == (const SkStrikeCache::ExclusiveStrikePtr& lhs, decltype(nullptr)) {
     return lhs.fNode == nullptr;
 }
+
 bool operator == (decltype(nullptr), const SkStrikeCache::ExclusiveStrikePtr& rhs) {
     return nullptr == rhs.fNode;
 }
@@ -86,10 +107,6 @@
     }
 }
 
-void SkStrikeCache::Attach(Node* node) {
-    GlobalStrikeCache()->attachNode(node);
-}
-
 SkExclusiveStrikePtr SkStrikeCache::FindStrikeExclusive(const SkDescriptor& desc) {
     return GlobalStrikeCache()->findStrikeExclusive(desc);
 }
@@ -124,10 +141,16 @@
 SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive(
         const SkDescriptor& desc, const SkScalerContextEffects& effects, const SkTypeface& typeface)
 {
-    auto cache = FindStrikeExclusive(desc);
+    return GlobalStrikeCache()->findOrCreateStrikeExclusive(desc, effects, typeface);
+}
+
+SkExclusiveStrikePtr SkStrikeCache::findOrCreateStrikeExclusive(
+        const SkDescriptor& desc, const SkScalerContextEffects& effects, const SkTypeface& typeface)
+{
+    auto cache = this->findStrikeExclusive(desc);
     if (cache == nullptr) {
         auto scaler = CreateScalerContext(desc, effects, typeface);
-        cache = CreateStrikeExclusive(desc, std::move(scaler));
+        cache = this->createStrikeExclusive(desc, std::move(scaler));
     }
     return cache;
 }
@@ -245,17 +268,16 @@
 }
 
 SkExclusiveStrikePtr SkStrikeCache::findStrikeExclusive(const SkDescriptor& desc) {
-    Node*           node;
     SkAutoExclusive ac(fLock);
 
-    for (node = internalGetHead(); node != nullptr; node = node->fNext) {
+    for (Node* node = internalGetHead(); node != nullptr; node = node->fNext) {
         if (node->fCache.getDescriptor() == desc) {
             this->internalDetachCache(node);
-            return SkExclusiveStrikePtr(node);
+            return SkExclusiveStrikePtr(node, this);
         }
     }
 
-    return SkExclusiveStrikePtr(nullptr);
+    return SkExclusiveStrikePtr();
 }
 
 static bool loose_compare(const SkDescriptor& lhs, const SkDescriptor& rhs) {
@@ -347,6 +369,16 @@
         SkPaint::FontMetrics* maybeMetrics,
         std::unique_ptr<SkStrikePinner> pinner)
 {
+    return GlobalStrikeCache()->createStrikeExclusive(
+            desc, std::move(scaler), maybeMetrics, std::move(pinner));
+}
+
+SkExclusiveStrikePtr SkStrikeCache::createStrikeExclusive(
+        const SkDescriptor& desc,
+        std::unique_ptr<SkScalerContext> scaler,
+        SkPaint::FontMetrics* maybeMetrics,
+        std::unique_ptr<SkStrikePinner> pinner)
+{
     SkPaint::FontMetrics fontMetrics;
     if (maybeMetrics != nullptr) {
         fontMetrics = *maybeMetrics;
@@ -354,7 +386,8 @@
         scaler->getFontMetrics(&fontMetrics);
     }
 
-    return SkExclusiveStrikePtr(new Node(desc, std::move(scaler), fontMetrics, std::move(pinner)));
+    auto* node = new Node(desc, std::move(scaler), fontMetrics, std::move(pinner));
+    return SkExclusiveStrikePtr(node, this);
 }
 
 void SkStrikeCache::purgeAll() {
diff --git a/src/core/SkStrikeCache.h b/src/core/SkStrikeCache.h
index dcec3de..7b60018 100644
--- a/src/core/SkStrikeCache.h
+++ b/src/core/SkStrikeCache.h
@@ -47,7 +47,7 @@
 
     class ExclusiveStrikePtr {
     public:
-        explicit ExclusiveStrikePtr(Node*);
+        explicit ExclusiveStrikePtr(Node*, SkStrikeCache*);
         ExclusiveStrikePtr();
         ExclusiveStrikePtr(const ExclusiveStrikePtr&) = delete;
         ExclusiveStrikePtr& operator = (const ExclusiveStrikePtr&) = delete;
@@ -65,18 +65,13 @@
 
     private:
         Node* fNode;
+        SkStrikeCache* fStrikeCache;
     };
 
     static SkStrikeCache* GlobalStrikeCache();
 
     static ExclusiveStrikePtr FindStrikeExclusive(const SkDescriptor&);
-
-    static bool DesperationSearchForImage(const SkDescriptor& desc,
-                                          SkGlyph* glyph,
-                                          SkGlyphCache* targetCache);
-
-    static bool DesperationSearchForPath(
-            const SkDescriptor& desc, SkGlyphID glyphID, SkPath* path);
+    ExclusiveStrikePtr findStrikeExclusive(const SkDescriptor&);
 
     static ExclusiveStrikePtr CreateStrikeExclusive(
             const SkDescriptor& desc,
@@ -84,11 +79,36 @@
             SkPaint::FontMetrics* maybeMetrics = nullptr,
             std::unique_ptr<SkStrikePinner> = nullptr);
 
+    ExclusiveStrikePtr createStrikeExclusive(
+            const SkDescriptor& desc,
+            std::unique_ptr<SkScalerContext> scaler,
+            SkPaint::FontMetrics* maybeMetrics = nullptr,
+            std::unique_ptr<SkStrikePinner> = nullptr);
+
     static ExclusiveStrikePtr FindOrCreateStrikeExclusive(
             const SkDescriptor& desc,
             const SkScalerContextEffects& effects,
             const SkTypeface& typeface);
 
+    ExclusiveStrikePtr findOrCreateStrikeExclusive(
+            const SkDescriptor& desc,
+            const SkScalerContextEffects& effects,
+            const SkTypeface& typeface);
+
+    // Routines to find suitable data when working in a remote cache situation. These are
+    // suitable as substitutes for similar calls in SkScalerContext.
+    static bool DesperationSearchForImage(const SkDescriptor& desc,
+                                          SkGlyph* glyph,
+                                          SkGlyphCache* targetCache);
+
+    bool desperationSearchForImage(const SkDescriptor& desc,
+                                   SkGlyph* glyph,
+                                   SkGlyphCache* targetCache);
+
+    static bool DesperationSearchForPath(
+            const SkDescriptor& desc, SkGlyphID glyphID, SkPath* path);
+    bool desperationSearchForPath(const SkDescriptor& desc, SkGlyphID glyphID, SkPath* path);
+
     static ExclusiveStrikePtr FindOrCreateStrikeExclusive(
             const SkPaint& paint,
             const SkSurfaceProps* surfaceProps,
@@ -110,14 +130,9 @@
 
     // call when a glyphcache is available for caching (i.e. not in use)
     void attachNode(Node* node);
-    ExclusiveStrikePtr findStrikeExclusive(const SkDescriptor&);
 
-    // Routines to find suitable data when working in a remote cache situation. These are
-    // suitable as substitutes for similar calls in SkScalerContext.
-    bool desperationSearchForImage(const SkDescriptor& desc,
-                                   SkGlyph* glyph,
-                                   SkGlyphCache* targetCache);
-    bool desperationSearchForPath(const SkDescriptor& desc, SkGlyphID glyphID, SkPath* path);
+
+
 
     void purgeAll(); // does not change budget
 
@@ -139,7 +154,6 @@
 #endif
 
 private:
-    static void Attach(Node* node);
 
     // The following methods can only be called when mutex is already held.
     Node* internalGetHead() const { return fHead; }