Emit new style key information in generated effects

All layout(key) fields include the field name meta-data, and use as few
bits as possible.

Bug: skia:11372
Change-Id: Ie12b3e0d01148457e5ea078cbf7d0a4bff35302e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/378596
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/include/private/GrSharedEnums.h b/include/private/GrSharedEnums.h
index cdb0f80..df73cc0 100644
--- a/include/private/GrSharedEnums.h
+++ b/include/private/GrSharedEnums.h
@@ -29,7 +29,8 @@
 enum class PMConversion {
     kToPremul        = 0,
     kToUnpremul      = 1,
-    kPMConversionCnt = 2
+
+    kLast = kToUnpremul
 };
 
 #endif
diff --git a/src/gpu/effects/GrConfigConversionEffect.fp b/src/gpu/effects/GrConfigConversionEffect.fp
index dcce447..b22b67f 100644
--- a/src/gpu/effects/GrConfigConversionEffect.fp
+++ b/src/gpu/effects/GrConfigConversionEffect.fp
@@ -148,7 +148,7 @@
 
 @test(data) {
     PMConversion pmConv = static_cast<PMConversion>(
-            data->fRandom->nextULessThan((int)PMConversion::kPMConversionCnt));
+            data->fRandom->nextRangeU(0, (int)PMConversion::kLast));
     return std::unique_ptr<GrFragmentProcessor>(
             new GrConfigConversionEffect(GrProcessorUnitTest::MakeChildFP(data), pmConv));
 }
diff --git a/src/gpu/effects/generated/GrAARectEffect.cpp b/src/gpu/effects/generated/GrAARectEffect.cpp
index 3e34f1f..bc4fcef 100644
--- a/src/gpu/effects/generated/GrAARectEffect.cpp
+++ b/src/gpu/effects/generated/GrAARectEffect.cpp
@@ -89,7 +89,7 @@
 }
 void GrAARectEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                            GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t)edgeType);
+    b->addBits(2, (uint32_t)edgeType, "edgeType");
 }
 bool GrAARectEffect::onIsEqual(const GrFragmentProcessor& other) const {
     const GrAARectEffect& that = other.cast<GrAARectEffect>();
diff --git a/src/gpu/effects/generated/GrArithmeticProcessor.cpp b/src/gpu/effects/generated/GrArithmeticProcessor.cpp
index 0b5d73e..2b97d2d 100644
--- a/src/gpu/effects/generated/GrArithmeticProcessor.cpp
+++ b/src/gpu/effects/generated/GrArithmeticProcessor.cpp
@@ -63,7 +63,7 @@
 }
 void GrArithmeticProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                   GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t)enforcePMColor);
+    b->addBits(1, (uint32_t)enforcePMColor, "enforcePMColor");
 }
 bool GrArithmeticProcessor::onIsEqual(const GrFragmentProcessor& other) const {
     const GrArithmeticProcessor& that = other.cast<GrArithmeticProcessor>();
diff --git a/src/gpu/effects/generated/GrCircleEffect.cpp b/src/gpu/effects/generated/GrCircleEffect.cpp
index e6f2af9..a6678c2 100644
--- a/src/gpu/effects/generated/GrCircleEffect.cpp
+++ b/src/gpu/effects/generated/GrCircleEffect.cpp
@@ -100,7 +100,7 @@
 }
 void GrCircleEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                            GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t)edgeType);
+    b->addBits(2, (uint32_t)edgeType, "edgeType");
 }
 bool GrCircleEffect::onIsEqual(const GrFragmentProcessor& other) const {
     const GrCircleEffect& that = other.cast<GrCircleEffect>();
diff --git a/src/gpu/effects/generated/GrClampFragmentProcessor.cpp b/src/gpu/effects/generated/GrClampFragmentProcessor.cpp
index 2cbe47a..16987b4 100644
--- a/src/gpu/effects/generated/GrClampFragmentProcessor.cpp
+++ b/src/gpu/effects/generated/GrClampFragmentProcessor.cpp
@@ -50,7 +50,7 @@
 }
 void GrClampFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                      GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t)clampToPremul);
+    b->addBits(1, (uint32_t)clampToPremul, "clampToPremul");
 }
 bool GrClampFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
     const GrClampFragmentProcessor& that = other.cast<GrClampFragmentProcessor>();
