Revert "Revert "Make GrAtlasTextOp a non-legacy GrMeshDrawOp""

This reverts commit e3e9628ecf863f433f26bf6107d6a39ced57fe30.

Adds blendmode_mask_* benchs to blacklist for Chromecast.
Otherwise a clean revert of the revert.

Bug: skia:
Change-Id: I9f64ae55804fa4aad97c1785834281039570c56c
Reviewed-on: https://skia-review.googlesource.com/24409
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/infra/bots/recipes/perf.expected/Perf-Chromecast-GCC-Chorizo-CPU-Cortex_A7-arm-Debug.json b/infra/bots/recipes/perf.expected/Perf-Chromecast-GCC-Chorizo-CPU-Cortex_A7-arm-Debug.json
index f8dc89c..7c6ae65 100644
--- a/infra/bots/recipes/perf.expected/Perf-Chromecast-GCC-Chorizo-CPU-Cortex_A7-arm-Debug.json
+++ b/infra/bots/recipes/perf.expected/Perf-Chromecast-GCC-Chorizo-CPU-Cortex_A7-arm-Debug.json
@@ -318,7 +318,8 @@
       "~matrixconvolution",
       "~blur_image_filter",
       "~blur_0.01",
-      "~GM_animated-image-blurs"
+      "~GM_animated-image-blurs",
+      "~blendmode_mask_"
     ],
     "env": {
       "BUILDTYPE": "Debug",
diff --git a/infra/bots/recipes/perf.expected/Perf-Chromecast-GCC-Chorizo-GPU-Cortex_A7-arm-Release.json b/infra/bots/recipes/perf.expected/Perf-Chromecast-GCC-Chorizo-GPU-Cortex_A7-arm-Release.json
index fe89726..9723087 100644
--- a/infra/bots/recipes/perf.expected/Perf-Chromecast-GCC-Chorizo-GPU-Cortex_A7-arm-Release.json
+++ b/infra/bots/recipes/perf.expected/Perf-Chromecast-GCC-Chorizo-GPU-Cortex_A7-arm-Release.json
@@ -355,6 +355,7 @@
       "~blur_image_filter",
       "~blur_0.01",
       "~GM_animated-image-blurs",
+      "~blendmode_mask_",
       "--outResultsFile",
       "/cache/skia/perf/nanobench_abc123_1337000001.json",
       "--properties",
diff --git a/infra/bots/recipes/perf.py b/infra/bots/recipes/perf.py
index 98ddb1d..c08888f 100644
--- a/infra/bots/recipes/perf.py
+++ b/infra/bots/recipes/perf.py
@@ -266,6 +266,7 @@
       '~blur_image_filter',
       '~blur_0.01',
       '~GM_animated-image-blurs',
+      '~blendmode_mask_',
     ])
 
   if api.vars.upload_perf_results:
diff --git a/src/gpu/GrDrawOpTest.h b/src/gpu/GrDrawOpTest.h
index a30ca28..b77fe48 100644
--- a/src/gpu/GrDrawOpTest.h
+++ b/src/gpu/GrDrawOpTest.h
@@ -27,12 +27,13 @@
 #define GR_DRAW_OP_TEST_DEFINE(Op)                                                              \
     std::unique_ptr<GrDrawOp> Op##__Test(GrPaint&& paint, SkRandom* random, GrContext* context, \
                                          GrFSAAType fsaaType)
+#define GR_DRAW_OP_TEST_FRIEND(Op)                                                 \
+    friend std::unique_ptr<GrDrawOp> Op##__Test(GrPaint&& paint, SkRandom* random, \
+                                                GrContext* context, GrFSAAType fsaaType)
 
 /** Variations for GrLegacyMeshDrawOps. To be deleted. */
 #define GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(Op) \
     std::unique_ptr<GrLegacyMeshDrawOp> Op##__Test(SkRandom* random, GrContext* context)
-#define GR_LEGACY_MESH_DRAW_OP_TEST_FRIEND(Op) \
-    friend std::unique_ptr<GrLegacyMeshDrawOp> Op##__Test(SkRandom* random, GrContext* context);
 
 /** Helper for op test factories to pick a random stencil state. */
 const GrUserStencilSettings* GrGetRandomStencil(SkRandom* random, GrContext*);
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
index 666e1c3..e3fe4c6 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -134,6 +134,7 @@
 
     bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); }
 
+    /** These are valid only for non-LCD coverage. */
     static const GrProcessorSet& EmptySet();
     static constexpr const Analysis EmptySetAnalysis() { return Analysis(Empty::kEmpty); }
 
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp
index 9c4172c..a7b4967 100644
--- a/src/gpu/ops/GrAtlasTextOp.cpp
+++ b/src/gpu/ops/GrAtlasTextOp.cpp
@@ -34,40 +34,45 @@
                     fGeoData[i].fBlob->runCount());
     }
 
-    str.append(DumpPipelineInfo(*this->pipeline()));
-    str.append(INHERITED::dumpInfo());
+    str += fProcessors.dumpProcessors();
+    str += INHERITED::dumpInfo();
     return str;
 }
 
-void GrAtlasTextOp::getProcessorAnalysisInputs(GrProcessorAnalysisColor* color,
-                                               GrProcessorAnalysisCoverage* coverage) const {
+GrDrawOp::FixedFunctionFlags GrAtlasTextOp::fixedFunctionFlags() const {
+    return FixedFunctionFlags::kNone;
+}
+
+GrDrawOp::RequiresDstTexture GrAtlasTextOp::finalize(const GrCaps& caps,
+                                                     const GrAppliedClip* clip) {
+    GrProcessorAnalysisCoverage coverage;
+    GrProcessorAnalysisColor color;
     if (kColorBitmapMask_MaskType == fMaskType) {
-        color->setToUnknown();
+        color.setToUnknown();
     } else {
-        color->setToConstant(fColor);
+        color.setToConstant(fColor);
     }
     switch (fMaskType) {
         case kGrayscaleCoverageMask_MaskType:
         case kAliasedDistanceField_MaskType:
         case kGrayscaleDistanceField_MaskType:
-            *coverage = GrProcessorAnalysisCoverage::kSingleChannel;
+            coverage = GrProcessorAnalysisCoverage::kSingleChannel;
             break;
         case kLCDCoverageMask_MaskType:
         case kLCDDistanceField_MaskType:
         case kLCDBGRDistanceField_MaskType:
-            *coverage = GrProcessorAnalysisCoverage::kLCD;
+            coverage = GrProcessorAnalysisCoverage::kLCD;
             break;
         case kColorBitmapMask_MaskType:
-            *coverage = GrProcessorAnalysisCoverage::kNone;
+            coverage = GrProcessorAnalysisCoverage::kNone;
             break;
     }
-}
-
-void GrAtlasTextOp::applyPipelineOptimizations(const PipelineOptimizations& optimizations) {
-    optimizations.getOverrideColorIfSet(&fGeoData[0].fColor);
-
-    fColor = fGeoData[0].fColor;
-    fUsesLocalCoords = optimizations.readsLocalCoords();
+    auto analysis = fProcessors.finalize(color, coverage, clip, false, caps, &fColor);
+    fUsesLocalCoords = analysis.usesLocalCoords();
+    fCanCombineOnTouchOrOverlap =
+            !analysis.requiresDstTexture() &&
+            !(fProcessors.xferProcessor() && fProcessors.xferProcessor()->xferBarrierType(caps));
+    return analysis.requiresDstTexture() ? RequiresDstTexture::kYes : RequiresDstTexture::kNo;
 }
 
 void GrAtlasTextOp::onPrepareDraws(Target* target) const {
@@ -88,15 +93,16 @@
     GrMaskFormat maskFormat = this->maskFormat();
 
     FlushInfo flushInfo;
+    flushInfo.fPipeline = target->makePipeline(fSRGBFlags, &fProcessors);
     if (this->usesDistanceFields()) {
         flushInfo.fGeometryProcessor =
                 this->setupDfProcessor(this->viewMatrix(),
                                        fLuminanceColor, this->color(), std::move(proxy));
     } else {
         GrSamplerParams params(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode);
-        flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
-                this->color(), std::move(proxy), params,
-                maskFormat, localMatrix, this->usesLocalCoords());
+        flushInfo.fGeometryProcessor =
+                GrBitmapTextGeoProc::Make(this->color(), std::move(proxy), params, maskFormat,
+                                          localMatrix, this->usesLocalCoords());
     }
 
     flushInfo.fGlyphsToFlush = 0;
@@ -145,15 +151,18 @@
     mesh.setIndexedPatterned(flushInfo->fIndexBuffer.get(), kIndicesPerGlyph, kVerticesPerGlyph,
                              flushInfo->fGlyphsToFlush, maxGlyphsPerDraw);
     mesh.setVertexData(flushInfo->fVertexBuffer.get(), flushInfo->fVertexOffset);
-    target->draw(flushInfo->fGeometryProcessor.get(), this->pipeline(), mesh);
+    target->draw(flushInfo->fGeometryProcessor.get(), flushInfo->fPipeline, mesh);
     flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush;
     flushInfo->fGlyphsToFlush = 0;
 }
 
 bool GrAtlasTextOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
     GrAtlasTextOp* that = t->cast<GrAtlasTextOp>();
-    if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
-                                that->bounds(), caps)) {
+    if (fProcessors != that->fProcessors) {
+        return false;
+    }
+
+    if (!fCanCombineOnTouchOrOverlap && GrRectsTouchOrOverlap(this->bounds(), that->bounds())) {
         return false;
     }
 
@@ -239,9 +248,8 @@
                 GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(
                         redCorrection, greenCorrection, blueCorrection);
 
-        return GrDistanceFieldLCDTextGeoProc::Make(color, viewMatrix, std::move(proxy),
-                                                   params, widthAdjust, flags,
-                                                   this->usesLocalCoords());
+        return GrDistanceFieldLCDTextGeoProc::Make(color, viewMatrix, std::move(proxy), params,
+                                                   widthAdjust, flags, this->usesLocalCoords());
     } else {
 #ifdef SK_GAMMA_APPLY_TO_A8
         float correction = 0;
@@ -250,10 +258,8 @@
             correction = fDistanceAdjustTable->getAdjustment(lum >> kDistanceAdjustLumShift,
                                                              fUseGammaCorrectDistanceTable);
         }
-        return GrDistanceFieldA8TextGeoProc::Make(color,
-                                                  viewMatrix, std::move(proxy),
-                                                  params, correction, flags,
-                                                  this->usesLocalCoords());
+        return GrDistanceFieldA8TextGeoProc::Make(color, viewMatrix, std::move(proxy), params,
+                                                  correction, flags, this->usesLocalCoords());
 #else
         return GrDistanceFieldA8TextGeoProc::Make(color,
                                                   viewMatrix, std::move(proxy),
diff --git a/src/gpu/ops/GrAtlasTextOp.h b/src/gpu/ops/GrAtlasTextOp.h
index 24166a1..449f1fa 100644
--- a/src/gpu/ops/GrAtlasTextOp.h
+++ b/src/gpu/ops/GrAtlasTextOp.h
@@ -9,11 +9,10 @@
 #define GrAtlasTextOp_DEFINED
 
 #include "ops/GrMeshDrawOp.h"
-
 #include "text/GrAtlasTextContext.h"
 #include "text/GrDistanceFieldAdjustTable.h"
 
-class GrAtlasTextOp final : public GrLegacyMeshDrawOp {
+class GrAtlasTextOp final : public GrMeshDrawOp {
 public:
     DEFINE_OP_CLASS_ID
 
@@ -37,9 +36,9 @@
         GrColor fColor;
     };
 
-    static std::unique_ptr<GrAtlasTextOp> MakeBitmap(GrMaskFormat maskFormat, int glyphCount,
-                                                     GrAtlasGlyphCache* fontCache) {
-        std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp);
+    static std::unique_ptr<GrAtlasTextOp> MakeBitmap(GrPaint&& paint, GrMaskFormat maskFormat,
+                                                     int glyphCount, GrAtlasGlyphCache* fontCache) {
+        std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(std::move(paint)));
 
         op->fFontCache = fontCache;
         switch (maskFormat) {
@@ -61,11 +60,11 @@
     }
 
     static std::unique_ptr<GrAtlasTextOp> MakeDistanceField(
-            int glyphCount, GrAtlasGlyphCache* fontCache,
+            GrPaint&& paint, int glyphCount, GrAtlasGlyphCache* fontCache,
             const GrDistanceFieldAdjustTable* distanceAdjustTable,
             bool useGammaCorrectDistanceTable, SkColor luminanceColor, bool isLCD, bool useBGR,
             bool isAntiAliased) {
-        std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp);
+        std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(std::move(paint)));
 
         op->fFontCache = fontCache;
         op->fMaskType = !isAntiAliased ? kAliasedDistanceField_MaskType
@@ -100,23 +99,28 @@
 
     SkString dumpInfo() const override;
 
+    FixedFunctionFlags fixedFunctionFlags() const override;
+
+    RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override;
+
 private:
-    void getProcessorAnalysisInputs(GrProcessorAnalysisColor*,
-                                    GrProcessorAnalysisCoverage*) const override;
-    void applyPipelineOptimizations(const PipelineOptimizations&) override;
+    GrAtlasTextOp(GrPaint&& paint)
+            : INHERITED(ClassID())
+            , fColor(paint.getColor())
+            , fSRGBFlags(GrPipeline::SRGBFlagsFromPaint(paint))
+            , fProcessors(std::move(paint)) {}
 
     struct FlushInfo {
         sk_sp<const GrBuffer> fVertexBuffer;
         sk_sp<const GrBuffer> fIndexBuffer;
         sk_sp<GrGeometryProcessor> fGeometryProcessor;
+        const GrPipeline* fPipeline;
         int fGlyphsToFlush;
         int fVertexOffset;
     };
 
     void onPrepareDraws(Target* target) const override;
 
-    GrAtlasTextOp() : INHERITED(ClassID()) {}  // initialized in factory functions.
-
     GrMaskFormat maskFormat() const {
         switch (fMaskType) {
             case kLCDCoverageMask_MaskType:
@@ -159,14 +163,9 @@
     sk_sp<GrGeometryProcessor> setupDfProcessor(const SkMatrix& viewMatrix, SkColor luminanceColor,
                                                 GrColor color, sk_sp<GrTextureProxy> proxy) const;
 
-    GrColor fColor;
-    bool fUsesLocalCoords;
-    int fNumGlyphs;
 
     // The minimum number of Geometry we will try to allocate.
     enum { kMinGeometryAllocated = 4 };
-    SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
-    int fGeoCount;
 
     enum MaskType {
         kGrayscaleCoverageMask_MaskType,
@@ -176,10 +175,18 @@
         kGrayscaleDistanceField_MaskType,
         kLCDDistanceField_MaskType,
         kLCDBGRDistanceField_MaskType,
-    } fMaskType;
+    };
 
+    SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
+    GrColor fColor;
+    uint32_t fSRGBFlags;
+    GrProcessorSet fProcessors;
+    bool fUsesLocalCoords;
+    bool fCanCombineOnTouchOrOverlap;
+    int fGeoCount;
+    int fNumGlyphs;
+    MaskType fMaskType;
     GrAtlasGlyphCache* fFontCache;
-
     // Distance field properties
     sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
     SkColor fLuminanceColor;
@@ -187,7 +194,7 @@
 
     friend class GrBlobRegenHelper;  // Needs to trigger flushes
 
-    typedef GrLegacyMeshDrawOp INHERITED;
+    typedef GrMeshDrawOp INHERITED;
 };
 
 /*
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 10b1c81..835105b 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -257,22 +257,26 @@
     return false;
 }
 
-inline std::unique_ptr<GrLegacyMeshDrawOp> GrAtlasTextBlob::makeOp(
+inline std::unique_ptr<GrDrawOp> GrAtlasTextBlob::makeOp(
         const Run::SubRunInfo& info, int glyphCount, int run, int subRun,
         const SkMatrix& viewMatrix, SkScalar x, SkScalar y, const GrTextUtils::Paint& paint,
         const SkSurfaceProps& props, const GrDistanceFieldAdjustTable* distanceAdjustTable,
-        bool useGammaCorrectDistanceTable, GrAtlasGlyphCache* cache) {
+        GrAtlasGlyphCache* cache, GrRenderTargetContext* renderTargetContext) {
     GrMaskFormat format = info.maskFormat();
 
+    GrPaint grPaint;
+    if (!paint.toGrPaint(info.maskFormat(), renderTargetContext, viewMatrix, &grPaint)) {
+        return nullptr;
+    }
     std::unique_ptr<GrAtlasTextOp> op;
     if (info.drawAsDistanceFields()) {
-        SkColor luminanceColor = paint.luminanceColor();
         bool useBGR = SkPixelGeometryIsBGR(props.pixelGeometry());
-        op = GrAtlasTextOp::MakeDistanceField(glyphCount, cache, distanceAdjustTable,
-                                              useGammaCorrectDistanceTable, luminanceColor,
-                                              info.hasUseLCDText(), useBGR, info.isAntiAliased());
+        op = GrAtlasTextOp::MakeDistanceField(
+                std::move(grPaint), glyphCount, cache, distanceAdjustTable,
+                renderTargetContext->isGammaCorrect(), paint.luminanceColor(), info.hasUseLCDText(),
+                useBGR, info.isAntiAliased());
     } else {
-        op = GrAtlasTextOp::MakeBitmap(format, glyphCount, cache);
+        op = GrAtlasTextOp::MakeBitmap(std::move(grPaint), format, glyphCount, cache);
     }
     GrAtlasTextOp::Geometry& geometry = op->geometry();
     geometry.fViewMatrix = viewMatrix;
@@ -284,7 +288,6 @@
     geometry.fX = x;
     geometry.fY = y;
     op->init();
-
     return std::move(op);
 }
 
@@ -304,13 +307,11 @@
         if (0 == glyphCount) {
             continue;
         }
-
-        std::unique_ptr<GrLegacyMeshDrawOp> op(
-                this->makeOp(info, glyphCount, run, subRun, viewMatrix, x, y, paint, props,
-                             distanceAdjustTable, rtc->isGammaCorrect(), cache));
-        GrPipelineBuilder pipelineBuilder(std::move(grPaint), GrAAType::kNone);
-
-        rtc->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op));
+        auto op = this->makeOp(info, glyphCount, run, subRun, viewMatrix, x, y, std::move(paint),
+                               props, distanceAdjustTable, cache, rtc);
+        if (op) {
+            rtc->addDrawOp(clip, std::move(op));
+        }
     }
 }
 
@@ -425,13 +426,14 @@
     this->flushBigGlyphs(context, rtc, clip, paint, viewMatrix, x, y, clipBounds);
 }
 
-std::unique_ptr<GrLegacyMeshDrawOp> GrAtlasTextBlob::test_makeOp(
+std::unique_ptr<GrDrawOp> GrAtlasTextBlob::test_makeOp(
         int glyphCount, int run, int subRun, const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
         const GrTextUtils::Paint& paint, const SkSurfaceProps& props,
-        const GrDistanceFieldAdjustTable* distanceAdjustTable, GrAtlasGlyphCache* cache) {
+        const GrDistanceFieldAdjustTable* distanceAdjustTable, GrAtlasGlyphCache* cache,
+        GrRenderTargetContext* rtc) {
     const GrAtlasTextBlob::Run::SubRunInfo& info = fRuns[run].fSubRunInfo[subRun];
     return this->makeOp(info, glyphCount, run, subRun, viewMatrix, x, y, paint, props,
-                        distanceAdjustTable, false, cache);
+                        distanceAdjustTable, cache, rtc);
 }
 
 void GrAtlasTextBlob::AssertEqual(const GrAtlasTextBlob& l, const GrAtlasTextBlob& r) {
diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h
index 12fe68b..1bce341 100644
--- a/src/gpu/text/GrAtlasTextBlob.h
+++ b/src/gpu/text/GrAtlasTextBlob.h
@@ -271,10 +271,11 @@
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
     // Internal test methods
-    std::unique_ptr<GrLegacyMeshDrawOp> test_makeOp(
-            int glyphCount, int run, int subRun, const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
-            const GrTextUtils::Paint& paint, const SkSurfaceProps& props,
-            const GrDistanceFieldAdjustTable* distanceAdjustTable, GrAtlasGlyphCache* cache);
+    std::unique_ptr<GrDrawOp> test_makeOp(int glyphCount, int run, int subRun,
+                                          const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
+                                          const GrTextUtils::Paint&, const SkSurfaceProps&,
+                                          const GrDistanceFieldAdjustTable*, GrAtlasGlyphCache*,
+                                          GrRenderTargetContext*);
 
 private:
     GrAtlasTextBlob()
@@ -497,11 +498,12 @@
                    Run* run, Run::SubRunInfo* info, SkAutoGlyphCache*, int glyphCount,
                    size_t vertexStride, GrColor color, SkScalar transX, SkScalar transY) const;
 
-    inline std::unique_ptr<GrLegacyMeshDrawOp> makeOp(
-            const Run::SubRunInfo& info, int glyphCount, int run, int subRun,
-            const SkMatrix& viewMatrix, SkScalar x, SkScalar y, const GrTextUtils::Paint& paint,
-            const SkSurfaceProps& props, const GrDistanceFieldAdjustTable* distanceAdjustTable,
-            bool useGammaCorrectDistanceTable, GrAtlasGlyphCache* cache);
+    inline std::unique_ptr<GrDrawOp> makeOp(const Run::SubRunInfo& info, int glyphCount, int run,
+                                            int subRun, const SkMatrix& viewMatrix, SkScalar x,
+                                            SkScalar y, const GrTextUtils::Paint& paint,
+                                            const SkSurfaceProps& props,
+                                            const GrDistanceFieldAdjustTable* distanceAdjustTable,
+                                            GrAtlasGlyphCache* cache, GrRenderTargetContext*);
 
     struct BigGlyph {
         BigGlyph(const SkPath& path, SkScalar vx, SkScalar vy, SkScalar scale, bool treatAsBMP)
diff --git a/src/gpu/text/GrAtlasTextContext.cpp b/src/gpu/text/GrAtlasTextContext.cpp
index 71c410e..22228ed 100644
--- a/src/gpu/text/GrAtlasTextContext.cpp
+++ b/src/gpu/text/GrAtlasTextContext.cpp
@@ -339,7 +339,7 @@
 
 #if GR_TEST_UTILS
 
-GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(TextBlobOp) {
+GR_DRAW_OP_TEST_DEFINE(GrAtlasTextOp) {
     static uint32_t gContextID = SK_InvalidGenID;
     static GrAtlasTextContext* gTextContext = nullptr;
     static SkSurfaceProps gSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);
@@ -356,11 +356,15 @@
         SkBackingFit::kApprox, 1024, 1024, kRGBA_8888_GrPixelConfig, nullptr));
 
     SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
+
+    // Because we the GrTextUtils::Paint requires an SkPaint for font info, we ignore the GrPaint
+    // param.
     SkPaint skPaint;
     skPaint.setColor(random->nextU());
     skPaint.setLCDRenderText(random->nextBool());
     skPaint.setAntiAlias(skPaint.isLCDRenderText() ? true : random->nextBool());
     skPaint.setSubpixelText(random->nextBool());
+    GrTextUtils::Paint utilsPaint(&skPaint, rtc->getColorSpace(), rtc->getColorXformFromSRGB());
 
     const char* text = "The quick brown fox jumps over the lazy dog.";
     int textLen = (int)strlen(text);
@@ -374,17 +378,17 @@
     SkScalar x = SkIntToScalar(xInt);
     SkScalar y = SkIntToScalar(yInt);
 
-    GrTextUtils::Paint paint(&skPaint, rtc->getColorSpace(), rtc->getColorXformFromSRGB());
     // right now we don't handle textblobs, nor do we handle drawPosText. Since we only intend to
     // test the text op with this unit test, that is okay.
     sk_sp<GrAtlasTextBlob> blob(GrAtlasTextContext::MakeDrawTextBlob(
             context->getTextBlobCache(), context->getAtlasGlyphCache(),
-            *context->caps()->shaderCaps(), paint,
+            *context->caps()->shaderCaps(), utilsPaint,
             GrAtlasTextContext::kTextBlobOpScalerContextFlags, viewMatrix, gSurfaceProps, text,
             static_cast<size_t>(textLen), x, y));
 
-    return blob->test_makeOp(textLen, 0, 0, viewMatrix, x, y, paint, gSurfaceProps,
-                             gTextContext->dfAdjustTable(), context->getAtlasGlyphCache());
+    return blob->test_makeOp(textLen, 0, 0, viewMatrix, x, y, utilsPaint, gSurfaceProps,
+                             gTextContext->dfAdjustTable(), context->getAtlasGlyphCache(),
+                             rtc.get());
 }
 
 #endif
diff --git a/src/gpu/text/GrAtlasTextContext.h b/src/gpu/text/GrAtlasTextContext.h
index e375195..c47ec65 100644
--- a/src/gpu/text/GrAtlasTextContext.h
+++ b/src/gpu/text/GrAtlasTextContext.h
@@ -89,7 +89,7 @@
 #if GR_TEST_UTILS
     static const uint32_t kTextBlobOpScalerContextFlags =
             SkPaint::kFakeGammaAndBoostContrast_ScalerContextFlags;
-    GR_LEGACY_MESH_DRAW_OP_TEST_FRIEND(TextBlobOp);
+    GR_DRAW_OP_TEST_FRIEND(GrAtlasTextOp);
 #endif
 };
 
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index 727c169..0265f6e 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -314,7 +314,6 @@
 #define DRAW_OP_TEST_ENTRY(Op) Op##__Test
 
 LEGACY_MESH_DRAW_OP_TEST_EXTERN(AnalyticRectOp);
-LEGACY_MESH_DRAW_OP_TEST_EXTERN(TextBlobOp);
 
 DRAW_OP_TEST_EXTERN(AAConvexPathOp);
 DRAW_OP_TEST_EXTERN(AAFillRectOp);
@@ -326,6 +325,7 @@
 DRAW_OP_TEST_EXTERN(DefaultPathOp);
 DRAW_OP_TEST_EXTERN(DIEllipseOp);
 DRAW_OP_TEST_EXTERN(EllipseOp);
+DRAW_OP_TEST_EXTERN(GrAtlasTextOp);
 DRAW_OP_TEST_EXTERN(GrDrawAtlasOp);
 DRAW_OP_TEST_EXTERN(GrDrawVerticesOp);
 DRAW_OP_TEST_EXTERN(NonAAFillRectOp);
@@ -342,7 +342,6 @@
     using MakeTestLegacyMeshDrawOpFn = std::unique_ptr<GrLegacyMeshDrawOp>(SkRandom*, GrContext*);
     static constexpr MakeTestLegacyMeshDrawOpFn* gLegacyFactories[] = {
         DRAW_OP_TEST_ENTRY(AnalyticRectOp),
-        DRAW_OP_TEST_ENTRY(TextBlobOp),
     };
 
     using MakeDrawOpFn = std::unique_ptr<GrDrawOp>(GrPaint&&, SkRandom*, GrContext*, GrFSAAType);
@@ -357,6 +356,7 @@
         DRAW_OP_TEST_ENTRY(DefaultPathOp),
         DRAW_OP_TEST_ENTRY(DIEllipseOp),
         DRAW_OP_TEST_ENTRY(EllipseOp),
+        DRAW_OP_TEST_ENTRY(GrAtlasTextOp),
         DRAW_OP_TEST_ENTRY(GrDrawAtlasOp),
         DRAW_OP_TEST_ENTRY(GrDrawVerticesOp),
         DRAW_OP_TEST_ENTRY(NonAAFillRectOp),
diff --git a/whitespace.txt b/whitespace.txt
index f9ffb83..e08b3f9 100644
--- a/whitespace.txt
+++ b/whitespace.txt
@@ -1,7 +1,7 @@
 You can modify this file to create no-op changelists (like this one).
 I LOVE W	H	I	T	E	S	P	A	C	E!
 Python also loves\n\twhitespace.¯\_(ツ)_/¯
-
+ 
 Lithp.
 Use the Forth.
 Life is a mistry.  Everyone must WAKA WAKA WAKA