Only use fake gamma with linear devices.
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1711223003

Review URL: https://codereview.chromium.org/1711223003
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index d42a179..b041df8 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1556,6 +1556,10 @@
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
+SkPaint::FakeGamma SkDraw::fakeGamma() const {
+    return fDevice->imageInfo().isLinear() ? SkPaint::FakeGamma::On : SkPaint::FakeGamma::Off;
+}
+
 void SkDraw::drawText(const char text[], size_t byteLength,
                       SkScalar x, SkScalar y, const SkPaint& paint) const {
     SkASSERT(byteLength == 0 || text != nullptr);
@@ -1574,17 +1578,16 @@
         return;
     }
 
-    SkAutoGlyphCache       autoCache(paint, &fDevice->surfaceProps(), fMatrix);
-    SkGlyphCache*          cache = autoCache.getCache();
+    SkAutoGlyphCache cache(paint, &fDevice->surfaceProps(), this->fakeGamma(), fMatrix);
 
     // The Blitter Choose needs to be live while using the blitter below.
     SkAutoBlitterChoose    blitterChooser(fDst, *fMatrix, paint);
     SkAAClipBlitterWrapper wrapper(*fRC, blitterChooser.get());
-    DrawOneGlyph           drawOneGlyph(*this, paint, cache, wrapper.getBlitter());
+    DrawOneGlyph           drawOneGlyph(*this, paint, cache.get(), wrapper.getBlitter());
 
     SkFindAndPlaceGlyph::ProcessText(
         paint.getTextEncoding(), text, byteLength,
-        {x, y}, *fMatrix, paint.getTextAlign(), cache, drawOneGlyph);
+        {x, y}, *fMatrix, paint.getTextAlign(), cache.get(), drawOneGlyph);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1604,8 +1607,7 @@
     paint.setPathEffect(nullptr);
 
     SkDrawCacheProc     glyphCacheProc = paint.getDrawCacheProc();
-    SkAutoGlyphCache    autoCache(paint, &fDevice->surfaceProps(), nullptr);
-    SkGlyphCache*       cache = autoCache.getCache();
+    SkAutoGlyphCache    cache(paint, &fDevice->surfaceProps(), this->fakeGamma(), nullptr);
 
     const char*        stop = text + byteLength;
     SkTextAlignProc    alignProc(paint.getTextAlign());
@@ -1616,7 +1618,7 @@
     paint.setPathEffect(origPaint.getPathEffect());
 
     while (text < stop) {
-        const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
+        const SkGlyph& glyph = glyphCacheProc(cache.get(), &text, 0, 0);
         if (glyph.fWidth) {
             const SkPath* path = cache->findPath(glyph);
             if (path) {
@@ -1656,18 +1658,17 @@
         return;
     }
 
-    SkAutoGlyphCache       autoCache(paint, &fDevice->surfaceProps(), fMatrix);
-    SkGlyphCache*          cache = autoCache.getCache();
+    SkAutoGlyphCache cache(paint, &fDevice->surfaceProps(), this->fakeGamma(), fMatrix);
 
     // The Blitter Choose needs to be live while using the blitter below.
     SkAutoBlitterChoose    blitterChooser(fDst, *fMatrix, paint);
     SkAAClipBlitterWrapper wrapper(*fRC, blitterChooser.get());
-    DrawOneGlyph           drawOneGlyph(*this, paint, cache, wrapper.getBlitter());
+    DrawOneGlyph           drawOneGlyph(*this, paint, cache.get(), wrapper.getBlitter());
     SkPaint::Align         textAlignment = paint.getTextAlign();
 
     SkFindAndPlaceGlyph::ProcessPosText(
         paint.getTextEncoding(), text, byteLength,
-        offset, *fMatrix, pos, scalarsPerPosition, textAlignment, cache, drawOneGlyph);
+        offset, *fMatrix, pos, scalarsPerPosition, textAlignment, cache.get(), drawOneGlyph);
 }
 
 #if defined _WIN32 && _MSC_VER >= 1300
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h
index cd0b05c..2c49530 100644
--- a/src/core/SkGlyphCache.h
+++ b/src/core/SkGlyphCache.h
@@ -11,12 +11,12 @@
 #include "SkChunkAlloc.h"
 #include "SkDescriptor.h"
 #include "SkGlyph.h"
+#include "SkPaint.h"
 #include "SkTHash.h"
 #include "SkScalerContext.h"
 #include "SkTemplates.h"
 #include "SkTDArray.h"
 
-class SkPaint;
 class SkTraceMemoryDump;
 
 class SkGlyphCache_Globals;
