Revert "Switch atlas clients over to using absolute texture coordinates"

This reverts commit e84c087e621978e6d298b8ca950521601a0366cb.

Reason for revert: ANGLE is unhappy

Original change's description:
> Switch atlas clients over to using absolute texture coordinates
> 
> This is a prerequisite for being able to resize the atlas with impunity.
> 
> Change-Id: I509816c8d6f38fbc92fa39aeab303b42ab09f58b
> Reviewed-on: https://skia-review.googlesource.com/37560
> Reviewed-by: Robert Phillips <robertphillips@google.com>
> Commit-Queue: Robert Phillips <robertphillips@google.com>

TBR=egdaniel@google.com,jvanverth@google.com,robertphillips@google.com,brianosman@google.com

Change-Id: I329efd642c22e11a5c576a4632fc557759b200d5
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/38400
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/ccpr/GrCCPRPathProcessor.cpp b/src/gpu/ccpr/GrCCPRPathProcessor.cpp
index 54ffb9b..1292553 100644
--- a/src/gpu/ccpr/GrCCPRPathProcessor.cpp
+++ b/src/gpu/ccpr/GrCCPRPathProcessor.cpp
@@ -56,7 +56,6 @@
     this->addInstanceAttrib("view_matrix", kVec4f_GrVertexAttribType, kHigh_GrSLPrecision);
     this->addInstanceAttrib("view_translate", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision);
     // FIXME: this could be a vector of two shorts if it were supported by Ganesh.
-    // Note: this should be doable now with kVec2us_uint_GrVertexAttribType
     this->addInstanceAttrib("atlas_offset", kVec2i_GrVertexAttribType, kHigh_GrSLPrecision);
     this->addInstanceAttrib("color", kVec4ub_GrVertexAttribType, kLow_GrSLPrecision);
 
diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp
index d24ddf8..a934ff1 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.cpp
+++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp
@@ -17,53 +17,50 @@
 
 class GrGLBitmapTextGeoProc : public GrGLSLGeometryProcessor {
 public:
-    GrGLBitmapTextGeoProc() : fColor(GrColor_ILLEGAL), fAtlasSize({0,0}) {}
+    GrGLBitmapTextGeoProc() : fColor(GrColor_ILLEGAL) {}
 
     void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
-        const GrBitmapTextGeoProc& btgp = args.fGP.cast<GrBitmapTextGeoProc>();
+        const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>();
 
         GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
         GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
         GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
 
         // emit attributes
-        varyingHandler->emitAttributes(btgp);
+        varyingHandler->emitAttributes(cte);
 
-        const char* atlasSizeInvName;
-        fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag,
-                                                          kVec2f_GrSLType,
-                                                          kHigh_GrSLPrecision,
-                                                          "AtlasSizeInv",
-                                                          &atlasSizeInvName);
+        // compute numbers to be hardcoded to convert texture coordinates from int to float
+        SkASSERT(cte.numTextureSamplers() == 1);
+        SkDEBUGCODE(GrTexture* atlas = cte.textureSampler(0).peekTexture());
+        SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
 
         GrGLSLVertToFrag v(kVec2f_GrSLType);
         varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
-        vertBuilder->codeAppendf("%s = %s * %s;", v.vsOut(),
-                                 btgp.inTextureCoords()->fName,
-                                 atlasSizeInvName);
+        vertBuilder->codeAppendf("%s = %s;", v.vsOut(),
+                                 cte.inTextureCoords()->fName);
 
         GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
         // Setup pass through color
-        if (btgp.hasVertexColor()) {
-            varyingHandler->addPassThroughAttribute(btgp.inColor(), args.fOutputColor);
+        if (cte.hasVertexColor()) {
+            varyingHandler->addPassThroughAttribute(cte.inColor(), args.fOutputColor);
         } else {
             this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
                                     &fColorUniform);
         }
 
         // Setup position
-        this->writeOutputPosition(vertBuilder, gpArgs, btgp.inPosition()->fName);
+        this->writeOutputPosition(vertBuilder, gpArgs, cte.inPosition()->fName);
 
         // emit transforms
         this->emitTransforms(vertBuilder,
                              varyingHandler,
                              uniformHandler,
                              gpArgs->fPositionVar,
-                             btgp.inPosition()->fName,
-                             btgp.localMatrix(),
+                             cte.inPosition()->fName,
+                             cte.localMatrix(),
                              args.fFPCoordTransformHandler);
 
