Check that mask to path fallback happens

BUG=chromium:876767

Change-Id: I6aadf329af836a1e03aa85b34a58830be00ff750
Reviewed-on: https://skia-review.googlesource.com/150135
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Khusal Sagar <khushalsagar@chromium.org>
diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp
index dc79fc3..30d30dc 100644
--- a/src/core/SkGlyphRun.cpp
+++ b/src/core/SkGlyphRun.cpp
@@ -765,7 +765,7 @@
         if (glyph.fWidth > 0) {
             if (glyph.fMaskFormat == SkMask::kSDF_Format) {
 
-                if (glyph_too_big_for_atlas(glyph)) {
+                if (SkGlyphCacheCommon::GlyphTooBigForAtlas(glyph)) {
                     SkRect glyphRect =
                             rect_to_draw(glyph, glyphPos, textRatio, true);
                     if (!glyphRect.isEmpty()) {
diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h
index 3cfee0f..04339ac 100644
--- a/src/core/SkGlyphRun.h
+++ b/src/core/SkGlyphRun.h
@@ -76,6 +76,12 @@
 
         return {lookupX, lookupY};
     }
+
+    static constexpr uint16_t kSkSideTooBigForAtlas = 256;
+
+    inline static bool GlyphTooBigForAtlas(const SkGlyph& glyph) {
+        return glyph.fWidth > kSkSideTooBigForAtlas || glyph.fHeight > kSkSideTooBigForAtlas;
+    }
 };
 
 class SkGlyphRun {
@@ -343,10 +349,6 @@
     }
 }
 
-inline static bool glyph_too_big_for_atlas(const SkGlyph& glyph) {
-    return glyph.fWidth > 256 || glyph.fHeight > 256;
-}
-
 inline static SkRect rect_to_draw(
         const SkGlyph& glyph, SkPoint origin, SkScalar textScale, bool isDFT) {
 
@@ -406,7 +408,7 @@
     auto eachGlyph =
             [perGlyph{std::move(perGlyph)}, perPath{std::move(perPath)}]
                     (const SkGlyph& glyph, SkPoint pt, SkPoint mappedPt) {
-                if (glyph_too_big_for_atlas(glyph)) {
+                if (SkGlyphCacheCommon::GlyphTooBigForAtlas(glyph)) {
                     SkScalar sx = SkScalarFloorToScalar(mappedPt.fX),
                             sy = SkScalarFloorToScalar(mappedPt.fY);
 
diff --git a/tests/SkRemoteGlyphCacheTest.cpp b/tests/SkRemoteGlyphCacheTest.cpp
index c23e9a5..8a2fc0d 100644
--- a/tests/SkRemoteGlyphCacheTest.cpp
+++ b/tests/SkRemoteGlyphCacheTest.cpp
@@ -5,6 +5,7 @@
  * found in the LICENSE file.
  */
 
+#include "Resources.h"
 #include "SkDraw.h"
 #include "SkGraphics.h"
 #include "SkMutex.h"
@@ -350,6 +351,85 @@
     discardableManager->unlockAndDeleteAll();
 }
 
+sk_sp<SkTextBlob> make_blob_causing_fallback(
+        sk_sp<SkTypeface> targetTf, const SkTypeface* glyphTf, skiatest::Reporter* reporter) {
+    SkPaint paint;
+    paint.setSubpixelText(true);
+    paint.setTextSize(96);
+    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    paint.setTextAlign(SkPaint::kLeft_Align);
+    paint.setStyle(SkPaint::kFill_Style);
+    paint.setHinting(SkPaint::kNormal_Hinting);
+
+    paint.setTypeface(targetTf);
+
+    REPORTER_ASSERT(reporter, !SkDraw::ShouldDrawTextAsPaths(paint, SkMatrix::I()));
+
+    char s[] = "Skia";
+    int runSize = strlen(s);
+
+    SkTextBlobBuilder builder;
+    SkRect bounds = SkRect::MakeIWH(100, 100);
+    const auto& runBuffer = builder.allocRunPosH(paint, runSize, 10, &bounds);
+    SkASSERT(runBuffer.utf8text == nullptr);
+    SkASSERT(runBuffer.clusters == nullptr);
+
+    glyphTf->charsToGlyphs(s, SkTypeface::kUTF8_Encoding, runBuffer.glyphs, runSize);
+
+    SkRect glyphBounds;
+    paint.measureText(runBuffer.glyphs, 2, &glyphBounds);
+
+    REPORTER_ASSERT(reporter, glyphBounds.width() > SkGlyphCacheCommon::kSkSideTooBigForAtlas);
+
+    for (int i = 0; i < runSize; i++) {
+        runBuffer.pos[i] = i * 10;
+    }
+
+    return builder.make();
+}
+
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextAsMaskWithPathFallback,
+        reporter, ctxInfo) {
+    sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
+    SkStrikeServer server(discardableManager.get());
+    SkStrikeClient client(discardableManager, false);
+
+    SkPaint paint;
+
+    auto serverTf = MakeResourceAsTypeface("fonts/HangingS.ttf");
+    // TODO: when the cq bots can handle this font remove the check.
+    if (serverTf == nullptr) {
+        return;
+    }
+    auto serverTfData = server.serializeTypeface(serverTf.get());
+
+    auto serverBlob = make_blob_causing_fallback(serverTf, serverTf.get(), reporter);
+
+    const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
+    SkTextBlobCacheDiffCanvas cache_diff_canvas(10, 10, SkMatrix::I(), props, &server,
+                                                MakeSettings(ctxInfo.grContext()));
+    cache_diff_canvas.drawTextBlob(serverBlob.get(), 0, 0, paint);
+
+    std::vector<uint8_t> serverStrikeData;
+    server.writeStrikeData(&serverStrikeData);
+
+    // Client.
+    auto clientTf = client.deserializeTypeface(serverTfData->data(), serverTfData->size());
+    REPORTER_ASSERT(reporter,
+                    client.readStrikeData(serverStrikeData.data(), serverStrikeData.size()));
+
+    auto clientBlob = make_blob_causing_fallback(clientTf, serverTf.get(), reporter);
+
+    SkBitmap expected = RasterBlob(serverBlob, 10, 10, paint, ctxInfo.grContext());
+    SkBitmap actual = RasterBlob(clientBlob, 10, 10, paint, ctxInfo.grContext());
+    compare_blobs(expected, actual, reporter);
+    REPORTER_ASSERT(reporter, !discardableManager->hasCacheMiss());
+    SkStrikeCache::ValidateGlyphCacheDataSize();
+
+    // Must unlock everything on termination, otherwise valgrind complains about memory leaks.
+    discardableManager->unlockAndDeleteAll();
+}
+
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextXY, reporter, ctxInfo) {
     sk_sp<DiscardableManager> discardableManager = sk_make_sp<DiscardableManager>();
     SkStrikeServer server(discardableManager.get());