re-land of new SkSL precisions

Bug: skia:
Change-Id: Ic1deb3db2cbda6ca45f93dee99832971a36a2119
Reviewed-on: https://skia-review.googlesource.com/47841
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/gpu/glsl/GrGLSL.cpp b/src/gpu/glsl/GrGLSL.cpp
index 6fe1e26..db8b7d6 100644
--- a/src/gpu/glsl/GrGLSL.cpp
+++ b/src/gpu/glsl/GrGLSL.cpp
@@ -30,33 +30,47 @@
     switch (t) {
         case kVoid_GrSLType:
             return "void";
-        case kFloat_GrSLType:
-            return "float";
-        case kVec2f_GrSLType:
-            return "float2";
-        case kVec3f_GrSLType:
-            return "float3";
-        case kVec4f_GrSLType:
-            return "float4";
-        case kVec2us_GrSLType:
+        case kHalf_GrSLType:
+            return "half";
+        case kHalf2_GrSLType:
+            return "half2";
+        case kHalf3_GrSLType:
+            return "half3";
+        case kHalf4_GrSLType:
+            return "half4";
+        case kHighFloat_GrSLType:
+            return "highfloat";
+        case kHighFloat2_GrSLType:
+            return "highfloat2";
+        case kHighFloat3_GrSLType:
+            return "highfloat3";
+        case kHighFloat4_GrSLType:
+            return "highfloat4";
+        case kUint2_GrSLType:
             if (shaderCaps->integerSupport()) {
                 return "uint2";
             } else {
                 // uint2 (aka uvec2) isn't supported in GLSL ES 1.00/GLSL 1.20
-                return "float2";
+                return "highfloat2";
             }
-        case kVec2i_GrSLType:
+        case kInt2_GrSLType:
             return "int2";
-        case kVec3i_GrSLType:
+        case kInt3_GrSLType:
             return "int3";
-        case kVec4i_GrSLType:
+        case kInt4_GrSLType:
             return "int4";
-        case kMat22f_GrSLType:
-            return "float2x2";
-        case kMat33f_GrSLType:
-            return "float3x3";
-        case kMat44f_GrSLType:
-            return "float4x4";
+        case kHighFloat2x2_GrSLType:
+            return "highfloat2x2";
+        case kHighFloat3x3_GrSLType:
+            return "highfloat3x3";
+        case kHighFloat4x4_GrSLType:
+            return "highfloat4x4";
+        case kHalf2x2_GrSLType:
+            return "half2x2";
+        case kHalf3x3_GrSLType:
+            return "half3x3";
+        case kHalf4x4_GrSLType:
+            return "half4x4";
         case kTexture2DSampler_GrSLType:
             return "sampler2D";
         case kITexture2DSampler_GrSLType:
@@ -73,6 +87,10 @@
             return "int";
         case kUint_GrSLType:
             return "uint";
+        case kShort_GrSLType:
+            return "short";
+        case kUShort_GrSLType:
+            return "ushort";
         case kTexture2D_GrSLType:
             return "texture2D";
         case kSampler_GrSLType:
diff --git a/src/gpu/glsl/GrGLSLBlend.cpp b/src/gpu/glsl/GrGLSLBlend.cpp
index 34df0df..254f481 100644
--- a/src/gpu/glsl/GrGLSLBlend.cpp
+++ b/src/gpu/glsl/GrGLSLBlend.cpp
@@ -50,7 +50,7 @@
     fsBuilder->codeAppendf("%s.%c = %s.%c * (1.0 - %s.a);",
                            final, component, src, component, dst);
     fsBuilder->codeAppend("} else {");
-    fsBuilder->codeAppendf("float d = %s.a - %s.%c;", src, src, component);
+    fsBuilder->codeAppendf("half d = %s.a - %s.%c;", src, src, component);
     fsBuilder->codeAppend("if (0.0 == d) {");
     fsBuilder->codeAppendf("%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);",
                            final, component, src, dst, src, component, dst, dst, component,
@@ -84,7 +84,7 @@
     fsBuilder->codeAppendf("%s.%c = %s.%c * (1.0 - %s.a);",
                            final, component, dst, component, src);
     fsBuilder->codeAppend("} else {");
-    fsBuilder->codeAppendf("float d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / (%s.%c %s));",
+    fsBuilder->codeAppendf("half d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / (%s.%c %s));",
                            dst, dst, dst, component, src, src, component, divisorGuard);
     fsBuilder->codeAppendf("%s.%c = %s.a * d + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);",
                            final, component, src, src, component, dst, dst, component, src);
@@ -114,11 +114,11 @@
     // else if (4D < Da)
     fsBuilder->codeAppendf("} else if (4.0 * %s.%c <= %s.a) {",
                            dst, component, dst);
-    fsBuilder->codeAppendf("float DSqd = %s.%c * %s.%c;",
+    fsBuilder->codeAppendf("half DSqd = %s.%c * %s.%c;",
                            dst, component, dst, component);
-    fsBuilder->codeAppendf("float DCub = DSqd * %s.%c;", dst, component);
-    fsBuilder->codeAppendf("float DaSqd = %s.a * %s.a;", dst, dst);
-    fsBuilder->codeAppendf("float DaCub = DaSqd * %s.a;", dst);
+    fsBuilder->codeAppendf("half DCub = DSqd * %s.%c;", dst, component);
+    fsBuilder->codeAppendf("half DaSqd = %s.a * %s.a;", dst, dst);
+    fsBuilder->codeAppendf("half DaCub = DaSqd * %s.a;", dst);
     // (Da^3 (-S)+Da^2 (S-D (3 Sa-6 S-1))+12 Da D^2 (Sa-2 S)-16 D^3 (Sa-2 S))/Da^2
     fsBuilder->codeAppendf("%s.%c ="
                            "(DaSqd*(%s.%c - %s.%c * (3.0*%s.a - 6.0*%s.%c - 1.0)) +"
@@ -144,10 +144,10 @@
     // Emit a helper that gets the luminance of a color.
     SkString getFunction;
     GrShaderVar getLumArgs[] = {
-        GrShaderVar("color", kVec3f_GrSLType),
+        GrShaderVar("color", kHalf3_GrSLType),
     };
-    SkString getLumBody("return dot(float3(0.3, 0.59, 0.11), color);");
-    fsBuilder->emitFunction(kFloat_GrSLType,
+    SkString getLumBody("return dot(highfloat3(0.3, 0.59, 0.11), color);");
+    fsBuilder->emitFunction(kHalf_GrSLType,
                             "luminance",
                             SK_ARRAY_COUNT(getLumArgs), getLumArgs,
                             getLumBody.c_str(),
@@ -155,27 +155,27 @@
 
     // Emit the set luminance function.
     GrShaderVar setLumArgs[] = {
-        GrShaderVar("hueSat", kVec3f_GrSLType),
-        GrShaderVar("alpha", kFloat_GrSLType),
-        GrShaderVar("lumColor", kVec3f_GrSLType),
+        GrShaderVar("hueSat", kHalf3_GrSLType),
+        GrShaderVar("alpha", kHalf_GrSLType),
+        GrShaderVar("lumColor", kHalf3_GrSLType),
     };
     SkString setLumBody;
-    setLumBody.printf("float diff = %s(lumColor - hueSat);", getFunction.c_str());
-    setLumBody.append("float3 outColor = hueSat + diff;");
-    setLumBody.appendf("float outLum = %s(outColor);", getFunction.c_str());
-    setLumBody.append("float minComp = min(min(outColor.r, outColor.g), outColor.b);"
-                      "float maxComp = max(max(outColor.r, outColor.g), outColor.b);"
+    setLumBody.printf("half diff = %s(lumColor - hueSat);", getFunction.c_str());
+    setLumBody.append("half3 outColor = hueSat + diff;");
+    setLumBody.appendf("half outLum = %s(outColor);", getFunction.c_str());
+    setLumBody.append("half minComp = min(min(outColor.r, outColor.g), outColor.b);"
+                      "half maxComp = max(max(outColor.r, outColor.g), outColor.b);"
                       "if (minComp < 0.0 && outLum != minComp) {"
-                      "outColor = outLum + ((outColor - float3(outLum, outLum, outLum)) * outLum) /"
+                      "outColor = outLum + ((outColor - half3(outLum, outLum, outLum)) * outLum) /"
                       "(outLum - minComp);"
                       "}"
                       "if (maxComp > alpha && maxComp != outLum) {"
                       "outColor = outLum +"
-                      "((outColor - float3(outLum, outLum, outLum)) * (alpha - outLum)) /"
+                      "((outColor - half3(outLum, outLum, outLum)) * (alpha - outLum)) /"
                       "(maxComp - outLum);"
                       "}"
                       "return outColor;");
-    fsBuilder->emitFunction(kVec3f_GrSLType,
+    fsBuilder->emitFunction(kHalf3_GrSLType,
                             "set_luminance",
                             SK_ARRAY_COUNT(setLumArgs), setLumArgs,
                             setLumBody.c_str(),
@@ -188,11 +188,11 @@
 static void add_sat_function(GrGLSLFragmentBuilder* fsBuilder, SkString* setSatFunction) {
     // Emit a helper that gets the saturation of a color
     SkString getFunction;
-    GrShaderVar getSatArgs[] = { GrShaderVar("color", kVec3f_GrSLType) };
+    GrShaderVar getSatArgs[] = { GrShaderVar("color", kHalf3_GrSLType) };
     SkString getSatBody;
     getSatBody.printf("return max(max(color.r, color.g), color.b) - "
                       "min(min(color.r, color.g), color.b);");
-    fsBuilder->emitFunction(kFloat_GrSLType,
+    fsBuilder->emitFunction(kHalf_GrSLType,
                             "saturation",
                             SK_ARRAY_COUNT(getSatArgs), getSatArgs,
                             getSatBody.c_str(),
@@ -204,33 +204,33 @@
     // adjusted min, mid, and max inputs, respectively.
     SkString helperFunction;
     GrShaderVar helperArgs[] = {
-        GrShaderVar("minComp", kFloat_GrSLType),
-        GrShaderVar("midComp", kFloat_GrSLType),
-        GrShaderVar("maxComp", kFloat_GrSLType),
-        GrShaderVar("sat", kFloat_GrSLType),
+        GrShaderVar("minComp", kHalf_GrSLType),
+        GrShaderVar("midComp", kHalf_GrSLType),
+        GrShaderVar("maxComp", kHalf_GrSLType),
+        GrShaderVar("sat", kHalf_GrSLType),
     };
     static const char kHelperBody[] = "if (minComp < maxComp) {"
-        "float3 result;"
+        "half3 result;"
         "result.r = 0.0;"
         "result.g = sat * (midComp - minComp) / (maxComp - minComp);"
         "result.b = sat;"
         "return result;"
         "} else {"
-        "return float3(0, 0, 0);"
+        "return half3(0, 0, 0);"
         "}";
-    fsBuilder->emitFunction(kVec3f_GrSLType,
+    fsBuilder->emitFunction(kHalf3_GrSLType,
                             "set_saturation_helper",
                             SK_ARRAY_COUNT(helperArgs), helperArgs,
                             kHelperBody,
                             &helperFunction);
 
     GrShaderVar setSatArgs[] = {
-        GrShaderVar("hueLumColor", kVec3f_GrSLType),
-        GrShaderVar("satColor", kVec3f_GrSLType),
+        GrShaderVar("hueLumColor", kHalf3_GrSLType),
+        GrShaderVar("satColor", kHalf3_GrSLType),
     };
     const char* helpFunc = helperFunction.c_str();
     SkString setSatBody;
-    setSatBody.appendf("float sat = %s(satColor);"
+    setSatBody.appendf("half sat = %s(satColor);"
                        "if (hueLumColor.r <= hueLumColor.g) {"
                        "if (hueLumColor.g <= hueLumColor.b) {"
                        "hueLumColor.rgb = %s(hueLumColor.r, hueLumColor.g, hueLumColor.b, sat);"
@@ -249,7 +249,7 @@
                        "return hueLumColor;",
                        getFunction.c_str(), helpFunc, helpFunc, helpFunc, helpFunc,
                        helpFunc, helpFunc);
-    fsBuilder->emitFunction(kVec3f_GrSLType,
+    fsBuilder->emitFunction(kHalf3_GrSLType,
                             "set_saturation",
                             SK_ARRAY_COUNT(setSatArgs), setSatArgs,
                             setSatBody.c_str(),
@@ -330,7 +330,7 @@
             SkString setSat, setLum;
             add_sat_function(fsBuilder, &setSat);
             add_lum_function(fsBuilder, &setLum);
-            fsBuilder->codeAppendf("float4 dstSrcAlpha = %s * %s.a;",
+            fsBuilder->codeAppendf("half4 dstSrcAlpha = %s * %s.a;",
                                    dstColor, srcColor);
             fsBuilder->codeAppendf("%s.rgb = %s(%s(%s.rgb * %s.a, dstSrcAlpha.rgb),"
                                    "dstSrcAlpha.a, dstSrcAlpha.rgb);",
@@ -345,7 +345,7 @@
             SkString setSat, setLum;
             add_sat_function(fsBuilder, &setSat);
             add_lum_function(fsBuilder, &setLum);
-            fsBuilder->codeAppendf("float4 dstSrcAlpha = %s * %s.a;",
+            fsBuilder->codeAppendf("half4 dstSrcAlpha = %s * %s.a;",
                                    dstColor, srcColor);
             fsBuilder->codeAppendf("%s.rgb = %s(%s(dstSrcAlpha.rgb, %s.rgb * %s.a),"
                                    "dstSrcAlpha.a, dstSrcAlpha.rgb);",
@@ -359,7 +359,7 @@
             //  SetLum(S * Da, Sa* Da, D * Sa) + (1 - Sa) * D + (1 - Da) * S
             SkString setLum;
             add_lum_function(fsBuilder, &setLum);
-            fsBuilder->codeAppendf("float4 srcDstAlpha = %s * %s.a;",
+            fsBuilder->codeAppendf("half4 srcDstAlpha = %s * %s.a;",
                                    srcColor, dstColor);
             fsBuilder->codeAppendf("%s.rgb = %s(srcDstAlpha.rgb, srcDstAlpha.a, %s.rgb * %s.a);",
                                    outputColor, setLum.c_str(), dstColor, srcColor);
@@ -371,7 +371,7 @@
             //  SetLum(D * Sa, Sa* Da, S * Da) + (1 - Sa) * D + (1 - Da) * S
             SkString setLum;
             add_lum_function(fsBuilder, &setLum);
-            fsBuilder->codeAppendf("float4 srcDstAlpha = %s * %s.a;",
+            fsBuilder->codeAppendf("half4 srcDstAlpha = %s * %s.a;",
                                    srcColor, dstColor);
             fsBuilder->codeAppendf("%s.rgb = %s(%s.rgb * %s.a, srcDstAlpha.a, srcDstAlpha.rgb);",
                                    outputColor, setLum.c_str(), dstColor, srcColor);
@@ -406,13 +406,13 @@
                 fsBuilder->codeAppendf(" * %s", srcColorName);
                 break;
             case SkBlendModeCoeff::kISC:
-                fsBuilder->codeAppendf(" * (float4(1.0) - %s)", srcColorName);
+                fsBuilder->codeAppendf(" * (half4(1.0) - %s)", srcColorName);
                 break;
             case SkBlendModeCoeff::kDC:
                 fsBuilder->codeAppendf(" * %s", dstColorName);
                 break;
             case SkBlendModeCoeff::kIDC:
-                fsBuilder->codeAppendf(" * (float4(1.0) - %s)", dstColorName);
+                fsBuilder->codeAppendf(" * (half4(1.0) - %s)", dstColorName);
                 break;
             case SkBlendModeCoeff::kSA:
                 fsBuilder->codeAppendf(" * %s.a", srcColorName);
@@ -453,7 +453,7 @@
                                                 false);
         // append dst blend
         if(!append_porterduff_term(fsBuilder, dstCoeff, dstColor, srcColor, dstColor, didAppend)) {
-            fsBuilder->codeAppend("float4(0, 0, 0, 0)");
+            fsBuilder->codeAppend("half4(0, 0, 0, 0)");
         }
         if (clamp) {
             fsBuilder->codeAppend(", 0, 1);");
@@ -505,7 +505,7 @@
                                             false);
     // append dst blend
     if(!append_porterduff_term(fsBuilder, dstCoeff, dstColor, srcColor, dstColor, didAppend)) {
-        fsBuilder->codeAppend("float4(0, 0, 0, 0)");
+        fsBuilder->codeAppend("half4(0, 0, 0, 0)");
     }
     fsBuilder->codeAppend(";");
 }
diff --git a/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h b/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h
index b4605ba..f9ac30b 100644
--- a/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h
+++ b/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h
@@ -24,8 +24,8 @@
                   uint32_t visibility = kFragment_GrShaderFlag) {
         SkASSERT(uniformHandler);
         if (colorSpaceXform) {
-            fGamutXformVar = uniformHandler->addUniform(visibility, kMat44f_GrSLType,
-                                                        kDefault_GrSLPrecision, "ColorXform");
+            fGamutXformVar = uniformHandler->addUniform(visibility, kHalf4x4_GrSLType,
+                                                        "ColorXform");
             fValid = true;
         }
     }
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index 6f75c16..ac2de13 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -29,7 +29,7 @@
     SkASSERT(outputColor);
     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
     outputColor->append(fragBuilder->getMangleString());
-    fragBuilder->codeAppendf("float4 %s;", outputColor->c_str());
+    fragBuilder->codeAppendf("half4 %s;", outputColor->c_str());
     this->internalEmitChild(childIndex, inputColor, outputColor->c_str(), args);
 }
 
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
index ed4b71f..68bd1f2 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h
@@ -86,9 +86,9 @@
         @param fp                The processor that generated this program stage.
         @param key               The key that was computed by GenKey() from the generating
                                  GrProcessor.
-        @param outputColor       A predefined float4 in the FS in which the stage should place its
+        @param outputColor       A predefined half4 in the FS in which the stage should place its
                                  output color (or coverage).
-        @param inputColor        A float4 that holds the input color to the stage in the FS. This may
+        @param inputColor        A half4 that holds the input color to the stage in the FS. This may
                                  be nullptr in which case the implied input is solid white (all
                                  ones). TODO: Better system for communicating optimization info
                                  (e.g. input color is solid white, trans black, known to be opaque,
@@ -152,7 +152,7 @@
     }
 
     inline void emitChild(int childIndex, SkString* outputColor, EmitArgs& parentArgs) {
-        this->emitChild(childIndex, "float4(1.0)", outputColor, parentArgs);
+        this->emitChild(childIndex, "half4(1.0)", outputColor, parentArgs);
     }
 
     /** Will emit the code of a child proc in its own scope. Pass in the parent's EmitArgs and
@@ -167,7 +167,7 @@
                    EmitArgs& parentArgs);
 
     inline void emitChild(int childIndex, EmitArgs& args) {
-        this->emitChild(childIndex, "float4(1.0)", args);
+        this->emitChild(childIndex, "half4(1.0)", args);
     }
 
     /** Variation that uses the parent's output color variable to hold the child's output.*/
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
index 7e6b8f7..ad39497 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
@@ -86,7 +86,7 @@
     , fHasSecondaryOutput(false)
     , fUsedSampleOffsetArrays(0)
     , fHasInitializedSampleMask(false)
-    , fDefaultPrecision(kMedium_GrSLPrecision) {
+    , fForceHighPrecision(false) {
     fSubstageIndices.push_back(0);
 #ifdef SK_DEBUG
     fUsedProcessorFeatures = GrProcessor::kNone_RequiredFeatures;
@@ -112,14 +112,14 @@
 }
 
 SkString GrGLSLFragmentShaderBuilder::ensureCoords2D(const GrShaderVar& coords) {
-    if (kVec3f_GrSLType != coords.getType()) {
-        SkASSERT(kVec2f_GrSLType == coords.getType());
+    if (kHighFloat3_GrSLType != coords.getType() && kHalf3_GrSLType != coords.getType()) {
+        SkASSERT(kHighFloat2_GrSLType == coords.getType() || kHalf2_GrSLType == coords.getType());
         return coords.getName();
     }
 
     SkString coords2D;
     coords2D.printf("%s_ensure2D", coords.c_str());
-    this->codeAppendf("\tfloat2 %s = %s.xy / %s.z;", coords2D.c_str(), coords.c_str(),
+    this->codeAppendf("\thighfloat2 %s = %s.xy / %s.z;", coords2D.c_str(), coords.c_str(),
                       coords.c_str());
     return coords2D;
 }
@@ -175,10 +175,6 @@
     fHasInitializedSampleMask = true;
 }
 
-void GrGLSLFragmentShaderBuilder::elevateDefaultPrecision(GrSLPrecision precision) {
-    fDefaultPrecision = SkTMax(fDefaultPrecision, precision);
-}
-
 const char* GrGLSLFragmentShaderBuilder::dstColor() {
     SkDEBUGCODE(fHasReadDstColor = true;)
 
@@ -199,7 +195,7 @@
             fOutputs[fCustomColorOutputIndex].setTypeModifier(GrShaderVar::kInOut_TypeModifier);
             fbFetchColorName = DeclaredColorOutputName();
             // Set the dstColor to an intermediate variable so we don't override it with the output
-            this->codeAppendf("float4 %s = %s;", kDstColorName, fbFetchColorName);
+            this->codeAppendf("half4 %s = %s;", kDstColorName, fbFetchColorName);
         } else {
             return fbFetchColorName;
         }
@@ -228,7 +224,7 @@
     if (!fHasCustomColorOutput) {
         fHasCustomColorOutput = true;
         fCustomColorOutputIndex = fOutputs.count();
-        fOutputs.push_back().set(kVec4f_GrSLType, DeclaredColorOutputName(),
+        fOutputs.push_back().set(kHalf4_GrSLType, DeclaredColorOutputName(),
                                  GrShaderVar::kOut_TypeModifier);
         fProgramBuilder->finalizeFragmentOutputColor(fOutputs.back()); 
     }
@@ -247,7 +243,7 @@
     // output. The condition also co-incides with the condition in whici GLES SL 2.0
     // requires the built-in gl_SecondaryFragColorEXT, where as 3.0 requires a custom output.
     if (caps.mustDeclareFragmentShaderOutput()) {
-        fOutputs.push_back().set(kVec4f_GrSLType, DeclaredSecondaryColorOutputName(),
+        fOutputs.push_back().set(kHalf4_GrSLType, DeclaredSecondaryColorOutputName(),
                                  GrShaderVar::kOut_TypeModifier);
         fProgramBuilder->finalizeFragmentSecondaryColor(fOutputs.back());
     }
@@ -280,9 +276,6 @@
 
 void GrGLSLFragmentShaderBuilder::onFinalize() {
     fProgramBuilder->varyingHandler()->getFragDecls(&this->inputs(), &this->outputs());
-    GrGLSLAppendDefaultFloatPrecisionDeclaration(fDefaultPrecision,
-                                                 *fProgramBuilder->shaderCaps(),
-                                                 &this->precisionQualifier());
     if (fUsedSampleOffsetArrays & (1 << kSkiaDevice_Coordinates)) {
         this->defineSampleOffsetArray(sample_offset_array_name(kSkiaDevice_Coordinates),
                                       SkMatrix::MakeTrans(-0.5f, -0.5f));
@@ -305,9 +298,9 @@
     SkSTArray<16, SkPoint, true> offsets;
     offsets.push_back_n(specs.fEffectiveSampleCnt);
     m.mapPoints(offsets.begin(), specs.fSampleLocations, specs.fEffectiveSampleCnt);
-    this->definitions().appendf("const highp float2 %s[] = float2[](", name);
+    this->definitions().appendf("const highfloat2 %s[] = highfloat2[](", name);
     for (int i = 0; i < specs.fEffectiveSampleCnt; ++i) {
-        this->definitions().appendf("float2(%f, %f)", offsets[i].x(), offsets[i].y());
+        this->definitions().appendf("highfloat2(%f, %f)", offsets[i].x(), offsets[i].y());
         this->definitions().append(i + 1 != specs.fEffectiveSampleCnt ? ", " : ");\n");
     }
 }
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
index 73fe51f..f124a44 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
@@ -40,7 +40,7 @@
 
     /**
      * This returns a variable name to access the 2D, perspective correct version of the coords in
-     * the fragment shader. The passed in coordinates must either be of type kVec2f or kVec3f. If
+     * the fragment shader. The passed in coordinates must either be of type kHalf2 or kHalf3. If
      * the coordinates are 3-dimensional, it a perspective divide into is emitted into the
      * fragment shader (xy / z) to convert them to 2D.
      */
@@ -90,13 +90,6 @@
     virtual void maskSampleCoverage(const char* mask, bool invert = false) = 0;
 
     /**
-     * Overrides the default precision for the entire fragment program. Processors that require
-     * high precision input (eg from incoming texture samples) may use this. For calculations that
-     * are limited to a single processor's code, it is better to annotate individual declarations.
-     */
-    virtual void elevateDefaultPrecision(GrSLPrecision) = 0;
-
-    /**
      * Fragment procs with child procs should call these functions before/after calling emitCode
      * on a child proc.
      */
@@ -104,6 +97,8 @@
     virtual void onAfterChildProcEmitCode() = 0;
 
     virtual const SkString& getMangleString() const = 0;
+
+    virtual void forceHighPrecision() = 0;
 };
 
 /*
@@ -169,10 +164,10 @@
     void appendOffsetToSample(const char* sampleIdx, Coordinates) override;
     void maskSampleCoverage(const char* mask, bool invert = false) override;
     void overrideSampleCoverage(const char* mask) override;
-    void elevateDefaultPrecision(GrSLPrecision) override;
     const SkString& getMangleString() const override { return fMangleString; }
     void onBeforeChildProcEmitCode() override;
     void onAfterChildProcEmitCode() override;
+    void forceHighPrecision() override { fForceHighPrecision = true; }
 
     // GrGLSLXPFragmentBuilder interface.
     bool hasCustomColorOutput() const override { return fHasCustomColorOutput; }
@@ -234,7 +229,7 @@
     bool          fHasSecondaryOutput;
     uint8_t       fUsedSampleOffsetArrays;
     bool          fHasInitializedSampleMask;
-    GrSLPrecision fDefaultPrecision;
+    bool          fForceHighPrecision;
 
 #ifdef SK_DEBUG
     // some state to verify shaders and effects are consistent, this is reset between effects by
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
index a390036..072d62c 100644
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
@@ -18,7 +18,8 @@
     GrGPArgs gpArgs;
     this->onEmitCode(args, &gpArgs);
     vBuilder->transformToNormalizedDeviceSpace(gpArgs.fPositionVar, args.fRTAdjustName);
-    if (kVec2f_GrSLType == gpArgs.fPositionVar.getType()) {
+    if (kHighFloat2_GrSLType == gpArgs.fPositionVar.getType() ||
+        kHalf2_GrSLType == gpArgs.fPositionVar.getType()) {
         args.fVaryingHandler->setNoPerspective();
     }
 }
@@ -39,32 +40,28 @@
         uint32_t type = coordTransform->getMatrix().getType();
         type |= localMatrix.getType();
 
-        varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType :
-                                                                     kVec2f_GrSLType;
-        // Coord transforms are always handled at high precision
-        const GrSLPrecision precision = kHigh_GrSLPrecision;
-
+        varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kHighFloat3_GrSLType :
+                                                                     kHighFloat2_GrSLType;
         const char* uniName;
 
 
         fInstalledTransforms.push_back().fHandle = uniformHandler->addUniform(kVertex_GrShaderFlag,
-                                                                              kMat33f_GrSLType,
-                                                                              precision,
+                                                                              kHighFloat3x3_GrSLType,
                                                                               strUniName.c_str(),
                                                                               &uniName).toIndex();
         SkString strVaryingName;
         strVaryingName.printf("TransformedCoords_%d", i);
 
         GrGLSLVertToFrag v(varyingType);
-        varyingHandler->addVarying(strVaryingName.c_str(), &v, precision);
+        varyingHandler->addVarying(strVaryingName.c_str(), &v, kHigh_GrSLPrecision);
 
-        SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
+        SkASSERT(kHighFloat2_GrSLType == varyingType || kHighFloat3_GrSLType == varyingType);
         handler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType);
 
-        if (kVec2f_GrSLType == varyingType) {
-            vb->codeAppendf("%s = (%s * float3(%s, 1)).xy;", v.vsOut(), uniName, localCoords);
+        if (kHighFloat2_GrSLType == varyingType) {
+            vb->codeAppendf("%s = (%s * highfloat3(%s, 1)).xy;", v.vsOut(), uniName, localCoords);
         } else {
-            vb->codeAppendf("%s = %s * float3(%s, 1);", v.vsOut(), uniName, localCoords);
+            vb->codeAppendf("%s = %s * highfloat3(%s, 1);", v.vsOut(), uniName, localCoords);
         }
         ++i;
     }
@@ -88,8 +85,8 @@
 void GrGLSLGeometryProcessor::writeOutputPosition(GrGLSLVertexBuilder* vertBuilder,
                                                   GrGPArgs* gpArgs,
                                                   const char* posName) {
-    gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2");
-    vertBuilder->codeAppendf("float2 %s = %s;", gpArgs->fPositionVar.c_str(), posName);
+    gpArgs->fPositionVar.set(kHighFloat2_GrSLType, "pos2");
+    vertBuilder->codeAppendf("highfloat2 %s = %s;", gpArgs->fPositionVar.c_str(), posName);
 }
 
 void GrGLSLGeometryProcessor::writeOutputPosition(GrGLSLVertexBuilder* vertBuilder,
@@ -99,21 +96,21 @@
                                                   const SkMatrix& mat,
                                                   UniformHandle* viewMatrixUniform) {
     if (mat.isIdentity()) {
-        gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2");
-        vertBuilder->codeAppendf("float2 %s = %s;", gpArgs->fPositionVar.c_str(), posName);
+        gpArgs->fPositionVar.set(kHighFloat2_GrSLType, "pos2");
+        vertBuilder->codeAppendf("highfloat2 %s = %s;", gpArgs->fPositionVar.c_str(), posName);
     } else {
         const char* viewMatrixName;
         *viewMatrixUniform = uniformHandler->addUniform(kVertex_GrShaderFlag,
-                                                        kMat33f_GrSLType, kHigh_GrSLPrecision,
+                                                        kHighFloat3x3_GrSLType,
                                                         "uViewM",
                                                         &viewMatrixName);
         if (!mat.hasPerspective()) {
-            gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2");
-            vertBuilder->codeAppendf("float2 %s = (%s * float3(%s, 1)).xy;",
+            gpArgs->fPositionVar.set(kHighFloat2_GrSLType, "pos2");
+            vertBuilder->codeAppendf("highfloat2 %s = (%s * highfloat3(%s, 1)).xy;",
                                      gpArgs->fPositionVar.c_str(), viewMatrixName, posName);
         } else {
-            gpArgs->fPositionVar.set(kVec3f_GrSLType, "pos3");
-            vertBuilder->codeAppendf("float3 %s = %s * float3(%s, 1);",
+            gpArgs->fPositionVar.set(kHighFloat3_GrSLType, "pos3");
+            vertBuilder->codeAppendf("highfloat3 %s = %s * highfloat3(%s, 1);",
                                      gpArgs->fPositionVar.c_str(), viewMatrixName, posName);
         }
     }
diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
index d9d17e5..0cb7e4d 100644
--- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
@@ -43,13 +43,12 @@
     SkASSERT(colorUniform);
     const char* stagedLocalVarName;
     *colorUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
-                                               kVec4f_GrSLType,
-                                               kDefault_GrSLPrecision,
+                                               kHalf4_GrSLType,
                                                "Color",
                                                &stagedLocalVarName);
     fragBuilder->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
     if (fragBuilder->getProgramBuilder()->shaderCaps()->mustObfuscateUniformColor()) {
-        fragBuilder->codeAppendf("%s = max(%s, float4(0, 0, 0, 0));", outputName, outputName);
+        fragBuilder->codeAppendf("%s = max(%s, half4(0, 0, 0, 0));", outputName, outputName);
     }
 }
 
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index bb3dc4f..c2a0d64 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -82,8 +82,7 @@
         rtAdjustVisibility |= kGeometry_GrShaderFlag;
     }
     fUniformHandles.fRTAdjustmentUni = this->uniformHandler()->addUniform(rtAdjustVisibility,
-                                                                          kVec4f_GrSLType,
-                                                                          kHigh_GrSLPrecision,
+                                                                          kHighFloat4_GrSLType,
                                                                           "rtAdjustment");
     const char* rtAdjustName =
         this->uniformHandler()->getUniformCStr(fUniformHandles.fRTAdjustmentUni);
@@ -455,7 +454,7 @@
     } else {
         this->nameVariable(&outName, '\0', baseName);
     }
-    fFS.codeAppendf("float4 %s;", outName.c_str());
+    fFS.codeAppendf("half4 %s;", outName.c_str());
     *output = outName;
 }
 
@@ -468,7 +467,7 @@
         GrGLSLUniformHandler* uniformHandler = this->uniformHandler();
         fUniformHandles.fRTHeightUni =
             uniformHandler->internalAddUniformArray(kFragment_GrShaderFlag,
-                                                    kFloat_GrSLType, kDefault_GrSLPrecision,
+                                                    kHalf_GrSLType, kDefault_GrSLPrecision,
                                                     name, false, 0, nullptr);
 }
 
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.cpp b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
index 4d54c75..f87194e 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
@@ -122,16 +122,16 @@
     // re-insert the original alpha. The supplied srcColor is likely to be of the form
     // "texture(...)", and we don't want to evaluate that twice, so wrap everything in a function.
     static const GrShaderVar gColorGamutXformArgs[] = {
-        GrShaderVar("color", kVec4f_GrSLType),
-        GrShaderVar("xform", kMat44f_GrSLType),
+        GrShaderVar("color", kHalf4_GrSLType),
+        GrShaderVar("xform", kHalf4x4_GrSLType),
     };
     SkString functionBody;
     // Gamut xform, clamp to destination gamut. We only support/have premultiplied textures, so we
     // always just clamp to alpha.
-    functionBody.append("\tcolor.rgb = clamp((xform * float4(color.rgb, 1.0)).rgb, 0.0, color.a);\n");
+    functionBody.append("\tcolor.rgb = clamp((xform * half4(color.rgb, 1.0)).rgb, 0.0, color.a);\n");
     functionBody.append("\treturn color;");
     SkString colorGamutXformFuncName;
-    this->emitFunction(kVec4f_GrSLType,
+    this->emitFunction(kHalf4_GrSLType,
                        "colorGamutXform",
                        SK_ARRAY_COUNT(gColorGamutXformArgs),
                        gColorGamutXformArgs,
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h
index 4906c03..9ac6ab7 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.h
@@ -37,23 +37,23 @@
     void appendTextureLookup(SkString* out,
                              SamplerHandle,
                              const char* coordName,
-                             GrSLType coordType = kVec2f_GrSLType) const;
+                             GrSLType coordType = kHalf2_GrSLType) const;
 
     /** Version of above that appends the result to the shader code instead.*/
     void appendTextureLookup(SamplerHandle,
                              const char* coordName,
-                             GrSLType coordType = kVec2f_GrSLType,
+                             GrSLType coordType = kHalf2_GrSLType,
                              GrGLSLColorSpaceXformHelper* colorXformHelper = nullptr);
 
 
     /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
-        always a float4. modulation and the swizzle specified by SamplerHandle must both be
-        float4 or float. If modulation is "" or nullptr it this function acts as though
+        always a half4. modulation and the swizzle specified by SamplerHandle must both be
+        half4 or half. If modulation is "" or nullptr it this function acts as though
         appendTextureLookup were called. */
     void appendTextureLookupAndModulate(const char* modulation,
                                         SamplerHandle,
                                         const char* coordName,
-                                        GrSLType coordType = kVec2f_GrSLType,
+                                        GrSLType coordType = kHalf2_GrSLType,
                                         GrGLSLColorSpaceXformHelper* colorXformHelper = nullptr);
 
     /** Adds a helper function to facilitate color gamut transformation, and produces code that
diff --git a/src/gpu/glsl/GrGLSLUniformHandler.h b/src/gpu/glsl/GrGLSLUniformHandler.h
index cf80c3f..84bbfa1 100644
--- a/src/gpu/glsl/GrGLSLUniformHandler.h
+++ b/src/gpu/glsl/GrGLSLUniformHandler.h
@@ -38,6 +38,13 @@
         return this->addUniformArray(visibility, type, precision, name, 0, outName);
     }
 
+    UniformHandle addUniform(uint32_t visibility,
+                             GrSLType type,
+                             const char* name,
+                             const char** outName = nullptr) {
+        return this->addUniform(visibility, type, kDefault_GrSLPrecision, name, outName);
+    }
+
     UniformHandle addUniformArray(uint32_t visibility,
                                   GrSLType type,
                                   GrSLPrecision precision,
@@ -49,6 +56,16 @@
                                              outName);
     }
 
+    UniformHandle addUniformArray(uint32_t visibility,
+                                  GrSLType type,
+                                  const char* name,
+                                  int arrayCount,
+                                  const char** outName = nullptr) {
+        SkASSERT(!GrSLTypeIsCombinedSamplerType(type));
+        return this->internalAddUniformArray(visibility, type, kDefault_GrSLPrecision, name, true,
+                                             arrayCount, outName);
+    }
+
     virtual const GrShaderVar& getUniformVariable(UniformHandle u) const = 0;
 
     /**
diff --git a/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp b/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp
index e06ee2d..4e3b644 100644
--- a/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp
@@ -18,25 +18,25 @@
                                                            const char* rtAdjustName) {
     // setup RT Uniform
     if (this->getProgramBuilder()->desc()->header().fSnapVerticesToPixelCenters) {
-        if (kVec3f_GrSLType == posVar.getType()) {
+        if (kHighFloat3_GrSLType == posVar.getType()) {
             const char* p = posVar.c_str();
-            this->codeAppendf("{float2 _posTmp = float2(%s.x/%s.z, %s.y/%s.z);", p, p, p, p);
+            this->codeAppendf("{highfloat2 _posTmp = highfloat2(%s.x/%s.z, %s.y/%s.z);", p, p, p, p);
         } else {
-            SkASSERT(kVec2f_GrSLType == posVar.getType());
-            this->codeAppendf("{float2 _posTmp = %s;", posVar.c_str());
+            SkASSERT(kHighFloat2_GrSLType == posVar.getType());
+            this->codeAppendf("{highfloat2 _posTmp = %s;", posVar.c_str());
         }
-        this->codeAppendf("_posTmp = floor(_posTmp) + float2(0.5, 0.5);"
-                          "gl_Position = float4(_posTmp.x * %s.x + %s.y,"
+        this->codeAppendf("_posTmp = floor(_posTmp) + half2(0.5, 0.5);"
+                          "gl_Position = highfloat4(_posTmp.x * %s.x + %s.y,"
                                                "_posTmp.y * %s.z + %s.w, 0, 1);}",
                           rtAdjustName, rtAdjustName, rtAdjustName, rtAdjustName);
-    } else if (kVec3f_GrSLType == posVar.getType()) {
-        this->codeAppendf("gl_Position = float4(dot(%s.xz, %s.xy), dot(%s.yz, %s.zw), 0, %s.z);",
+    } else if (kHighFloat3_GrSLType == posVar.getType()) {
+        this->codeAppendf("gl_Position = highfloat4(dot(%s.xz, %s.xy), dot(%s.yz, %s.zw), 0, %s.z);",
                           posVar.c_str(), rtAdjustName,
                           posVar.c_str(), rtAdjustName,
                           posVar.c_str());
     } else {
-        SkASSERT(kVec2f_GrSLType == posVar.getType());
-        this->codeAppendf("gl_Position = float4(%s.x * %s.x + %s.y, %s.y * %s.z + %s.w, 0, 1);",
+        SkASSERT(kHighFloat2_GrSLType == posVar.getType());
+        this->codeAppendf("gl_Position = highfloat4(%s.x * %s.x + %s.y, %s.y * %s.z + %s.w, 0, 1);",
                           posVar.c_str(), rtAdjustName, rtAdjustName,
                           posVar.c_str(), rtAdjustName, rtAdjustName);
     }
diff --git a/src/gpu/glsl/GrGLSLXferProcessor.cpp b/src/gpu/glsl/GrGLSLXferProcessor.cpp
index 6c2c460..99862e2 100644
--- a/src/gpu/glsl/GrGLSLXferProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLXferProcessor.cpp
@@ -52,7 +52,7 @@
             // The discard here also helps for batching text draws together which need to read from
             // a dst copy for blends. Though this only helps the case where the outer bounding boxes
             // of each letter overlap and not two actually parts of the text.
-            fragBuilder->codeAppendf("if (all(lessThanEqual(%s.rgb, float3(0)))) {"
+            fragBuilder->codeAppendf("if (all(lessThanEqual(%s.rgb, half3(0)))) {"
                                      "    discard;"
                                      "}", args.fInputCoverage);
         }
@@ -61,27 +61,25 @@
         const char* dstCoordScaleName;
 
         fDstTopLeftUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
-                                                    kVec2f_GrSLType,
-                                                    kDefault_GrSLPrecision,
+                                                    kHalf2_GrSLType,
                                                     "DstTextureUpperLeft",
                                                     &dstTopLeftName);
         fDstScaleUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
-                                                  kVec2f_GrSLType,
-                                                  kDefault_GrSLPrecision,
+                                                  kHalf2_GrSLType,
                                                   "DstTextureCoordScale",
                                                   &dstCoordScaleName);
 
         fragBuilder->codeAppend("// Read color from copy of the destination.\n");
-        fragBuilder->codeAppendf("float2 _dstTexCoord = (sk_FragCoord.xy - %s) * %s;",
+        fragBuilder->codeAppendf("half2 _dstTexCoord = (sk_FragCoord.xy - %s) * %s;",
                                  dstTopLeftName, dstCoordScaleName);
 
         if (flipY) {
             fragBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
         }
 
-        fragBuilder->codeAppendf("float4 %s = ", dstColor);
+        fragBuilder->codeAppendf("half4 %s = ", dstColor);
         fragBuilder->appendTextureLookup(args.fDstTextureSamplerHandle, "_dstTexCoord",
-                                         kVec2f_GrSLType);
+                                         kHalf2_GrSLType);
         fragBuilder->codeAppend(";");
     } else {
         needsLocalOutColor = args.fShaderCaps->requiresLocalOutputColorForFBFetch();
@@ -91,7 +89,7 @@
     if (!needsLocalOutColor) {
         outColor = args.fOutputPrimary;
     } else {
-        fragBuilder->codeAppendf("float4 %s;", outColor);
+        fragBuilder->codeAppendf("half4 %s;", outColor);
     }
 
     this->emitBlendCodeForDstRead(fragBuilder,
@@ -139,18 +137,18 @@
             fragBuilder->codeAppendf("%s *= %s;", outColor, srcCoverage);
             fragBuilder->codeAppendf("%s = %s;", outColorSecondary, srcCoverage);
         } else {
-            fragBuilder->codeAppendf("%s = float4(1.0);", outColorSecondary);
+            fragBuilder->codeAppendf("%s = half4(1.0);", outColorSecondary);
         }
     } else if (srcCoverage) {
         if (proc.isLCD()) {
-            fragBuilder->codeAppendf("float lerpRed = mix(%s.a, %s.a, %s.r);",
+            fragBuilder->codeAppendf("half lerpRed = mix(%s.a, %s.a, %s.r);",
                                      dstColor, outColor, srcCoverage);
-            fragBuilder->codeAppendf("float lerpBlue = mix(%s.a, %s.a, %s.g);",
+            fragBuilder->codeAppendf("half lerpBlue = mix(%s.a, %s.a, %s.g);",
                                      dstColor, outColor, srcCoverage);
-            fragBuilder->codeAppendf("float lerpGreen = mix(%s.a, %s.a, %s.b);",
+            fragBuilder->codeAppendf("half lerpGreen = mix(%s.a, %s.a, %s.b);",
                                      dstColor, outColor, srcCoverage);
         }
-        fragBuilder->codeAppendf("%s = %s * %s + (float4(1.0) - %s) * %s;",
+        fragBuilder->codeAppendf("%s = %s * %s + (half4(1.0) - %s) * %s;",
                                  outColor, srcCoverage, outColor, srcCoverage, dstColor);
         if (proc.isLCD()) {
             fragBuilder->codeAppendf("%s.a = max(max(lerpRed, lerpBlue), lerpGreen);", outColor);