Optimize GPU text regen for full pixel position text

If the GrTextBlob does not contain any subpixel position text,
then any translation is ok. This is because all positions and
SkGlyphCache entries will be aligned to pixel boundaries.

Change-Id: Ie2bfd72710295b98c65052a857b6bd33a4858b65
Reviewed-on: https://skia-review.googlesource.com/c/162860
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/text/GrTextBlob.cpp b/src/gpu/text/GrTextBlob.cpp
index 659a545..6249c3a 100644
--- a/src/gpu/text/GrTextBlob.cpp
+++ b/src/gpu/text/GrTextBlob.cpp
@@ -144,9 +144,9 @@
     run.fPathGlyphs.push_back(GrTextBlob::Run::PathGlyph(path, x, y, scale, preTransformed));
 }
 
-bool GrTextBlob::mustRegenerate(const SkPaint& paint,
-                                     const SkMaskFilterBase::BlurRec& blurRec,
-                                     const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
+bool GrTextBlob::mustRegenerate(const SkPaint& paint, bool anyRunHasSubpixelPosition,
+                                const SkMaskFilterBase::BlurRec& blurRec,
+                                const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
     // If we have LCD text then our canonical color will be set to transparent, in this case we have
     // to regenerate the blob on any color change
     // We use the grPaint to get any color filter effects
@@ -196,20 +196,22 @@
             return true;
         }
 
-        // We can update the positions in the cachedtextblobs without regenerating the whole blob,
-        // but only for integer translations.
-        // This cool bit of math will determine the necessary translation to apply to the already
-        // generated vertex coordinates to move them to the correct position
-        SkScalar transX = viewMatrix.getTranslateX() +
-                          viewMatrix.getScaleX() * (x - fInitialX) +
-                          viewMatrix.getSkewX() * (y - fInitialY) -
-                          fInitialViewMatrix.getTranslateX();
-        SkScalar transY = viewMatrix.getTranslateY() +
-                          viewMatrix.getSkewY() * (x - fInitialX) +
-                          viewMatrix.getScaleY() * (y - fInitialY) -
-                          fInitialViewMatrix.getTranslateY();
-        if (!SkScalarIsInt(transX) || !SkScalarIsInt(transY)) {
-            return true;
+        if (!anyRunHasSubpixelPosition) {
+            // We can update the positions in the cachedtextblobs without regenerating the whole
+            // blob, but only for integer translations.
+            // This cool bit of math will determine the necessary translation to apply to the
+            // already generated vertex coordinates to move them to the correct position.
+            SkScalar transX = viewMatrix.getTranslateX() +
+                              viewMatrix.getScaleX() * (x - fInitialX) +
+                              viewMatrix.getSkewX() * (y - fInitialY) -
+                              fInitialViewMatrix.getTranslateX();
+            SkScalar transY = viewMatrix.getTranslateY() +
+                              viewMatrix.getSkewY() * (x - fInitialX) +
+                              viewMatrix.getScaleY() * (y - fInitialY) -
+                              fInitialViewMatrix.getTranslateY();
+            if (!SkScalarIsInt(transX) || !SkScalarIsInt(transY)) {
+                return true;
+            }
         }
     } else if (this->hasDistanceField()) {
         // A scale outside of [blob.fMaxMinScale, blob.fMinMaxScale] would result in a different