Dump out path-mask generation and caching stats

These stats would've helped block https://skia-review.googlesource.com/c/skia/+/286902 (Add path bounds to SW path mask key) from landing.

Change-Id: I684f39de53fb2678c7a679e4e4aafdbb39a154ca
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/287499
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index fce2526..52b6e4b 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -683,6 +683,9 @@
     writer.appendName("gpu");
     this->fGpu->dumpJSON(&writer);
 
+    writer.appendName("context");
+    this->dumpJSON(&writer);
+
     // Flush JSON to the memory stream
     writer.endObject();
     writer.flush();
diff --git a/src/gpu/GrContextPriv.cpp b/src/gpu/GrContextPriv.cpp
index cc2fbea..0c6eb1d 100644
--- a/src/gpu/GrContextPriv.cpp
+++ b/src/gpu/GrContextPriv.cpp
@@ -80,13 +80,7 @@
 
 
 //////////////////////////////////////////////////////////////////////////////
-
 #if GR_TEST_UTILS
-void GrContextPriv::resetGpuStats() const {
-#if GR_GPU_STATS
-    fContext->fGpu->stats()->reset();
-#endif
-}
 
 void GrContextPriv::dumpCacheStats(SkString* out) const {
 #if GR_CACHE_STATS
@@ -107,6 +101,13 @@
     SkDebugf("%s", out.c_str());
 }
 
+/////////////////////////////////////////////////
+void GrContextPriv::resetGpuStats() const {
+#if GR_GPU_STATS
+    fContext->fGpu->stats()->reset();
+#endif
+}
+
 void GrContextPriv::dumpGpuStats(SkString* out) const {
 #if GR_GPU_STATS
     return fContext->fGpu->stats()->dump(out);
@@ -126,6 +127,33 @@
     SkDebugf("%s", out.c_str());
 }
 
+/////////////////////////////////////////////////
+void GrContextPriv::resetContextStats() const {
+#if GR_GPU_STATS
+    fContext->stats()->reset();
+#endif
+}
+
+void GrContextPriv::dumpContextStats(SkString* out) const {
+#if GR_GPU_STATS
+    return fContext->stats()->dump(out);
+#endif
+}
+
+void GrContextPriv::dumpContextStatsKeyValuePairs(SkTArray<SkString>* keys,
+                                                  SkTArray<double>* values) const {
+#if GR_GPU_STATS
+    return fContext->stats()->dumpKeyValuePairs(keys, values);
+#endif
+}
+
+void GrContextPriv::printContextStats() const {
+    SkString out;
+    this->dumpContextStats(&out);
+    SkDebugf("%s", out.c_str());
+}
+
+/////////////////////////////////////////////////
 void GrContextPriv::testingOnly_setTextBlobCacheLimit(size_t bytes) {
     fContext->priv().getTextBlobCache()->setBudget(bytes);
 }
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index 3d71d7e..8411059 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -136,7 +136,7 @@
 
 #if GR_TEST_UTILS
     /** Reset GPU stats */
-    void resetGpuStats() const ;
+    void resetGpuStats() const;
 
     /** Prints cache stats to the string if GR_CACHE_STATS == 1. */
     void dumpCacheStats(SkString*) const;
@@ -148,6 +148,12 @@
     void dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const;
     void printGpuStats() const;
 
+    /** These are only active if GR_GPU_STATS == 1. */
+    void resetContextStats() const;
+    void dumpContextStats(SkString*) const;
+    void dumpContextStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const;
+    void printContextStats() const;
+
     /** Specify the TextBlob cache limit. If the current cache exceeds this limit it will purge.
         this is for testing only */
     void testingOnly_setTextBlobCacheLimit(size_t bytes);
diff --git a/src/gpu/GrRecordingContext.cpp b/src/gpu/GrRecordingContext.cpp
index 5153461..2c7c64d 100644
--- a/src/gpu/GrRecordingContext.cpp
+++ b/src/gpu/GrRecordingContext.cpp
@@ -190,3 +190,43 @@
     return (GrContext*) fContext;
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_ENABLE_DUMP_GPU
+#include "src/utils/SkJSONWriter.h"
+
+void GrRecordingContext::dumpJSON(SkJSONWriter* writer) const {
+    writer->beginObject();
+
+#if GR_GPU_STATS
+    writer->appendS32("path_masks_generated", this->stats()->numPathMasksGenerated());
+    writer->appendS32("path_mask_cache_hits", this->stats()->numPathMaskCacheHits());
+#endif
+
+    writer->endObject();
+}
+#else
+void GrRecordingContext::dumpJSON(SkJSONWriter*) const { }
+#endif
+
+#if GR_TEST_UTILS
+
+#if GR_GPU_STATS
+
+void GrRecordingContext::Stats::dump(SkString* out) {
+    out->appendf("Num Path Masks Generated: %d\n", fNumPathMasksGenerated);
+    out->appendf("Num Path Mask Cache Hits: %d\n", fNumPathMaskCacheHits);
+}
+
+void GrRecordingContext::Stats::dumpKeyValuePairs(SkTArray<SkString>* keys,
+                                                  SkTArray<double>* values) {
+    keys->push_back(SkString("path_masks_generated"));
+    values->push_back(fNumPathMasksGenerated);
+
+    keys->push_back(SkString("path_mask_cache_hits"));
+    values->push_back(fNumPathMaskCacheHits);
+}
+
+#endif // GR_GPU_STATS
+#endif // GR_TEST_UTILS
+
diff --git a/src/gpu/GrRecordingContextPriv.h b/src/gpu/GrRecordingContextPriv.h
index 8a10563..4337d3f 100644
--- a/src/gpu/GrRecordingContextPriv.h
+++ b/src/gpu/GrRecordingContextPriv.h
@@ -98,6 +98,10 @@
         SkDebugf(msg);
     }
 
+    GrRecordingContext::Stats* stats() {
+        return &fContext->fStats;
+    }
+
 private:
     explicit GrRecordingContextPriv(GrRecordingContext* context) : fContext(context) {}
     GrRecordingContextPriv(const GrRecordingContextPriv&); // unimpl
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index 36994fc..20850f8 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -321,6 +321,7 @@
             GrSwizzle swizzle = args.fRenderTargetContext->caps()->getReadSwizzle(
                     proxy->backendFormat(), GrColorType::kAlpha_8);
             view = {std::move(proxy), kTopLeft_GrSurfaceOrigin, swizzle};
+            args.fContext->priv().stats()->incNumPathMasksCacheHits();
         }
     }
     if (!view) {
@@ -378,6 +379,8 @@
             fProxyProvider->assignUniqueKeyToProxy(maskKey, view.asTextureProxy());
             args.fShape->addGenIDChangeListener(std::move(listener));
         }
+
+        args.fContext->priv().stats()->incNumPathMasksGenerated();
     }
     SkASSERT(view);
     if (inverseFilled) {