diff --git a/src/gpu/effects/generated/GrColorMatrixFragmentProcessor.cpp b/src/gpu/effects/generated/GrColorMatrixFragmentProcessor.cpp
index 327fcec..73cb763 100644
--- a/src/gpu/effects/generated/GrColorMatrixFragmentProcessor.cpp
+++ b/src/gpu/effects/generated/GrColorMatrixFragmentProcessor.cpp
@@ -92,9 +92,9 @@
 }
 void GrColorMatrixFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                            GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t)unpremulInput);
-    b->add32((uint32_t)clampRGBOutput);
-    b->add32((uint32_t)premulOutput);
+    b->addBits(1, (uint32_t)unpremulInput, "unpremulInput");
+    b->addBits(1, (uint32_t)clampRGBOutput, "clampRGBOutput");
+    b->addBits(1, (uint32_t)premulOutput, "premulOutput");
 }
 bool GrColorMatrixFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
     const GrColorMatrixFragmentProcessor& that = other.cast<GrColorMatrixFragmentProcessor>();
diff --git a/src/gpu/effects/generated/GrConfigConversionEffect.cpp b/src/gpu/effects/generated/GrConfigConversionEffect.cpp
index 9278808..b8495c4 100644
--- a/src/gpu/effects/generated/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/generated/GrConfigConversionEffect.cpp
@@ -53,7 +53,7 @@
 }
 void GrConfigConversionEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                      GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t)pmConversion);
+    b->addBits(1, (uint32_t)pmConversion, "pmConversion");
 }
 bool GrConfigConversionEffect::onIsEqual(const GrFragmentProcessor& other) const {
     const GrConfigConversionEffect& that = other.cast<GrConfigConversionEffect>();
@@ -78,8 +78,8 @@
 #if GR_TEST_UTILS
 std::unique_ptr<GrFragmentProcessor> GrConfigConversionEffect::TestCreate(
         GrProcessorTestData* data) {
-    PMConversion pmConv = static_cast<PMConversion>(
-            data->fRandom->nextULessThan((int)PMConversion::kPMConversionCnt));
+    PMConversion pmConv =
+            static_cast<PMConversion>(data->fRandom->nextRangeU(0, (int)PMConversion::kLast));
     return std::unique_ptr<GrFragmentProcessor>(
             new GrConfigConversionEffect(GrProcessorUnitTest::MakeChildFP(data), pmConv));
 }
diff --git a/src/gpu/effects/generated/GrEllipseEffect.cpp b/src/gpu/effects/generated/GrEllipseEffect.cpp
index 2649f1e..a022722 100644
--- a/src/gpu/effects/generated/GrEllipseEffect.cpp
+++ b/src/gpu/effects/generated/GrEllipseEffect.cpp
@@ -136,7 +136,7 @@
 }
 void GrEllipseEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                             GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t)edgeType);
+    b->addBits(2, (uint32_t)edgeType, "edgeType");
 }
 bool GrEllipseEffect::onIsEqual(const GrFragmentProcessor& other) const {
     const GrEllipseEffect& that = other.cast<GrEllipseEffect>();
diff --git a/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp b/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp
index ec020f9..e53fb65 100644
--- a/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp
+++ b/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp
@@ -67,14 +67,14 @@
 }
 void GrOverrideInputFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                              GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t)useUniform);
+    b->addBits(1, (uint32_t)useUniform, "useUniform");
     if (!useUniform) {
         uint16_t red = SkFloatToHalf(literalColor.fR);
         uint16_t green = SkFloatToHalf(literalColor.fG);
         uint16_t blue = SkFloatToHalf(literalColor.fB);
         uint16_t alpha = SkFloatToHalf(literalColor.fA);
-        b->add32(((uint32_t)red << 16) | green);
-        b->add32(((uint32_t)blue << 16) | alpha);
+        b->add32(((uint32_t)red << 16) | green, "literalColor.rg");
+        b->add32(((uint32_t)blue << 16) | alpha, "literalColor.ba");
     }
 }
 bool GrOverrideInputFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
diff --git a/src/gpu/effects/generated/GrRectBlurEffect.cpp b/src/gpu/effects/generated/GrRectBlurEffect.cpp
index 92b86f8..553b06b 100644
--- a/src/gpu/effects/generated/GrRectBlurEffect.cpp
+++ b/src/gpu/effects/generated/GrRectBlurEffect.cpp
@@ -159,9 +159,9 @@
     bool highPrecision = ((abs(rect.left()) > 16000.0 || abs(rect.top()) > 16000.0) ||
                           abs(rect.right()) > 16000.0) ||
                          abs(rect.bottom()) > 16000.0;
