Re-re-land sksl fragment processor support

This reverts commit 5ce397205528f82084fc650c2ce27d246c01da33.

Bug: skia:
Change-Id: I88260c90004610a1cf8ad1a87c2b4b222525bbb6
Reviewed-on: https://skia-review.googlesource.com/21108
Reviewed-by: Ben Wagner <benjaminwagner@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 39ac315..593397b 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -8,7 +8,9 @@
 #include "SkSLCompiler.h"
 
 #include "SkSLCFGGenerator.h"
+#include "SkSLCPPCodeGenerator.h"
 #include "SkSLGLSLCodeGenerator.h"
+#include "SkSLHCodeGenerator.h"
 #include "SkSLIRGenerator.h"
 #include "SkSLSPIRVCodeGenerator.h"
 #include "ir/SkSLExpression.h"
@@ -45,6 +47,11 @@
 #include "sksl_geom.include"
 ;
 
+static const char* SKSL_FP_INCLUDE =
+#include "sksl_fp.include"
+;
+
+
 namespace SkSL {
 
 Compiler::Compiler()
@@ -146,12 +153,18 @@
     ADD_TYPE(SamplerCubeArrayShadow);
     ADD_TYPE(GSampler2DArrayShadow);
     ADD_TYPE(GSamplerCubeArrayShadow);
+    ADD_TYPE(ColorSpaceXform);
 
     String skCapsName("sk_Caps");
     Variable* skCaps = new Variable(Position(), Modifiers(), skCapsName,
                                     *fContext.fSkCaps_Type, Variable::kGlobal_Storage);
     fIRGenerator->fSymbolTable->add(skCapsName, std::unique_ptr<Symbol>(skCaps));
 
+    String skArgsName("sk_Args");
+    Variable* skArgs = new Variable(Position(), Modifiers(), skArgsName,
+                                    *fContext.fSkArgs_Type, Variable::kGlobal_Storage);
+    fIRGenerator->fSymbolTable->add(skArgsName, std::unique_ptr<Symbol>(skArgs));
+
     Modifiers::Flag ignored1;
     std::vector<std::unique_ptr<ProgramElement>> ignored2;
     fIRGenerator->convertProgram(String(SKSL_INCLUDE), *fTypes, &ignored1, &ignored2);
@@ -778,7 +791,6 @@
     }
 }
 
-
 // returns true if this statement could potentially execute a break at the current level (we ignore
 // nested loops and switches, since any breaks inside of them will merely break the loop / switch)
 static bool contains_break(Statement& s) {
@@ -1097,6 +1109,9 @@
         case Program::kGeometry_Kind:
             fIRGenerator->convertProgram(String(SKSL_GEOM_INCLUDE), *fTypes, &ignored, &elements);
             break;
+        case Program::kFragmentProcessor_Kind:
+            fIRGenerator->convertProgram(String(SKSL_FP_INCLUDE), *fTypes, &ignored, &elements);
+            break;
     }
     fIRGenerator->fSymbolTable->markAllFunctionsBuiltin();
     Modifiers::Flag defaultPrecision;
@@ -1127,15 +1142,16 @@
     bool result = cg.generateCode();
     if (result) {
         spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0);
-        ASSERT(0 == buffer.size() % 4);
+        const String& data = buffer.str();
+        ASSERT(0 == data.size() % 4);
         auto dumpmsg = [](spv_message_level_t, const char*, const spv_position_t&, const char* m) {
             SkDebugf("SPIR-V validation error: %s\n", m);
         };
         tools.SetMessageConsumer(dumpmsg);
         // Verify that the SPIR-V we produced is valid. If this assert fails, check the logs prior
         // to the failure to see the validation errors.
-        ASSERT_RESULT(tools.Validate((const uint32_t*) buffer.data(), buffer.size() / 4));
-        out.write(buffer.data(), buffer.size());
+        ASSERT_RESULT(tools.Validate((const uint32_t*) data.c_str(), data.size() / 4));
+        out.write(data.c_str(), data.size());
     }
 #else
     SPIRVCodeGenerator cg(&fContext, &program, this, &out);
@@ -1149,7 +1165,7 @@
     StringStream buffer;
     bool result = this->toSPIRV(program, buffer);
     if (result) {
-        *out = String(buffer.data(), buffer.size());
+        *out = buffer.str();
     }
     return result;
 }
@@ -1165,11 +1181,24 @@
     StringStream buffer;
     bool result = this->toGLSL(program, buffer);
     if (result) {
-        *out = String(buffer.data(), buffer.size());
+        *out = buffer.str();
     }
     return result;
 }
 
+bool Compiler::toCPP(const Program& program, String name, OutputStream& out) {
+    CPPCodeGenerator cg(&fContext, &program, this, name, &out);
+    bool result = cg.generateCode();
+    this->writeErrorCount();
+    return result;
+}
+
+bool Compiler::toH(const Program& program, String name, OutputStream& out) {
+    HCodeGenerator cg(&program, this, name, &out);
+    bool result = cg.generateCode();
+    this->writeErrorCount();
+    return result;
+}
 
 void Compiler::error(Position position, String msg) {
     fErrorCount++;