Reland "Rearrange SkSL pre-include modules to hide things"

This reverts commit 4cb5c5e1728933637ca9b8653ff95f876871dc9b, and fixes
the Chromium issue by declaring sign(x) in sksl_public.sksl.

Original description:

This makes numerous internal and GLSL types or intrinsics hidden from
public (runtime effect) SkSL. In particular:

- Only core numeric types are visible to all program types. GLSL types
  involving images, textures, and sampling are restricted to internal use.
- sk_Caps is no longer visible to runtime effects.
- The set of intrinsics available to runtime effects is now a separate,
  curated list in sksl_public.sksl. It exactly matches the GLSL ES 1.00
  spec order.
- The blend intrinsics are no longer visible, which also fixes a bug.
  These are nice, but we're not going to offer them yet - they involve
  enums, which creates complications.

Bug: skia:10680
Bug: skia:10709
Bug: skia:10913

Cq-Include-Trybots: luci.chromium.try:linux-chromeos-rel,linux-rel
Change-Id: I42deeeccd725a9fe18314d091ce253404e3572e2
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/332750
Commit-Queue: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
Auto-Submit: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 6a1db1c..27d389a 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -61,6 +61,7 @@
 #include "src/sksl/generated/sksl_gpu.dehydrated.sksl"
 #include "src/sksl/generated/sksl_interp.dehydrated.sksl"
 #include "src/sksl/generated/sksl_pipeline.dehydrated.sksl"
+#include "src/sksl/generated/sksl_public.dehydrated.sksl"
 #include "src/sksl/generated/sksl_vert.dehydrated.sksl"
 
 #define MODULE_DATA(name) MakeModuleData(SKSL_INCLUDE_sksl_##name,\
@@ -89,142 +90,93 @@
 , fContext(std::make_shared<Context>())
 , fErrorCount(0) {
     fRootSymbolTable = std::make_shared<SymbolTable>(this, /*builtin=*/true);
+    fPrivateSymbolTable = std::make_shared<SymbolTable>(fRootSymbolTable, /*builtin=*/true);
     fIRGenerator = std::make_unique<IRGenerator>(fContext.get(), &fInliner, *this);
-#define ADD_TYPE(t) fRootSymbolTable->addWithoutOwnership(fContext->f##t##_Type.get())
-    ADD_TYPE(Void);
-    ADD_TYPE(Float);
-    ADD_TYPE(Float2);
-    ADD_TYPE(Float3);
-    ADD_TYPE(Float4);
-    ADD_TYPE(Half);
-    ADD_TYPE(Half2);
-    ADD_TYPE(Half3);
-    ADD_TYPE(Half4);
-    ADD_TYPE(Int);
-    ADD_TYPE(Int2);
-    ADD_TYPE(Int3);
-    ADD_TYPE(Int4);
-    ADD_TYPE(UInt);
-    ADD_TYPE(UInt2);
-    ADD_TYPE(UInt3);
-    ADD_TYPE(UInt4);
-    ADD_TYPE(Short);
-    ADD_TYPE(Short2);
-    ADD_TYPE(Short3);
-    ADD_TYPE(Short4);
-    ADD_TYPE(UShort);
-    ADD_TYPE(UShort2);
-    ADD_TYPE(UShort3);
-    ADD_TYPE(UShort4);
-    ADD_TYPE(Byte);
-    ADD_TYPE(Byte2);
-    ADD_TYPE(Byte3);
-    ADD_TYPE(Byte4);
-    ADD_TYPE(UByte);
-    ADD_TYPE(UByte2);
-    ADD_TYPE(UByte3);
-    ADD_TYPE(UByte4);
-    ADD_TYPE(Bool);
-    ADD_TYPE(Bool2);
-    ADD_TYPE(Bool3);
-    ADD_TYPE(Bool4);
-    ADD_TYPE(Float2x2);
-    ADD_TYPE(Float2x3);
-    ADD_TYPE(Float2x4);
-    ADD_TYPE(Float3x2);
-    ADD_TYPE(Float3x3);
-    ADD_TYPE(Float3x4);
-    ADD_TYPE(Float4x2);
-    ADD_TYPE(Float4x3);
-    ADD_TYPE(Float4x4);
-    ADD_TYPE(Half2x2);
-    ADD_TYPE(Half2x3);
-    ADD_TYPE(Half2x4);
-    ADD_TYPE(Half3x2);
-    ADD_TYPE(Half3x3);
-    ADD_TYPE(Half3x4);
-    ADD_TYPE(Half4x2);
-    ADD_TYPE(Half4x3);
-    ADD_TYPE(Half4x4);
-    ADD_TYPE(GenType);
-    ADD_TYPE(GenHType);
-    ADD_TYPE(GenIType);
-    ADD_TYPE(GenUType);
-    ADD_TYPE(GenBType);
-    ADD_TYPE(Mat);
-    ADD_TYPE(Vec);
-    ADD_TYPE(GVec);
-    ADD_TYPE(GVec2);
-    ADD_TYPE(GVec3);
-    ADD_TYPE(GVec4);
-    ADD_TYPE(HVec);
-    ADD_TYPE(IVec);
-    ADD_TYPE(UVec);
-    ADD_TYPE(SVec);
-    ADD_TYPE(USVec);
-    ADD_TYPE(ByteVec);
-    ADD_TYPE(UByteVec);
-    ADD_TYPE(BVec);
 
-    ADD_TYPE(Sampler1D);
-    ADD_TYPE(Sampler2D);
-    ADD_TYPE(Sampler3D);
-    ADD_TYPE(SamplerExternalOES);
-    ADD_TYPE(SamplerCube);
-    ADD_TYPE(Sampler2DRect);
-    ADD_TYPE(Sampler1DArray);
-    ADD_TYPE(Sampler2DArray);
-    ADD_TYPE(SamplerCubeArray);
-    ADD_TYPE(SamplerBuffer);
-    ADD_TYPE(Sampler2DMS);
-    ADD_TYPE(Sampler2DMSArray);
+#define TYPE(t) fContext->f##t##_Type.get()
 
-    ADD_TYPE(ISampler2D);
+    const SkSL::Symbol* rootTypes[] = {
+        TYPE(Void),
 
-    ADD_TYPE(Image2D);
-    ADD_TYPE(IImage2D);
+        TYPE( Float), TYPE( Float2), TYPE( Float3), TYPE( Float4),
+        TYPE(  Half), TYPE(  Half2), TYPE(  Half3), TYPE(  Half4),
+        TYPE(   Int), TYPE(   Int2), TYPE(   Int3), TYPE(   Int4),
+        TYPE(  UInt), TYPE(  UInt2), TYPE(  UInt3), TYPE(  UInt4),
+        TYPE( Short), TYPE( Short2), TYPE( Short3), TYPE( Short4),
+        TYPE(UShort), TYPE(UShort2), TYPE(UShort3), TYPE(UShort4),
+        TYPE(  Byte), TYPE(  Byte2), TYPE(  Byte3), TYPE(  Byte4),
+        TYPE( UByte), TYPE( UByte2), TYPE( UByte3), TYPE( UByte4),
+        TYPE(  Bool), TYPE(  Bool2), TYPE(  Bool3), TYPE(  Bool4),
 
-    ADD_TYPE(SubpassInput);
-    ADD_TYPE(SubpassInputMS);
+        TYPE(Float2x2), TYPE(Float2x3), TYPE(Float2x4),
+        TYPE(Float3x2), TYPE(Float3x3), TYPE(Float3x4),
+        TYPE(Float4x2), TYPE(Float4x3), TYPE(Float4x4),
 
-    ADD_TYPE(GSampler1D);
-    ADD_TYPE(GSampler2D);
-    ADD_TYPE(GSampler3D);
-    ADD_TYPE(GSamplerCube);
-    ADD_TYPE(GSampler2DRect);
-    ADD_TYPE(GSampler1DArray);
-    ADD_TYPE(GSampler2DArray);
-    ADD_TYPE(GSamplerCubeArray);
-    ADD_TYPE(GSamplerBuffer);
-    ADD_TYPE(GSampler2DMS);
-    ADD_TYPE(GSampler2DMSArray);
+        TYPE(Half2x2),  TYPE(Half2x3),  TYPE(Half2x4),
+        TYPE(Half3x2),  TYPE(Half3x3),  TYPE(Half3x4),
+        TYPE(Half4x2),  TYPE(Half4x3),  TYPE(Half4x4),
 
-    ADD_TYPE(Sampler1DShadow);
-    ADD_TYPE(Sampler2DShadow);
-    ADD_TYPE(SamplerCubeShadow);
-    ADD_TYPE(Sampler2DRectShadow);
-    ADD_TYPE(Sampler1DArrayShadow);
-    ADD_TYPE(Sampler2DArrayShadow);
-    ADD_TYPE(SamplerCubeArrayShadow);
-    ADD_TYPE(GSampler2DArrayShadow);
-    ADD_TYPE(GSamplerCubeArrayShadow);
-    ADD_TYPE(FragmentProcessor);
-    ADD_TYPE(Sampler);
-    ADD_TYPE(Texture2D);
+        TYPE(GenType), TYPE(GenHType), TYPE(GenIType), TYPE(GenUType), TYPE(GenBType),
+        TYPE(Mat), TYPE(Vec),
+        TYPE(GVec), TYPE(GVec2), TYPE(GVec3), TYPE(GVec4),
+        TYPE(HVec), TYPE(IVec), TYPE(UVec), TYPE(SVec), TYPE(USVec),
+        TYPE(ByteVec), TYPE(UByteVec), TYPE(BVec),
+
+        TYPE(FragmentProcessor),
+    };
+
+    const SkSL::Symbol* privateTypes[] = {
+        TYPE(Sampler1D), TYPE(Sampler2D), TYPE(Sampler3D),
+        TYPE(SamplerExternalOES),
+        TYPE(SamplerCube),
+        TYPE(Sampler2DRect),
+        TYPE(Sampler1DArray), TYPE(Sampler2DArray), TYPE(SamplerCubeArray),
+        TYPE(SamplerBuffer),
+        TYPE(Sampler2DMS), TYPE(Sampler2DMSArray),
+
+        TYPE(ISampler2D),
+        TYPE(Image2D), TYPE(IImage2D),
+        TYPE(SubpassInput), TYPE(SubpassInputMS),
+
+        TYPE(GSampler1D), TYPE(GSampler2D), TYPE(GSampler3D),
+        TYPE(GSamplerCube),
+        TYPE(GSampler2DRect),
+        TYPE(GSampler1DArray), TYPE(GSampler2DArray), TYPE(GSamplerCubeArray),
+        TYPE(GSamplerBuffer),
+        TYPE(GSampler2DMS), TYPE(GSampler2DMSArray),
+
+        TYPE(Sampler1DShadow), TYPE(Sampler2DShadow), TYPE(SamplerCubeShadow),
+        TYPE(Sampler2DRectShadow),
+        TYPE(Sampler1DArrayShadow), TYPE(Sampler2DArrayShadow), TYPE(SamplerCubeArrayShadow),
+
+        TYPE(GSampler2DArrayShadow), TYPE(GSamplerCubeArrayShadow),
+        TYPE(Sampler),
+        TYPE(Texture2D),
+    };
+
+    for (const SkSL::Symbol* type : rootTypes) {
+        fRootSymbolTable->addWithoutOwnership(type);
+    }
+    for (const SkSL::Symbol* type : privateTypes) {
+        fPrivateSymbolTable->addWithoutOwnership(type);
+    }
+
+#undef TYPE
 
     // sk_Caps is "builtin", but all references to it are resolved to Settings, so we don't need to
     // treat it as builtin (ie, no need to clone it into the Program).
-    StringFragment skCapsName("sk_Caps");
-    fRootSymbolTable->add(std::make_unique<Variable>(/*offset=*/-1,
-                                                     fIRGenerator->fModifiers->handle(Modifiers()),
-                                                     skCapsName,
-                                                     fContext->fSkCaps_Type.get(),
-                                                     /*builtin=*/false,
-                                                     Variable::Storage::kGlobal));
+    fPrivateSymbolTable->add(
+            std::make_unique<Variable>(/*offset=*/-1,
+                                       fIRGenerator->fModifiers->handle(Modifiers()),
+                                       "sk_Caps",
+                                       fContext->fSkCaps_Type.get(),
+                                       /*builtin=*/false,
+                                       Variable::Storage::kGlobal));
 
     fRootModule = {fRootSymbolTable, /*fIntrinsics=*/nullptr};
+    fPrivateModule = {fPrivateSymbolTable, /*fIntrinsics=*/nullptr};
 
-    fGPUModule = this->parseModule(Program::kFragment_Kind, MODULE_DATA(gpu), fRootModule);
+    fGPUModule = this->parseModule(Program::kFragment_Kind, MODULE_DATA(gpu), fPrivateModule);
     fVertexModule = this->parseModule(Program::kVertex_Kind, MODULE_DATA(vert), fGPUModule);
     fFragmentModule = this->parseModule(Program::kFragment_Kind, MODULE_DATA(frag), fGPUModule);
 }
@@ -246,10 +198,17 @@
     return fFPModule;
 }
 
+const ParsedModule& Compiler::loadPublicModule() {
+    if (!fPublicModule.fSymbols) {
+        fPublicModule = this->parseModule(Program::kGeneric_Kind, MODULE_DATA(public), fRootModule);
+    }
+    return fPublicModule;
+}
+
 const ParsedModule& Compiler::loadPipelineModule() {
     if (!fPipelineModule.fSymbols) {
-        fPipelineModule =
-                this->parseModule(Program::kPipelineStage_Kind, MODULE_DATA(pipeline), fGPUModule);
+        fPipelineModule = this->parseModule(Program::kPipelineStage_Kind, MODULE_DATA(pipeline),
+                                            this->loadPublicModule());
 
         // Add some aliases to the pipeline module so that it's friendlier, and more like GLSL
         fPipelineModule.fSymbols->addAlias("shader", fContext->fFragmentProcessor_Type.get());
@@ -283,8 +242,8 @@
 
 const ParsedModule& Compiler::loadInterpreterModule() {
     if (!fInterpreterModule.fSymbols) {
-        fInterpreterModule =
-                this->parseModule(Program::kGeneric_Kind, MODULE_DATA(interp), fRootModule);
+        fInterpreterModule = this->parseModule(Program::kGeneric_Kind, MODULE_DATA(interp),
+                                               this->loadPublicModule());
     }
     return fInterpreterModule;
 }
@@ -305,7 +264,13 @@
                                   ModuleData data,
                                   std::shared_ptr<SymbolTable> base) {
     if (!base) {
-        base = fRootSymbolTable;
+        // NOTE: This is a workaround. The only time 'base' is null is when dehydrating includes.
+        // In that case, skslc doesn't know which module it's preparing, nor what the correct base
+        // module is. We can't use 'Root', because many GPU intrinsics reference private types,
+        // like samplers or textures. Today, 'Private' does contain the union of all known types,
+        // so this is safe. If we ever have types that only exist in 'Public' (for example), this
+        // logic needs to be smarter (by choosing the correct base for the module we're compiling).
+        base = fPrivateSymbolTable;
     }
 
 #if defined(SKSL_STANDALONE)