Break GrTextContext's reliance on SkGpuDevice

This CL seems to have 2 main downsides:

1) It duplicates some code in SkBaseDevice::filterTextFlags
2) It makes it tougher to derive from SkGpuDevice

It seems reasonable (at least to me) that the TextContexts get the power to reset the LCD flags.

Review URL: https://codereview.chromium.org/1159973002
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp
index 14f8ef7..1d2cc4c 100644
--- a/src/gpu/GrAtlasTextContext.cpp
+++ b/src/gpu/GrAtlasTextContext.cpp
@@ -344,7 +344,7 @@
     return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc());
 }
 
-void GrAtlasTextContext::drawTextBlob(SkGpuDevice* gpuDevice, GrRenderTarget* rt,
+void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt,
                                       const GrClip& clip, const SkPaint& skPaint,
                                       const SkMatrix& viewMatrix, const SkTextBlob* blob,
                                       SkScalar x, SkScalar y,
@@ -411,7 +411,7 @@
             fCache->remove(cacheBlob);
             cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, skPaint,
                                                            kGrayTextVASize)));
-            this->regenerateTextBlob(gpuDevice, cacheBlob, skPaint, grPaint.getColor(), viewMatrix,
+            this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMatrix,
                                      blob, x, y, drawFilter, clipRect, rt, clip, grPaint);
         } else {
             // If we can reuse the blob, then make sure we update the blob's viewmatrix, and x/y
@@ -428,12 +428,12 @@
         } else {
             cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize));
         }
-        this->regenerateTextBlob(gpuDevice, cacheBlob, skPaint, grPaint.getColor(), viewMatrix,
+        this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMatrix,
                                  blob, x, y, drawFilter, clipRect, rt, clip, grPaint);
     }
 
     cacheBlob->fPaintColor = skPaint.getColor();
-    this->flush(gpuDevice, drawContext, blob, cacheBlob, rt, skPaint, grPaint, drawFilter,
+    this->flush(drawContext, blob, cacheBlob, rt, skPaint, grPaint, drawFilter,
                 clip, viewMatrix, clipBounds, x, y, transX, transY);
 }
 
@@ -472,7 +472,7 @@
     return true;
 }
 
-void GrAtlasTextContext::regenerateTextBlob(SkGpuDevice* gpuDevice, BitmapTextBlob* cacheBlob,
+void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob,
                                             const SkPaint& skPaint, GrColor color,
                                             const SkMatrix& viewMatrix,
                                             const SkTextBlob* blob, SkScalar x, SkScalar y,
@@ -500,7 +500,7 @@
             continue;
         }
 
-        runPaint.setFlags(gpuDevice->filterTextFlags(runPaint));
+        runPaint.setFlags(FilterTextFlags(fDeviceProperties, runPaint));
 
         // setup vertex / glyphIndex for the new run
         if (run > 0) {
@@ -2043,7 +2043,7 @@
     float fGamma;
 };
 
-void GrAtlasTextContext::flushRunAsPaths(SkGpuDevice* gpuDevice, GrDrawContext* drawContext,
+void GrAtlasTextContext::flushRunAsPaths(GrDrawContext* drawContext,
                                          GrRenderTarget* rt, const SkTextBlob::RunIterator& it, 
                                          const GrClip& clip, const SkPaint& skPaint,
                                          SkDrawFilter* drawFilter, const SkMatrix& viewMatrix,
@@ -2059,7 +2059,7 @@
         return;
     }
 
-    runPaint.setFlags(gpuDevice->filterTextFlags(runPaint));
+    runPaint.setFlags(FilterTextFlags(fDeviceProperties, runPaint));
 
     switch (it.positioning()) {
         case SkTextBlob::kDefault_Positioning:
@@ -2172,8 +2172,7 @@
     }
 }
 
