ccpr: Rework the path cache to support sporadic flushing

Removes the notion of a stashed atlas that we store from the previous
flush. Now we just cache every atlas we ever render. Cached atlases
can either be 16-bit or 8-bit.

The "reuse" and "animation" cases should both behave exactly the same
as before: Where before we would copy from the stashed atlas to 8-bit
atlases, we now copy from a cached 16-bit atlas and then invalidate
it. Where before we would recycle the stashed atlas's backing texture
object, we now recycle this same texture object from an invalidated
16-bit cached atlas.

The main difference is that cases like tiled rendering now work. If
you draw your whole scene in one flush, you still get one big 16-bit
cached atlas, just like the "stashed atlas" implementation. But if you
draw your scene in tiles, you now get lots of little cached 16-bit
atlases, which can be reused and eventually copied to 8-bit atlases.

Bug: skia:8462
Change-Id: Ibae65febb948230aaaf1f1361eef9c8f06ebef18
Reviewed-on: https://skia-review.googlesource.com/c/179991
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp
index a41eb38..4d147fd 100644
--- a/src/gpu/ccpr/GrCCAtlas.cpp
+++ b/src/gpu/ccpr/GrCCAtlas.cpp
@@ -16,6 +16,7 @@
 #include "GrTextureProxy.h"
 #include "SkMakeUnique.h"
 #include "SkMathPriv.h"
+#include "ccpr/GrCCPathCache.h"
 #include <atomic>
 
 class GrCCAtlas::Node {
@@ -47,8 +48,9 @@
     GrRectanizerSkyline fRectanizer;
 };
 
-GrCCAtlas::GrCCAtlas(GrPixelConfig pixelConfig, const Specs& specs, const GrCaps& caps)
-        : fMaxTextureSize(SkTMax(SkTMax(specs.fMinHeight, specs.fMinWidth),
+GrCCAtlas::GrCCAtlas(CoverageType coverageType, const Specs& specs, const GrCaps& caps)
+        : fCoverageType(coverageType)
+        , fMaxTextureSize(SkTMax(SkTMax(specs.fMinHeight, specs.fMinWidth),
                                  specs.fMaxPreferredTextureSize)) {
     // Caller should have cropped any paths to the destination render target instead of asking for
     // an atlas larger than maxRenderTargetSize.
@@ -73,12 +75,12 @@
 
     fTopNode = skstd::make_unique<Node>(nullptr, 0, 0, fWidth, fHeight);
 
-    // TODO: don't have this rely on the GrPixelConfig
-    GrSRGBEncoded srgbEncoded = GrSRGBEncoded::kNo;
-    GrColorType colorType = GrPixelConfigToColorTypeAndEncoding(pixelConfig, &srgbEncoded);
-
+    GrColorType colorType = (CoverageType::kFP16_CoverageCount == fCoverageType)
+            ? GrColorType::kAlpha_F16 : GrColorType::kAlpha_8;
     const GrBackendFormat format =
-            caps.getBackendFormatFromGrColorType(colorType, srgbEncoded);
+            caps.getBackendFormatFromGrColorType(colorType, GrSRGBEncoded::kNo);
+    GrPixelConfig pixelConfig = (CoverageType::kFP16_CoverageCount == fCoverageType)
+            ? kAlpha_half_GrPixelConfig : kAlpha_8_GrPixelConfig;
 
     fTextureProxy = GrProxyProvider::MakeFullyLazyProxy(
             [this, pixelConfig](GrResourceProvider* resourceProvider) {
@@ -159,27 +161,23 @@
     return nextID++;
 }
 
-const GrUniqueKey& GrCCAtlas::getOrAssignUniqueKey(GrOnFlushResourceProvider* onFlushRP) {
-    static const GrUniqueKey::Domain kAtlasDomain = GrUniqueKey::GenerateDomain();
+sk_sp<GrCCCachedAtlas> GrCCAtlas::refOrMakeCachedAtlas(GrOnFlushResourceProvider* onFlushRP) {
+    if (!fCachedAtlas) {
+        static const GrUniqueKey::Domain kAtlasDomain = GrUniqueKey::GenerateDomain();
 
-    if (!fUniqueKey.isValid()) {
-        GrUniqueKey::Builder builder(&fUniqueKey, kAtlasDomain, 1, "CCPR Atlas");
+        GrUniqueKey atlasUniqueKey;
+        GrUniqueKey::Builder builder(&atlasUniqueKey, kAtlasDomain, 1, "CCPR Atlas");
         builder[0] = next_atlas_unique_id();
         builder.finish();
 
-        if (fTextureProxy->isInstantiated()) {
-            onFlushRP->assignUniqueKeyToProxy(fUniqueKey, fTextureProxy.get());
-        }
-    }
-    return fUniqueKey;
-}
+        onFlushRP->assignUniqueKeyToProxy(atlasUniqueKey, fTextureProxy.get());
 
-sk_sp<GrCCAtlas::CachedAtlasInfo> GrCCAtlas::refOrMakeCachedAtlasInfo(uint32_t contextUniqueID) {
-    if (!fCachedAtlasInfo) {
-        fCachedAtlasInfo = sk_make_sp<CachedAtlasInfo>(contextUniqueID);
+        fCachedAtlas = sk_make_sp<GrCCCachedAtlas>(fCoverageType, atlasUniqueKey, fTextureProxy);
     }
-    SkASSERT(fCachedAtlasInfo->fContextUniqueID == contextUniqueID);
-    return fCachedAtlasInfo;
+
+    SkASSERT(fCachedAtlas->coverageType() == fCoverageType);
+    SkASSERT(fCachedAtlas->getOnFlushProxy() == fTextureProxy.get());
+    return fCachedAtlas;
 }
 
 sk_sp<GrRenderTargetContext> GrCCAtlas::makeRenderTargetContext(
@@ -205,10 +203,6 @@
         return nullptr;
     }
 
-    if (fUniqueKey.isValid()) {
-        onFlushRP->assignUniqueKeyToProxy(fUniqueKey, fTextureProxy.get());
-    }
-
     SkIRect clearRect = SkIRect::MakeSize(fDrawBounds);
     rtc->clear(&clearRect, SK_PMColor4fTRANSPARENT,
                GrRenderTargetContext::CanClearFullscreen::kYes);
@@ -220,7 +214,7 @@
     if (fAtlases.empty() || !fAtlases.back().addRect(devIBounds, devToAtlasOffset)) {
         // The retired atlas is out of room and can't grow any bigger.
         retiredAtlas = !fAtlases.empty() ? &fAtlases.back() : nullptr;
-        fAtlases.emplace_back(fPixelConfig, fSpecs, *fCaps);
+        fAtlases.emplace_back(fCoverageType, fSpecs, *fCaps);
         SkASSERT(devIBounds.width() <= fSpecs.fMinWidth);
         SkASSERT(devIBounds.height() <= fSpecs.fMinHeight);
         SkAssertResult(fAtlases.back().addRect(devIBounds, devToAtlasOffset));