converted GrRectBlurEffect to SkSL

Bug: skia:
Change-Id: I3a8e16fd2792e6fb5711815d8aad46ae30c2872e
Reviewed-on: https://skia-review.googlesource.com/59163
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/sksl/SkSLCPP.h b/src/sksl/SkSLCPP.h
index 808e832..d679908 100644
--- a/src/sksl/SkSLCPP.h
+++ b/src/sksl/SkSLCPP.h
@@ -10,8 +10,11 @@
 
 // functions used by CPP programs created by skslc
 
+#include <cmath>
 #include "SkPoint.h"
 
+using std::abs;
+
 // macros to make sk_Caps.<cap name> work from C++ code
 #define sk_Caps (*args.fShaderCaps)
 
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
index a7008400..0b2ef78 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -148,10 +148,15 @@
         this->write(type.name() + "(%f, %f)");
         fFormatArgs.push_back(cppCode + ".fX");
         fFormatArgs.push_back(cppCode + ".fY");
+    } else if (type == *fContext.fFloat4_Type || type == *fContext.fHalf4_Type) {
+        this->write(type.name() + "(%f, %f, %f, %f)");
+        fFormatArgs.push_back(cppCode + ".left()");
+        fFormatArgs.push_back(cppCode + ".top()");
+        fFormatArgs.push_back(cppCode + ".right()");
+        fFormatArgs.push_back(cppCode + ".bottom()");
     } else {
-        this->write(type.name());
-        this->write("\n");
-        ABORT("unsupported runtime value type\n");
+        printf("unsupported runtime value type '%s'\n", String(type.fName).c_str());
+        ASSERT(false);
     }
 }
 
@@ -180,7 +185,26 @@
     this->write(to_string((int32_t) i.fValue));
 }
 
+void CPPCodeGenerator::writeSwizzle(const Swizzle& swizzle) {
+    if (fCPPMode) {
+        ASSERT(swizzle.fComponents.size() == 1); // no support for multiple swizzle components yet
+        this->writeExpression(*swizzle.fBase, kPostfix_Precedence);
+        switch (swizzle.fComponents[0]) {
+            case 0: this->write(".left()");   break;
+            case 1: this->write(".top()");    break;
+            case 2: this->write(".right()");  break;
+            case 3: this->write(".bottom()"); break;
+        }
+    } else {
+        INHERITED::writeSwizzle(swizzle);
+    }
+}
+
 void CPPCodeGenerator::writeVariableReference(const VariableReference& ref) {
+    if (fCPPMode) {
+        this->write(ref.fVariable.fName);
+        return;
+    }
     switch (ref.fVariable.fModifiers.fLayout.fBuiltin) {
         case SK_INCOLOR_BUILTIN:
             this->write("%s");
@@ -434,15 +458,22 @@
             for (const auto& raw : decls->fVars) {
                 VarDeclaration& decl = (VarDeclaration&) *raw;
                 if (is_private(*decl.fVar) && decl.fValue) {
-                    this->writef("%s = %s;\n",
-                                 String(decl.fVar->fName).c_str(),
-                                 decl.fValue->description().c_str());
+                    this->writef("%s = ", String(decl.fVar->fName).c_str());
+                    fCPPMode = true;
+                    this->writeExpression(*decl.fValue, kAssignment_Precedence);
+                    fCPPMode = false;
+                    this->write(";\n");
                 }
             }
         }
     }
 }
 
+static bool is_accessible(const Variable& var) {
+    return Type::kSampler_Kind != var.fType.kind() &&
+           Type::kOther_Kind != var.fType.kind();
+}
+
 void CPPCodeGenerator::writeCodeAppend(const String& code) {
     // codeAppendf can only handle appending 1024 bytes at a time, so we need to break the string
     // into chunks. Unfortunately we can't tell exactly how long the string is going to end up,
@@ -484,6 +515,22 @@
     this->writef("        const %s& _outer = args.fFp.cast<%s>();\n"
                  "        (void) _outer;\n",
                  fFullName.c_str(), fFullName.c_str());
+    for (const auto& p : fProgram.fElements) {
+        if (ProgramElement::kVar_Kind == p->fKind) {
+            const VarDeclarations* decls = (const VarDeclarations*) p.get();
+            for (const auto& raw : decls->fVars) {
+                VarDeclaration& decl = (VarDeclaration&) *raw;
+                String nameString(decl.fVar->fName);
+                const char* name = nameString.c_str();
+                if (SectionAndParameterHelper::IsParameter(*decl.fVar) &&
+                    is_accessible(*decl.fVar)) {
+                    this->writef("        auto %s = _outer.%s();\n"
+                                 "        (void) %s;\n",
+                                 name, name, name);
+                }
+            }
+        }
+    }
     this->writePrivateVarValues();
     for (const auto u : uniforms) {
         this->addUniform(*u);
diff --git a/src/sksl/SkSLCPPCodeGenerator.h b/src/sksl/SkSLCPPCodeGenerator.h
index ea4d030..a93b885 100644
--- a/src/sksl/SkSLCPPCodeGenerator.h
+++ b/src/sksl/SkSLCPPCodeGenerator.h
@@ -41,6 +41,8 @@
 
     void writeIntLiteral(const IntLiteral& i) override;
 
+    void writeSwizzle(const Swizzle& swizzle) override;
+
     void writeVariableReference(const VariableReference& ref) override;
 
     String getSamplerHandle(const Variable& var);
@@ -87,6 +89,8 @@
     std::vector<String> fFormatArgs;
     std::set<int> fWrittenTransformedCoords;
     bool fNeedColorSpaceHelper = false;
+    // if true, we are writing a C++ expression instead of a GLSL expression
+    bool fCPPMode = false;
 
     typedef GLSLCodeGenerator INHERITED;
 };
diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h
index 7c736b3..e9a63ac 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.h
+++ b/src/sksl/SkSLGLSLCodeGenerator.h
@@ -142,7 +142,7 @@
 
     void writeFieldAccess(const FieldAccess& f);
 
-    void writeSwizzle(const Swizzle& swizzle);
+    virtual void writeSwizzle(const Swizzle& swizzle);
 
     static Precedence GetBinaryPrecedence(Token::Kind op);
 
diff --git a/src/sksl/ir/SkSLLayout.h b/src/sksl/ir/SkSLLayout.h
index 8bf0472..dc67628 100644
--- a/src/sksl/ir/SkSLLayout.h
+++ b/src/sksl/ir/SkSLLayout.h
@@ -232,18 +232,6 @@
             result += separator + "when = " + fWhen;
             separator = ", ";
         }
-        switch (fKey) {
-            case kNo_Key:
-                break;
-            case kKey_Key:
-                result += separator + "key";
-                separator = ", ";
-                break;
-            case kIdentity_Key:
-                result += separator + "key=identity";
-                separator = ", ";
-                break;
-        }
         if (result.size() > 0) {
             result = "layout (" + result + ")";
         }