-void GrAtlasTextContext::flush(SkGpuDevice* gpuDevice,
-                               GrDrawContext* drawContext,
+void GrAtlasTextContext::flush(GrDrawContext* drawContext,
                                const SkTextBlob* blob,
                                BitmapTextBlob* cacheBlob,
                                GrRenderTarget* rt,
@@ -2195,7 +2194,7 @@
     SkTextBlob::RunIterator it(blob);
     for (int run = 0; !it.done(); it.next(), run++) {
         if (cacheBlob->fRuns[run].fDrawAsPaths) {
-            this->flushRunAsPaths(gpuDevice, drawContext, rt, it, clip, skPaint,
+            this->flushRunAsPaths(drawContext, rt, it, clip, skPaint,
                                   drawFilter, viewMatrix, clipBounds, x, y);
             continue;
         }
diff --git a/src/gpu/GrAtlasTextContext.h b/src/gpu/GrAtlasTextContext.h
index 3a8c37e..9a4ef6a 100644
--- a/src/gpu/GrAtlasTextContext.h
+++ b/src/gpu/GrAtlasTextContext.h
@@ -52,7 +52,7 @@
                        const char text[], size_t byteLength,
                        const SkScalar pos[], int scalarsPerPosition,
                        const SkPoint& offset, const SkIRect& regionClipBounds) override;
-    void drawTextBlob(SkGpuDevice*, GrRenderTarget*, const GrClip&, const SkPaint&,
+    void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&,
                       const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x, SkScalar y,
                       SkDrawFilter*, const SkIRect& clipBounds) override;
 
@@ -271,7 +271,7 @@
                                   size_t vertexStride, bool useVertexColor,
                                   GrGlyph*);
 
-    inline void flushRunAsPaths(SkGpuDevice*, GrDrawContext*, GrRenderTarget*,
+    inline void flushRunAsPaths(GrDrawContext*, GrRenderTarget*,
                                 const SkTextBlob::RunIterator&, const GrClip& clip,
                                 const SkPaint&, SkDrawFilter*,
                                 const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x,
@@ -287,7 +287,7 @@
                                SkScalar transX, SkScalar transY, const SkIRect& clipBounds);
 
     // We have to flush SkTextBlobs differently from drawText / drawPosText
-    void flush(SkGpuDevice*, GrDrawContext*, const SkTextBlob*, BitmapTextBlob*, GrRenderTarget*,
+    void flush(GrDrawContext*, const SkTextBlob*, BitmapTextBlob*, GrRenderTarget*,
                const SkPaint&, const GrPaint&, SkDrawFilter*, const GrClip&,
                const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, SkScalar y,
                SkScalar transX, SkScalar transY);
@@ -339,7 +339,7 @@
                                           const BitmapTextBlob&, const SkPaint&,
                                           const SkMaskFilter::BlurRec&,
                                           const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
-    void regenerateTextBlob(SkGpuDevice*, BitmapTextBlob* bmp, const SkPaint& skPaint, GrColor,
+    void regenerateTextBlob(BitmapTextBlob* bmp, const SkPaint& skPaint, GrColor,
                             const SkMatrix& viewMatrix,
                             const SkTextBlob* blob, SkScalar x, SkScalar y,
                             SkDrawFilter* drawFilter, const SkIRect& clipRect, GrRenderTarget*,
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index 1edacfc..91c8e85 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -101,7 +101,37 @@
                             scalarsPerPosition, offset, clipBounds);
 }
 
-void GrTextContext::drawTextBlob(SkGpuDevice* gpuDevice, GrRenderTarget* rt,
+bool GrTextContext::ShouldDisableLCD(const SkPaint& paint) {
+    if (paint.getShader() ||
+        !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode) ||
+        paint.getMaskFilter() ||
+        paint.getRasterizer() ||
+        paint.getColorFilter() ||
+        paint.getPathEffect() ||
+        paint.isFakeBoldText() ||
+        paint.getStyle() != SkPaint::kFill_Style)
+    {
+        return true;
+    }
+    return false;
+}
+
+uint32_t GrTextContext::FilterTextFlags(const SkDeviceProperties& devProps, const SkPaint& paint) {
+    uint32_t flags = paint.getFlags();
+
+    if (!paint.isLCDRenderText() || !paint.isAntiAlias()) {
+        return flags;
+    }
+
+    if (kUnknown_SkPixelGeometry == devProps.pixelGeometry() || ShouldDisableLCD(paint)) {
+        flags &= ~SkPaint::kLCDRenderText_Flag;
+        flags |= SkPaint::kGenA8FromLCD_Flag;
+    }
+
+    return flags;
+}
+
+void GrTextContext::drawTextBlob(GrRenderTarget* rt,
                                  const GrClip& clip, const SkPaint& skPaint,
                                  const SkMatrix& viewMatrix, const SkTextBlob* blob,
                                  SkScalar x, SkScalar y,
@@ -122,7 +152,7 @@
             continue;
         }
 
-        runPaint.setFlags(gpuDevice->filterTextFlags(runPaint));
+        runPaint.setFlags(FilterTextFlags(fDeviceProperties, runPaint));
 
         GrPaint grPaint;
         if (!SkPaint2GrPaint(fContext, fRenderTarget, runPaint, viewMatrix, true, &grPaint)) {
diff --git a/src/gpu/GrTextContext.h b/src/gpu/GrTextContext.h
index 07485f4..f4c0982 100644
--- a/src/gpu/GrTextContext.h
+++ b/src/gpu/GrTextContext.h
@@ -19,7 +19,6 @@
 class GrDrawContext;
 class GrFontScaler;
 class SkDrawFilter;
-class SkGpuDevice;
 class SkTextBlob;
 
 /*
@@ -37,11 +36,13 @@
                      const char text[], size_t byteLength,
                      const SkScalar pos[], int scalarsPerPosition,
                      const SkPoint& offset, const SkIRect& clipBounds);
-    virtual void drawTextBlob(SkGpuDevice*, GrRenderTarget*, const GrClip&, const SkPaint&,
+    virtual void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&,
                               const SkMatrix& viewMatrix, const SkTextBlob*,
                               SkScalar x, SkScalar y,
                               SkDrawFilter*, const SkIRect& clipBounds);
 
+    static bool ShouldDisableLCD(const SkPaint& paint);
+
 protected:
     GrTextContext*                 fFallbackTextContext;
     GrContext*                     fContext;
@@ -87,6 +88,7 @@
     // sets extent in stopVector and returns glyph count
     static int MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
                            const char text[], size_t byteLength, SkVector* stopVector);
+    static uint32_t FilterTextFlags(const SkDeviceProperties& devProps, const SkPaint& paint);
 
     friend class BitmapTextBatch;
 };
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 0008540..90e53a0 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1659,25 +1659,14 @@
 
     SkDEBUGCODE(this->validate();)
 
-    fTextContext->drawTextBlob(this, fRenderTarget, fClip, paint, *draw.fMatrix,
+    fTextContext->drawTextBlob(fRenderTarget, fClip, paint, *draw.fMatrix,
                                blob, x, y, drawFilter, draw.fClip->getBounds());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 bool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const {
-    if (paint.getShader() ||
-        !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode) ||
-        paint.getMaskFilter() ||
-        paint.getRasterizer() ||
-        paint.getColorFilter() ||
-        paint.getPathEffect() ||
-        paint.isFakeBoldText() ||
-        paint.getStyle() != SkPaint::kFill_Style)
-    {
-        return true;
-    }
-    return false;
+    return GrTextContext::ShouldDisableLCD(paint);
 }
 
 void SkGpuDevice::flush() {
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index d7dceed..d1070e5 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -138,7 +138,7 @@
 protected:
     bool onReadPixels(const SkImageInfo&, void*, size_t, int, int) override;
     bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) override;
-    bool onShouldDisableLCD(const SkPaint&) const override;
+    bool onShouldDisableLCD(const SkPaint&) const final;
 
     /**  PRIVATE / EXPERIMENTAL -- do not call */
     virtual bool EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture,