ccpr: Add an MSAA atlas mode

Adds the option to use a multisampled (or mixed sampled) atlas, and
uses the sample mask and stencil buffer instead of coverage counts.

Bug: skia:
Change-Id: I9fb76d17895ae25208124f6c27e37977ac31b5eb
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/227428
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp
index 3a5eca3..0b2332e 100644
--- a/src/gpu/ccpr/GrCCAtlas.cpp
+++ b/src/gpu/ccpr/GrCCAtlas.cpp
@@ -7,6 +7,7 @@
 
 #include "src/gpu/ccpr/GrCCAtlas.h"
 
+#include "include/gpu/GrRenderTarget.h"
 #include "include/gpu/GrTexture.h"
 #include "src/core/SkIPoint16.h"
 #include "src/core/SkMakeUnique.h"
@@ -49,6 +50,42 @@
     GrRectanizerSkyline fRectanizer;
 };
 
+sk_sp<GrTextureProxy> GrCCAtlas::MakeLazyAtlasProxy(
+        const LazyInstantiateAtlasCallback& callback, CoverageType coverageType, const GrCaps& caps) {
+    GrColorType colorType;
+    GrPixelConfig pixelConfig;
+    int sampleCount;
+
+    switch (coverageType) {
+        case CoverageType::kFP16_CoverageCount:
+            colorType = GrColorType::kAlpha_F16;
+            pixelConfig = kAlpha_half_GrPixelConfig;
+            sampleCount = 1;
+            break;
+        case CoverageType::kA8_Multisample:
+            SkASSERT(caps.internalMultisampleCount(kAlpha_8_GrPixelConfig) > 1);
+            colorType = GrColorType::kAlpha_8;
+            pixelConfig = kAlpha_8_GrPixelConfig;
+            sampleCount = (caps.mixedSamplesSupport())
+                    ? 1 : caps.internalMultisampleCount(pixelConfig);
+            break;
+        case CoverageType::kA8_LiteralCoverage:
+            colorType = GrColorType::kAlpha_8;
+            pixelConfig = kAlpha_8_GrPixelConfig;
+            sampleCount = 1;
+            break;
+    }
+
+    const GrBackendFormat format = caps.getBackendFormatFromColorType(colorType);
+
+    sk_sp<GrTextureProxy> proxy = GrProxyProvider::MakeFullyLazyProxy(
+            std::bind(callback, std::placeholders::_1, pixelConfig, sampleCount),
+            format, GrProxyProvider::Renderable::kYes, GrProtected::kNo, kTextureOrigin,
+            pixelConfig, caps, sampleCount);
+
+    return proxy;
+}
+
 GrCCAtlas::GrCCAtlas(CoverageType coverageType, const Specs& specs, const GrCaps& caps)
         : fCoverageType(coverageType)
         , fMaxTextureSize(SkTMax(SkTMax(specs.fMinHeight, specs.fMinWidth),
@@ -76,27 +113,20 @@
 
     fTopNode = skstd::make_unique<Node>(nullptr, 0, 0, fWidth, fHeight);
 
-    GrColorType colorType = (CoverageType::kFP16_CoverageCount == fCoverageType)
-            ? GrColorType::kAlpha_F16 : GrColorType::kAlpha_8;
-    const GrBackendFormat format = caps.getBackendFormatFromColorType(colorType);
-    GrPixelConfig pixelConfig = (CoverageType::kFP16_CoverageCount == fCoverageType)
-            ? kAlpha_half_GrPixelConfig : kAlpha_8_GrPixelConfig;
-
-    fTextureProxy = GrProxyProvider::MakeFullyLazyProxy(
-            [this, pixelConfig](GrResourceProvider* resourceProvider) {
-                if (!fBackingTexture) {
-                    GrSurfaceDesc desc;
-                    desc.fWidth = fWidth;
-                    desc.fHeight = fHeight;
-                    desc.fConfig = pixelConfig;
-                    fBackingTexture = resourceProvider->createTexture(
-                            desc, GrRenderable::kYes, SkBudgeted::kYes, GrProtected::kNo,
-                            GrResourceProvider::Flags::kNoPendingIO);
-                }
-                return GrSurfaceProxy::LazyInstantiationResult(fBackingTexture);
-            },
-            format, GrProxyProvider::Renderable::kYes, GrProtected::kNo, kTextureOrigin,
-            pixelConfig, caps);
+    fTextureProxy = MakeLazyAtlasProxy([this](
+            GrResourceProvider* resourceProvider, GrPixelConfig pixelConfig, int sampleCount) {
+        if (!fBackingTexture) {
+            GrSurfaceDesc desc;
+            desc.fWidth = fWidth;
+            desc.fHeight = fHeight;
+            desc.fConfig = pixelConfig;
+            desc.fSampleCnt = sampleCount;
+            fBackingTexture = resourceProvider->createTexture(
+                    desc, GrRenderable::kYes, SkBudgeted::kYes, GrProtected::kNo,
+                    GrResourceProvider::Flags::kNoPendingIO);
+        }
+        return fBackingTexture;
+    }, fCoverageType, caps);
 
     fTextureProxy->priv().setIgnoredByResourceAllocator();
 }
@@ -157,6 +187,12 @@
     fStrokeBatchID = id;
 }
 
+void GrCCAtlas::setEndStencilResolveInstance(int idx) {
+    // This can't be called anymore once makeRenderTargetContext() has been called.
+    SkASSERT(!fTextureProxy->isInstantiated());
+    fEndStencilResolveInstance = idx;
+}
+
 static uint32_t next_atlas_unique_id() {
     static std::atomic<uint32_t> nextID;
     return nextID++;
@@ -194,13 +230,18 @@
     fTextureProxy->priv().setLazySize(fDrawBounds.width(), fDrawBounds.height());
 
     if (backingTexture) {
-        SkASSERT(backingTexture->config() == kAlpha_half_GrPixelConfig);
-        SkASSERT(backingTexture->width() == fWidth);
-        SkASSERT(backingTexture->height() == fHeight);
+#ifdef SK_DEBUG
+        auto backingRT = backingTexture->asRenderTarget();
+        SkASSERT(backingRT);
+        SkASSERT(backingRT->config() == fTextureProxy->config());
+        SkASSERT(backingRT->numSamples() == fTextureProxy->asRenderTargetProxy()->numSamples());
+        SkASSERT(backingRT->width() == fWidth);
+        SkASSERT(backingRT->height() == fHeight);
+#endif
         fBackingTexture = std::move(backingTexture);
     }
-    auto colorType = (CoverageType::kFP16_CoverageCount == fCoverageType) ? GrColorType::kAlpha_F16
-                                                                          : GrColorType::kAlpha_8;
+    auto colorType = (CoverageType::kFP16_CoverageCount == fCoverageType)
+            ? GrColorType::kAlpha_F16 : GrColorType::kAlpha_8;
     sk_sp<GrRenderTargetContext> rtc =
             onFlushRP->makeRenderTargetContext(fTextureProxy, colorType, nullptr, nullptr);
     if (!rtc) {