| Index: src/gpu/gl/GrGLProgramDesc.cpp | 
| diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp | 
| index 68020a92d5977accaa513eabb52944a6ffffdec9..dde0a3e619cf8b634784f9634a82d2bb0cd5a731 100644 | 
| --- a/src/gpu/gl/GrGLProgramDesc.cpp | 
| +++ b/src/gpu/gl/GrGLProgramDesc.cpp | 
| @@ -17,24 +17,27 @@ | 
| #include "glsl/GrGLSLFragmentShaderBuilder.h" | 
| #include "glsl/GrGLSLCaps.h" | 
|  | 
| -static uint8_t texture_target_key(GrGLenum target) { | 
| -    switch (target) { | 
| -        case GR_GL_TEXTURE_2D: | 
| -            return 0; | 
| -        case GR_GL_TEXTURE_EXTERNAL: | 
| -            return 1; | 
| -        case GR_GL_TEXTURE_RECTANGLE: | 
| -            return 2; | 
| -        default: | 
| -            SkFAIL("Unexpected texture target."); | 
| -            return 0; | 
| -    } | 
| +static uint8_t sampler_type_key_4_bits(GrSLType samplerType) { | 
| +    static constexpr int kFirstSamplerType = kSampler2D_GrSLType; | 
| +    static constexpr int kLastSamplerType = kSampler2DRect_GrSLType; | 
| + | 
| +    SkASSERT(samplerType >= kFirstSamplerType && samplerType <= kLastSamplerType); | 
| +    return samplerType - kFirstSamplerType; | 
| + | 
| +    GR_STATIC_ASSERT(kLastSamplerType - kFirstSamplerType < (1 << 4)); | 
| +} | 
| + | 
| +static uint8_t precision_key_nonzero_2_bits(GrShaderType shaderType, GrSLPrecision precision, | 
| +                                            const GrShaderCaps& caps) { | 
| +    return 1 + caps.effectiveFloatPrecision(shaderType, precision); | 
| + | 
| +    GR_STATIC_ASSERT(1 + kLast_GrSLPrecision < (1 << 2)); | 
| } | 
|  | 
| static void add_texture_key(GrProcessorKeyBuilder* b, const GrProcessor& proc, | 
| const GrGLSLCaps& caps) { | 
| int numTextures = proc.numTextures(); | 
| -    // Need two bytes per key (swizzle and target). | 
| +    // Need two bytes per key (swizzle, sampler type, and precision). | 
| int word32Count = (proc.numTextures() + 1) / 2; | 
| if (0 == word32Count) { | 
| return; | 
| @@ -44,7 +47,18 @@ static void add_texture_key(GrProcessorKeyBuilder* b, const GrProcessor& proc, | 
| const GrTextureAccess& access = proc.textureAccess(i); | 
| GrGLTexture* texture = static_cast<GrGLTexture*>(access.getTexture()); | 
| k16[i] = SkToU16(caps.configTextureSwizzle(texture->config()).asKey() | | 
| -                         (texture_target_key(texture->target()) << 8)); | 
| +                         (sampler_type_key_4_bits(texture->samplerType()) << 8)); | 
| +        if (caps.usesPrecisionModifiers()) { | 
| +            GrSLPrecision p = GrPixelConfigPrecision(texture->config()); | 
| +            if (access.getVisibility() & kFragment_GrShaderFlag) { | 
| +                k16[i] |= precision_key_nonzero_2_bits(kFragment_GrShaderType, p, caps) << 12; | 
| +            } | 
| +            if (access.getVisibility() & (kVertex_GrShaderFlag | kGeometry_GrShaderFlag)) { | 
| +                SkASSERT(precision_key_nonzero_2_bits(kVertex_GrShaderType, p, caps) == | 
| +                         precision_key_nonzero_2_bits(kGeometry_GrShaderType, p, caps)); | 
| +                k16[i] |= precision_key_nonzero_2_bits(kVertex_GrShaderType, p, caps) << 14; | 
| +            } | 
| +        } | 
| } | 
| // zero the last 16 bits if the number of textures is odd. | 
| if (numTextures & 0x1) { | 
|  |