@@ -137,6 +137,7 @@
         the global cache list (after which the caller should not reference it anymore.
     */
     static void AttachCache(SkGlyphCache*);
+    using AttachCacheFunctor = SkFunctionWrapper<void, SkGlyphCache, AttachCache>;
 
     /** Detach a strike from the global cache matching the specified descriptor. Once detached,
         it can be queried/modified by the current thread, and when finished, be reattached to the
@@ -271,74 +272,40 @@
     AuxProcRec*            fAuxProcList;
 };
 
-class SkAutoGlyphCacheBase {
+class SkAutoGlyphCache : public skstd::unique_ptr<SkGlyphCache, SkGlyphCache::AttachCacheFunctor> {
 public:
-    SkGlyphCache* getCache() const { return fCache; }
+    /** deprecated: use get() */
+    SkGlyphCache* getCache() const { return this->get(); }
 
-    void release() {
-        if (fCache) {
-            SkGlyphCache::AttachCache(fCache);
-            fCache = nullptr;
-        }
-    }
-
-protected:
-    // Hide the constructors so we can't create one of these directly. Create SkAutoGlyphCache or
-    // SkAutoGlyphCacheNoCache instead.
-    SkAutoGlyphCacheBase(SkGlyphCache* cache) : fCache(cache) {}
-    SkAutoGlyphCacheBase(SkTypeface* typeface, const SkDescriptor* desc) {
-        fCache = SkGlyphCache::DetachCache(typeface, desc);
-    }
-    SkAutoGlyphCacheBase(const SkPaint& /*paint*/,
-                         const SkSurfaceProps* /*surfaceProps*/,
-                         const SkMatrix* /*matrix*/) {
-        fCache = nullptr;
-    }
-    SkAutoGlyphCacheBase() {
-        fCache = nullptr;
-    }
-    ~SkAutoGlyphCacheBase() {
-        if (fCache) {
-            SkGlyphCache::AttachCache(fCache);
-        }
-    }
-
-    SkGlyphCache*   fCache;
-
-private:
-    static bool DetachProc(const SkGlyphCache*, void*);
-};
-
-class SkAutoGlyphCache : public SkAutoGlyphCacheBase {
-public:
-    SkAutoGlyphCache(SkGlyphCache* cache) : SkAutoGlyphCacheBase(cache) {}
-    SkAutoGlyphCache(SkTypeface* typeface, const SkDescriptor* desc) :
-        SkAutoGlyphCacheBase(typeface, desc) {}
+    SkAutoGlyphCache(SkGlyphCache* cache) : INHERITED(cache) {}
+    SkAutoGlyphCache(SkTypeface* typeface, const SkDescriptor* desc)
+        : INHERITED(SkGlyphCache::DetachCache(typeface, desc))
+    {}
+    /** deprecated: always enables fake gamma */
     SkAutoGlyphCache(const SkPaint& paint,
                      const SkSurfaceProps* surfaceProps,
-                     const SkMatrix* matrix) {
-        fCache = paint.detachCache(surfaceProps, matrix, false);
-    }
-
+                     const SkMatrix* matrix)
+        : INHERITED(paint.detachCache(surfaceProps, SkPaint::FakeGamma::On, matrix))
+    {}
+    SkAutoGlyphCache(const SkPaint& paint,
+                     const SkSurfaceProps* surfaceProps,
+                     SkPaint::FakeGamma fakeGamma,
+                     const SkMatrix* matrix)
+        : INHERITED(paint.detachCache(surfaceProps, fakeGamma, matrix))
+    {}
 private:
-    SkAutoGlyphCache() : SkAutoGlyphCacheBase() {}
+    using INHERITED = skstd::unique_ptr<SkGlyphCache, SkGlyphCache::AttachCacheFunctor>;
 };
-#define SkAutoGlyphCache(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCache)
 
-class SkAutoGlyphCacheNoGamma : public SkAutoGlyphCacheBase {
+class SkAutoGlyphCacheNoGamma : public SkAutoGlyphCache {
 public:
-    SkAutoGlyphCacheNoGamma(SkGlyphCache* cache) : SkAutoGlyphCacheBase(cache) {}
-    SkAutoGlyphCacheNoGamma(SkTypeface* typeface, const SkDescriptor* desc) :
-        SkAutoGlyphCacheBase(typeface, desc) {}
     SkAutoGlyphCacheNoGamma(const SkPaint& paint,
                             const SkSurfaceProps* surfaceProps,
-                            const SkMatrix* matrix) {
-        fCache = paint.detachCache(surfaceProps, matrix, true);
-    }
-
-private:
-    SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {}
+                            const SkMatrix* matrix)
+        : SkAutoGlyphCache(paint, surfaceProps, SkPaint::FakeGamma::Off, matrix)
+    {}
 };
