Remove hacks for UShort2 texture coords

Plumb GPU type down for binding of vertex attributes in GL. Use that
to select between float and int versions of VertexAttribPointer.

For client code that was relying on the strange behavior of UShort2,
use shader caps to pick the appropriate GrSLType.

Bug: skia:
Change-Id: If52ea49e0a5667246687e90e088d0823dbedb921
Reviewed-on: https://skia-review.googlesource.com/155401
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp
index 02a9c46..667f13b 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.cpp
+++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp
@@ -8,6 +8,8 @@
 #include "GrBitmapTextGeoProc.h"
 
 #include "GrAtlasedShaderHelpers.h"
+#include "GrCaps.h"
+#include "GrShaderCaps.h"
 #include "GrTexture.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
 #include "glsl/GrGLSLGeometryProcessor.h"
@@ -119,7 +121,8 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color,
+GrBitmapTextGeoProc::GrBitmapTextGeoProc(const GrShaderCaps& caps,
+                                         GrColor color,
                                          const sk_sp<GrTextureProxy>* proxies,
                                          int numActiveProxies,
                                          const GrSamplerState& params, GrMaskFormat format,
@@ -136,8 +139,9 @@
     } else {
         fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
     }
-    fInTextureCoords =
-            {"inTextureCoords", kUShort2_GrVertexAttribType, kUShort2_GrSLType};
+
+    fInTextureCoords = {"inTextureCoords", kUShort2_GrVertexAttribType,
+                        caps.integerSupport() ? kUShort2_GrSLType : kFloat2_GrSLType };
     int cnt = 2;
 
     bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat ||
@@ -228,8 +232,8 @@
             break;
     }
 
-    return GrBitmapTextGeoProc::Make(GrRandomColor(d->fRandom), proxies, 1, samplerState,
-                                     format, GrTest::TestMatrix(d->fRandom),
+    return GrBitmapTextGeoProc::Make(*d->caps()->shaderCaps(), GrRandomColor(d->fRandom), proxies,
+                                     1, samplerState, format, GrTest::TestMatrix(d->fRandom),
                                      d->fRandom->nextBool());
 }
 #endif
diff --git a/src/gpu/effects/GrBitmapTextGeoProc.h b/src/gpu/effects/GrBitmapTextGeoProc.h
index d2d530e..5f671b2 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.h
+++ b/src/gpu/effects/GrBitmapTextGeoProc.h
@@ -23,13 +23,13 @@
 public:
     static constexpr int kMaxTextures = 4;
 
-    static sk_sp<GrGeometryProcessor> Make(GrColor color,
+    static sk_sp<GrGeometryProcessor> Make(const GrShaderCaps& caps, GrColor color,
                                            const sk_sp<GrTextureProxy>* proxies,
                                            int numActiveProxies,
                                            const GrSamplerState& p, GrMaskFormat format,
                                            const SkMatrix& localMatrix, bool usesW) {
         return sk_sp<GrGeometryProcessor>(
-            new GrBitmapTextGeoProc(color, proxies, numActiveProxies, p, format,
+            new GrBitmapTextGeoProc(caps, color, proxies, numActiveProxies, p, format,
                                     localMatrix, usesW));
     }
 
@@ -54,8 +54,8 @@
     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override;
 
 private:
-    GrBitmapTextGeoProc(GrColor, const sk_sp<GrTextureProxy>* proxies, int numProxies,
-                        const GrSamplerState& params, GrMaskFormat format,
+    GrBitmapTextGeoProc(const GrShaderCaps&, GrColor, const sk_sp<GrTextureProxy>* proxies,
+                        int numProxies, const GrSamplerState& params, GrMaskFormat format,
                         const SkMatrix& localMatrix, bool usesW);
 
     const Attribute& onVertexAttribute(int i) const override;
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
index 04f73c8..2ef7f9d 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
@@ -7,6 +7,8 @@
 
 #include "GrDistanceFieldGeoProc.h"
 #include "GrAtlasedShaderHelpers.h"
+#include "GrCaps.h"
+#include "GrShaderCaps.h"
 #include "GrTexture.h"
 #include "SkDistanceFieldGen.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
@@ -205,9 +207,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldA8TextGeoProc::kInColor;
-constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldA8TextGeoProc::kInTextureCoords;
 
-GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(const sk_sp<GrTextureProxy>* proxies,
+GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(const GrShaderCaps& caps,
+                                                           const sk_sp<GrTextureProxy>* proxies,
                                                            int numProxies,
                                                            const GrSamplerState& params,
 #ifdef SK_GAMMA_APPLY_TO_A8
@@ -230,6 +232,8 @@
     } else {
         fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
     }
+    fInTextureCoords = {"inTextureCoords", kUShort2_GrVertexAttribType,
+                        caps.integerSupport() ? kUShort2_GrSLType : kFloat2_GrSLType};
     this->setVertexAttributeCnt(3);
 
     if (numProxies) {
@@ -302,7 +306,8 @@
 #ifdef SK_GAMMA_APPLY_TO_A8
     float lum = d->fRandom->nextF();
 #endif
-    return GrDistanceFieldA8TextGeoProc::Make(proxies, 1,
+    return GrDistanceFieldA8TextGeoProc::Make(*d->caps()->shaderCaps(),
+                                              proxies, 1,
                                               samplerState,
 #ifdef SK_GAMMA_APPLY_TO_A8
                                               lum,
@@ -506,9 +511,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldPathGeoProc::kInPosition;
 constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldPathGeoProc::kInColor;
-constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldPathGeoProc::kInTextureCoords;
 
-GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(const SkMatrix& matrix,
+GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(const GrShaderCaps& caps,
+                                                       const SkMatrix& matrix,
                                                        const sk_sp<GrTextureProxy>* proxies,
                                                        int numProxies,
                                                        const GrSamplerState& params,
@@ -519,6 +524,8 @@
     SkASSERT(numProxies <= kMaxTextures);
     SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
 
+    fInTextureCoords = {"inTextureCoords", kUShort2_GrVertexAttribType,
+                        caps.integerSupport() ? kUShort2_GrSLType : kFloat2_GrSLType};
     this->setVertexAttributeCnt(3);
 
     if (numProxies) {
@@ -564,7 +571,7 @@
 }
 
 const GrPrimitiveProcessor::Attribute& GrDistanceFieldPathGeoProc::onVertexAttribute(int i) const {
-    return IthAttribute(i, kInPosition, kInColor, kInTextureCoords);
+    return IthAttribute(i, kInPosition, kInColor, fInTextureCoords);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -594,7 +601,8 @@
         flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0;
     }
 
-    return GrDistanceFieldPathGeoProc::Make(GrTest::TestMatrix(d->fRandom),
+    return GrDistanceFieldPathGeoProc::Make(*d->caps()->shaderCaps(),
+                                            GrTest::TestMatrix(d->fRandom),
                                             proxies, 1,
                                             samplerState,
                                             flags);
@@ -821,9 +829,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldLCDTextGeoProc::kInColor;
-constexpr GrPrimitiveProcessor::Attribute GrDistanceFieldLCDTextGeoProc::kInTextureCoords;
 
-GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc(const sk_sp<GrTextureProxy>* proxies,
+GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc(const GrShaderCaps& caps,
+                                                             const sk_sp<GrTextureProxy>* proxies,
                                                              int numProxies,
                                                              const GrSamplerState& params,
                                                              DistanceAdjust distanceAdjust,
@@ -841,6 +849,8 @@
     } else {
         fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
     }
+    fInTextureCoords = {"inTextureCoords", kUShort2_GrVertexAttribType,
+                        caps.integerSupport() ? kUShort2_GrSLType : kFloat2_GrSLType};
     this->setVertexAttributeCnt(3);
 
     if (numProxies) {
@@ -886,7 +896,7 @@
 
 const GrPrimitiveProcessor::Attribute& GrDistanceFieldLCDTextGeoProc::onVertexAttribute(
         int i) const {
-    return IthAttribute(i, fInPosition, kInColor, kInTextureCoords);
+    return IthAttribute(i, fInPosition, kInColor, fInTextureCoords);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -917,6 +927,7 @@
     }
     flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
     SkMatrix localMatrix = GrTest::TestMatrix(d->fRandom);
-    return GrDistanceFieldLCDTextGeoProc::Make(proxies, 1, samplerState, wa, flags, localMatrix);
+    return GrDistanceFieldLCDTextGeoProc::Make(*d->caps()->shaderCaps(), proxies, 1, samplerState,
+                                               wa, flags, localMatrix);
 }
 #endif
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.h b/src/gpu/effects/GrDistanceFieldGeoProc.h
index c311908..2c449f6 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.h
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.h
@@ -57,20 +57,22 @@
 
     /** The local matrix should be identity if local coords are not required by the GrPipeline. */
 #ifdef SK_GAMMA_APPLY_TO_A8
-    static sk_sp<GrGeometryProcessor> Make(const sk_sp<GrTextureProxy>* proxies,
+    static sk_sp<GrGeometryProcessor> Make(const GrShaderCaps& caps,
+                                           const sk_sp<GrTextureProxy>* proxies,
                                            int numActiveProxies,
                                            const GrSamplerState& params, float lum, uint32_t flags,
                                            const SkMatrix& localMatrixIfUsesLocalCoords) {
         return sk_sp<GrGeometryProcessor>(new GrDistanceFieldA8TextGeoProc(
-                proxies, numActiveProxies, params, lum, flags, localMatrixIfUsesLocalCoords));
+                caps, proxies, numActiveProxies, params, lum, flags, localMatrixIfUsesLocalCoords));
     }
 #else
-    static sk_sp<GrGeometryProcessor> Make(const sk_sp<GrTextureProxy>* proxies,
+    static sk_sp<GrGeometryProcessor> Make(const GrShaderCaps& caps,
+                                           const sk_sp<GrTextureProxy>* proxies,
                                            int numActiveProxies,
                                            const GrSamplerState& params, uint32_t flags,
                                            const SkMatrix& localMatrixIfUsesLocalCoords) {
         return sk_sp<GrGeometryProcessor>(new GrDistanceFieldA8TextGeoProc(
-                proxies, numActiveProxies, params, flags, localMatrixIfUsesLocalCoords));
+                caps, proxies, numActiveProxies, params, flags, localMatrixIfUsesLocalCoords));
     }
 #endif
 
@@ -80,7 +82,7 @@
 
     const Attribute& inPosition() const { return fInPosition; }
     const Attribute& inColor() const { return kInColor; }
-    const Attribute& inTextureCoords() const { return kInTextureCoords; }
+    const Attribute& inTextureCoords() const { return fInTextureCoords; }
     const SkMatrix& localMatrix() const { return fLocalMatrix; }
 #ifdef SK_GAMMA_APPLY_TO_A8
     float getDistanceAdjust() const { return fDistanceAdjust; }
@@ -95,7 +97,8 @@
     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
 
 private:
-    GrDistanceFieldA8TextGeoProc(const sk_sp<GrTextureProxy>* proxies,
+    GrDistanceFieldA8TextGeoProc(const GrShaderCaps& caps,
+                                 const sk_sp<GrTextureProxy>* proxies,
                                  int numActiveProxies,
                                  const GrSamplerState& params,
 #ifdef SK_GAMMA_APPLY_TO_A8
@@ -104,7 +107,7 @@
                                  uint32_t flags, const SkMatrix& localMatrix);
 
     const Attribute& onVertexAttribute(int i) const override {
-        return IthAttribute(i, fInPosition, kInColor, kInTextureCoords);
+        return IthAttribute(i, fInPosition, kInColor, fInTextureCoords);
     }
 
     const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
@@ -113,6 +116,7 @@
     SkISize          fAtlasSize;  // size for all textures used with fTextureSamplers[].
     SkMatrix         fLocalMatrix;
     Attribute        fInPosition;
+    Attribute        fInTextureCoords;
     uint32_t         fFlags;
 #ifdef SK_GAMMA_APPLY_TO_A8
     float            fDistanceAdjust;
@@ -120,8 +124,6 @@
 
     static constexpr Attribute kInColor =
             {"inColor", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType};
-    static constexpr Attribute kInTextureCoords =
-            {"inTextureCoords", kUShort2_GrVertexAttribType, kUShort2_GrSLType};
 
     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
 
@@ -139,12 +141,13 @@
     static constexpr int kMaxTextures = 4;
 
     /** The local matrix should be identity if local coords are not required by the GrPipeline. */
-    static sk_sp<GrGeometryProcessor> Make(const SkMatrix& matrix,
+    static sk_sp<GrGeometryProcessor> Make(const GrShaderCaps& caps,
+                                           const SkMatrix& matrix,
                                            const sk_sp<GrTextureProxy>* proxies,
                                            int numActiveProxies,
                                            const GrSamplerState& params, uint32_t flags) {
         return sk_sp<GrGeometryProcessor>(
-            new GrDistanceFieldPathGeoProc(matrix, proxies, numActiveProxies, params, flags));
+            new GrDistanceFieldPathGeoProc(caps, matrix, proxies, numActiveProxies, params, flags));
     }
 
     ~GrDistanceFieldPathGeoProc() override {}
@@ -153,7 +156,7 @@
 
     const Attribute& inPosition() const { return kInPosition; }
     const Attribute& inColor() const { return kInColor; }
-    const Attribute& inTextureCoords() const { return kInTextureCoords; }
+    const Attribute& inTextureCoords() const { return fInTextureCoords; }
     const SkMatrix& matrix() const { return fMatrix; }
     uint32_t getFlags() const { return fFlags; }
     const SkISize& atlasSize() const { return fAtlasSize; }
@@ -165,7 +168,8 @@
     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
 
 private:
-    GrDistanceFieldPathGeoProc(const SkMatrix& matrix,
+    GrDistanceFieldPathGeoProc(const GrShaderCaps& caps,
+                               const SkMatrix& matrix,
                                const sk_sp<GrTextureProxy>* proxies,
                                int numActiveProxies,
                                const GrSamplerState&, uint32_t flags);
@@ -176,13 +180,12 @@
     SkMatrix         fMatrix;     // view matrix if perspective, local matrix otherwise
     TextureSampler   fTextureSamplers[kMaxTextures];
     SkISize          fAtlasSize;  // size for all textures used with fTextureSamplers[].
+    Attribute        fInTextureCoords;
     uint32_t         fFlags;
     static constexpr Attribute kInPosition =
             {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
     static constexpr Attribute kInColor =
             {"inColor", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType};
-    static constexpr Attribute kInTextureCoords =
-            {"inTextureCoords", kUShort2_GrVertexAttribType, kUShort2_GrSLType};
 
     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
 
@@ -214,15 +217,16 @@
         }
     };
 
-    static sk_sp<GrGeometryProcessor> Make(const sk_sp<GrTextureProxy>* proxies,
+    static sk_sp<GrGeometryProcessor> Make(const GrShaderCaps& caps,
+                                           const sk_sp<GrTextureProxy>* proxies,
                                            int numActiveProxies,
                                            const GrSamplerState& params,
                                            DistanceAdjust distanceAdjust,
                                            uint32_t flags,
                                            const SkMatrix& localMatrixIfUsesLocalCoords) {
         return sk_sp<GrGeometryProcessor>(
-            new GrDistanceFieldLCDTextGeoProc(proxies, numActiveProxies, params, distanceAdjust,
-                                              flags, localMatrixIfUsesLocalCoords));
+            new GrDistanceFieldLCDTextGeoProc(caps, proxies, numActiveProxies, params,
+                                              distanceAdjust, flags, localMatrixIfUsesLocalCoords));
     }
 
     ~GrDistanceFieldLCDTextGeoProc() override {}
@@ -231,7 +235,7 @@
 
     const Attribute& inPosition() const { return fInPosition; }
     const Attribute& inColor() const { return kInColor; }
-    const Attribute& inTextureCoords() const { return kInTextureCoords; }
+    const Attribute& inTextureCoords() const { return fInTextureCoords; }
     DistanceAdjust getDistanceAdjust() const { return fDistanceAdjust; }
     uint32_t getFlags() const { return fFlags; }
     const SkMatrix& localMatrix() const { return fLocalMatrix; }
@@ -244,9 +248,9 @@
     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
 
 private:
-    GrDistanceFieldLCDTextGeoProc(const sk_sp<GrTextureProxy>* proxies, int numActiveProxies,
-                                  const GrSamplerState& params, DistanceAdjust wa, uint32_t flags,
-                                  const SkMatrix& localMatrix);
+    GrDistanceFieldLCDTextGeoProc(const GrShaderCaps& caps, const sk_sp<GrTextureProxy>* proxies,
+                                  int numActiveProxies, const GrSamplerState& params,
+                                  DistanceAdjust wa, uint32_t flags, const SkMatrix& localMatrix);
 
     const Attribute& onVertexAttribute(int) const override;
     const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
@@ -256,12 +260,11 @@
     const SkMatrix   fLocalMatrix;
     DistanceAdjust   fDistanceAdjust;
     Attribute        fInPosition;
+    Attribute        fInTextureCoords;
     uint32_t         fFlags;
 
     static constexpr Attribute kInColor =
             {"inColor", kUByte4_norm_GrVertexAttribType, kHalf4_GrSLType};
-    static constexpr Attribute kInTextureCoords =
-            {"inTextureCoords", kUShort2_GrVertexAttribType, kUShort2_GrSLType};
 
     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
 
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index b5ee46e..f33fedc 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1828,8 +1828,8 @@
         for (int i = 0; i < fHWProgram->numVertexAttributes(); ++i) {
             const auto& attrib = fHWProgram->vertexAttribute(i);
             static constexpr int kDivisor = 0;
-            attribState->set(this, attrib.fLocation, vertexBuffer, attrib.fType, vertexStride,
-                             bufferOffset + attrib.fOffset, kDivisor);
+            attribState->set(this, attrib.fLocation, vertexBuffer, attrib.fCPUType, attrib.fGPUType,
+                             vertexStride, bufferOffset + attrib.fOffset, kDivisor);
         }
     }
     if (int instanceStride = fHWProgram->instanceStride()) {
@@ -1839,8 +1839,9 @@
         for (int i = 0; i < fHWProgram->numInstanceAttributes(); ++i, ++attribIdx) {
             const auto& attrib = fHWProgram->instanceAttribute(i);
             static constexpr int kDivisor = 1;
-            attribState->set(this, attrib.fLocation, instanceBuffer, attrib.fType, instanceStride,
-                             bufferOffset + attrib.fOffset, kDivisor);
+            attribState->set(this, attrib.fLocation, instanceBuffer, attrib.fCPUType,
+                             attrib.fGPUType, instanceStride, bufferOffset + attrib.fOffset,
+                             kDivisor);
         }
     }
 }
@@ -3462,7 +3463,7 @@
     GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
     attribs->enableVertexArrays(this, 1);
     attribs->set(this, 0, fStencilClipClearArrayBuffer.get(), kFloat2_GrVertexAttribType,
-                 2 * sizeof(GrGLfloat), 0);
+                 kFloat2_GrSLType, 2 * sizeof(GrGLfloat), 0);
 
     GrXferProcessor::BlendInfo blendInfo;
     blendInfo.reset();
@@ -3574,7 +3575,7 @@
     GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
     attribs->enableVertexArrays(this, 1);
     attribs->set(this, 0, fClearProgramArrayBuffer.get(), kFloat2_GrVertexAttribType,
-                 2 * sizeof(GrGLfloat), 0);
+                 kFloat2_GrSLType, 2 * sizeof(GrGLfloat), 0);
 
     GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(dst);
     this->flushScissor(clip.scissorState(), glrt->getViewport(), origin);
@@ -3634,7 +3635,7 @@
     GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
     attribs->enableVertexArrays(this, 1);
     attribs->set(this, 0, fCopyProgramArrayBuffer.get(), kFloat2_GrVertexAttribType,
-                 2 * sizeof(GrGLfloat), 0);
+                 kFloat2_GrSLType, 2 * sizeof(GrGLfloat), 0);
 
     // dst rect edges in NDC (-1 to 1)
     int dw = dst->width();
@@ -3833,7 +3834,7 @@
     GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
     attribs->enableVertexArrays(this, 1);
     attribs->set(this, 0, fMipmapProgramArrayBuffer.get(), kFloat2_GrVertexAttribType,
-                 2 * sizeof(GrGLfloat), 0);
+                 kFloat2_GrSLType, 2 * sizeof(GrGLfloat), 0);
 
     // Set "simple" state once:
     GrXferProcessor::BlendInfo blendInfo;
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 1a2ef20..f0d0395 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -33,7 +33,8 @@
      * Additionally, these store the attribute location.
      */
     struct Attribute {
-        GrVertexAttribType fType;
+        GrVertexAttribType fCPUType;
+        GrSLType fGPUType;
         size_t fOffset;
         GrGLint fLocation;
     };
diff --git a/src/gpu/gl/GrGLVertexArray.cpp b/src/gpu/gl/GrGLVertexArray.cpp
index 2f65ed5..4646adc 100644
--- a/src/gpu/gl/GrGLVertexArray.cpp
+++ b/src/gpu/gl/GrGLVertexArray.cpp
@@ -76,70 +76,11 @@
     return {false, 0, 0};
 };
 
-static bool GrVertexAttribTypeIsIntType(const GrShaderCaps* shaderCaps,
-                                        GrVertexAttribType type) {
-    switch (type) {
-        case kFloat_GrVertexAttribType:
-            return false;
-        case kFloat2_GrVertexAttribType:
-            return false;
-        case kFloat3_GrVertexAttribType:
-            return false;
-        case kFloat4_GrVertexAttribType:
-            return false;
-        case kHalf_GrVertexAttribType:
-            return false;
-        case kHalf2_GrVertexAttribType:
-            return false;
-        case kHalf3_GrVertexAttribType:
-            return false;
-        case kHalf4_GrVertexAttribType:
-            return false;
-        case kInt2_GrVertexAttribType:
-            return true;
-        case kInt3_GrVertexAttribType:
-            return true;
-        case kInt4_GrVertexAttribType:
-            return true;
-        case kByte_GrVertexAttribType:
-            return true;
-        case kByte2_GrVertexAttribType:
-            return true;
-        case kByte3_GrVertexAttribType:
-            return true;
-        case kByte4_GrVertexAttribType:
-            return true;
-        case kUByte_GrVertexAttribType:
-            return true;
-        case kUByte2_GrVertexAttribType:
-            return true;
-        case kUByte3_GrVertexAttribType:
-            return true;
-        case kUByte4_GrVertexAttribType:
-            return true;
-        case kUByte_norm_GrVertexAttribType:
-            return false;
-        case kUByte4_norm_GrVertexAttribType:
-            return false;
-        case kShort2_GrVertexAttribType:
-            return true;
-        case kUShort2_GrVertexAttribType:
-            return shaderCaps->integerSupport(); // FIXME: caller should handle this.
-        case kUShort2_norm_GrVertexAttribType:
-            return false;
-        case kInt_GrVertexAttribType:
-            return true;
-        case kUint_GrVertexAttribType:
-            return true;
-    }
-    SK_ABORT("Unexpected attribute type");
-    return false;
-}
-
 void GrGLAttribArrayState::set(GrGLGpu* gpu,
                                int index,
                                const GrBuffer* vertexBuffer,
-                               GrVertexAttribType type,
+                               GrVertexAttribType cpuType,
+                               GrSLType gpuType,
                                GrGLsizei stride,
                                size_t offsetInBytes,
                                int divisor) {
@@ -147,13 +88,14 @@
     SkASSERT(0 == divisor || gpu->caps()->instanceAttribSupport());
     AttribArrayState* array = &fAttribArrayStates[index];
     if (array->fVertexBufferUniqueID != vertexBuffer->uniqueID() ||
-        array->fType != type ||
+        array->fCPUType != cpuType ||
+        array->fGPUType != gpuType ||
         array->fStride != stride ||
         array->fOffset != offsetInBytes) {
         gpu->bindBuffer(kVertex_GrBufferType, vertexBuffer);
-        const AttribLayout& layout = attrib_layout(type);
+        const AttribLayout& layout = attrib_layout(cpuType);
         const GrGLvoid* offsetAsPtr = reinterpret_cast<const GrGLvoid*>(offsetInBytes);
-        if (!GrVertexAttribTypeIsIntType(gpu->caps()->shaderCaps(), type)) {
+        if (GrSLTypeIsFloatType(gpuType)) {
             GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
                                                                layout.fCount,
                                                                layout.fType,
@@ -170,7 +112,8 @@
                                                                 offsetAsPtr));
         }
         array->fVertexBufferUniqueID = vertexBuffer->uniqueID();
-        array->fType = type;
+        array->fCPUType = cpuType;
+        array->fGPUType = gpuType;
         array->fStride = stride;
         array->fOffset = offsetInBytes;
     }
diff --git a/src/gpu/gl/GrGLVertexArray.h b/src/gpu/gl/GrGLVertexArray.h
index e460c04..93bd526 100644
--- a/src/gpu/gl/GrGLVertexArray.h
+++ b/src/gpu/gl/GrGLVertexArray.h
@@ -40,7 +40,8 @@
     void set(GrGLGpu*,
              int attribIndex,
              const GrBuffer* vertexBuffer,
-             GrVertexAttribType type,
+             GrVertexAttribType cpuType,
+             GrSLType gpuType,
              GrGLsizei stride,
              size_t offsetInBytes,
              int divisor = 0);
@@ -77,7 +78,8 @@
         }
 
         GrGpuResource::UniqueID   fVertexBufferUniqueID;
-        GrVertexAttribType        fType;
+        GrVertexAttribType        fCPUType;
+        GrSLType                  fGPUType;
         GrGLsizei                 fStride;
         size_t                    fOffset;
         int                       fDivisor;
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index be72881..3904265 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -136,7 +136,8 @@
     fAttributes.reset(
             new GrGLProgram::Attribute[fVertexAttributeCnt + fInstanceAttributeCnt]);
     auto addAttr = [&](int i, const auto& a, size_t* stride) {
-        fAttributes[i].fType = a.cpuType();
+        fAttributes[i].fCPUType = a.cpuType();
+        fAttributes[i].fGPUType = a.gpuType();
         fAttributes[i].fOffset = *stride;
         *stride += a.sizeAlign4();
         fAttributes[i].fLocation = i;
diff --git a/src/gpu/glsl/GrGLSL.cpp b/src/gpu/glsl/GrGLSL.cpp
index 848f571..694aaa7 100644
--- a/src/gpu/glsl/GrGLSL.cpp
+++ b/src/gpu/glsl/GrGLSL.cpp
@@ -71,14 +71,7 @@
         case kUShort_GrSLType:
             return "ushort";
         case kUShort2_GrSLType:
-            if (shaderCaps->integerSupport()) {
-                return "ushort2";
-            } else {
-                // uint2 (aka uvec2) isn't supported in GLSL ES 1.00/GLSL 1.20
-                // FIXME: this should be handled by the client code rather than relying on
-                // unconventional ushort2 behavior.
-                return "float2";
-            }
+            return "ushort2";
         case kUShort3_GrSLType:
             return "ushort3";
         case kUShort4_GrSLType:
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp
index ba39b97..b45b2cf 100644
--- a/src/gpu/ops/GrAtlasTextOp.cpp
+++ b/src/gpu/ops/GrAtlasTextOp.cpp
@@ -7,6 +7,7 @@
 
 #include "GrAtlasTextOp.h"
 
+#include "GrCaps.h"
 #include "GrContext.h"
 #include "GrContextPriv.h"
 #include "GrMemoryPool.h"
@@ -312,13 +313,14 @@
 
     bool vmPerspective = fGeoData[0].fViewMatrix.hasPerspective();
     if (this->usesDistanceFields()) {
-        flushInfo.fGeometryProcessor = this->setupDfProcessor(proxies, numActiveProxies);
+        flushInfo.fGeometryProcessor = this->setupDfProcessor(*target->caps().shaderCaps(),
+                                                              proxies, numActiveProxies);
     } else {
         GrSamplerState samplerState = fNeedsGlyphTransform ? GrSamplerState::ClampBilerp()
                                                            : GrSamplerState::ClampNearest();
         flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
-            this->color(), proxies, numActiveProxies, samplerState, maskFormat,
-            localMatrix, vmPerspective);
+            *target->caps().shaderCaps(), this->color(), proxies, numActiveProxies, samplerState,
+            maskFormat, localMatrix, vmPerspective);
     }
 
     flushInfo.fGlyphsToFlush = 0;
@@ -521,7 +523,8 @@
 
 // TODO trying to figure out why lcd is so whack
 // (see comments in GrTextContext::ComputeCanonicalColor)
-sk_sp<GrGeometryProcessor> GrAtlasTextOp::setupDfProcessor(const sk_sp<GrTextureProxy>* proxies,
+sk_sp<GrGeometryProcessor> GrAtlasTextOp::setupDfProcessor(const GrShaderCaps& caps,
+                                                           const sk_sp<GrTextureProxy>* proxies,
                                                            unsigned int numActiveProxies) const {
     bool isLCD = this->isLCD();
 
@@ -546,7 +549,7 @@
         GrDistanceFieldLCDTextGeoProc::DistanceAdjust widthAdjust =
                 GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(
                         redCorrection, greenCorrection, blueCorrection);
-        return GrDistanceFieldLCDTextGeoProc::Make(proxies, numActiveProxies,
+        return GrDistanceFieldLCDTextGeoProc::Make(caps, proxies, numActiveProxies,
                                                    GrSamplerState::ClampBilerp(), widthAdjust,
                                                    fDFGPFlags, localMatrix);
     } else {
@@ -558,11 +561,11 @@
             correction = fDistanceAdjustTable->getAdjustment(lum >> kDistanceAdjustLumShift,
                                                              fUseGammaCorrectDistanceTable);
         }
-        return GrDistanceFieldA8TextGeoProc::Make(proxies, numActiveProxies,
+        return GrDistanceFieldA8TextGeoProc::Make(caps, proxies, numActiveProxies,
                                                   GrSamplerState::ClampBilerp(),
                                                   correction, fDFGPFlags, localMatrix);
 #else
-        return GrDistanceFieldA8TextGeoProc::Make(proxies, numActiveProxies,
+        return GrDistanceFieldA8TextGeoProc::Make(caps, proxies, numActiveProxies,
                                                   GrSamplerState::ClampBilerp(),
                                                   fDFGPFlags, localMatrix);
 #endif
diff --git a/src/gpu/ops/GrAtlasTextOp.h b/src/gpu/ops/GrAtlasTextOp.h
index e6e08dc..174f04c 100644
--- a/src/gpu/ops/GrAtlasTextOp.h
+++ b/src/gpu/ops/GrAtlasTextOp.h
@@ -151,7 +151,8 @@
 
     CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override;
 
-    sk_sp<GrGeometryProcessor> setupDfProcessor(const sk_sp<GrTextureProxy>* proxies,
+    sk_sp<GrGeometryProcessor> setupDfProcessor(const GrShaderCaps& caps,
+                                                const sk_sp<GrTextureProxy>* proxies,
                                                 unsigned int numActiveProxies) const;
 
     SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index c480bc0..220b219 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -348,8 +348,8 @@
                 matrix = &SkMatrix::I();
             }
             flushInfo.fGeometryProcessor = GrDistanceFieldPathGeoProc::Make(
-                    *matrix, fAtlas->getProxies(), fAtlas->numActivePages(),
-                    GrSamplerState::ClampBilerp(), flags);
+                    *target->caps().shaderCaps(), *matrix, fAtlas->getProxies(),
+                    fAtlas->numActivePages(), GrSamplerState::ClampBilerp(), flags);
         } else {
             SkMatrix invert;
             if (fHelper.usesLocalCoords()) {
@@ -359,9 +359,9 @@
             }
 
             flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
-                    this->color(), fAtlas->getProxies(), fAtlas->numActivePages(),
-                    GrSamplerState::ClampNearest(), kA8_GrMaskFormat, invert,
-                    false);
+                    *target->caps().shaderCaps(), this->color(), fAtlas->getProxies(),
+                    fAtlas->numActivePages(), GrSamplerState::ClampNearest(), kA8_GrMaskFormat,
+                    invert, false);
         }
 
         // allocate vertices