Revert "Revert "SkSL now supports null child processors""

This reverts commit bce7d8627045ff5ca51784edf84caa88e87e0162.

Bug: skia:
Change-Id: I3ccaf47b3d4b9dcb9e049671117183a374526032
Reviewed-on: https://skia-review.googlesource.com/c/194185
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLHCodeGenerator.cpp b/src/sksl/SkSLHCodeGenerator.cpp
index cb8712e..e4f0acd 100644
--- a/src/sksl/SkSLHCodeGenerator.cpp
+++ b/src/sksl/SkSLHCodeGenerator.cpp
@@ -41,7 +41,9 @@
     if (layout.fCType != Layout::CType::kDefault) {
         return layout.fCType;
     }
-    if (type == *context.fFloat_Type || type == *context.fHalf_Type) {
+    if (type.kind() == Type::kNullable_Kind) {
+        return ParameterCType(context, type.componentType(), layout);
+    } else if (type == *context.fFloat_Type || type == *context.fHalf_Type) {
         return Layout::CType::kFloat;
     } else if (type == *context.fInt_Type ||
                type == *context.fShort_Type ||
@@ -189,7 +191,7 @@
                      fFullName.c_str());
         separator = "";
         for (const auto& param : fSectionAndParameterHelper.getParameters()) {
-            if (param->fType == *fContext.fFragmentProcessor_Type) {
+            if (param->fType.nonnullable() == *fContext.fFragmentProcessor_Type) {
                 this->writef("%sstd::move(%s)", separator, String(param->fName).c_str());
             } else {
                 this->writef("%s%s", separator, String(param->fName).c_str());
@@ -237,7 +239,8 @@
     for (const auto& param : fSectionAndParameterHelper.getParameters()) {
         String nameString(param->fName);
         const char* name = nameString.c_str();
-        if (param->fType.kind() == Type::kSampler_Kind) {
+        const Type& type = param->fType.nonnullable();
+        if (type.kind() == Type::kSampler_Kind) {
             this->writef("\n    , %s(std::move(%s)", FieldName(name).c_str(), name);
             for (const Section* s : fSectionAndParameterHelper.getSections(
                                                                           SAMPLER_PARAMS_SECTION)) {
@@ -246,7 +249,7 @@
                 }
             }
             this->writef(")");
-        } else if (param->fType == *fContext.fFragmentProcessor_Type) {
+        } else if (type == *fContext.fFragmentProcessor_Type) {
             // do nothing
         } else {
             this->writef("\n    , %s(%s)", FieldName(name).c_str(), name);
@@ -270,9 +273,19 @@
     for (const auto& param : fSectionAndParameterHelper.getParameters()) {
         if (param->fType.kind() == Type::kSampler_Kind) {
             ++samplerCount;
-        } else if (param->fType == *fContext.fFragmentProcessor_Type) {
-            this->writef("        this->registerChildProcessor(std::move(%s));",
+        } else if (param->fType.nonnullable() == *fContext.fFragmentProcessor_Type) {
+            if (param->fType.kind() == Type::kNullable_Kind) {
+                this->writef("        if (%s) {\n", String(param->fName).c_str());
+            } else {
+                this->writef("        SkASSERT(%s);", String(param->fName).c_str());
+            }
+            this->writef("            %s_index = this->numChildProcessors();",
+                         FieldName(String(param->fName).c_str()).c_str());
+            this->writef("            this->registerChildProcessor(std::move(%s));",
                          String(param->fName).c_str());
+            if (param->fType.kind() == Type::kNullable_Kind) {
+                this->writef("       }");
+            }
         }
     }
     if (samplerCount) {
@@ -289,12 +302,14 @@
 void HCodeGenerator::writeFields() {
     this->writeSection(FIELDS_SECTION);
     for (const auto& param : fSectionAndParameterHelper.getParameters()) {
-        if (param->fType == *fContext.fFragmentProcessor_Type) {
-            continue;
+        String name = FieldName(String(param->fName).c_str());
+        if (param->fType.nonnullable() == *fContext.fFragmentProcessor_Type) {
+            this->writef("    int %s_index = -1;\n", name.c_str());
+        } else {
+            this->writef("    %s %s;\n", FieldType(fContext, param->fType,
+                                                   param->fModifiers.fLayout).c_str(),
+                                         name.c_str());
         }
-        this->writef("    %s %s;\n", FieldType(fContext, param->fType,
-                                               param->fModifiers.fLayout).c_str(),
-                     FieldName(String(param->fName).c_str()).c_str());
     }
     const auto transforms = fSectionAndParameterHelper.getSections(COORD_TRANSFORM_SECTION);
     for (size_t i = 0; i < transforms.size(); ++i) {
@@ -341,15 +356,19 @@
     }
     this->writeSection(CLASS_SECTION);
     for (const auto& param : fSectionAndParameterHelper.getParameters()) {
-        if (param->fType.kind() == Type::kSampler_Kind ||
-            param->fType.kind() == Type::kOther_Kind) {
+        if (param->fType.kind() == Type::kSampler_Kind) {
             continue;
         }
         String nameString(param->fName);
         const char* name = nameString.c_str();
-        this->writef("    %s %s() const { return %s; }\n",
-                     AccessType(fContext, param->fType, param->fModifiers.fLayout).c_str(), name,
-                     FieldName(name).c_str());
+        if (param->fType.nonnullable() == *fContext.fFragmentProcessor_Type) {
+            this->writef("    int %s_index() const { return %s_index; }\n", name,
+                         FieldName(name).c_str());
+        } else {
+            this->writef("    %s %s() const { return %s; }\n",
+                         AccessType(fContext, param->fType, param->fModifiers.fLayout).c_str(),
+                         name, FieldName(name).c_str());
+        }
     }
     this->writeMake();
     this->writef("    %s(const %s& src);\n"