+#define SkAutoGlyphCache(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCache)
 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamma)
 
 #endif
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index cea3d0f..d2ea8ee 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -1098,7 +1098,7 @@
         metrics = &storage;
     }
 
-    paint.descriptorProc(nullptr, zoomPtr, FontMetricsDescProc, metrics, true);
+    paint.descriptorProc(nullptr, FakeGamma::Off, zoomPtr, FontMetricsDescProc, metrics);
 
     if (scale) {
         metrics->fTop = SkScalarMul(metrics->fTop, scale);
@@ -1690,12 +1690,13 @@
 
 static size_t fill_out_rec(const SkPaint& paint, SkScalerContext::Rec* rec,
                            const SkSurfaceProps* surfaceProps,
-                           const SkMatrix* deviceMatrix, bool ignoreGamma,
+                           bool fakeGamma,
+                           const SkMatrix* deviceMatrix,
                            const SkPathEffect* pe, SkWriteBuffer* peBuffer,
                            const SkMaskFilter* mf, SkWriteBuffer* mfBuffer,
                            const SkRasterizer* ra, SkWriteBuffer* raBuffer) {
     SkScalerContext::MakeRec(paint, surfaceProps, deviceMatrix, rec);
-    if (ignoreGamma) {
+    if (!fakeGamma) {
         rec->ignorePreBlend();
     }
 
@@ -1785,7 +1786,8 @@
 /* see the note on ignoreGamma on descriptorProc */
 void SkPaint::getScalerContextDescriptor(SkAutoDescriptor* ad,
                                          const SkSurfaceProps& surfaceProps,
-                                         const SkMatrix* deviceMatrix, bool ignoreGamma) const {
+                                         FakeGamma fakeGamma,
+                                         const SkMatrix* deviceMatrix) const {
     SkScalerContext::Rec    rec;
 
     SkPathEffect*   pe = this->getPathEffect();
@@ -1793,7 +1795,8 @@
     SkRasterizer*   ra = this->getRasterizer();
 
     SkWriteBuffer   peBuffer, mfBuffer, raBuffer;
-    size_t descSize = fill_out_rec(*this, &rec, &surfaceProps, deviceMatrix, ignoreGamma,
+    size_t descSize = fill_out_rec(*this, &rec,
+                                   &surfaceProps, FakeGamma::On == fakeGamma, deviceMatrix,
                                    pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer);
 
     ad->reset(descSize);
@@ -1814,9 +1817,10 @@
  *  contrast = 0, luminanceColor = transparent black.
  */
 void SkPaint::descriptorProc(const SkSurfaceProps* surfaceProps,
+                             FakeGamma fakeGamma,
                              const SkMatrix* deviceMatrix,
                              void (*proc)(SkTypeface*, const SkDescriptor*, void*),
-                             void* context, bool ignoreGamma) const {
+                             void* context) const {
     SkScalerContext::Rec    rec;
 
     SkPathEffect*   pe = this->getPathEffect();
@@ -1824,7 +1828,8 @@
     SkRasterizer*   ra = this->getRasterizer();
 
     SkWriteBuffer   peBuffer, mfBuffer, raBuffer;
-    size_t descSize = fill_out_rec(*this, &rec, surfaceProps, deviceMatrix, ignoreGamma,
+    size_t descSize = fill_out_rec(*this, &rec,
+                                   surfaceProps, FakeGamma::On == fakeGamma, deviceMatrix,
                                    pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer);
 
     SkAutoDescriptor    ad(descSize);
@@ -1842,10 +1847,10 @@
 }
 
 SkGlyphCache* SkPaint::detachCache(const SkSurfaceProps* surfaceProps,
-                                   const SkMatrix* deviceMatrix,
-                                   bool ignoreGamma) const {
+                                   FakeGamma fakeGamma,
+                                   const SkMatrix* deviceMatrix) const {
     SkGlyphCache* cache;
-    this->descriptorProc(surfaceProps, deviceMatrix, DetachDescProc, &cache, ignoreGamma);
+    this->descriptorProc(surfaceProps, fakeGamma, deviceMatrix, DetachDescProc, &cache);
     return cache;
 }
 
@@ -2417,7 +2422,7 @@
         fPaint.setPathEffect(nullptr);
     }
 
-    fCache = fPaint.detachCache(nullptr, nullptr, false);
+    fCache = fPaint.detachCache(nullptr, SkPaint::FakeGamma::On, nullptr);
 
     SkPaint::Style  style = SkPaint::kFill_Style;
     SkPathEffect*   pe = nullptr;
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 26f6a7c..62591f8 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -51,15 +51,15 @@
 
 SkGlyphCache* GrAtlasTextBlob::setupCache(int runIndex,
                                           const SkSurfaceProps& props,
+                                          SkPaint::FakeGamma fakeGamma,
                                           const SkPaint& skPaint,
-                                          const SkMatrix* viewMatrix,
-                                          bool noGamma) {
+                                          const SkMatrix* viewMatrix) {
     GrAtlasTextBlob::Run* run = &fRuns[runIndex];
 
     // if we have an override descriptor for the run, then we should use that
     SkAutoDescriptor* desc = run->fOverrideDescriptor.get() ? run->fOverrideDescriptor.get() :
                                                               &run->fDescriptor;
-    skPaint.getScalerContextDescriptor(desc, props, viewMatrix, noGamma);
+    skPaint.getScalerContextDescriptor(desc, props, fakeGamma, viewMatrix);
     run->fTypeface.reset(SkSafeRef(skPaint.getTypeface()));
     return SkGlyphCache::DetachCache(run->fTypeface, desc->getDesc());
 }
diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h
index a026693..a6531f1 100644
--- a/src/gpu/text/GrAtlasTextBlob.h
+++ b/src/gpu/text/GrAtlasTextBlob.h
@@ -148,9 +148,9 @@
 
     SkGlyphCache* setupCache(int runIndex,
                              const SkSurfaceProps& props,
+                             SkPaint::FakeGamma fakeGamma,
                              const SkPaint& skPaint,
-                             const SkMatrix* viewMatrix,
-                             bool noGamma);
+                             const SkMatrix* viewMatrix);
 
     // Appends a glyph to the blob.  If the glyph is too large, the glyph will be appended
     // as a path.
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.cpp b/src/gpu/text/GrStencilAndCoverTextContext.cpp
index 205c6d9..a87e5d2 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/text/GrStencilAndCoverTextContext.cpp
@@ -629,7 +629,7 @@
 
 SkGlyphCache* GrStencilAndCoverTextContext::TextRun::getGlyphCache() const {
     if (!fDetachedGlyphCache) {
-        fDetachedGlyphCache = fFont.detachCache(nullptr, nullptr, true /*ignoreGamma*/);
+        fDetachedGlyphCache = fFont.detachCache(nullptr, SkPaint::FakeGamma::Off, nullptr);
     }
     return fDetachedGlyphCache;
 }
diff --git a/src/gpu/text/GrTextUtils.cpp b/src/gpu/text/GrTextUtils.cpp
index 59ecbc0..112f5bd 100644
--- a/src/gpu/text/GrTextUtils.cpp
+++ b/src/gpu/text/GrTextUtils.cpp
@@ -57,7 +57,8 @@
     GrBatchTextStrike* currStrike = nullptr;
 
     // Get GrFontScaler from cache
-    SkGlyphCache* cache = blob->setupCache(runIndex, props, skPaint, &viewMatrix, false);
+    SkGlyphCache* cache = blob->setupCache(runIndex, props, SkPaint::FakeGamma::On,
+                                           skPaint, &viewMatrix);
     GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache);
 
     SkFindAndPlaceGlyph::ProcessText(
@@ -98,7 +99,8 @@
     GrBatchTextStrike* currStrike = nullptr;
 
     // Get GrFontScaler from cache
-    SkGlyphCache* cache = blob->setupCache(runIndex, props, skPaint, &viewMatrix, false);
+    SkGlyphCache* cache = blob->setupCache(runIndex, props, SkPaint::FakeGamma::On,
+                                           skPaint, &viewMatrix);
     GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache);
 
     SkFindAndPlaceGlyph::ProcessPosText(
@@ -258,7 +260,7 @@
 
     SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc();
     SkAutoDescriptor desc;
-    skPaint.getScalerContextDescriptor(&desc, props, nullptr, true);
+    skPaint.getScalerContextDescriptor(&desc, props, SkPaint::FakeGamma::Off, nullptr);
     SkGlyphCache* origPaintCache = SkGlyphCache::DetachCache(skPaint.getTypeface(),
                                                              desc.getDesc());
 
@@ -339,7 +341,8 @@
 
     GrBatchTextStrike* currStrike = nullptr;
 
-    SkGlyphCache* cache = blob->setupCache(runIndex, props, dfPaint, nullptr, true);
+    SkGlyphCache* cache = blob->setupCache(runIndex, props, SkPaint::FakeGamma::Off,
+                                           dfPaint, nullptr);
     SkDrawCacheProc glyphCacheProc = dfPaint.getDrawCacheProc();
     GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache);