Reland "Redesign program key construction"

This is a reland of bbbf1a7f50a303bd76163793bd5968c72f5f4432

Original change's description:
> Redesign program key construction
>
> This does two things:
> 1) Moves responsibility for bit-packing portions of the key into the key
>    itself. A new GrKeyBuilder type manages adding bits, with asserts to
>    ensure a value always fits in the requested number. In theory this
>    will let us generate smaller keys overall, at the expense of slightly
>    more complex code during construction.
> 2) Adds a string label parameter for key methods that fold in data. For
>    new methods, the label is required. To ease migration, the old add32
>    does not require a label (yet). This will let us generate detailed,
>    human readable keys, either based on SK_DEBUG, or a runtime option
>    (if we're comfortable paying the cost).
>
> Bug: skia:11372
> Change-Id: Ib0f941551e0dbadabbd2a7de912b00e9e766b166
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/377876
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Brian Salomon <bsalomon@google.com>

Bug: skia:11372
Cq-Include-Trybots: luci.skia.skia.primary:Test-Win10-MSVC-Golo-GPU-QuadroP400-x86_64-Debug-All-Vulkan
Change-Id: I179ed581bc9ba772191e727274ac0ac6979ebdf3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/378778
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h
index 2ec0646..9bff731 100644
--- a/src/gpu/GrProcessor.h
+++ b/src/gpu/GrProcessor.h
@@ -13,6 +13,7 @@
 #include "src/gpu/GrColor.h"
 #include "src/gpu/GrGpuBuffer.h"
 #include "src/gpu/GrProcessorUnitTest.h"
+#include "src/gpu/GrProgramDesc.h"
 #include "src/gpu/GrSamplerState.h"
 #include "src/gpu/GrShaderVar.h"
 #include "src/gpu/GrSurfaceProxyPriv.h"
@@ -26,28 +27,36 @@
  */
 class GrProcessorKeyBuilder {
 public:
-    GrProcessorKeyBuilder(SkTArray<unsigned char, true>* data) : fData(data), fCount(0) {
-        SkASSERT(0 == fData->count() % sizeof(uint32_t));
+    GrProcessorKeyBuilder(GrKeyBuilder* key) : fKey(key) {
+        SkASSERT(0 == fKey->size() % sizeof(uint32_t));
     }
 
-    void add32(uint32_t v) {
-        ++fCount;
-        fData->push_back_n(4, reinterpret_cast<uint8_t*>(&v));
+    // Introduces a word-boundary in the underlying key. Must be called before using the key with
+    // any cache, but can be called elsewhere to create a clean break between generic data and
+    // backend-specific data.
+    void flush() { fKey->flush(); }
+
+    void addBits(uint32_t numBits, uint32_t val, const char* label) {
+        fKey->addBits(numBits, val, label);
     }
 
-    /** Inserts count uint32_ts into the key. The returned pointer is only valid until the next
-        add*() call. */
-    uint32_t* SK_WARN_UNUSED_RESULT add32n(int count) {
-        SkASSERT(count > 0);
-        fCount += count;
-        return reinterpret_cast<uint32_t*>(fData->push_back_n(4 * count));
+    void addBytes(uint32_t numBytes, const void* data, const char* label) {
+        fKey->addBytes(numBytes, data, label);
     }
 
-    size_t size() const { return sizeof(uint32_t) * fCount; }
+    void add32(uint32_t v, const char* label = "unknown") {
+        this->addBits(32, v, label);
+    }
+
+    template <typename StringFunc>
+    void addString(StringFunc&& sf) {
+        fKey->addString(std::move(sf));
+    }
+
+    size_t sizeInBits() const { return fKey->sizeInBits(); }
 
 private:
-    SkTArray<uint8_t, true>* fData; // unowned ptr to the larger key.
-    int fCount;                     // number of uint32_ts added to fData by the processor.
+    GrKeyBuilder* fKey;    // unowned ptr to the larger key.
 };
 
 /** Provides custom shader code to the Ganesh shading pipeline. GrProcessor objects *must* be