-        if (btgp.maskFormat() == kARGB_GrMaskFormat) {
+        if (cte.maskFormat() == kARGB_GrMaskFormat) {
             fragBuilder->codeAppendf("%s = ", args.fOutputColor);
             fragBuilder->appendTextureLookupAndModulate(args.fOutputColor,
                                                         args.fTexSamplers[0],
@@ -87,35 +84,31 @@
             pdman.set4fv(fColorUniform, 1, c);
             fColor = btgp.color();
         }
-
-        SkASSERT(btgp.numTextureSamplers() == 1);
-        GrTexture* atlas = btgp.textureSampler(0).peekTexture();
-        SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
-
-        if (fAtlasSize.fWidth != atlas->width() || fAtlasSize.fHeight != atlas->height()) {
-            pdman.set2f(fAtlasSizeInvUniform, 1.0f / atlas->width(), 1.0f / atlas->height());
-            fAtlasSize.set(atlas->width(), atlas->height());
-        }
         this->setTransformDataHelper(btgp.localMatrix(), pdman, &transformIter);
     }
 
     static inline void GenKey(const GrGeometryProcessor& proc,
                               const GrShaderCaps&,
                               GrProcessorKeyBuilder* b) {
-        const GrBitmapTextGeoProc& btgp = proc.cast<GrBitmapTextGeoProc>();
+        const GrBitmapTextGeoProc& gp = proc.cast<GrBitmapTextGeoProc>();
         uint32_t key = 0;
-        key |= (btgp.usesLocalCoords() && btgp.localMatrix().hasPerspective()) ? 0x1 : 0x0;
-        key |= btgp.maskFormat() << 1;
+        key |= (gp.usesLocalCoords() && gp.localMatrix().hasPerspective()) ? 0x1 : 0x0;
+        key |= gp.maskFormat() << 1;
         b->add32(key);
+
+        // Currently we hardcode numbers to convert atlas coordinates to normalized floating point
+        SkASSERT(gp.numTextureSamplers() == 1);
+        GrTextureProxy* atlas = gp.textureSampler(0).proxy();
+        if (atlas) {
+            b->add32(atlas->width());
+            b->add32(atlas->height());
+        }
     }
 
 private:
-    GrColor       fColor;
+    GrColor fColor;
     UniformHandle fColorUniform;
 
-    SkISize       fAtlasSize;
-    UniformHandle fAtlasSizeInvUniform;
-
     typedef GrGLSLGeometryProcessor INHERITED;
 };
 
@@ -140,8 +133,7 @@
     if (hasVertexColor) {
         fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
     }
-
-    fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType,
+    fInTextureCoords = &this->addVertexAttrib("inTextureCoords",  kVec2us_GrVertexAttribType,
                                               kHigh_GrSLPrecision);
     this->addTextureSampler(&fTextureSampler);
 }
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
index 37b1113..8dd2fa6 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
@@ -23,12 +23,11 @@
 class GrGLDistanceFieldA8TextGeoProc : public GrGLSLGeometryProcessor {
 public:
     GrGLDistanceFieldA8TextGeoProc()
-            : fViewMatrix(SkMatrix::InvalidMatrix())
-    #ifdef SK_GAMMA_APPLY_TO_A8
-            , fDistanceAdjust(-1.0f)
-    #endif
-            , fAtlasSize({0,0}) {
-    }
+        : fViewMatrix(SkMatrix::InvalidMatrix())
+#ifdef SK_GAMMA_APPLY_TO_A8
+        , fDistanceAdjust(-1.0f)
+#endif
+        {}
 
     void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
         const GrDistanceFieldA8TextGeoProc& dfTexEffect =
@@ -42,12 +41,6 @@
         // emit attributes
         varyingHandler->emitAttributes(dfTexEffect);
 
-        const char* atlasSizeInvName;
-        fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag,
-                                                          kVec2f_GrSLType,
-                                                          kHigh_GrSLPrecision,
-                                                          "AtlasSizeInv",
-                                                          &atlasSizeInvName);
 #ifdef SK_GAMMA_APPLY_TO_A8
         // adjust based on gamma
         const char* distanceAdjustUniName = nullptr;
@@ -77,17 +70,8 @@
                              args.fFPCoordTransformHandler);
 
         // add varyings
+        GrGLSLVertToFrag recipScale(kFloat_GrSLType);
         GrGLSLVertToFrag uv(kVec2f_GrSLType);
-        varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
-        vertBuilder->codeAppendf("%s = %s * %s;", uv.vsOut(),
-                                 dfTexEffect.inTextureCoords()->fName,
-                                 atlasSizeInvName);
-
-        GrGLSLVertToFrag st(kVec2f_GrSLType);
-        varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
-        vertBuilder->codeAppendf("%s = %s;", st.vsOut(),
-                                 dfTexEffect.inTextureCoords()->fName);
-
         bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
                               kUniformScale_DistanceFieldEffectMask;
         bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
@@ -95,14 +79,29 @@
             SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectFlag);
         bool isAliased =
             SkToBool(dfTexEffect.getFlags() & kAliased_DistanceFieldEffectFlag);
+        varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
+        vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCoords()->fName);
+
+        // compute numbers to be hardcoded to convert texture coordinates from float to int
+        SkASSERT(dfTexEffect.numTextureSamplers() == 1);
+        GrTexture* atlas = dfTexEffect.textureSampler(0).peekTexture();
+        SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
+
+        GrGLSLVertToFrag st(kVec2f_GrSLType);
+        varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
+        vertBuilder->codeAppendf("%s = float2(%d, %d) * %s;", st.vsOut(),
+                                 atlas->width(), atlas->height(),
+                                 dfTexEffect.inTextureCoords()->fName);
 
         // Use highp to work around aliasing issues
         fragBuilder->codeAppendf("highp float2 uv = %s;\n", uv.fsIn());
 
-        fragBuilder->codeAppend("float texColor = ");
-        fragBuilder->appendTextureLookup(args.fTexSamplers[0], "uv", kVec2f_GrSLType);
-        fragBuilder->codeAppend(".r;");
-        fragBuilder->codeAppend("float distance = "
+        fragBuilder->codeAppend("\tfloat texColor = ");
+        fragBuilder->appendTextureLookup(args.fTexSamplers[0],
+                                         "uv",
+                                         kVec2f_GrSLType);
+        fragBuilder->codeAppend(".r;\n");
+        fragBuilder->codeAppend("\tfloat distance = "
                        SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
 #ifdef SK_GAMMA_APPLY_TO_A8
         // adjust width based on gamma
@@ -178,15 +177,15 @@
 
     void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
                  FPCoordTransformIter&& transformIter) override {
-        const GrDistanceFieldA8TextGeoProc& dfa8gp = proc.cast<GrDistanceFieldA8TextGeoProc>();
-
 #ifdef SK_GAMMA_APPLY_TO_A8
-        float distanceAdjust = dfa8gp.getDistanceAdjust();
+        const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFieldA8TextGeoProc>();
+        float distanceAdjust = dfTexEffect.getDistanceAdjust();
         if (distanceAdjust != fDistanceAdjust) {
-            fDistanceAdjust = distanceAdjust;
             pdman.set1f(fDistanceAdjustUni, distanceAdjust);
+            fDistanceAdjust = distanceAdjust;
         }
 #endif
+        const GrDistanceFieldA8TextGeoProc& dfa8gp = proc.cast<GrDistanceFieldA8TextGeoProc>();
 
         if (!dfa8gp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dfa8gp.viewMatrix())) {
             fViewMatrix = dfa8gp.viewMatrix();
@@ -194,16 +193,6 @@
             GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
             pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
         }
-
-        SkASSERT(dfa8gp.numTextureSamplers() == 1);
-        GrTexture* atlas = dfa8gp.textureSampler(0).peekTexture();
-        SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
-
-        if (fAtlasSize.fWidth != atlas->width() || fAtlasSize.fHeight != atlas->height()) {
-            fAtlasSize.set(atlas->width(), atlas->height());
-            pdman.set2f(fAtlasSizeInvUniform, 1.0f / atlas->width(), 1.0f / atlas->height());
-        }
-
         this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
     }
 
@@ -214,6 +203,14 @@
         uint32_t key = dfTexEffect.getFlags();
         key |= ComputePosKey(dfTexEffect.viewMatrix()) << 16;
         b->add32(key);
+
+        // Currently we hardcode numbers to convert atlas coordinates to normalized floating point
+        SkASSERT(gp.numTextureSamplers() == 1);
+        GrTextureProxy* atlas = gp.textureSampler(0).proxy();
+        if (atlas) {
+            b->add32(atlas->width());
+            b->add32(atlas->height());
+        }
     }
 
 private:
@@ -223,8 +220,6 @@
     float         fDistanceAdjust;
     UniformHandle fDistanceAdjustUni;
 #endif
-    SkISize       fAtlasSize;
-    UniformHandle fAtlasSizeInvUniform;
 
     typedef GrGLSLGeometryProcessor INHERITED;
 };
@@ -254,7 +249,7 @@
     fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
                                          kHigh_GrSLPrecision);
     fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
-    fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType,
+    fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_GrVertexAttribType,
                                               kHigh_GrSLPrecision);
     this->addTextureSampler(&fTextureSampler);
 }
@@ -313,9 +308,8 @@
 class GrGLDistanceFieldPathGeoProc : public GrGLSLGeometryProcessor {
 public:
     GrGLDistanceFieldPathGeoProc()
-            : fViewMatrix(SkMatrix::InvalidMatrix())
-            , fAtlasSize({0,0}) {
-    }
+        : fViewMatrix(SkMatrix::InvalidMatrix())
+        , fTextureSize(SkISize::Make(-1, -1)) {}
 
     void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
         const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistanceFieldPathGeoProc>();
@@ -329,26 +323,12 @@
         // emit attributes
         varyingHandler->emitAttributes(dfTexEffect);
 
-        const char* atlasSizeInvName;
-        fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag,
-                                                          kVec2f_GrSLType,
-                                                          kHigh_GrSLPrecision,
-                                                          "AtlasSizeInv",
-                                                          &atlasSizeInvName);
-
-        GrGLSLVertToFrag uv(kVec2f_GrSLType);
-        varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
-        vertBuilder->codeAppendf("%s = %s * %s;", uv.vsOut(),
-                                 dfTexEffect.inTextureCoords()->fName,
-                                 atlasSizeInvName);
-
-        GrGLSLVertToFrag st(kVec2f_GrSLType);
-        varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
-        vertBuilder->codeAppendf("%s = %s;", st.vsOut(),
-                                 dfTexEffect.inTextureCoords()->fName);
+        GrGLSLVertToFrag v(kVec2f_GrSLType);
+        varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
 
         // setup pass through color
         varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
+        vertBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
 
         // Setup position
         this->writeOutputPosition(vertBuilder,
@@ -366,15 +346,23 @@
                              dfTexEffect.inPosition()->fName,
                              args.fFPCoordTransformHandler);
 
+        const char* textureSizeUniName = nullptr;
+        fTextureSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
+                                                     kVec2f_GrSLType, kDefault_GrSLPrecision,
+                                                     "TextureSize", &textureSizeUniName);
+
         // Use highp to work around aliasing issues
-        fragBuilder->codeAppendf("highp float2 uv = %s;", uv.fsIn());
+        fragBuilder->codeAppendf("highp float2 uv = %s;", v.fsIn());
 
         fragBuilder->codeAppend("float texColor = ");
-        fragBuilder->appendTextureLookup(args.fTexSamplers[0], "uv", kVec2f_GrSLType);
+        fragBuilder->appendTextureLookup(args.fTexSamplers[0],
+                                         "uv",
+                                         kVec2f_GrSLType);
         fragBuilder->codeAppend(".r;");
         fragBuilder->codeAppend("float distance = "
             SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
 
+        fragBuilder->codeAppendf("highp float2 st = uv*%s;", textureSizeUniName);
         fragBuilder->codeAppend("float afwidth;");
         bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
                                kUniformScale_DistanceFieldEffectMask;
@@ -388,12 +376,10 @@
 
             // this gives us a smooth step across approximately one fragment
 #ifdef SK_VULKAN
-            fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(%s.x));",
-                                     st.fsIn());
+            fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));");
 #else
             // We use the y gradient because there is a bug in the Mali 400 in the x direction.
-            fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
-                                     st.fsIn());
+            fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(st.y));");
 #endif
         } else if (isSimilarity) {
             // For similarity transform, we adjust the effect of the transformation on the distance
@@ -402,10 +388,10 @@
 
             // this gives us a smooth step across approximately one fragment
 #ifdef SK_VULKAN
-            fragBuilder->codeAppendf("float st_grad_len = length(dFdx(%s));", st.fsIn());
+            fragBuilder->codeAppend("float st_grad_len = length(dFdx(st));");
 #else
             // We use the y gradient because there is a bug in the Mali 400 in the x direction.
-            fragBuilder->codeAppendf("float st_grad_len = length(dFdy(%s));", st.fsIn());
+            fragBuilder->codeAppend("float st_grad_len = length(dFdy(st));");
 #endif
             fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*st_grad_len);");
         } else {
@@ -422,8 +408,8 @@
             fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
             fragBuilder->codeAppend("}");
 
-            fragBuilder->codeAppendf("float2 Jdx = dFdx(%s);", st.fsIn());
-            fragBuilder->codeAppendf("float2 Jdy = dFdy(%s);", st.fsIn());
+            fragBuilder->codeAppend("float2 Jdx = dFdx(st);");
+            fragBuilder->codeAppend("float2 Jdy = dFdy(st);");
             fragBuilder->codeAppend("float2 grad = float2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
             fragBuilder->codeAppend("                 dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
 
@@ -445,6 +431,17 @@
 
     void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
                  FPCoordTransformIter&& transformIter) override {
+        SkASSERT(fTextureSizeUni.isValid());
+
+        GrTexture* texture = proc.textureSampler(0).peekTexture();
+
+        if (texture->width() != fTextureSize.width() ||
+            texture->height() != fTextureSize.height()) {
+            fTextureSize = SkISize::Make(texture->width(), texture->height());
+            pdman.set2f(fTextureSizeUni,
+                        SkIntToScalar(fTextureSize.width()),
+                        SkIntToScalar(fTextureSize.height()));
+        }
 
         const GrDistanceFieldPathGeoProc& dfpgp = proc.cast<GrDistanceFieldPathGeoProc>();
 
@@ -454,16 +451,6 @@
             GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
             pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
         }
-
-        SkASSERT(dfpgp.numTextureSamplers() == 1);
-        GrTexture* atlas = dfpgp.textureSampler(0).peekTexture();
-        SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
-
-        if (fAtlasSize.fWidth != atlas->width() || fAtlasSize.fHeight != atlas->height()) {
-            fAtlasSize.set(atlas->width(), atlas->height());
-            pdman.set2f(fAtlasSizeInvUniform, 1.0f / atlas->width(), 1.0f / atlas->height());
-        }
-
         this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
     }
 
@@ -478,11 +465,10 @@
     }
 
 private:
-    SkMatrix      fViewMatrix;
+    UniformHandle fTextureSizeUni;
     UniformHandle fViewMatrixUniform;
-
-    SkISize       fAtlasSize;
-    UniformHandle fAtlasSizeInvUniform;
+    SkMatrix      fViewMatrix;
+    SkISize       fTextureSize;
 
     typedef GrGLSLGeometryProcessor INHERITED;
 };
@@ -505,7 +491,7 @@
     fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
                                          kHigh_GrSLPrecision);
     fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
-    fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType);
+    fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_GrVertexAttribType);
     this->addTextureSampler(&fTextureSampler);
 }
 
@@ -561,8 +547,7 @@
 class GrGLDistanceFieldLCDTextGeoProc : public GrGLSLGeometryProcessor {
 public:
     GrGLDistanceFieldLCDTextGeoProc()
-            : fViewMatrix(SkMatrix::InvalidMatrix())
-            , fAtlasSize({0,0}) {
+        : fViewMatrix(SkMatrix::InvalidMatrix()) {
         fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.0f, 1.0f, 1.0f);
     }
 
@@ -577,13 +562,6 @@
         // emit attributes
         varyingHandler->emitAttributes(dfTexEffect);
 
-        const char* atlasSizeInvName;
-        fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag,
-                                                          kVec2f_GrSLType,
-                                                          kHigh_GrSLPrecision,
-                                                          "AtlasSizeInv",
-                                                          &atlasSizeInvName);
-
         GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
 
         // setup pass through color
@@ -606,36 +584,39 @@
                              args.fFPCoordTransformHandler);
 
         // set up varyings
-        GrGLSLVertToFrag uv(kVec2f_GrSLType);
-        varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
-        vertBuilder->codeAppendf("%s = %s * %s;", uv.vsOut(),
-                                 dfTexEffect.inTextureCoords()->fName,
-                                 atlasSizeInvName);
-
-        GrGLSLVertToFrag st(kVec2f_GrSLType);
-        varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
-        vertBuilder->codeAppendf("%s = %s;", st.vsOut(),
-                                 dfTexEffect.inTextureCoords()->fName);
-
-        GrGLSLVertToFrag delta(kFloat_GrSLType);
-        varyingHandler->addVarying("Delta", &delta, kHigh_GrSLPrecision);
-        if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
-            vertBuilder->codeAppendf("%s = -%s.x/3.0;", delta.vsOut(), atlasSizeInvName);
-        } else {
-            vertBuilder->codeAppendf("%s = %s.x/3.0;", delta.vsOut(), atlasSizeInvName);
-        }
-
-        // add frag shader code
         bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
                               kUniformScale_DistanceFieldEffectMask;
         bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
         bool isGammaCorrect =
             SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectFlag);
+        GrGLSLVertToFrag recipScale(kFloat_GrSLType);
+        GrGLSLVertToFrag uv(kVec2f_GrSLType);
+        varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
+        vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCoords()->fName);
+
+        // compute numbers to be hardcoded to convert texture coordinates from float to int
+        SkASSERT(dfTexEffect.numTextureSamplers() == 1);
+        GrTexture* atlas = dfTexEffect.textureSampler(0).peekTexture();
+        SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
+
+        GrGLSLVertToFrag st(kVec2f_GrSLType);
+        varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
+        vertBuilder->codeAppendf("%s = float2(%d, %d) * %s;", st.vsOut(),
+                                 atlas->width(), atlas->height(),
+                                 dfTexEffect.inTextureCoords()->fName);
+
+        // add frag shader code
 
         // create LCD offset adjusted by inverse of transform
         // Use highp to work around aliasing issues
         fragBuilder->codeAppendf("highp float2 uv = %s;\n", uv.fsIn());
 
+        SkScalar lcdDelta = 1.0f / (3.0f * atlas->width());
+        if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
+            fragBuilder->codeAppendf("highp float delta = -%.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
+        } else {
+            fragBuilder->codeAppendf("highp float delta = %.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
+        }
         if (isUniformScale) {
 #ifdef SK_VULKAN
             fragBuilder->codeAppendf("float st_grad_len = abs(dFdx(%s.x));", st.fsIn());
@@ -643,19 +624,18 @@
             // We use the y gradient because there is a bug in the Mali 400 in the x direction.
             fragBuilder->codeAppendf("float st_grad_len = abs(dFdy(%s.y));", st.fsIn());
 #endif
-            fragBuilder->codeAppendf("float2 offset = float2(st_grad_len*%s, 0.0);", delta.fsIn());
+            fragBuilder->codeAppend("float2 offset = float2(st_grad_len*delta, 0.0);");
         } else if (isSimilarity) {
             // For a similarity matrix with rotation, the gradient will not be aligned
             // with the texel coordinate axes, so we need to calculate it.
 #ifdef SK_VULKAN
             fragBuilder->codeAppendf("float2 st_grad = dFdx(%s);", st.fsIn());
-            fragBuilder->codeAppendf("float2 offset = %s*st_grad;", delta.fsIn());
+            fragBuilder->codeAppend("float2 offset = delta*st_grad;");
 #else
             // We use dFdy because of a Mali 400 bug, and rotate -90 degrees to
             // get the gradient in the x direction.
             fragBuilder->codeAppendf("float2 st_grad = dFdy(%s);", st.fsIn());
-            fragBuilder->codeAppendf("float2 offset = %s*float2(st_grad.y, -st_grad.x);",
-                                     delta.fsIn());
+            fragBuilder->codeAppend("float2 offset = delta*float2(st_grad.y, -st_grad.x);");
 #endif
             fragBuilder->codeAppend("float st_grad_len = length(st_grad);");
         } else {
@@ -663,7 +643,7 @@
 
             fragBuilder->codeAppend("float2 Jdx = dFdx(st);");
             fragBuilder->codeAppend("float2 Jdy = dFdy(st);");
-            fragBuilder->codeAppendf("float2 offset = %s*Jdx;", delta.fsIn());
+            fragBuilder->codeAppend("float2 offset = delta*Jdx;");
         }
 
         // green is distance to uv center
@@ -762,16 +742,6 @@
             GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
             pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
         }
-
-        SkASSERT(dflcd.numTextureSamplers() == 1);
-        GrTexture* atlas = dflcd.textureSampler(0).peekTexture();
-        SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
-
-        if (fAtlasSize.fWidth != atlas->width() || fAtlasSize.fHeight != atlas->height()) {
-            fAtlasSize.set(atlas->width(), atlas->height());
-            pdman.set2f(fAtlasSizeInvUniform, 1.0f / atlas->width(), 1.0f / atlas->height());
-        }
-
         this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
     }
 
@@ -783,17 +753,22 @@
         uint32_t key = dfTexEffect.getFlags();
         key |= ComputePosKey(dfTexEffect.viewMatrix()) << 16;
         b->add32(key);
+
+        // Currently we hardcode numbers to convert atlas coordinates to normalized floating point
+        SkASSERT(gp.numTextureSamplers() == 1);
+        GrTextureProxy* atlas = gp.textureSampler(0).proxy();
+        if (atlas) {
+            b->add32(atlas->width());
+            b->add32(atlas->height());
+        }
     }
 
 private:
-    SkMatrix                                      fViewMatrix;
-    UniformHandle                                 fViewMatrixUniform;
-
+    SkMatrix                                     fViewMatrix;
+    UniformHandle                                fViewMatrixUniform;
+    UniformHandle                                fColorUniform;
     GrDistanceFieldLCDTextGeoProc::DistanceAdjust fDistanceAdjust;
-    UniformHandle                                 fDistanceAdjustUni;
-
-    SkISize                                       fAtlasSize;
-    UniformHandle                                 fAtlasSizeInvUniform;
+    UniformHandle                                fDistanceAdjustUni;
 
     typedef GrGLSLGeometryProcessor INHERITED;
 };
@@ -816,7 +791,7 @@
     fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
                                          kHigh_GrSLPrecision);
     fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
-    fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType,
+    fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_GrVertexAttribType,
                                               kHigh_GrSLPrecision);
     this->addTextureSampler(&fTextureSampler);
 }
diff --git a/src/gpu/gl/GrGLVertexArray.cpp b/src/gpu/gl/GrGLVertexArray.cpp
index b4df8b8..745e532 100644
--- a/src/gpu/gl/GrGLVertexArray.cpp
+++ b/src/gpu/gl/GrGLVertexArray.cpp
@@ -37,10 +37,8 @@
             return {true, 1, GR_GL_UNSIGNED_BYTE};
         case kVec4ub_GrVertexAttribType:
             return {true, 4, GR_GL_UNSIGNED_BYTE};
-        case kVec2us_norm_GrVertexAttribType:
+        case kVec2us_GrVertexAttribType:
             return {true, 2, GR_GL_UNSIGNED_SHORT};
-        case kVec2us_uint_GrVertexAttribType:
-            return {false, 2, GR_GL_UNSIGNED_SHORT};
         case kInt_GrVertexAttribType:
             return {false, 1, GR_GL_INT};
         case kUint_GrVertexAttribType:
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index 7e7a496..69cd669 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -351,11 +351,11 @@
 
                     shapeData = new ShapeData;
                     if (!this->addBMPathToAtlas(target,
-                                                &flushInfo,
-                                                atlas,
-                                                shapeData,
-                                                args.fShape,
-                                                this->viewMatrix())) {
+                                              &flushInfo,
+                                              atlas,
+                                              shapeData,
+                                              args.fShape,
+                                              this->viewMatrix())) {
                         delete shapeData;
                         continue;
                     }
@@ -479,6 +479,7 @@
         shapeData->fKey.set(shape, dimension);
         shapeData->fID = id;
 
+        // set the bounds rect to the original bounds
         shapeData->fBounds = SkRect::Make(devPathBounds);
         shapeData->fBounds.offset(-translateX, -translateY);
         shapeData->fBounds.fLeft /= scale;
@@ -614,10 +615,22 @@
         }
 
         // set up texture coordinates
-        uint16_t l = shapeData->fTextureCoords.fLeft;
-        uint16_t t = shapeData->fTextureCoords.fTop;
-        uint16_t r = shapeData->fTextureCoords.fRight;
-        uint16_t b = shapeData->fTextureCoords.fBottom;
+        SkScalar texLeft = shapeData->fTextureCoords.fLeft;
+        SkScalar texTop = shapeData->fTextureCoords.fTop;
+        SkScalar texRight = shapeData->fTextureCoords.fRight;
+        SkScalar texBottom = shapeData->fTextureCoords.fBottom;
+
+        // convert texcoords to unsigned short format
+        sk_sp<GrTextureProxy> proxy = atlas->getProxy();
+
+        // The proxy must be functionally exact for this normalization to work correctly
+        SkASSERT(GrResourceProvider::IsFunctionallyExact(proxy.get()));
+        SkScalar uFactor = 65535.f / proxy->width();
+        SkScalar vFactor = 65535.f / proxy->height();
+        uint16_t l = (uint16_t)(texLeft*uFactor);
+        uint16_t t = (uint16_t)(texTop*vFactor);
+        uint16_t r = (uint16_t)(texRight*uFactor);
+        uint16_t b = (uint16_t)(texBottom*vFactor);
 
         // set vertex texture coords
         intptr_t textureCoordOffset = offset + sizeof(SkPoint) + sizeof(GrColor);
diff --git a/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp b/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp
index 96f0080..3150988 100644
--- a/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp
+++ b/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp
@@ -21,8 +21,9 @@
 template <bool regenPos, bool regenCol, bool regenTexCoords>
 inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexStride,
                            bool useDistanceFields, SkScalar transX, SkScalar transY,
+                           int32_t log2Width, int32_t log2Height,
                            GrColor color) {
-    uint16_t u0, v0, u1, v1;
+    int u0, v0, u1, v1;
     if (regenTexCoords) {
         SkASSERT(glyph);
         int width = glyph->fBounds.width();
@@ -39,6 +40,20 @@
             u1 = u0 + width;
             v1 = v0 + height;
         }
+
+        // normalize
+        u0 *= 65535;
+        u0 >>= log2Width;
+        u1 *= 65535;
+        u1 >>= log2Width;
+        v0 *= 65535;
+        v0 >>= log2Height;
+        v1 *= 65535;
+        v1 >>= log2Height;
+        SkASSERT(u0 >= 0 && u0 <= 65535);
+        SkASSERT(u1 >= 0 && u1 <= 65535);
+        SkASSERT(v0 >= 0 && v0 <= 65535);
+        SkASSERT(v1 >= 0 && v1 <= 65535);
     }
 
     // This is a bit wonky, but sometimes we have LCD text, in which case we won't have color
@@ -60,8 +75,8 @@
 
     if (regenTexCoords) {
         uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset);
-        textureCoords[0] = u0;
-        textureCoords[1] = v0;
+        textureCoords[0] = (uint16_t) u0;
+        textureCoords[1] = (uint16_t) v0;
     }
     vertex += vertexStride;
 
@@ -79,8 +94,8 @@
 
     if (regenTexCoords) {
         uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset);
-        textureCoords[0] = u0;
-        textureCoords[1] = v1;
+        textureCoords[0] = (uint16_t)u0;
+        textureCoords[1] = (uint16_t)v1;
     }
     vertex += vertexStride;
 
@@ -98,8 +113,8 @@
 
     if (regenTexCoords) {
         uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset);
-        textureCoords[0] = u1;
-        textureCoords[1] = v1;
+        textureCoords[0] = (uint16_t)u1;
+        textureCoords[1] = (uint16_t)v1;
     }
     vertex += vertexStride;
 
@@ -117,8 +132,8 @@
 
     if (regenTexCoords) {
         uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset);
-        textureCoords[0] = u1;
-        textureCoords[1] = v0;
+        textureCoords[0] = (uint16_t)u1;
+        textureCoords[1] = (uint16_t)v0;
     }
 }
 
@@ -155,6 +170,7 @@
     bool brokenRun = false;
     for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) {
         GrGlyph* glyph = nullptr;
+        int log2Width = 0, log2Height = 0;
         if (regenTexCoords) {
             size_t glyphOffset = glyphIdx + info->glyphStartIndex();
 
@@ -181,6 +197,8 @@
             }
             fontCache->addGlyphToBulkAndSetUseToken(info->bulkUseToken(), glyph,
                                                     target->nextDrawToken());
+            log2Width = fontCache->log2Width(info->maskFormat());
+            log2Height = fontCache->log2Height(info->maskFormat());
         }
 
         intptr_t vertex = reinterpret_cast<intptr_t>(fVertices);
@@ -188,7 +206,7 @@
         vertex += vertexStride * glyphIdx * GrAtlasTextOp::kVerticesPerGlyph;
         regen_vertices<regenPos, regenCol, regenTexCoords>(vertex, glyph, vertexStride,
                                                            info->drawAsDistanceFields(), transX,
-                                                           transY, color);
+                                                           transY, log2Width, log2Height, color);
         helper->incGlyphCount();
     }
 
diff --git a/src/gpu/vk/GrVkPipeline.cpp b/src/gpu/vk/GrVkPipeline.cpp
index 22777df..1a61605 100644
--- a/src/gpu/vk/GrVkPipeline.cpp
+++ b/src/gpu/vk/GrVkPipeline.cpp
@@ -34,10 +34,8 @@
             return VK_FORMAT_R8_UNORM;
         case kVec4ub_GrVertexAttribType:
             return VK_FORMAT_R8G8B8A8_UNORM;
-        case kVec2us_norm_GrVertexAttribType:
+        case kVec2us_GrVertexAttribType:
             return VK_FORMAT_R16G16_UNORM;
-        case kVec2us_uint_GrVertexAttribType:
-            return VK_FORMAT_R16G16_UINT;
         case kInt_GrVertexAttribType:
             return VK_FORMAT_R32_SINT;
         case kUint_GrVertexAttribType:
diff --git a/src/gpu/vk/GrVkUniformHandler.cpp b/src/gpu/vk/GrVkUniformHandler.cpp
index 98a2751..be746cd 100644
--- a/src/gpu/vk/GrVkUniformHandler.cpp
+++ b/src/gpu/vk/GrVkUniformHandler.cpp
@@ -28,8 +28,6 @@
             return 0xF;
         case kVec4f_GrSLType:
             return 0xF;
-        case kVec2us_GrSLType:
-            return 0x3;
         case kVec2i_GrSLType:
             return 0x7;
         case kVec3i_GrSLType:
@@ -78,8 +76,6 @@
             return 3 * sizeof(float);
         case kVec4f_GrSLType:
             return 4 * sizeof(float);
-        case kVec2us_GrSLType:
-            return 2 * sizeof(uint16_t);
         case kVec2i_GrSLType:
             return 2 * sizeof(int32_t);
         case kVec3i_GrSLType:
diff --git a/src/gpu/vk/GrVkVaryingHandler.cpp b/src/gpu/vk/GrVkVaryingHandler.cpp
index 5912098..8e43b76 100644
--- a/src/gpu/vk/GrVkVaryingHandler.cpp
+++ b/src/gpu/vk/GrVkVaryingHandler.cpp
@@ -21,8 +21,6 @@
             return 1;
         case kVec4f_GrSLType:
             return 1;
-        case kVec2us_GrSLType:
-            return 1;
         case kVec2i_GrSLType:
             return 1;
         case kVec3i_GrSLType: