Fix GrAtlasTextBlob bounds management

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

Committed: https://skia.googlesource.com/skia/+/ae473fdfc3db2d9dd82b05b2568767d6d4038fcd

Review URL: https://codereview.chromium.org/1605013002
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 05fb5ad..bf8f286 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -63,7 +63,7 @@
 
     subRun->setMaskFormat(format);
 
-    run.fVertexBounds.joinNonEmptyArg(positions);
+    subRun->joinGlyphBounds(positions);
     subRun->setColor(color);
 
     intptr_t vertex = reinterpret_cast<intptr_t>(this->fVertices + subRun->vertexEndIndex());
@@ -219,7 +219,6 @@
         (*outTransY) = y - fY;
     }
 
-
     // If we can reuse the blob, then make sure we update the blob's viewmatrix, and x/y
     // offsets.  Note, we offset the vertex bounds right before flushing
     fViewMatrix = viewMatrix;
@@ -383,7 +382,6 @@
                                   drawFilter, viewMatrix, clipBounds, x, y);
             continue;
         }
-        fRuns[run].fVertexBounds.offset(transX, transY);
         this->flushRun(dc, &pipelineBuilder, run, color,
                        transX, transY, skPaint, props,
                        distanceAdjustTable, context->getBatchFontCache());
@@ -419,8 +417,8 @@
                                               const SkPaint& skPaint, const SkSurfaceProps& props,
                                               const GrDistanceFieldAdjustTable* distanceAdjustTable,
                                               GrBatchFontCache* cache) {
-    const GrAtlasTextBlob::Run::SubRunInfo& info = fRuns[0].fSubRunInfo[0];
-    return this->createBatch(info, glyphCount, 0, 0, color, transX, transY, skPaint,
+    const GrAtlasTextBlob::Run::SubRunInfo& info = fRuns[run].fSubRunInfo[subRun];
+    return this->createBatch(info, glyphCount, run, subRun, color, transX, transY, skPaint,
                              props, distanceAdjustTable, cache);
 }
 
diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h
index 1c5ea5e..af6441e 100644
--- a/src/gpu/text/GrAtlasTextBlob.h
+++ b/src/gpu/text/GrAtlasTextBlob.h
@@ -210,13 +210,11 @@
     // We use this color vs the SkPaint color because it has the colorfilter applied.
     void initReusableBlob(GrColor color, const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
         fPaintColor = color;
-        fViewMatrix = viewMatrix;
-        fX = x;
-        fY = y;
+        this->setupViewMatrix(viewMatrix, x, y);
     }
 
-    void initThrowawayBlob(const SkMatrix& viewMatrix) {
-        fViewMatrix = viewMatrix;
+    void initThrowawayBlob(const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
+        this->setupViewMatrix(viewMatrix, x, y);
     }
 
     GrDrawBatch* test_createBatch(int glyphCount, int run, int subRun,
@@ -249,6 +247,20 @@
                          SkDrawFilter* drawFilter, const SkMatrix& viewMatrix,
                          const SkIRect& clipBounds, SkScalar x, SkScalar y);
 
+    // This function will only be called when we are regenerating a blob from scratch. We record the
+    // initial view matrix and initial offsets(x,y), because we record vertex bounds relative to
+    // these numbers.  When blobs are reused with new matrices, we need to return to model space so
+    // we can update the vertex bounds appropriately.
+    void setupViewMatrix(const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
+        fViewMatrix = viewMatrix;
+        if (!viewMatrix.invert(&fInitialViewMatrixInverse)) {
+            fInitialViewMatrixInverse = SkMatrix::I();
+            SkDebugf("Could not invert viewmatrix\n");
+        }
+        fX = fInitialX = x;
+        fY = fInitialY = y;
+    }
+
     /*
      * Each Run inside of the blob can have its texture coordinates regenerated if required.
      * To determine if regeneration is necessary, fAtlasGeneration is used.  If there have been
@@ -276,7 +288,6 @@
         Run()
             : fInitialized(false)
             , fDrawAsPaths(false) {
-            fVertexBounds.setLargestInverted();
             // To ensure we always have one subrun, we push back a fresh run here
             fSubRunInfo.push_back();
         }
@@ -290,10 +301,13 @@
                 , fColor(GrColor_ILLEGAL)
                 , fMaskFormat(kA8_GrMaskFormat)
                 , fDrawAsDistanceFields(false)
-                , fUseLCDText(false) {}
+                , fUseLCDText(false) {
+                fVertexBounds.setLargestInverted();
+            }
             SubRunInfo(const SubRunInfo& that)
                 : fBulkUseToken(that.fBulkUseToken)
                 , fStrike(SkSafeRef(that.fStrike.get()))
+                , fVertexBounds(that.fVertexBounds)
                 , fAtlasGeneration(that.fAtlasGeneration)
                 , fVertexStartIndex(that.fVertexStartIndex)
                 , fVertexEndIndex(that.fVertexEndIndex)
@@ -338,6 +352,11 @@
                 fVertexEndIndex = prev.vertexEndIndex();
             }
 
+            const SkRect& vertexBounds() const { return fVertexBounds; }
+            void joinGlyphBounds(const SkRect& glyphBounds) {
+                fVertexBounds.joinNonEmptyArg(glyphBounds);
+            }
+
             // df properties
             void setUseLCDText(bool useLCDText) { fUseLCDText = useLCDText; }
             bool hasUseLCDText() const { return fUseLCDText; }
@@ -347,6 +366,7 @@
         private:
             GrBatchAtlas::BulkUseTokenUpdater fBulkUseToken;
             SkAutoTUnref<GrBatchTextStrike> fStrike;
+            SkRect fVertexBounds;
             uint64_t fAtlasGeneration;
             size_t fVertexStartIndex;
             size_t fVertexEndIndex;
@@ -368,7 +388,6 @@
         }
         static const int kMinSubRuns = 1;
         SkAutoTUnref<SkTypeface> fTypeface;
-        SkRect fVertexBounds;
         SkSTArray<kMinSubRuns, SubRunInfo> fSubRunInfo;
         SkAutoDescriptor fDescriptor;
 
@@ -423,7 +442,10 @@
     SkTArray<BigGlyph> fBigGlyphs;
     Key fKey;
     SkMatrix fViewMatrix;
+    SkMatrix fInitialViewMatrixInverse;
     GrColor fPaintColor;
+    SkScalar fInitialX;
+    SkScalar fInitialY;
     SkScalar fX;
     SkScalar fY;
 
diff --git a/src/gpu/text/GrAtlasTextContext.cpp b/src/gpu/text/GrAtlasTextContext.cpp
index e286aa6..eef4f0b 100644
--- a/src/gpu/text/GrAtlasTextContext.cpp
+++ b/src/gpu/text/GrAtlasTextContext.cpp
@@ -281,7 +281,7 @@
     int glyphCount = skPaint.countText(text, byteLength);
 
     GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::kGrayTextVASize);
-    blob->initThrowawayBlob(viewMatrix);
+    blob->initThrowawayBlob(viewMatrix, x, y);
 
     if (GrTextUtils::CanDrawAsDistanceFields(skPaint, viewMatrix, fSurfaceProps,
                                              *fContext->caps()->shaderCaps())) {
@@ -304,7 +304,7 @@
     int glyphCount = skPaint.countText(text, byteLength);
 
     GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBlob::kGrayTextVASize);
-    blob->initThrowawayBlob(viewMatrix);
+    blob->initThrowawayBlob(viewMatrix, offset.x(), offset.y());
 
     if (GrTextUtils::CanDrawAsDistanceFields(skPaint, viewMatrix, fSurfaceProps,
                                              *fContext->caps()->shaderCaps())) {
@@ -393,8 +393,10 @@
             gTextContext->createDrawTextBlob(grPaint, skPaint, viewMatrix, text,
                                              static_cast<size_t>(textLen), 0, 0));
 
-    SkScalar transX = static_cast<SkScalar>(random->nextU());
-    SkScalar transY = static_cast<SkScalar>(random->nextU());
+    // We'd like to be able to test this with random translations, but currently the vertex
+    // bounds and vertices will get out of sync
+    SkScalar transX = 0.f;//SkIntToScalar(random->nextU());
+    SkScalar transY = 0.f;//SkIntToScalar(random->nextU());
     return blob->test_createBatch(textLen, 0, 0, color, transX, transY, skPaint,
                                   gSurfaceProps, gTextContext->dfAdjustTable(),
                                   context->getBatchFontCache());