Use mixed samples internally for default coverage AA

Lays the infrastructure to use mixed samples internally, and begins
using nvpr with mixed samples on the default "gl" and "gles" configs.

In this rendition, we take the simplest approach possible re: stencil
attachments. We initially create a render target without stencil
(i.e., 0 samples). Then, any time a proxy needs a stencil buffer with
more samples than its target currently has, we create and attach a new
stencil buffer. However, we never "downgrade" a render target's
stencil attachment to one with fewer samples. So if the proxy only
needs one sample and the target has many, we leave it.

Bug: skia:
Change-Id: I8558ba799ac3dee457f349f77d4517c11413c9a9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/224456
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrResourceAllocator.cpp b/src/gpu/GrResourceAllocator.cpp
index 4c83509..f73f5be 100644
--- a/src/gpu/GrResourceAllocator.cpp
+++ b/src/gpu/GrResourceAllocator.cpp
@@ -75,17 +75,19 @@
                                       ActualUse actualUse
                                       SkDEBUGCODE(, bool isDirectDstRead)) {
 
-    bool needsStencil = proxy->asRenderTargetProxy()
-                                        ? proxy->asRenderTargetProxy()->needsStencil()
-                                        : false;
-
     if (proxy->canSkipResourceAllocator()) {
-        if (needsStencil && proxy->isInstantiated()) {
-            // If the proxy is still not instantiated at this point but will need stencil, it will
-            // attach its own stencil buffer upon onFlush instantiation.
-            if (!GrSurfaceProxyPriv::AttachStencilIfNeeded(
-                    fResourceProvider, proxy->peekSurface(), true /*needsStencil*/)) {
-                SkDebugf("WARNING: failed to attach stencil buffer. Rendering may be incorrect.\n");
+        // If the proxy is still not instantiated at this point but will need stencil, it will
+        // attach its own stencil buffer upon onFlush instantiation.
+        if (proxy->isInstantiated()) {
+            int minStencilSampleCount = (proxy->asRenderTargetProxy())
+                    ? proxy->asRenderTargetProxy()->numStencilSamples()
+                    : 0;
+            if (minStencilSampleCount) {
+                if (!GrSurfaceProxyPriv::AttachStencilIfNeeded(
+                        fResourceProvider, proxy->peekSurface(), minStencilSampleCount)) {
+                    SkDebugf("WARNING: failed to attach stencil buffer. "
+                             "Rendering may be incorrect.\n");
+                }
             }
         }
         return;
@@ -283,7 +285,7 @@
 // First try to reuse one of the recently allocated/used GrSurfaces in the free pool.
 // If we can't find a useable one, create a new one.
 sk_sp<GrSurface> GrResourceAllocator::findSurfaceFor(const GrSurfaceProxy* proxy,
-                                                     bool needsStencil) {
+                                                     int minStencilSampleCount) {
 
     if (proxy->asTextureProxy() && proxy->asTextureProxy()->getUniqueKey().isValid()) {
         // First try to reattach to a cached version if the proxy is uniquely keyed
@@ -291,7 +293,7 @@
                                                         proxy->asTextureProxy()->getUniqueKey());
         if (surface) {
             if (!GrSurfaceProxyPriv::AttachStencilIfNeeded(fResourceProvider, surface.get(),
-                                                           needsStencil)) {
+                                                           minStencilSampleCount)) {
                 return nullptr;
             }
 
@@ -317,7 +319,7 @@
         }
 
         if (!GrSurfaceProxyPriv::AttachStencilIfNeeded(fResourceProvider, surface.get(),
-                                                       needsStencil)) {
+                                                       minStencilSampleCount)) {
             return nullptr;
         }
         SkASSERT(!surface->getUniqueKey().isValid());
@@ -422,13 +424,13 @@
 
         this->expire(cur->start());
 
-        bool needsStencil = cur->proxy()->asRenderTargetProxy()
-                                            ? cur->proxy()->asRenderTargetProxy()->needsStencil()
-                                            : false;
+        int minStencilSampleCount = (cur->proxy()->asRenderTargetProxy())
+                ? cur->proxy()->asRenderTargetProxy()->numStencilSamples()
+                : 0;
 
         if (cur->proxy()->isInstantiated()) {
             if (!GrSurfaceProxyPriv::AttachStencilIfNeeded(
-                        fResourceProvider, cur->proxy()->peekSurface(), needsStencil)) {
+                        fResourceProvider, cur->proxy()->peekSurface(), minStencilSampleCount)) {
                 *outError = AssignError::kFailedProxyInstantiation;
             }
 
@@ -454,7 +456,8 @@
                     fDeinstantiateTracker->addProxy(cur->proxy());
                 }
             }
-        } else if (sk_sp<GrSurface> surface = this->findSurfaceFor(cur->proxy(), needsStencil)) {
+        } else if (sk_sp<GrSurface> surface = this->findSurfaceFor(
+                cur->proxy(), minStencilSampleCount)) {
             // TODO: make getUniqueKey virtual on GrSurfaceProxy
             GrTextureProxy* texProxy = cur->proxy()->asTextureProxy();