Update how the GrSmallPathRenderer's cache entries are created and destroyed

The main thrust of this CL is to centralize creation and deletion
of the small path renderer's cache entries within the nascent
GrSmallPathAtlasMgr class.

It is pulled out of the omnibus CL:

https://skia-review.googlesource.com/c/skia/+/307776 (Split the small path renderer into record-time and flush-time pieces)

Change-Id: I13ccaca428e8c019540624dbcd0703540418f9a0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/308691
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrDrawOpAtlas.h b/src/gpu/GrDrawOpAtlas.h
index ead1ede..a6d1c4e 100644
--- a/src/gpu/GrDrawOpAtlas.h
+++ b/src/gpu/GrDrawOpAtlas.h
@@ -87,6 +87,12 @@
             return fGenID != 0 || fPlotIndex != 0 || fPageIndex != 0;
         }
 
+        void makeInvalid() {
+            fGenID = 0;
+            fPlotIndex = 0;
+            fPageIndex = 0;
+        }
+
         bool operator==(const PlotLocator& other) const {
             return fGenID == other.fGenID &&
                    fPlotIndex == other.fPlotIndex &&
@@ -108,6 +114,8 @@
     public:
         std::array<uint16_t, 4> getUVs() const;
 
+        void invalidatePlotLocator() { fPlotLocator.makeInvalid(); }
+
         // TODO: Remove the small path renderer's use of this for eviction
         PlotLocator plotLocator() const { return fPlotLocator; }
 
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index 10c1686..4487020 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -62,6 +62,33 @@
      atlas->setLastUseToken(shapeData->fAtlasLocator, token);
 }
 
+static GrSmallPathShapeData* FindOrCreate(GrDrawOpAtlas* atlas,
+                                          GrSmallPathRenderer::ShapeCache* shapeCache,
+                                          GrSmallPathRenderer::ShapeDataList* shapeList,
+                                          const GrSmallPathShapeDataKey& key) {
+    auto shapeData = shapeCache->find(key);
+    if (!shapeData) {
+        shapeData = new GrSmallPathShapeData(key);
+        shapeCache->add(shapeData);
+        shapeList->addToTail(shapeData);
+#ifdef DF_PATH_TRACKING
+        ++g_NumCachedPaths;
+#endif
+    } else if (!atlas->hasID(shapeData->fAtlasLocator.plotLocator())) {
+        shapeData->fAtlasLocator.invalidatePlotLocator();
+    }
+
+    return shapeData;
+}
+
+static void DeleteCacheEntry(GrSmallPathRenderer::ShapeCache* shapeCache,
+                             GrSmallPathRenderer::ShapeDataList* shapeList,
+                             GrSmallPathShapeData* shapeData) {
+    shapeCache->remove(shapeData->fKey);
+    shapeList->remove(shapeData);
+    delete shapeData;
+}
+
 }  // namespace GrSmallPathAtlasMgr
 
 // Callback to clear out internal path cache when eviction occurs
@@ -383,17 +410,10 @@
 
                 // check to see if df path is cached
                 GrSmallPathShapeDataKey key(args.fShape, SkScalarCeilToInt(desiredDimension));
-                shapeData = fShapeCache->find(key);
-                if (!shapeData || !fAtlas->hasID(shapeData->fAtlasLocator.plotLocator())) {
-                    // Remove the stale cache entry
-                    if (shapeData) {
-                        fShapeCache->remove(shapeData->fKey);
-                        fShapeList->remove(shapeData);
-                        delete shapeData;
-                    }
+                shapeData = GrSmallPathAtlasMgr::FindOrCreate(fAtlas, fShapeCache, fShapeList, key);
+                if (!shapeData->fAtlasLocator.plotLocator().isValid()) {
                     SkScalar scale = desiredDimension / maxDim;
 
-                    shapeData = new GrSmallPathShapeData;
                     if (!this->addDFPathToAtlas(target,
                                                 &flushInfo,
                                                 fAtlas,
@@ -401,30 +421,22 @@
                                                 args.fShape,
                                                 SkScalarCeilToInt(desiredDimension),
                                                 scale)) {
-                        delete shapeData;
+                        GrSmallPathAtlasMgr::DeleteCacheEntry(fShapeCache, fShapeList, shapeData);
                         continue;
                     }
                 }
             } else {
                 // check to see if bitmap path is cached
                 GrSmallPathShapeDataKey key(args.fShape, args.fViewMatrix);
-                shapeData = fShapeCache->find(key);
-                if (!shapeData || !fAtlas->hasID(shapeData->fAtlasLocator.plotLocator())) {
-                    // Remove the stale cache entry
-                    if (shapeData) {
-                        fShapeCache->remove(shapeData->fKey);
-                        fShapeList->remove(shapeData);
-                        delete shapeData;
-                    }
-
-                    shapeData = new GrSmallPathShapeData;
+                shapeData = GrSmallPathAtlasMgr::FindOrCreate(fAtlas, fShapeCache, fShapeList, key);
+                if (!shapeData->fAtlasLocator.plotLocator().isValid()) {
                     if (!this->addBMPathToAtlas(target,
                                                 &flushInfo,
                                                 fAtlas,
                                                 shapeData,
                                                 args.fShape,
                                                 args.fViewMatrix)) {
-                        delete shapeData;
+                        GrSmallPathAtlasMgr::DeleteCacheEntry(fShapeCache, fShapeList, shapeData);
                         continue;
                     }
                 }
@@ -554,21 +566,12 @@
 
         shapeData->fAtlasLocator.insetSrc(SK_DistanceFieldPad);
 
-        // add to cache
-        shapeData->fKey.set(shape, dimension);
-
         shapeData->fBounds = SkRect::Make(devPathBounds);
         shapeData->fBounds.offset(-translateX, -translateY);
         shapeData->fBounds.fLeft /= scale;
         shapeData->fBounds.fTop /= scale;
         shapeData->fBounds.fRight /= scale;
         shapeData->fBounds.fBottom /= scale;
-
-        fShapeCache->add(shapeData);
-        fShapeList->addToTail(shapeData);
-#ifdef DF_PATH_TRACKING
-        ++g_NumCachedPaths;
-#endif
         return true;
     }
 
@@ -639,17 +642,8 @@
             return false;
         }
 
-        // add to cache
-        shapeData->fKey.set(shape, ctm);
-
         shapeData->fBounds = SkRect::Make(devPathBounds);
         shapeData->fBounds.offset(-translateX, -translateY);
-
-        fShapeCache->add(shapeData);
-        fShapeList->addToTail(shapeData);
-#ifdef DF_PATH_TRACKING
-        ++g_NumCachedPaths;
-#endif
         return true;
     }
 
diff --git a/src/gpu/ops/GrSmallPathShapeData.h b/src/gpu/ops/GrSmallPathShapeData.h
index dca8a18..34628eb 100644
--- a/src/gpu/ops/GrSmallPathShapeData.h
+++ b/src/gpu/ops/GrSmallPathShapeData.h
@@ -82,9 +82,11 @@
 
 class GrSmallPathShapeData  {
 public:
-    GrSmallPathShapeDataKey     fKey;
-    SkRect                      fBounds;
-    GrDrawOpAtlas::AtlasLocator fAtlasLocator;
+    GrSmallPathShapeData(const GrSmallPathShapeDataKey &key) : fKey(key) {}
+
+    const GrSmallPathShapeDataKey fKey;
+    SkRect                        fBounds;
+    GrDrawOpAtlas::AtlasLocator   fAtlasLocator;
 
     SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrSmallPathShapeData);