Improve GLSL integer support

 - Adds shader types for uint.
 - Adds a cap for integer support.
 - Uses glVertexAttribIPointer for integer attribs.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1669853002

Committed: https://skia.googlesource.com/skia/+/3a2caf8ecf38124f4ad21a0f6c4dabfcfa17911a

Review URL: https://codereview.chromium.org/1669853002
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h
index 944fb14..fc68206 100644
--- a/include/gpu/GrCaps.h
+++ b/include/gpu/GrCaps.h
@@ -62,6 +62,7 @@
     bool pathRenderingSupport() const { return fPathRenderingSupport; }
     bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
     bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
+    bool integerSupport() const { return fIntegerSupport; }
 
     /**
     * Get the precision info for a variable of type kFloat_GrSLType, kVec2f_GrSLType, etc in a
@@ -109,6 +110,7 @@
     bool fPathRenderingSupport : 1;
     bool fDstReadInShaderSupport : 1;
     bool fDualSourceBlendingSupport : 1;
+    bool fIntegerSupport : 1;
 
     bool fShaderPrecisionVaries;
     PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount];
diff --git a/include/gpu/GrTypesPriv.h b/include/gpu/GrTypesPriv.h
index bc107b5..4026eb7 100644
--- a/include/gpu/GrTypesPriv.h
+++ b/include/gpu/GrTypesPriv.h
@@ -29,8 +29,9 @@
     kSampler2DRect_GrSLType,
     kBool_GrSLType,
     kInt_GrSLType,
+    kUint_GrSLType,
 
-    kLast_GrSLType = kInt_GrSLType
+    kLast_GrSLType = kUint_GrSLType
 };
 static const int kGrSLTypeCount = kLast_GrSLType + 1;
 
@@ -67,7 +68,7 @@
  */
 static inline int GrSLTypeVectorCount(GrSLType type) {
     SkASSERT(type >= 0 && type < static_cast<GrSLType>(kGrSLTypeCount));
-    static const int kCounts[] = { -1, 1, 2, 3, 4, -1, -1, -1, -1, -1, -1, -1 };
+    static const int kCounts[] = { -1, 1, 2, 3, 4, -1, -1, -1, -1, -1, 1, 1, 1 };
     return kCounts[type];
 
     GR_STATIC_ASSERT(0 == kVoid_GrSLType);
@@ -82,6 +83,7 @@
     GR_STATIC_ASSERT(9 == kSampler2DRect_GrSLType);
     GR_STATIC_ASSERT(10 == kBool_GrSLType);
     GR_STATIC_ASSERT(11 == kInt_GrSLType);
+    GR_STATIC_ASSERT(12 == kUint_GrSLType);
     GR_STATIC_ASSERT(SK_ARRAY_COUNT(kCounts) == kGrSLTypeCount);
 }
 
@@ -114,13 +116,14 @@
     GR_STATIC_ASSERT(9 == kSampler2DRect_GrSLType);
     GR_STATIC_ASSERT(10 == kBool_GrSLType);
     GR_STATIC_ASSERT(11 == kInt_GrSLType);
-    GR_STATIC_ASSERT(12 == kGrSLTypeCount);
+    GR_STATIC_ASSERT(12 == kUint_GrSLType);
+    GR_STATIC_ASSERT(13 == kGrSLTypeCount);
 }
 
 /** Is the shading language type integral (including vectors/matrices)? */
 static inline bool GrSLTypeIsIntType(GrSLType type) {
     SkASSERT(type >= 0 && type < static_cast<GrSLType>(kGrSLTypeCount));
-    return type == kInt_GrSLType;
+    return type >= kInt_GrSLType;
 
     GR_STATIC_ASSERT(0 == kVoid_GrSLType);
     GR_STATIC_ASSERT(1 == kFloat_GrSLType);
@@ -134,7 +137,8 @@
     GR_STATIC_ASSERT(9 == kSampler2DRect_GrSLType);
     GR_STATIC_ASSERT(10 == kBool_GrSLType);
     GR_STATIC_ASSERT(11 == kInt_GrSLType);
-    GR_STATIC_ASSERT(12 == kGrSLTypeCount);
+    GR_STATIC_ASSERT(12 == kUint_GrSLType);
+    GR_STATIC_ASSERT(13 == kGrSLTypeCount);
 }
 
 /** Is the shading language type numeric (including vectors/matrices)? */
@@ -158,6 +162,7 @@
         0,                        // kSampler2DRect_GrSLType
         0,                        // kBool_GrSLType
         0,                        // kInt_GrSLType
+        0,                        // kUint_GrSLType
     };
     return kSizes[type];
 
@@ -173,7 +178,8 @@
     GR_STATIC_ASSERT(9 == kSampler2DRect_GrSLType);
     GR_STATIC_ASSERT(10 == kBool_GrSLType);
     GR_STATIC_ASSERT(11 == kInt_GrSLType);
-    GR_STATIC_ASSERT(12 == kGrSLTypeCount);
+    GR_STATIC_ASSERT(12 == kUint_GrSLType);
+    GR_STATIC_ASSERT(13 == kGrSLTypeCount);
 }
 
 static inline bool GrSLTypeIsSamplerType(GrSLType type) {
@@ -202,8 +208,9 @@
     kVec2s_GrVertexAttribType,   // vector of 2 shorts, e.g. texture coordinates
 
     kInt_GrVertexAttribType,
+    kUint_GrVertexAttribType,
     
-    kLast_GrVertexAttribType = kInt_GrVertexAttribType
+    kLast_GrVertexAttribType = kUint_GrVertexAttribType
 };
 static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
 
@@ -211,7 +218,8 @@
  * Returns the vector size of the type.
  */
 static inline int GrVertexAttribTypeVectorCount(GrVertexAttribType type) {
-    static const int kCounts[] = { 1, 2, 3, 4, 1, 4, 2, 1 };
+    SkASSERT(type >= 0 && type < kGrVertexAttribTypeCount);
+    static const int kCounts[] = { 1, 2, 3, 4, 1, 4, 2, 1, 1 };
     return kCounts[type];
 
     GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
@@ -222,6 +230,7 @@
     GR_STATIC_ASSERT(5 == kVec4ub_GrVertexAttribType);
     GR_STATIC_ASSERT(6 == kVec2s_GrVertexAttribType);
     GR_STATIC_ASSERT(7 == kInt_GrVertexAttribType);
+    GR_STATIC_ASSERT(8 == kUint_GrVertexAttribType);
     GR_STATIC_ASSERT(SK_ARRAY_COUNT(kCounts) == kGrVertexAttribTypeCount);
 }
 
@@ -237,7 +246,8 @@
         1*sizeof(char),         // kUByte_GrVertexAttribType
         4*sizeof(char),         // kVec4ub_GrVertexAttribType
         2*sizeof(int16_t),      // kVec2s_GrVertexAttribType
-        sizeof(int32_t)         // kInt_GrVertexAttribType
+        sizeof(int32_t),        // kInt_GrVertexAttribType
+        sizeof(uint32_t)        // kUint_GrVertexAttribType
     };
     return kSizes[type];
 
@@ -249,10 +259,30 @@
     GR_STATIC_ASSERT(5 == kVec4ub_GrVertexAttribType);
     GR_STATIC_ASSERT(6 == kVec2s_GrVertexAttribType);
     GR_STATIC_ASSERT(7 == kInt_GrVertexAttribType);
+    GR_STATIC_ASSERT(8 == kUint_GrVertexAttribType);
     GR_STATIC_ASSERT(SK_ARRAY_COUNT(kSizes) == kGrVertexAttribTypeCount);
 }
 
 /**
+ * Is the attrib type integral?
+ */
+static inline bool GrVertexAttribTypeIsIntType(GrVertexAttribType type) {
+    SkASSERT(type >= 0 && type < static_cast<GrVertexAttribType>(kGrVertexAttribTypeCount));
+    return type >= kInt_GrVertexAttribType;
+
+    GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
+    GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
+    GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
+    GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
+    GR_STATIC_ASSERT(4 == kUByte_GrVertexAttribType);
+    GR_STATIC_ASSERT(5 == kVec4ub_GrVertexAttribType);
+    GR_STATIC_ASSERT(6 == kVec2s_GrVertexAttribType);
+    GR_STATIC_ASSERT(7 == kInt_GrVertexAttribType);
+    GR_STATIC_ASSERT(8 == kUint_GrVertexAttribType);
+    GR_STATIC_ASSERT(9 == kGrVertexAttribTypeCount);
+}
+
+/**
  * converts a GrVertexAttribType to a GrSLType
  */
 static inline GrSLType GrVertexAttribTypeToSLType(GrVertexAttribType type) {
@@ -273,6 +303,8 @@
             return kVec4f_GrSLType;
         case kInt_GrVertexAttribType:
             return kInt_GrSLType;
+        case kUint_GrVertexAttribType:
+            return kUint_GrSLType;
     }
 }
 
diff --git a/include/gpu/gl/GrGLFunctions.h b/include/gpu/gl/GrGLFunctions.h
index 118269b..4d0d654 100644
--- a/include/gpu/gl/GrGLFunctions.h
+++ b/include/gpu/gl/GrGLFunctions.h
@@ -178,6 +178,7 @@
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLVertexAttrib3fvProc)(GrGLuint indx, const GrGLfloat* values);
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLVertexAttrib4fvProc)(GrGLuint indx, const GrGLfloat* values);
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLVertexAttribDivisorProc)(GrGLuint index, GrGLuint divisor);
+typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLVertexAttribIPointerProc)(GrGLuint indx, GrGLint size, GrGLenum type, GrGLsizei stride, const GrGLvoid* ptr);
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLVertexAttribPointerProc)(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr);
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLViewportProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height);
 
diff --git a/include/gpu/gl/GrGLInterface.h b/include/gpu/gl/GrGLInterface.h
index 841a513..1a91afb 100644
--- a/include/gpu/gl/GrGLInterface.h
+++ b/include/gpu/gl/GrGLInterface.h
@@ -310,6 +310,7 @@
         GrGLFunction<GrGLVertexAttrib3fvProc> fVertexAttrib3fv;
         GrGLFunction<GrGLVertexAttrib4fvProc> fVertexAttrib4fv;
         GrGLFunction<GrGLVertexAttribDivisorProc> fVertexAttribDivisor;
+        GrGLFunction<GrGLVertexAttribIPointerProc> fVertexAttribIPointer;
         GrGLFunction<GrGLVertexAttribPointerProc> fVertexAttribPointer;
         GrGLFunction<GrGLViewportProc> fViewport;
 
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 46f4935..2568e56 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -15,6 +15,7 @@
     fPathRenderingSupport = false;
     fDstReadInShaderSupport = false;
     fDualSourceBlendingSupport = false;
+    fIntegerSupport = false;
     fShaderPrecisionVaries = false;
 }
 
@@ -50,6 +51,7 @@
     r.appendf("Path Rendering Support             : %s\n", gNY[fPathRenderingSupport]);
     r.appendf("Dst Read In Shader Support         : %s\n", gNY[fDstReadInShaderSupport]);
     r.appendf("Dual Source Blending Support       : %s\n", gNY[fDualSourceBlendingSupport]);
+    r.appendf("Integer Support                    : %s\n", gNY[fIntegerSupport]);
 
     r.appendf("Shader Float Precisions (varies: %s):\n", gNY[fShaderPrecisionVaries]);
 
diff --git a/src/gpu/gl/GrGLAssembleInterface.cpp b/src/gpu/gl/GrGLAssembleInterface.cpp
index 30eed62..e52d302 100644
--- a/src/gpu/gl/GrGLAssembleInterface.cpp
+++ b/src/gpu/gl/GrGLAssembleInterface.cpp
@@ -246,6 +246,10 @@
         GET_PROC(VertexAttribDivisor);
     }
 
+    if (glVer >= GR_GL_VER(3,0)) {
+        GET_PROC(VertexAttribIPointer);
+    }
+
     GET_PROC(VertexAttribPointer);
     GET_PROC(Viewport);
     GET_PROC(BindFragDataLocationIndexed);
@@ -678,6 +682,10 @@
         GET_PROC_SUFFIX(VertexAttribDivisor, EXT);
     }
 
+    if (version >= GR_GL_VER(3,0)) {
+        GET_PROC(VertexAttribIPointer);
+    }
+
     GET_PROC(VertexAttribPointer);
     GET_PROC(Viewport);
     GET_PROC(BindFramebuffer);
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 3b06c57..c2ace6c 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -279,12 +279,17 @@
         // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
         glslCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2) &&
             ctxInfo.glslGeneration() >= k150_GrGLSLGeneration;
+        glslCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
+            ctxInfo.glslGeneration() >= k130_GrGLSLGeneration;
     }
     else {
         glslCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blend_func_extended");
 
         glslCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0) ||
             ctxInfo.hasExtension("GL_OES_standard_derivatives");
+
+        glslCaps->fIntegerSupport = ctxInfo.version() >= GR_GL_VER(3, 0) &&
+            ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; // We use this value for GLSL ES 3.0.
     }
 
     if (ctxInfo.hasExtension("GL_EXT_shader_pixel_local_storage")) {
diff --git a/src/gpu/gl/GrGLCreateNullInterface.cpp b/src/gpu/gl/GrGLCreateNullInterface.cpp
index f0a3e7d..f56b1d9 100644
--- a/src/gpu/gl/GrGLCreateNullInterface.cpp
+++ b/src/gpu/gl/GrGLCreateNullInterface.cpp
@@ -465,8 +465,9 @@
     functions->fVertexAttrib2fv = noOpGLVertexAttrib2fv;
     functions->fVertexAttrib3fv = noOpGLVertexAttrib3fv;
     functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv;
-    functions->fVertexAttribPointer = noOpGLVertexAttribPointer;
     functions->fVertexAttribDivisor = noOpGLVertexAttribDivisor;
+    functions->fVertexAttribIPointer = noOpGLVertexAttribIPointer;
+    functions->fVertexAttribPointer = noOpGLVertexAttribPointer;
     functions->fViewport = nullGLViewport;
     functions->fBindFramebuffer = nullGLBindFramebuffer;
     functions->fBindRenderbuffer = nullGLBindRenderbuffer;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index f916b4f..cd28eca 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1759,9 +1759,7 @@
             attribState->set(this,
                              attribIndex,
                              vbuf->bufferID(),
-                             GrGLAttribTypeToLayout(attribType).fCount,
-                             GrGLAttribTypeToLayout(attribType).fType,
-                             GrGLAttribTypeToLayout(attribType).fNormalized,
+                             attribType,
                              stride,
                              reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + offset));
             offset += attrib.fOffset;
@@ -2540,7 +2538,7 @@
 
     GrGLAttribArrayState* attribs =
             this->fHWGeometryState.bindArrayAndBufferToDraw(this, arrayBuffer);
-    attribs->set(this, 0, arrayBuffer, 2, GR_GL_FLOAT, false, 2 * sizeof(GrGLfloat), 0);
+    attribs->set(this, 0, arrayBuffer, kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat), 0);
     attribs->disableUnusedArrays(this, 0x1);
 
     GL_CALL(Uniform4f(posXformUniform, bounds.width(), bounds.height(), bounds.left(), 
@@ -3481,7 +3479,8 @@
 
     GrGLAttribArrayState* attribs =
         fHWGeometryState.bindArrayAndBufferToDraw(this, fWireRectArrayBuffer);
-    attribs->set(this, 0, fWireRectArrayBuffer, 2, GR_GL_FLOAT, false, 2 * sizeof(GrGLfloat), 0);
+    attribs->set(this, 0, fWireRectArrayBuffer, kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat),
+                 0);
     attribs->disableUnusedArrays(this, 0x1);
 
     GL_CALL(Uniform4fv(fWireRectProgram.fRectUniform, 1, edges));
@@ -3526,7 +3525,8 @@
 
     GrGLAttribArrayState* attribs =
         fHWGeometryState.bindArrayAndBufferToDraw(this, fCopyProgramArrayBuffer);
-    attribs->set(this, 0, fCopyProgramArrayBuffer, 2, GR_GL_FLOAT, false, 2 * sizeof(GrGLfloat), 0);
+    attribs->set(this, 0, fCopyProgramArrayBuffer, kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat),
+                 0);
     attribs->disableUnusedArrays(this, 0x1);
 
     // dst rect edges in NDC (-1 to 1)
diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp
index 925f081..c09efae 100644
--- a/src/gpu/gl/GrGLInterface.cpp
+++ b/src/gpu/gl/GrGLInterface.cpp
@@ -416,6 +416,13 @@
         }
     }
 
+    // glVertexAttribIPointer was added in version 3.0 of both desktop and ES.
+    if (glVer >= GR_GL_VER(3, 0)) {
+        if (NULL == fFunctions.fVertexAttribIPointer) {
+            RETURN_FALSE_INTERFACE
+        }
+    }
+
     if (kGL_GrGLStandard == fStandard) {
         if (glVer >= GR_GL_VER(3, 0) || fExtensions.has("GL_ARB_vertex_array_object")) {
             if (nullptr == fFunctions.fBindVertexArray ||
diff --git a/src/gpu/gl/GrGLNoOpInterface.cpp b/src/gpu/gl/GrGLNoOpInterface.cpp
index 113c47d..f08d737 100644
--- a/src/gpu/gl/GrGLNoOpInterface.cpp
+++ b/src/gpu/gl/GrGLNoOpInterface.cpp
@@ -394,6 +394,13 @@
  GrGLvoid GR_GL_FUNCTION_TYPE noOpGLVertexAttrib4fv(GrGLuint indx, const GrGLfloat* values) {
 }
 
+GrGLvoid GR_GL_FUNCTION_TYPE noOpGLVertexAttribIPointer(GrGLuint indx,
+                                                        GrGLint size,
+                                                        GrGLenum type,
+                                                        GrGLsizei stride,
+                                                        const GrGLvoid* ptr) {
+}
+
 GrGLvoid GR_GL_FUNCTION_TYPE noOpGLVertexAttribPointer(GrGLuint indx,
                                                        GrGLint size,
                                                        GrGLenum type,
diff --git a/src/gpu/gl/GrGLNoOpInterface.h b/src/gpu/gl/GrGLNoOpInterface.h
index 627de63..44894b7 100644
--- a/src/gpu/gl/GrGLNoOpInterface.h
+++ b/src/gpu/gl/GrGLNoOpInterface.h
@@ -287,6 +287,12 @@
 
  GrGLvoid GR_GL_FUNCTION_TYPE noOpGLVertexAttrib4fv(GrGLuint indx, const GrGLfloat* values);
 
+GrGLvoid GR_GL_FUNCTION_TYPE noOpGLVertexAttribIPointer(GrGLuint indx,
+                                                        GrGLint size,
+                                                        GrGLenum type,
+                                                        GrGLsizei stride,
+                                                        const GrGLvoid* ptr);
+
 GrGLvoid GR_GL_FUNCTION_TYPE noOpGLVertexAttribPointer(GrGLuint indx,
                                                        GrGLint size,
                                                        GrGLenum type,
diff --git a/src/gpu/gl/GrGLVertexArray.cpp b/src/gpu/gl/GrGLVertexArray.cpp
index 8cfa8d6..2048e2c 100644
--- a/src/gpu/gl/GrGLVertexArray.cpp
+++ b/src/gpu/gl/GrGLVertexArray.cpp
@@ -8,14 +8,38 @@
 #include "GrGLVertexArray.h"
 #include "GrGLGpu.h"
 
+struct AttribLayout {
+    GrGLint     fCount;
+    GrGLenum    fType;
+    GrGLboolean fNormalized;  // Only used by floating point types.
+};
 
+static const AttribLayout gLayouts[kGrVertexAttribTypeCount] = {
+    {1, GR_GL_FLOAT, false},         // kFloat_GrVertexAttribType
+    {2, GR_GL_FLOAT, false},         // kVec2f_GrVertexAttribType
+    {3, GR_GL_FLOAT, false},         // kVec3f_GrVertexAttribType
+    {4, GR_GL_FLOAT, false},         // kVec4f_GrVertexAttribType
+    {1, GR_GL_UNSIGNED_BYTE, true},  // kUByte_GrVertexAttribType
+    {4, GR_GL_UNSIGNED_BYTE, true},  // kVec4ub_GrVertexAttribType
+    {2, GR_GL_SHORT, false},         // kVec2s_GrVertexAttribType
+    {1, GR_GL_INT, false},           // kInt_GrVertexAttribType
+    {1, GR_GL_UNSIGNED_INT, false},  // kUint_GrVertexAttribType
+};
+
+GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
+GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
+GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
+GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
+GR_STATIC_ASSERT(4 == kUByte_GrVertexAttribType);
+GR_STATIC_ASSERT(5 == kVec4ub_GrVertexAttribType);
+GR_STATIC_ASSERT(6 == kVec2s_GrVertexAttribType);
+GR_STATIC_ASSERT(7 == kInt_GrVertexAttribType);
+GR_STATIC_ASSERT(8 == kUint_GrVertexAttribType);
 
 void GrGLAttribArrayState::set(GrGLGpu* gpu,
                                int index,
                                GrGLuint vertexBufferID,
-                               GrGLint size,
-                               GrGLenum type,
-                               GrGLboolean normalized,
+                               GrVertexAttribType type,
                                GrGLsizei stride,
                                GrGLvoid* offset) {
     SkASSERT(index >= 0 && index < fAttribArrayStates.count());
@@ -27,22 +51,31 @@
     }
     if (!array->fAttribPointerIsValid ||
         array->fVertexBufferID != vertexBufferID ||
-        array->fSize != size ||
-        array->fNormalized != normalized ||
+        array->fType != type ||
         array->fStride != stride ||
         array->fOffset != offset) {
 
         gpu->bindVertexBuffer(vertexBufferID);
-        GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
-                                                           size,
-                                                           type,
-                                                           normalized,
-                                                           stride,
-                                                           offset));
+        const AttribLayout& layout = gLayouts[type];
+        if (!GrVertexAttribTypeIsIntType(type)) {
+            GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
+                                                               layout.fCount,
+                                                               layout.fType,
+                                                               layout.fNormalized,
+                                                               stride,
+                                                               offset));
+        } else {
+            SkASSERT(gpu->caps()->shaderCaps()->integerSupport());
+            SkASSERT(!layout.fNormalized);
+            GR_GL_CALL(gpu->glInterface(), VertexAttribIPointer(index,
+                                                                layout.fCount,
+                                                                layout.fType,
+                                                                stride,
+                                                                offset));
+        }
         array->fAttribPointerIsValid = true;
         array->fVertexBufferID = vertexBufferID;
-        array->fSize = size;
-        array->fNormalized = normalized;
+        array->fType = type;
         array->fStride = stride;
         array->fOffset = offset;
     }
diff --git a/src/gpu/gl/GrGLVertexArray.h b/src/gpu/gl/GrGLVertexArray.h
index 0a5dea6..f5a9767 100644
--- a/src/gpu/gl/GrGLVertexArray.h
+++ b/src/gpu/gl/GrGLVertexArray.h
@@ -17,35 +17,6 @@
 class GrGLIndexBuffer;
 class GrGLGpu;
 
-struct GrGLAttribLayout {
-    GrGLint     fCount;
-    GrGLenum    fType;
-    GrGLboolean fNormalized;
-};
-
-static inline const GrGLAttribLayout& GrGLAttribTypeToLayout(GrVertexAttribType type) {
-    static const GrGLAttribLayout kLayouts[kGrVertexAttribTypeCount] = {
-        {1, GR_GL_FLOAT, false},         // kFloat_GrVertexAttribType
-        {2, GR_GL_FLOAT, false},         // kVec2f_GrVertexAttribType
-        {3, GR_GL_FLOAT, false},         // kVec3f_GrVertexAttribType
-        {4, GR_GL_FLOAT, false},         // kVec4f_GrVertexAttribType
-        {1, GR_GL_UNSIGNED_BYTE, true},  // kUByte_GrVertexAttribType
-        {4, GR_GL_UNSIGNED_BYTE, true},  // kVec4ub_GrVertexAttribType
-        {2, GR_GL_SHORT, false},         // kVec2s_GrVertexAttribType
-        {4, GR_GL_INT, false},           // kInt_GrVertexAttribType
-    };
-    GR_STATIC_ASSERT(0 == kFloat_GrVertexAttribType);
-    GR_STATIC_ASSERT(1 == kVec2f_GrVertexAttribType);
-    GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType);
-    GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType);
-    GR_STATIC_ASSERT(4 == kUByte_GrVertexAttribType);
-    GR_STATIC_ASSERT(5 == kVec4ub_GrVertexAttribType);
-    GR_STATIC_ASSERT(6 == kVec2s_GrVertexAttribType);
-    GR_STATIC_ASSERT(7 == kInt_GrVertexAttribType);
-    GR_STATIC_ASSERT(SK_ARRAY_COUNT(kLayouts) == kGrVertexAttribTypeCount);
-    return kLayouts[type];
-}
-
 /**
  * This sets and tracks the vertex attribute array state. It is used internally by GrGLVertexArray
  * (below) but is separate because it is also used to track the state of vertex array object 0.
@@ -71,9 +42,7 @@
     void set(GrGLGpu*,
              int attribIndex,
              GrGLuint vertexBufferID,
-             GrGLint size,
-             GrGLenum type,
-             GrGLboolean normalized,
+             GrVertexAttribType type,
              GrGLsizei stride,
              GrGLvoid* offset);
 
@@ -115,15 +84,13 @@
                 fAttribPointerIsValid = false;
             }
 
-            bool        fEnableIsValid;
-            bool        fAttribPointerIsValid;
-            bool        fEnabled;
-            GrGLuint    fVertexBufferID;
-            GrGLint     fSize;
-            GrGLenum    fType;
-            GrGLboolean fNormalized;
-            GrGLsizei   fStride;
-            GrGLvoid*   fOffset;
+            bool                  fEnableIsValid;
+            bool                  fAttribPointerIsValid;
+            bool                  fEnabled;
+            GrGLuint              fVertexBufferID;
+            GrVertexAttribType    fType;
+            GrGLsizei             fStride;
+            GrGLvoid*             fOffset;
     };
 
     SkSTArray<16, AttribArrayState, true> fAttribArrayStates;
diff --git a/src/gpu/gl/SkNullGLContext.cpp b/src/gpu/gl/SkNullGLContext.cpp
index dafa1ef..68b19ce 100644
--- a/src/gpu/gl/SkNullGLContext.cpp
+++ b/src/gpu/gl/SkNullGLContext.cpp
@@ -514,8 +514,9 @@
     functions->fVertexAttrib2fv = noOpGLVertexAttrib2fv;
     functions->fVertexAttrib3fv = noOpGLVertexAttrib3fv;
     functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv;
-    functions->fVertexAttribPointer = noOpGLVertexAttribPointer;
     functions->fVertexAttribDivisor = noOpGLVertexAttribDivisor;
+    functions->fVertexAttribIPointer = noOpGLVertexAttribIPointer;
+    functions->fVertexAttribPointer = noOpGLVertexAttribPointer;
     functions->fViewport = nullGLViewport;
     functions->fBindFramebuffer = nullGLBindFramebuffer;
     functions->fBindRenderbuffer = nullGLBindRenderbuffer;
diff --git a/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp b/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
index bcc3007..2118c02 100644
--- a/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
+++ b/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
@@ -956,8 +956,9 @@
     functions->fVertexAttrib2fv = noOpGLVertexAttrib2fv;
     functions->fVertexAttrib3fv = noOpGLVertexAttrib3fv;
     functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv;
-    functions->fVertexAttribPointer = noOpGLVertexAttribPointer;
     functions->fVertexAttribDivisor = noOpGLVertexAttribDivisor;
+    functions->fVertexAttribIPointer = noOpGLVertexAttribIPointer;
+    functions->fVertexAttribPointer = noOpGLVertexAttribPointer;
     functions->fViewport = noOpGLViewport;
     functions->fBindFramebuffer = debugGLBindFramebuffer;
     functions->fBindRenderbuffer = debugGLBindRenderbuffer;
diff --git a/src/gpu/glsl/GrGLSL.h b/src/gpu/glsl/GrGLSL.h
index dc53d7b..6fc8f83 100644
--- a/src/gpu/glsl/GrGLSL.h
+++ b/src/gpu/glsl/GrGLSL.h
@@ -104,6 +104,8 @@
             return "bool";
         case kInt_GrSLType:
             return "int";
+        case kUint_GrSLType:
+            return "uint";
         default:
             SkFAIL("Unknown shader var type.");
             return ""; // suppress warning