-    b->add32((uint32_t)highPrecision);
-    b->add32((uint32_t)applyInvVM);
-    b->add32((uint32_t)isFast);
+    b->addBits(1, (uint32_t)highPrecision, "highPrecision");
+    b->addBits(1, (uint32_t)applyInvVM, "applyInvVM");
+    b->addBits(1, (uint32_t)isFast, "isFast");
 }
 bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const {
     const GrRectBlurEffect& that = other.cast<GrRectBlurEffect>();
diff --git a/src/gpu/gradients/generated/GrClampedGradientEffect.cpp b/src/gpu/gradients/generated/GrClampedGradientEffect.cpp
index bc4015d..8503508 100644
--- a/src/gpu/gradients/generated/GrClampedGradientEffect.cpp
+++ b/src/gpu/gradients/generated/GrClampedGradientEffect.cpp
@@ -93,8 +93,8 @@
 }
 void GrClampedGradientEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                     GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t)makePremul);
-    b->add32((uint32_t)layoutPreservesOpacity);
+    b->addBits(1, (uint32_t)makePremul, "makePremul");
+    b->addBits(1, (uint32_t)layoutPreservesOpacity, "layoutPreservesOpacity");
 }
 bool GrClampedGradientEffect::onIsEqual(const GrFragmentProcessor& other) const {
     const GrClampedGradientEffect& that = other.cast<GrClampedGradientEffect>();
diff --git a/src/gpu/gradients/generated/GrTiledGradientEffect.cpp b/src/gpu/gradients/generated/GrTiledGradientEffect.cpp
index 876ff5e..ff490dd 100644
--- a/src/gpu/gradients/generated/GrTiledGradientEffect.cpp
+++ b/src/gpu/gradients/generated/GrTiledGradientEffect.cpp
@@ -79,9 +79,9 @@
 }
 void GrTiledGradientEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                   GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t)mirror);
-    b->add32((uint32_t)makePremul);
-    b->add32((uint32_t)layoutPreservesOpacity);
+    b->addBits(1, (uint32_t)mirror, "mirror");
+    b->addBits(1, (uint32_t)makePremul, "makePremul");
+    b->addBits(1, (uint32_t)layoutPreservesOpacity, "layoutPreservesOpacity");
 }
 bool GrTiledGradientEffect::onIsEqual(const GrFragmentProcessor& other) const {
     const GrTiledGradientEffect& that = other.cast<GrTiledGradientEffect>();
diff --git a/src/gpu/gradients/generated/GrTwoPointConicalGradientLayout.cpp b/src/gpu/gradients/generated/GrTwoPointConicalGradientLayout.cpp
index 42cc7c6..62ef4ec 100644
--- a/src/gpu/gradients/generated/GrTwoPointConicalGradientLayout.cpp
+++ b/src/gpu/gradients/generated/GrTwoPointConicalGradientLayout.cpp
@@ -150,12 +150,12 @@
 }
 void GrTwoPointConicalGradientLayout::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                             GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t)type);
-    b->add32((uint32_t)isRadiusIncreasing);
-    b->add32((uint32_t)isFocalOnCircle);
-    b->add32((uint32_t)isWellBehaved);
-    b->add32((uint32_t)isSwapped);
-    b->add32((uint32_t)isNativelyFocal);
+    b->addBits(2, (uint32_t)type, "type");
+    b->addBits(1, (uint32_t)isRadiusIncreasing, "isRadiusIncreasing");
+    b->addBits(1, (uint32_t)isFocalOnCircle, "isFocalOnCircle");
+    b->addBits(1, (uint32_t)isWellBehaved, "isWellBehaved");
+    b->addBits(1, (uint32_t)isSwapped, "isSwapped");
+    b->addBits(1, (uint32_t)isNativelyFocal, "isNativelyFocal");
 }
 bool GrTwoPointConicalGradientLayout::onIsEqual(const GrFragmentProcessor& other) const {
     const GrTwoPointConicalGradientLayout& that = other.cast<GrTwoPointConicalGradientLayout>();
diff --git a/src/gpu/gradients/generated/GrUnrolledBinaryGradientColorizer.cpp b/src/gpu/gradients/generated/GrUnrolledBinaryGradientColorizer.cpp
index 2a27601..08fc66b 100644
--- a/src/gpu/gradients/generated/GrUnrolledBinaryGradientColorizer.cpp
+++ b/src/gpu/gradients/generated/GrUnrolledBinaryGradientColorizer.cpp
@@ -292,7 +292,7 @@
 }
 void GrUnrolledBinaryGradientColorizer::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                                               GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t)intervalCount);
