Add a cap to allow coverage counting or not

We don't want to just disable the "ccpr" path renderer anymore (or
whatever it should be called), because we are adding an MSAA
implementation. This new cap will eventually tell ccpr whether it can
use coverage counting, or if it should just use the MSAA impl.

Bug: skia:
Change-Id: Ie6e5ca1a637ca4408bc6bb844153afa9da26f58e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/204883
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/include/gpu/GrContextOptions.h b/include/gpu/GrContextOptions.h
index 804efb7..3bfe6f3 100644
--- a/include/gpu/GrContextOptions.h
+++ b/include/gpu/GrContextOptions.h
@@ -78,9 +78,9 @@
     bool fDoManualMipmapping = false;
 
     /**
-     * Disables the coverage counting path renderer. Coverage counting can sometimes cause new
-     * rendering artifacts along shared edges if care isn't taken to ensure both contours wind in
-     * the same direction.
+     * Disables the use of coverage counting shortcuts to render paths. Coverage counting can cause
+     * artifacts along shared edges if care isn't taken to ensure both contours wind in the same
+     * direction.
      */
     // FIXME: Once this is removed from Chrome and Android, rename to fEnable"".
     bool fDisableCoverageCountingPaths = true;
@@ -219,7 +219,7 @@
     /**
      * Include or exclude specific GPU path renderers.
      */
-    GpuPathRenderers fGpuPathRenderers = GpuPathRenderers::kDefault;
+    GpuPathRenderers fGpuPathRenderers = GpuPathRenderers::kAll;
 #endif
 
 #if SK_SUPPORT_ATLAS_TEXT
diff --git a/infra/bots/recipes/skpbench.expected/Perf-Android-Clang-Pixel-GPU-Adreno530-arm64-Release-All-Android_CCPR_Skpbench.json b/infra/bots/recipes/skpbench.expected/Perf-Android-Clang-Pixel-GPU-Adreno530-arm64-Release-All-Android_CCPR_Skpbench.json
index 6d7641c..c302564 100644
--- a/infra/bots/recipes/skpbench.expected/Perf-Android-Clang-Pixel-GPU-Adreno530-arm64-Release-All-Android_CCPR_Skpbench.json
+++ b/infra/bots/recipes/skpbench.expected/Perf-Android-Clang-Pixel-GPU-Adreno530-arm64-Release-All-Android_CCPR_Skpbench.json
@@ -236,6 +236,7 @@
       "adb.1.0.35",
       "--pr",
       "ccpr",
+      "--cc",
       "--nocache",
       "/sdcard/revenge_of_the_skiabot/skps/desk_*svg.skp",
       "/sdcard/revenge_of_the_skiabot/skps/desk_chalkboard.skp"
diff --git a/infra/bots/recipes/skpbench.py b/infra/bots/recipes/skpbench.py
index c0c54bd..09e4bac 100644
--- a/infra/bots/recipes/skpbench.py
+++ b/infra/bots/recipes/skpbench.py
@@ -77,8 +77,7 @@
         '--adb_binary', ADB_BINARY]
   if 'CCPR' in api.vars.builder_name:
     skpbench_args += [
-        '--pr', 'ccpr',
-        '--nocache',
+        '--pr', 'ccpr', '--cc', '--nocache',
         api.path.join(api.flavor.device_dirs.skp_dir, 'desk_*svg.skp'),
         api.path.join(api.flavor.device_dirs.skp_dir, 'desk_chalkboard.skp')]
   else:
diff --git a/infra/bots/recipes/test.expected/Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-All-Android_CCPR.json b/infra/bots/recipes/test.expected/Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-All-Android_CCPR.json
index dfeeacd..aaf582a 100644
--- a/infra/bots/recipes/test.expected/Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-All-Android_CCPR.json
+++ b/infra/bots/recipes/test.expected/Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-All-Android_CCPR.json
@@ -677,7 +677,7 @@
       "--json-output",
       "/path/to/tmp/json",
       "copy",
-      "set -x; /data/local/tmp/dm --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 builder Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-All-Android_CCPR buildbucket_build_id 123454321 task_id task_12345 swarming_bot_id skia-bot-123 swarming_task_id 123456 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm64 compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value TegraX1 extra_config Android_CCPR model NVIDIA_Shield os Android style default --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --dont_write pdf --nocpu --pr ccpr --cachePathMasks false --config gl --src tests gm image colorImage svg --blacklist _ svg _ svgparse_ _ image gen_platf error _ test _ GrShape _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW --nonativeFonts --verbose; echo $? >/data/local/tmp/rc",
+      "set -x; /data/local/tmp/dm --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 builder Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-All-Android_CCPR buildbucket_build_id 123454321 task_id task_12345 swarming_bot_id skia-bot-123 swarming_task_id 123456 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm64 compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value TegraX1 extra_config Android_CCPR model NVIDIA_Shield os Android style default --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --dont_write pdf --nocpu --pr ccpr --cc true --cachePathMasks false --config gl --src tests gm image colorImage svg --blacklist _ svg _ svgparse_ _ image gen_platf error _ test _ GrShape _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW --nonativeFonts --verbose; echo $? >/data/local/tmp/rc",
       "[START_DIR]/tmp/dm.sh"
     ],
     "env": {
diff --git a/infra/bots/recipes/test.py b/infra/bots/recipes/test.py
index 3436dbc..beb4528 100644
--- a/infra/bots/recipes/test.py
+++ b/infra/bots/recipes/test.py
@@ -253,7 +253,7 @@
     # Test coverage counting path renderer.
     if 'CCPR' in bot:
       configs = [c for c in configs if c == 'gl' or c == 'gles']
-      args.extend(['--pr', 'ccpr', '--cachePathMasks', 'false'])
+      args.extend(['--pr', 'ccpr', '--cc', 'true', '--cachePathMasks', 'false'])
 
     # DDL is a GPU-only feature
     if 'DDL1' in bot:
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index f07f907..7b576a7 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -42,6 +42,8 @@
     fPerformPartialClearsAsDraws = false;
     fPerformColorClearsAsDraws = false;
     fPerformStencilClearsAsDraws = false;
+    fAllowCoverageCounting = false;
+    fDriverBlacklistCCPR = false;
 
     fBlendEquationSupport = kBasic_BlendEquationSupport;
     fAdvBlendEqBlacklist = 0;
@@ -69,7 +71,6 @@
     fWireframeMode = false;
 #endif
     fBufferMapThreshold = options.fBufferMapThreshold;
-    fBlacklistCoverageCounting = false;
     fAvoidStencilBuffers = false;
     fAvoidWritePixelsFastPath = false;
 
@@ -86,9 +87,7 @@
 void GrCaps::applyOptionsOverrides(const GrContextOptions& options) {
     this->onApplyOptionsOverrides(options);
     if (options.fDisableDriverCorrectnessWorkarounds) {
-        // We always blacklist coverage counting on Vulkan currently. TODO: Either stop doing that
-        // or disambiguate blacklisting from incomplete implementation.
-        // SkASSERT(!fBlacklistCoverageCounting);
+        SkASSERT(!fDriverBlacklistCCPR);
         SkASSERT(!fAvoidStencilBuffers);
         SkASSERT(!fAdvBlendEqBlacklist);
         SkASSERT(!fPerformColorClearsAsDraws);
@@ -104,6 +103,8 @@
         fPerformStencilClearsAsDraws = true;
     }
 
+    fAllowCoverageCounting = !options.fDisableCoverageCountingPaths;
+
     fMaxTextureSize = SkTMin(fMaxTextureSize, options.fMaxTextureSizeOverride);
     fMaxTileSize = fMaxTextureSize;
 #if GR_TEST_UTILS
@@ -209,10 +210,10 @@
     writer->appendBool("Use draws for partial clears", fPerformPartialClearsAsDraws);
     writer->appendBool("Use draws for color clears", fPerformColorClearsAsDraws);
     writer->appendBool("Use draws for stencil clip clears", fPerformStencilClearsAsDraws);
+    writer->appendBool("Allow coverage counting shortcuts", fAllowCoverageCounting);
+    writer->appendBool("Blacklist CCPR on current driver [workaround]", fDriverBlacklistCCPR);
     writer->appendBool("Clamp-to-border", fClampToBorderSupport);
 
-    writer->appendBool("Blacklist Coverage Counting Path Renderer [workaround]",
-                       fBlacklistCoverageCounting);
     writer->appendBool("Prefer VRAM Use over flushes [workaround]", fPreferVRAMUseOverFlushes);
     writer->appendBool("Prefer more triangles over sample mask [MSAA only]",
                        fPreferTrianglesOverSampleMask);
diff --git a/src/gpu/GrCaps.h b/src/gpu/GrCaps.h
index b7f7731..1348bed 100644
--- a/src/gpu/GrCaps.h
+++ b/src/gpu/GrCaps.h
@@ -75,8 +75,6 @@
 
     bool preferTrianglesOverSampleMask() const { return fPreferTrianglesOverSampleMask; }
 
-    bool blacklistCoverageCounting() const { return fBlacklistCoverageCounting; }
-
     bool avoidStencilBuffers() const { return fAvoidStencilBuffers; }
 
     bool avoidWritePixelsFastPath() const { return fAvoidWritePixelsFastPath; }
@@ -267,16 +265,19 @@
     }
 
     // Many drivers have issues with color clears.
-    bool performColorClearsAsDraws() const {
-        return fPerformColorClearsAsDraws;
-    }
+    bool performColorClearsAsDraws() const { return fPerformColorClearsAsDraws; }
 
     /// Adreno 4xx devices experience an issue when there are a large number of stencil clip bit
     /// clears. The minimal repro steps are not precisely known but drawing a rect with a stencil
     /// op instead of using glClear seems to resolve the issue.
-    bool performStencilClearsAsDraws() const {
-        return fPerformStencilClearsAsDraws;
-    }
+    bool performStencilClearsAsDraws() const { return fPerformStencilClearsAsDraws; }
+
+    // Can we use coverage counting shortcuts to render paths? Coverage counting can cause artifacts
+    // along shared edges if care isn't taken to ensure both contours wind in the same direction.
+    bool allowCoverageCounting() const { return fAllowCoverageCounting; }
+
+    // Should we disable the CCPR code due to a faulty driver?
+    bool driverBlacklistCCPR() const { return fDriverBlacklistCCPR; }
 
     /**
      * This is can be called before allocating a texture to be a dst for copySurface. This is only
@@ -359,9 +360,10 @@
     bool fPerformPartialClearsAsDraws                : 1;
     bool fPerformColorClearsAsDraws                  : 1;
     bool fPerformStencilClearsAsDraws                : 1;
+    bool fAllowCoverageCounting                      : 1;
 
     // Driver workaround
-    bool fBlacklistCoverageCounting                  : 1;
+    bool fDriverBlacklistCCPR                        : 1;
     bool fAvoidStencilBuffers                        : 1;
     bool fAvoidWritePixelsFastPath                   : 1;
 
diff --git a/src/gpu/GrPathRendererChain.h b/src/gpu/GrPathRendererChain.h
index 473d4e6..3542ec4 100644
--- a/src/gpu/GrPathRendererChain.h
+++ b/src/gpu/GrPathRendererChain.h
@@ -28,7 +28,7 @@
 public:
     struct Options {
         bool fAllowPathMaskCaching = false;
-        GpuPathRenderers fGpuPathRenderers = GpuPathRenderers::kDefault;
+        GpuPathRenderers fGpuPathRenderers = GpuPathRenderers::kAll;
     };
     GrPathRendererChain(GrRecordingContext* context, const Options&);
 
diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
index 484bd08..c31af4f 100644
--- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
+++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
@@ -20,14 +20,17 @@
 
 bool GrCoverageCountingPathRenderer::IsSupported(const GrCaps& caps) {
     const GrShaderCaps& shaderCaps = *caps.shaderCaps();
-    return caps.instanceAttribSupport() && shaderCaps.integerSupport() &&
-           shaderCaps.floatIs32Bits() && GrCaps::kNone_MapFlags != caps.mapBufferFlags() &&
-           caps.isConfigTexturable(kAlpha_half_GrPixelConfig) &&
-           caps.isConfigRenderable(kAlpha_half_GrPixelConfig) &&
-           caps.isConfigTexturable(kAlpha_8_GrPixelConfig) &&
-           caps.isConfigRenderable(kAlpha_8_GrPixelConfig) &&
-           caps.halfFloatVertexAttributeSupport() &&
-           !caps.blacklistCoverageCounting();
+    if (caps.driverBlacklistCCPR() || !caps.allowCoverageCounting() ||
+        !shaderCaps.integerSupport() || !caps.instanceAttribSupport() ||
+        !shaderCaps.floatIs32Bits() || GrCaps::kNone_MapFlags == caps.mapBufferFlags() ||
+        !caps.isConfigTexturable(kAlpha_half_GrPixelConfig) ||
+        !caps.isConfigRenderable(kAlpha_half_GrPixelConfig) ||
+        !caps.isConfigTexturable(kAlpha_8_GrPixelConfig) ||
+        !caps.isConfigRenderable(kAlpha_8_GrPixelConfig) ||
+        !caps.halfFloatVertexAttributeSupport()) {
+        return false;
+    }
+    return true;
 }
 
 sk_sp<GrCoverageCountingPathRenderer> GrCoverageCountingPathRenderer::CreateIfSupported(
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index b7bf16e..553332c 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2967,7 +2967,7 @@
     if (kMesa_GrGLDriver == ctxInfo.driver() &&
         (kIntelSandyBridge_GrGLRenderer == ctxInfo.renderer() ||
          kIntelBayTrail_GrGLRenderer == ctxInfo.renderer())) {
-        fBlacklistCoverageCounting = true;
+        fDriverBlacklistCCPR = true;
     }
 
 #ifdef SK_BUILD_FOR_ANDROID
diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm
index 41094cb..17656d0 100644
--- a/src/gpu/mtl/GrMtlCaps.mm
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -31,7 +31,6 @@
 
     // The following are disabled due to the unfinished Metal backend, not because Metal itself
     // doesn't support it.
-    fBlacklistCoverageCounting = true;   // CCPR shaders have some incompatabilities with SkSLC
     fFenceSyncSupport = false;           // Fences are not implemented yet
     fMipMapSupport = false;              // GrMtlGpu::onRegenerateMipMapLevels() not implemented
     fMultisampleDisableSupport = true;   // MSAA and resolving not implemented yet
diff --git a/tools/flags/CommonFlagsGpu.cpp b/tools/flags/CommonFlagsGpu.cpp
index 3c5393a..5a90789 100644
--- a/tools/flags/CommonFlagsGpu.cpp
+++ b/tools/flags/CommonFlagsGpu.cpp
@@ -20,6 +20,8 @@
 
 static DEFINE_bool(noGS, false, "Disables support for geometry shaders.");
 
+static DEFINE_bool(cc, false, "Allow coverage counting shortcuts to render paths?");
+
 static DEFINE_string(pr, "",
               "Set of enabled gpu path renderers. Defined as a list of: "
               "[~]none [~]dashline [~]nvpr [~]ccpr [~]aahairline [~]aaconvex [~]aalinearizing "
@@ -59,11 +61,12 @@
 
 static GpuPathRenderers collect_gpu_path_renderers_from_flags() {
     if (FLAGS_pr.isEmpty()) {
-        return GpuPathRenderers::kDefault;
+        return GpuPathRenderers::kAll;
     }
+
     GpuPathRenderers gpuPathRenderers = ('~' == FLAGS_pr[0][0])
-        ? GpuPathRenderers::kDefault
-        : GpuPathRenderers::kNone;
+            ? GpuPathRenderers::kAll
+            : GpuPathRenderers::kNone;
 
     for (int i = 0; i < FLAGS_pr.count(); ++i) {
         const char* name = FLAGS_pr[i];
@@ -82,6 +85,7 @@
         : nullptr;
 
     ctxOptions->fExecutor                            = gGpuExecutor.get();
+    ctxOptions->fDisableCoverageCountingPaths        = !FLAGS_cc;
     ctxOptions->fAllowPathMaskCaching                = FLAGS_cachePathMasks;
     ctxOptions->fSuppressGeometryShaders             = FLAGS_noGS;
     ctxOptions->fGpuPathRenderers                    = collect_gpu_path_renderers_from_flags();
diff --git a/tools/skpbench/skpbench.py b/tools/skpbench/skpbench.py
index 9d111f0..df26232 100755
--- a/tools/skpbench/skpbench.py
+++ b/tools/skpbench/skpbench.py
@@ -60,6 +60,8 @@
   help="comma- or space-separated list of GPU path renderers, including: "
        "[[~]all [~]default [~]dashline [~]nvpr [~]msaa [~]aaconvex "
        "[~]aalinearizing [~]small [~]tess]")
+__argparse.add_argument('--cc',
+  action='store_true', help="allow coverage counting shortcuts to render paths")
 __argparse.add_argument('--nocache',
   action='store_true', help="disable caching of path mask textures")
 __argparse.add_argument('-c', '--config',
@@ -131,6 +133,8 @@
     ARGV.extend(['--fps', 'true'])
   if FLAGS.pr:
     ARGV.extend(['--pr'] + re.split(r'[ ,]', FLAGS.pr))
+  if FLAGS.cc:
+    ARGV.extend(['--cc', 'true'])
   if FLAGS.nocache:
     ARGV.extend(['--cachePathMasks', 'false'])
   if FLAGS.gpuThreads != -1:
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index 3350cd4..3a610ac 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -245,7 +245,6 @@
 {
     SkGraphics::Init();
 
-    gPathRendererNames[GpuPathRenderers::kDefault] = "Default Path Renderers";
     gPathRendererNames[GpuPathRenderers::kAll] = "All Path Renderers";
     gPathRendererNames[GpuPathRenderers::kStencilAndCover] = "NV_path_rendering";
     gPathRendererNames[GpuPathRenderers::kSmall] = "Small paths (cached sdf or alpha masks)";
@@ -883,7 +882,7 @@
     title.append("]");
 
     GpuPathRenderers pr = fWindow->getRequestedDisplayParams().fGrContextOptions.fGpuPathRenderers;
-    if (GpuPathRenderers::kDefault != pr) {
+    if (GpuPathRenderers::kAll != pr) {
         title.appendf(" [Path renderer: %s]", gPathRendererNames[pr].c_str());
     }
 
@@ -1577,7 +1576,6 @@
                     if (!ctx) {
                         ImGui::RadioButton("Software", true);
                     } else if (fWindow->sampleCount() > 1) {
-                        prButton(GpuPathRenderers::kDefault);
                         prButton(GpuPathRenderers::kAll);
                         if (ctx->priv().caps()->shaderCaps()->pathRenderingSupport()) {
                             prButton(GpuPathRenderers::kStencilAndCover);
@@ -1585,7 +1583,6 @@
                         prButton(GpuPathRenderers::kTessellating);
                         prButton(GpuPathRenderers::kNone);
                     } else {
-                        prButton(GpuPathRenderers::kDefault);
                         prButton(GpuPathRenderers::kAll);
                         if (GrCoverageCountingPathRenderer::IsSupported(
                                     *ctx->priv().caps())) {
@@ -2100,7 +2097,6 @@
             } else {
                 const auto* caps = ctx->priv().caps();
 
-                writer.appendString(gPathRendererNames[GpuPathRenderers::kDefault].c_str());
                 writer.appendString(gPathRendererNames[GpuPathRenderers::kAll].c_str());
                 if (fWindow->sampleCount() > 1) {
                     if (caps->shaderCaps()->pathRenderingSupport()) {