Revert "Cleanup of large text rendering."

This reverts commit 2fb7c8aef57e4b94d5215e618d8c3b4cccd35edf.

Reason for revert: Causing flakes and incorrect GMs on ChromeOS.

Original change's description:
> Cleanup of large text rendering.
> 
> * Switch all path glyphs to be rendered as part of the fBigGlyphs
> (now fPathGlyphs) system
> * Use one flush command for both cached and throwaway blobs
> * Store and render path glyphs per run rather than one list for the
> entire blob (fixes a layering bug)
> * Fix bug with scaled fallback glyphs, where fallback glyphs were
> trying to use more than one descriptor
> 
> Bug: skia:7562
> Change-Id: Ic3d01887e2203a844102a04afe8674a16149b4bb
> Reviewed-on: https://skia-review.googlesource.com/102400
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Jim Van Verth <jvanverth@google.com>

TBR=jvanverth@google.com,bsalomon@google.com,robertphillips@google.com

Change-Id: I103a7419df96db9859e0f6f4d0a8e5aea4ba8ddc
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:7562
Reviewed-on: https://skia-review.googlesource.com/104640
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 12ad89a..887addd 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -73,22 +73,14 @@
                                   GrAtlasTextStrike* strike,
                                   GrGlyph* glyph,
                                   SkGlyphCache* cache, const SkGlyph& skGlyph,
-                                  SkScalar x, SkScalar y, SkScalar scale, bool preTransformed) {
+                                  SkScalar x, SkScalar y, SkScalar scale, bool treatAsBMP) {
     if (positions.isEmpty()) {
         return;
     }
 
     // If the glyph is too large we fall back to paths
     if (glyph->fTooLargeForAtlas) {
-        if (nullptr == glyph->fPath) {
-            const SkPath* glyphPath = cache->findPath(skGlyph);
-            if (!glyphPath) {
-                return;
-            }
-
-            glyph->fPath = new SkPath(*glyphPath);
-        }
-        this->appendPathGlyph(runIndex, *glyph->fPath, x, y, scale, preTransformed);
+        this->appendBigGlyph(glyph, cache, skGlyph, x, y, scale, treatAsBMP);
         return;
     }
 
@@ -148,10 +140,17 @@
     subRun->glyphAppended();
 }
 
-void GrAtlasTextBlob::appendPathGlyph(int runIndex, const SkPath& path, SkScalar x, SkScalar y,
-                                      SkScalar scale, bool preTransformed) {
-    Run& run = fRuns[runIndex];
-    run.fPathGlyphs.push_back(GrAtlasTextBlob::Run::PathGlyph(path, x, y, scale, preTransformed));
+void GrAtlasTextBlob::appendBigGlyph(GrGlyph* glyph, SkGlyphCache* cache, const SkGlyph& skGlyph,
+                                       SkScalar x, SkScalar y, SkScalar scale, bool treatAsBMP) {
+    if (nullptr == glyph->fPath) {
+        const SkPath* glyphPath = cache->findPath(skGlyph);
+        if (!glyphPath) {
+            return;
+        }
+
+        glyph->fPath = new SkPath(*glyphPath);
+    }
+    fBigGlyphs.push_back(GrAtlasTextBlob::BigGlyph(*glyph->fPath, x, y, scale, treatAsBMP));
 }
 
 bool GrAtlasTextBlob::mustRegenerate(const GrTextUtils::Paint& paint,
@@ -274,6 +273,62 @@
     return op;
 }
 
+inline void GrAtlasTextBlob::flushRun(GrTextUtils::Target* target, const GrClip& clip, int run,
+                                      const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
+                                      const GrTextUtils::Paint& paint, const SkSurfaceProps& props,
+                                      const GrDistanceFieldAdjustTable* distanceAdjustTable,
+                                      GrAtlasGlyphCache* cache) {
+    // GrAtlasTextBlob::makeOp only takes uint16_t values for run and subRun indices.
+    // Encountering something larger than this is highly unlikely, so we'll just not draw it.
+    if (run >= (1 << 16)) {
+        return;
+    }
+    int lastRun = SkTMin(fRuns[run].fSubRunInfo.count(), 1 << 16) - 1;
+    for (int subRun = 0; subRun <= lastRun; subRun++) {
+        const Run::SubRunInfo& info = fRuns[run].fSubRunInfo[subRun];
+        int glyphCount = info.glyphCount();
+        if (0 == glyphCount) {
+            continue;
+        }
+
+        bool skipClip = false;
+        bool submitOp = true;
+        SkIRect clipRect = SkIRect::MakeEmpty();
+        SkRect rtBounds = SkRect::MakeWH(target->width(), target->height());
+        SkRRect clipRRect;
+        GrAA aa;
+        // We can clip geometrically if we're not using SDFs,
+        // and we have an axis-aligned rectangular non-AA clip
+        if (!info.drawAsDistanceFields() && clip.isRRect(rtBounds, &clipRRect, &aa) &&
+            clipRRect.isRect() && GrAA::kNo == aa) {
+            skipClip = true;
+            // We only need to do clipping work if the subrun isn't contained by the clip
+            SkRect subRunBounds;
+            this->computeSubRunBounds(&subRunBounds, run, subRun, viewMatrix, x, y);
+            if (!clipRRect.getBounds().contains(subRunBounds)) {
+                // If the subrun is completely outside, don't add an op for it
+                if (!clipRRect.getBounds().intersects(subRunBounds)) {
+                    submitOp = false;
+                } else {
+                    clipRRect.getBounds().round(&clipRect);
+                }
+            }
+        }
+
+        if (submitOp) {
+            auto op = this->makeOp(info, glyphCount, run, subRun, viewMatrix, x, y, clipRect,
+                                   std::move(paint), props, distanceAdjustTable, cache, target);
+            if (op) {
+                if (skipClip) {
+                    target->addDrawOp(GrNoClip(), std::move(op));
+                } else {
+                    target->addDrawOp(clip, std::move(op));
+                }
+            }
+        }
+    }
+}
+
 static void calculate_translation(bool applyVM,
                                   const SkMatrix& newViewMatrix, SkScalar newX, SkScalar newY,
                                   const SkMatrix& currentViewMatrix, SkScalar currentX,
@@ -294,83 +349,96 @@
     }
 }
 
-void GrAtlasTextBlob::flush(GrAtlasGlyphCache* atlasGlyphCache, GrTextUtils::Target* target,
-                            const SkSurfaceProps& props,
-                            const GrDistanceFieldAdjustTable* distanceAdjustTable,
-                            const GrTextUtils::Paint& paint, const GrClip& clip,
-                            const SkMatrix& viewMatrix, const SkIRect& clipBounds,
-                            SkScalar x, SkScalar y) {
-
-    // GrAtlasTextBlob::makeOp only takes uint16_t values for run and subRun indices.
-    // Encountering something larger than this is highly unlikely, so we'll just not draw it.
-    int lastRun = SkTMin(fRunCount, (1 << 16)) - 1;
-    for (int runIndex = 0; runIndex <= lastRun; runIndex++) {
-        Run& run = fRuns[runIndex];
-
-        // first flush each subrun
-        int lastSubRun = SkTMin(run.fSubRunInfo.count(), 1 << 16) - 1;
-        for (int subRun = 0; subRun <= lastSubRun; subRun++) {
-            const Run::SubRunInfo& info = run.fSubRunInfo[subRun];
-            int glyphCount = info.glyphCount();
-            if (0 == glyphCount) {
-                continue;
-            }
-
-            bool skipClip = false;
-            bool submitOp = true;
-            SkIRect clipRect = SkIRect::MakeEmpty();
-            SkRect rtBounds = SkRect::MakeWH(target->width(), target->height());
-            SkRRect clipRRect;
-            GrAA aa;
-            // We can clip geometrically if we're not using SDFs,
-            // and we have an axis-aligned rectangular non-AA clip
-            if (!info.drawAsDistanceFields() && clip.isRRect(rtBounds, &clipRRect, &aa) &&
-                clipRRect.isRect() && GrAA::kNo == aa) {
-                skipClip = true;
-                // We only need to do clipping work if the subrun isn't contained by the clip
-                SkRect subRunBounds;
-                this->computeSubRunBounds(&subRunBounds, runIndex, subRun, viewMatrix, x, y);
-                if (!clipRRect.getBounds().contains(subRunBounds)) {
-                    // If the subrun is completely outside, don't add an op for it
-                    if (!clipRRect.getBounds().intersects(subRunBounds)) {
-                        submitOp = false;
-                    }
-                    else {
-                        clipRRect.getBounds().round(&clipRect);
-                    }
-                }
-            }
-
-            if (submitOp) {
-                auto op = this->makeOp(info, glyphCount, runIndex, subRun, viewMatrix, x, y,
-                                       clipRect, std::move(paint), props, distanceAdjustTable,
-                                       atlasGlyphCache, target);
-                if (op) {
-                    if (skipClip) {
-                        target->addDrawOp(GrNoClip(), std::move(op));
-                    }
-                    else {
-                        target->addDrawOp(clip, std::move(op));
-                    }
-                }
-            }
+void GrAtlasTextBlob::flushBigGlyphs(GrTextUtils::Target* target,
+                                     const GrClip& clip, const SkPaint& paint,
+                                     const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
+                                     const SkIRect& clipBounds) {
+    SkScalar transX, transY;
+    for (int i = 0; i < fBigGlyphs.count(); i++) {
+        GrAtlasTextBlob::BigGlyph& bigGlyph = fBigGlyphs[i];
+        calculate_translation(bigGlyph.fTreatAsBMP, viewMatrix, x, y,
+                              fInitialViewMatrix, fInitialX, fInitialY, &transX, &transY);
+        SkMatrix ctm;
+        ctm.setScale(bigGlyph.fScale, bigGlyph.fScale);
+        ctm.postTranslate(bigGlyph.fX + transX, bigGlyph.fY + transY);
+        if (!bigGlyph.fTreatAsBMP) {
+            ctm.postConcat(viewMatrix);
         }
-
-        // now flush any path glyphs
-        SkScalar transX, transY;
-        for (int i = 0; i < run.fPathGlyphs.count(); i++) {
-            GrAtlasTextBlob::Run::PathGlyph& pathGlyph = run.fPathGlyphs[i];
-            calculate_translation(pathGlyph.fPreTransformed, viewMatrix, x, y,
-                fInitialViewMatrix, fInitialX, fInitialY, &transX, &transY);
-            const SkMatrix& ctm = pathGlyph.fPreTransformed ? SkMatrix::I() : viewMatrix;
-            SkMatrix pathMatrix;
-            pathMatrix.setScale(pathGlyph.fScale, pathGlyph.fScale);
-            pathMatrix.postTranslate(pathGlyph.fX + transX, pathGlyph.fY + transY);
-            target->drawPath(clip, pathGlyph.fPath, paint, ctm, &pathMatrix, clipBounds);
-        }
+        target->drawPath(clip, bigGlyph.fPath, paint, ctm, nullptr, clipBounds);
     }
 }
 
+void GrAtlasTextBlob::flushBigRun(GrTextUtils::Target* target,
+                                  const SkSurfaceProps& props, const SkTextBlobRunIterator& it,
+                                  const GrClip& clip, const GrTextUtils::Paint& paint,
+                                  SkDrawFilter* drawFilter, const SkMatrix& viewMatrix,
+                                  const SkIRect& clipBounds, SkScalar x, SkScalar y) {
+    size_t textLen = it.glyphCount() * sizeof(uint16_t);
+    const SkPoint& offset = it.offset();
+
+    GrTextUtils::RunPaint runPaint(&paint, drawFilter, props);
+    if (!runPaint.modifyForRun(it)) {
+        return;
+    }
+
+    switch (it.positioning()) {
+        case SkTextBlob::kDefault_Positioning:
+            GrTextUtils::DrawBigText(target, clip, runPaint, viewMatrix,
+                                     (const char*)it.glyphs(), textLen, x + offset.x(),
+                                     y + offset.y(), clipBounds);
+            break;
+        case SkTextBlob::kHorizontal_Positioning:
+            GrTextUtils::DrawBigPosText(target, props, clip, runPaint, viewMatrix,
+                                        (const char*)it.glyphs(), textLen, it.pos(), 1,
+                                        SkPoint::Make(x, y + offset.y()), clipBounds);
+            break;
+        case SkTextBlob::kFull_Positioning:
+            GrTextUtils::DrawBigPosText(target, props, clip, runPaint, viewMatrix,
+                                        (const char*)it.glyphs(), textLen, it.pos(), 2,
+                                        SkPoint::Make(x, y), clipBounds);
+            break;
+    }
+}
+
+void GrAtlasTextBlob::flushCached(GrAtlasGlyphCache* atlasGlyphCache, GrTextUtils::Target* target,
+                                  const SkTextBlob* blob, const SkSurfaceProps& props,
+                                  const GrDistanceFieldAdjustTable* distanceAdjustTable,
+                                  const GrTextUtils::Paint& paint, SkDrawFilter* drawFilter,
+                                  const GrClip& clip, const SkMatrix& viewMatrix,
+                                  const SkIRect& clipBounds, SkScalar x, SkScalar y) {
+    // We loop through the runs of the blob, flushing each.  If any run is too large, then we flush
+    // it as paths
+    SkTextBlobRunIterator it(blob);
+    for (int run = 0; !it.done(); it.next(), run++) {
+        if (fRuns[run].fTooBigForAtlas) {
+            this->flushBigRun(target, props, it, clip, paint, drawFilter, viewMatrix,
+                              clipBounds, x, y);
+            continue;
+        }
+        this->flushRun(target, clip, run, viewMatrix, x, y, paint, props, distanceAdjustTable,
+                       atlasGlyphCache);
+    }
+
+    // Now flush big glyphs
+    this->flushBigGlyphs(target, clip, paint, viewMatrix, x, y, clipBounds);
+}
+
+void GrAtlasTextBlob::flushThrowaway(GrAtlasGlyphCache* atlasGlyphCache,
+                                     GrTextUtils::Target* target,
+                                     const SkSurfaceProps& props,
+                                     const GrDistanceFieldAdjustTable* distanceAdjustTable,
+                                     const GrTextUtils::Paint& paint, const GrClip& clip,
+                                     const SkMatrix& viewMatrix, const SkIRect& clipBounds,
+                                     SkScalar x, SkScalar y) {
+    for (int run = 0; run < fRunCount; run++) {
+        this->flushRun(target, clip, run, viewMatrix, x, y, paint, props, distanceAdjustTable,
+                       atlasGlyphCache);
+    }
+
+    // Now flush big glyphs
+    this->flushBigGlyphs(target, clip, paint, viewMatrix, x, y, clipBounds);
+}
+
 std::unique_ptr<GrDrawOp> GrAtlasTextBlob::test_makeOp(
         int glyphCount, uint16_t run, uint16_t subRun, const SkMatrix& viewMatrix,
         SkScalar x, SkScalar y, const GrTextUtils::Paint& paint, const SkSurfaceProps& props,
@@ -394,6 +462,15 @@
     SkASSERT_RELEASE(l.fStrokeInfo.fMiterLimit == r.fStrokeInfo.fMiterLimit);
     SkASSERT_RELEASE(l.fStrokeInfo.fJoin == r.fStrokeInfo.fJoin);
 
+    SkASSERT_RELEASE(l.fBigGlyphs.count() == r.fBigGlyphs.count());
+    for (int i = 0; i < l.fBigGlyphs.count(); i++) {
+        const BigGlyph& lBigGlyph = l.fBigGlyphs[i];
+        const BigGlyph& rBigGlyph = r.fBigGlyphs[i];
+
+        SkASSERT_RELEASE(lBigGlyph.fPath == rBigGlyph.fPath);
+        // We can't assert that these have the same translations
+    }
+
     SkASSERT_RELEASE(l.fKey == r.fKey);
     //SkASSERT_RELEASE(l.fPaintColor == r.fPaintColor); // Colors might not actually be identical
     SkASSERT_RELEASE(l.fMaxMinScale == r.fMaxMinScale);
@@ -429,6 +506,7 @@
         // color can be changed
         //SkASSERT(lRun.fColor == rRun.fColor);
         SkASSERT_RELEASE(lRun.fInitialized == rRun.fInitialized);
+        SkASSERT_RELEASE(lRun.fTooBigForAtlas == rRun.fTooBigForAtlas);
 
         SkASSERT_RELEASE(lRun.fSubRunInfo.count() == rRun.fSubRunInfo.count());
         for(int j = 0; j < lRun.fSubRunInfo.count(); j++) {
@@ -455,15 +533,6 @@
             SkASSERT_RELEASE(lSubRun.drawAsDistanceFields() == rSubRun.drawAsDistanceFields());
             SkASSERT_RELEASE(lSubRun.hasUseLCDText() == rSubRun.hasUseLCDText());
         }
-
-        SkASSERT_RELEASE(lRun.fPathGlyphs.count() == rRun.fPathGlyphs.count());
-        for (int i = 0; i < lRun.fPathGlyphs.count(); i++) {
-            const Run::PathGlyph& lPathGlyph = lRun.fPathGlyphs[i];
-            const Run::PathGlyph& rPathGlyph = rRun.fPathGlyphs[i];
-
-            SkASSERT_RELEASE(lPathGlyph.fPath == rPathGlyph.fPath);
-            // We can't assert that these have the same translations
-        }
     }
 }