+    b->add32((uint32_t)intervalCount, "intervalCount");
 }
 bool GrUnrolledBinaryGradientColorizer::onIsEqual(const GrFragmentProcessor& other) const {
     const GrUnrolledBinaryGradientColorizer& that = other.cast<GrUnrolledBinaryGradientColorizer>();
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
index 487bf65..d43b6fc 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -12,6 +12,7 @@
 #include "src/sksl/SkSLCPPUniformCTypes.h"
 #include "src/sksl/SkSLCompiler.h"
 #include "src/sksl/SkSLHCodeGenerator.h"
+#include "src/sksl/ir/SkSLEnum.h"
 
 #include <algorithm>
 
@@ -1238,7 +1239,37 @@
     }
 }
 
+static int bits_needed(uint32_t v) {
+    int bits = 1;
+    while (v >= (1u << bits)) {
+        bits++;
+    }
+    return bits;
+}
+
 void CPPCodeGenerator::writeGetKey() {
+    auto bitsForEnum = [&](const Type& type) {
+        for (const ProgramElement* e : fProgram.elements()) {
+            if (!e->is<Enum>() || type.name() != e->as<Enum>().typeName()) {
+                continue;
+            }
+            SKSL_INT minVal = 0, maxVal = 0;
+            auto gatherEnumRange = [&](StringFragment, SKSL_INT value) {
+                minVal = std::min(minVal, value);
+                maxVal = std::max(maxVal, value);
+            };
+            e->as<Enum>().foreach(gatherEnumRange);
+            if (minVal < 0) {
+                // Found a negative value in the enum, just use 32 bits
+                return 32;
+            }
+            SkASSERT(SkTFitsIn<uint32_t>(maxVal));
+            return bits_needed(maxVal);
+        }
+        SK_ABORT("Didn't find declaring element for enum type!");
+        return 32;
+    };
+
     this->writef("void %s::onGetGLSLProcessorKey(const GrShaderCaps& caps, "
                                                 "GrProcessorKeyBuilder* b) const {\n",
                  fFullName.c_str());
@@ -1281,15 +1312,23 @@
                                  HCodeGenerator::FieldName(name).c_str());
                     this->writef("    uint16_t alpha = SkFloatToHalf(%s.fA);\n",
                                  HCodeGenerator::FieldName(name).c_str());
-                    this->write("    b->add32(((uint32_t)red << 16) | green);\n");
-                    this->write("    b->add32(((uint32_t)blue << 16) | alpha);\n");
+                    this->writef("    b->add32(((uint32_t)red << 16) | green, \"%s.rg\");\n", name);
+                    this->writef("    b->add32(((uint32_t)blue << 16) | alpha, \"%s.ba\");\n",
+                                 name);
                 } else if (varType == *fContext.fTypes.fHalf ||
                            varType == *fContext.fTypes.fFloat) {
-                    this->writef("    b->add32(sk_bit_cast<uint32_t>(%s));\n",
-                                 HCodeGenerator::FieldName(name).c_str());
-                } else if (varType.isInteger() || varType.isBoolean() || varType.isEnum()) {
-                    this->writef("    b->add32((uint32_t) %s);\n",
-                                 HCodeGenerator::FieldName(name).c_str());
+                    this->writef("    b->add32(sk_bit_cast<uint32_t>(%s), \"%s\");\n",
+                                 HCodeGenerator::FieldName(name).c_str(), name);
+                } else if (varType.isBoolean()) {
+                    this->writef("    b->addBits(1, (uint32_t) %s, \"%s\");\n",
+                                 HCodeGenerator::FieldName(name).c_str(), name);
+                } else if (varType.isEnum()) {
+                    this->writef("    b->addBits(%d, (uint32_t) %s, \"%s\");\n",
+                                 bitsForEnum(varType), HCodeGenerator::FieldName(name).c_str(),
+                                 name);
+                } else if (varType.isInteger()) {
+                    this->writef("    b->add32((uint32_t) %s, \"%s\");\n",
+                                 HCodeGenerator::FieldName(name).c_str(), name);
                 } else {
                     SK_ABORT("NOT YET IMPLEMENTED: automatic key handling for %s\n",
                              varType.displayName().c_str());
diff --git a/src/sksl/generated/sksl_fp.dehydrated.sksl b/src/sksl/generated/sksl_fp.dehydrated.sksl
index 90c14d0..70dfe00 100644
--- a/src/sksl/generated/sksl_fp.dehydrated.sksl
+++ b/src/sksl/generated/sksl_fp.dehydrated.sksl
@@ -1,4 +1,4 @@
-static uint8_t SKSL_INCLUDE_sksl_fp[] = {77,1,
+static uint8_t SKSL_INCLUDE_sksl_fp[] = {60,1,
 14,71,114,67,108,105,112,69,100,103,101,84,121,112,101,
 12,80,77,67,111,110,118,101,114,115,105,111,110,
 0,
@@ -29,7 +29,6 @@
 5,107,76,97,115,116,
 9,107,84,111,80,114,101,109,117,108,
 11,107,84,111,85,110,112,114,101,109,117,108,
-16,107,80,77,67,111,110,118,101,114,115,105,111,110,67,110,116,
 42,36,0,
 15,1,0,2,0,
 15,2,0,17,0,
@@ -202,11 +201,11 @@
 40,2,0,0,
 46,51,0,
 30,
-8,1,62,1,
+8,1,34,1,
 40,2,0,0,3,0,
 2,0,
 0,0,
-1,0,0,0,0,0,1,0,0,0,2,0,0,0,
+1,0,0,0,0,0,1,0,0,0,1,0,0,0,
 48,
 47,3,0,
 40,4,0,0,
diff --git a/tests/sksl/fp/GrConditionalInUniform.cpp b/tests/sksl/fp/GrConditionalInUniform.cpp
index 6cd086b..1695007 100644
--- a/tests/sksl/fp/GrConditionalInUniform.cpp
+++ b/tests/sksl/fp/GrConditionalInUniform.cpp
@@ -55,7 +55,7 @@
     return std::make_unique<GrGLSLConditionalInUniform>();
 }
 void GrConditionalInUniform::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
-    b->add32((uint32_t) test);
+    b->addBits(1, (uint32_t) test, "test");
 }
 bool GrConditionalInUniform::onIsEqual(const GrFragmentProcessor& other) const {
     const GrConditionalInUniform& that = other.cast<GrConditionalInUniform>();
diff --git a/tests/sksl/fp/GrKeyIn.cpp b/tests/sksl/fp/GrKeyIn.cpp
index 9d3c03a..b72e74e 100644
--- a/tests/sksl/fp/GrKeyIn.cpp
+++ b/tests/sksl/fp/GrKeyIn.cpp
@@ -38,8 +38,8 @@
     uint16_t green = SkFloatToHalf(color.fG);
     uint16_t blue = SkFloatToHalf(color.fB);
     uint16_t alpha = SkFloatToHalf(color.fA);
-    b->add32(((uint32_t)red << 16) | green);
-    b->add32(((uint32_t)blue << 16) | alpha);
+    b->add32(((uint32_t)red << 16) | green, "color.rg");
+    b->add32(((uint32_t)blue << 16) | alpha, "color.ba");
 }
 bool GrKeyIn::onIsEqual(const GrFragmentProcessor& other) const {
     const GrKeyIn& that = other.cast<GrKeyIn>();
diff --git a/tests/sksl/fp/GrSectionSetData.cpp b/tests/sksl/fp/GrSectionSetData.cpp
index b5a0f4f..b3477f8 100644
--- a/tests/sksl/fp/GrSectionSetData.cpp
+++ b/tests/sksl/fp/GrSectionSetData.cpp
@@ -41,7 +41,7 @@
     return std::make_unique<GrGLSLSectionSetData>();
 }
 void GrSectionSetData::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
-    b->add32(sk_bit_cast<uint32_t>(provided));
+    b->add32(sk_bit_cast<uint32_t>(provided), "provided");
 }
 bool GrSectionSetData::onIsEqual(const GrFragmentProcessor& other) const {
     const GrSectionSetData& that = other.cast<GrSectionSetData>();