Remove GrTextureStripAtlas, textured gradients use independent textures

The texture strip atlas code path has been disabled without performance
regressions since 8/3/18, so this deletes it completely from the code
base since it is complex and difficult to manage.

GrTextureStripAtlas, GrDynamicTextureStripAtlas, and
GrDDLTextureStripAtlas completely deleted, everything else is cleaning
up references/dead code using the atlas.

Bug: skia:
Change-Id: Ieb967b6e291a1d76da62fce9fa384acbda8c51c0
Reviewed-on: https://skia-review.googlesource.com/150472
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/gn/gpu.gni b/gn/gpu.gni
index a0d010f..b453962 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -221,7 +221,6 @@
   "$_src/gpu/GrTextureProxy.cpp",
   "$_src/gpu/GrTextureRenderTargetProxy.cpp",
   "$_src/gpu/GrTextureRenderTargetProxy.h",
-  "$_src/gpu/GrTextureStripAtlas.h",
   "$_src/gpu/GrTRecorder.h",
   "$_src/gpu/GrUninstantiateProxyTracker.cpp",
   "$_src/gpu/GrUninstantiateProxyTracker.h",
@@ -354,14 +353,10 @@
   "$_src/gpu/effects/GrBicubicEffect.h",
   "$_src/gpu/effects/GrBitmapTextGeoProc.cpp",
   "$_src/gpu/effects/GrBitmapTextGeoProc.h",
-  "$_src/gpu/effects/GrDDLTextureStripAtlas.cpp",
-  "$_src/gpu/effects/GrDDLTextureStripAtlas.h",
   "$_src/gpu/effects/GrDisableColorXP.cpp",
   "$_src/gpu/effects/GrDisableColorXP.h",
   "$_src/gpu/effects/GrDistanceFieldGeoProc.cpp",
   "$_src/gpu/effects/GrDistanceFieldGeoProc.h",
-  "$_src/gpu/effects/GrDynamicTextureStripAtlas.cpp",
-  "$_src/gpu/effects/GrDynamicTextureStripAtlas.h",
   "$_src/gpu/effects/GrEllipseEffect.cpp",
   "$_src/gpu/effects/GrEllipseEffect.h",
   "$_src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp",
@@ -396,7 +391,6 @@
   "$_src/gpu/effects/GrSRGBEffect.h",
   "$_src/gpu/effects/GrTextureDomain.cpp",
   "$_src/gpu/effects/GrTextureDomain.h",
-  "$_src/gpu/effects/GrTextureStripAtlas.cpp",
   "$_src/gpu/effects/GrUnpremulInputFragmentProcessor.cpp",
   "$_src/gpu/effects/GrUnpremulInputFragmentProcessor.h",
   "$_src/gpu/effects/GrXfermodeFragmentProcessor.cpp",
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 116c8bf..55c79bd 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -48,7 +48,6 @@
 class GrTextBlobCache;
 class GrTextContext;
 class GrTextureProxy;
-class GrTextureStripAtlasManager;
 class GrVertexBuffer;
 struct GrVkBackendContext;
 
@@ -309,7 +308,6 @@
     GrResourceCache*                        fResourceCache;
     GrResourceProvider*                     fResourceProvider;
     GrProxyProvider*                        fProxyProvider;
-    std::unique_ptr<GrTextureStripAtlasManager> fTextureStripAtlasManager;
 
     // All the GrOp-derived classes use this pool.
     sk_sp<GrOpMemoryPool>                   fOpMemoryPool;
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 8b97a93..7952666 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -25,7 +25,6 @@
 #include "GrSurfaceProxyPriv.h"
 #include "GrTexture.h"
 #include "GrTextureContext.h"
-#include "GrTextureStripAtlas.h"
 #include "GrTracing.h"
 #include "SkAutoPixmapStorage.h"
 #include "SkDeferredDisplayList.h"
@@ -97,8 +96,6 @@
         fResourceCache->setProxyProvider(fProxyProvider);
     }
 
-    fTextureStripAtlasManager.reset(new GrTextureStripAtlasManager);
-
     fDisableGpuYUVConversion = options.fDisableGpuYUVConversion;
     fSharpenMipmappedTextures = options.fSharpenMipmappedTextures;
     fDidTestPMConversions = false;
@@ -162,7 +159,6 @@
     if (fDrawingManager) {
         fDrawingManager->cleanup();
     }
-    fTextureStripAtlasManager = nullptr;
     delete fResourceProvider;
     delete fResourceCache;
     delete fProxyProvider;
@@ -243,7 +239,6 @@
 void GrContext::abandonContext() {
     ASSERT_SINGLE_OWNER
 
-    fTextureStripAtlasManager->abandon();
     fProxyProvider->abandon();
     fResourceProvider->abandon();
 
@@ -269,7 +264,6 @@
 void GrContext::releaseResourcesAndAbandonContext() {
     ASSERT_SINGLE_OWNER
 
-    fTextureStripAtlasManager->abandon();
     fProxyProvider->abandon();
     fResourceProvider->abandon();
 
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index 1b90daf..f68cc83 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -189,10 +189,6 @@
 
     GrResourceCache* getResourceCache() { return fContext->fResourceCache; }
 
-    GrTextureStripAtlasManager* textureStripAtlasManager() {
-        return fContext->fTextureStripAtlasManager.get();
-    }
-
     GrGpu* getGpu() { return fContext->fGpu.get(); }
     const GrGpu* getGpu() const { return fContext->fGpu.get(); }
 
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 5b0f5cb..edde1ec 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -25,7 +25,6 @@
 #include "GrTexturePriv.h"
 #include "GrTextureProxy.h"
 #include "GrTextureProxyPriv.h"
-#include "GrTextureStripAtlas.h"
 #include "GrTracing.h"
 #include "SkDeferredDisplayList.h"
 #include "SkSurface_Gpu.h"
@@ -397,9 +396,6 @@
 }
 
 void GrDrawingManager::moveOpListsToDDL(SkDeferredDisplayList* ddl) {
-    fContext->contextPriv().textureStripAtlasManager()->finish(
-                                                          fContext->contextPriv().proxyProvider());
-
     for (int i = 0; i < fOpLists.count(); ++i) {
         // no opList should receive a new command after this
         fOpLists[i]->makeClosed(*fContext->contextPriv().caps());
diff --git a/src/gpu/GrTextureStripAtlas.h b/src/gpu/GrTextureStripAtlas.h
deleted file mode 100644
index 3f4e897..0000000
--- a/src/gpu/GrTextureStripAtlas.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrTextureStripAtlas_DEFINED
-#define GrTextureStripAtlas_DEFINED
-
-#include "SkNoncopyable.h"
-#include "SkOpts.h"
-#include "SkRefCnt.h"
-#include "SkTDynamicHash.h"
-
-class GrContext;
-class GrProxyProvider;
-class GrTextureProxy;
-class SkBitmap;
-
-/**
- * Base class for the texture strip atlases.
- * It is ref counted because the GradientShader and TableColorFilter are given a pointer to it
- * so that they can lock and unlock rows.
- */
-class GrTextureStripAtlas : public SkRefCnt {
-public:
-    /**
-     * Descriptor struct which we'll use both to find and initialize an atlas and as a hash
-     * table key in the GrTextureStripAtlasManager.
-     */
-    struct Desc {
-        Desc() { sk_bzero(this, sizeof(*this)); }
-        SkColorType fColorType;
-        uint16_t    fWidth;
-        uint16_t    fHeight; // the max height for the DDL version, the size of the atlas for normal
-        uint16_t    fRowHeight;
-        uint16_t    fUnusedPadding;
-
-        bool operator==(const Desc& other) const {
-            return 0 == memcmp(this, &other, sizeof(Desc));
-        }
-    };
-
-    ~GrTextureStripAtlas() override {}
-
-    /**
-     * This is intended to be used when cloning a processor that already holds a lock. It is
-     * assumed that the row already has at least one lock.
-     */
-    virtual void lockRow(int row) = 0;
-
-    /**
-     * Some user of a given row is done. Release that row for reuse.
-     */
-    virtual void unlockRow(int row) = 0;
-
-    /**
-     * This returns the absolute Y location of the given row in the atlas. For atlases with
-     * 'fRowHeight' > 1, this is Y location of the topmost row of the atlas entry. It is always
-     * the middle of the row.
-     */
-    SkScalar rowToTextureY(int row) const {
-        return row * fDesc.fRowHeight + SK_ScalarHalf;
-    }
-
-    /**
-     * Get the texture proxy backing this atlas. Note that the texture proxy may be fully lazy
-     * (i.e., when recording DDLs) and, in particular, the final height may not be known.
-     */
-    virtual sk_sp<GrTextureProxy> asTextureProxyRef() const = 0;
-
-protected:
-    GrTextureStripAtlas(const Desc& desc) : fDesc(desc) {}
-
-    const Desc fDesc;
-
-private:
-    friend class GrTextureStripAtlasManager; // for addStrip, finish
-
-    /**
-     * Add a texture strip to the atlas
-     *  @param context Everyone's favorite class
-     *  @param bitmap  Bitmap data to copy into the row
-     *  @return The row index we inserted into, or -1 if we failed to find an open row. The caller
-     *      is responsible for calling unlockRow() with this row index when it's done with it.
-     */
-    virtual int addStrip(GrContext*, const SkBitmap& bitmap) = 0;
-
-    /**
-     * This method is called when an atlas needs to finish its work on the current texture.
-     * Currently it is only called in DDL mode and when either:
-     *        a given atlas has become full or,
-     *        a DDL is being snapped from a DDL recorder
-     */
-    virtual void finish(GrProxyProvider*) = 0;
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-class GrTextureStripAtlasManager {
-public:
-    GrTextureStripAtlasManager() {}
-    ~GrTextureStripAtlasManager();
-
-    void abandon();
-    void finish(GrProxyProvider*);
-
-    /**
-     * Add a new texture strip to the atlas matching the descriptor. Upon failure, nullptr
-     * will be returned and 'row' will be set to -1.
-     */
-    sk_sp<GrTextureStripAtlas> addStrip(GrContext*,
-                                        const GrTextureStripAtlas::Desc&,
-                                        const SkBitmap&, int* row);
-
-private:
-    void deleteAllAtlases();
-
-    // Hash table entry for atlases
-    class AtlasEntry : public ::SkNoncopyable {
-    public:
-        AtlasEntry(sk_sp<GrTextureStripAtlas> atlas) : fAtlas(std::move(atlas)) {}
-        ~AtlasEntry() { }
-
-        // for SkTDynamicHash
-        static const GrTextureStripAtlas::Desc& GetKey(const AtlasEntry& entry) {
-            return entry.fAtlas->fDesc;
-        }
-        static uint32_t Hash(const GrTextureStripAtlas::Desc& desc) {
-            return SkOpts::hash(&desc, sizeof(GrTextureStripAtlas::Desc));
-        }
-
-        sk_sp<GrTextureStripAtlas> fAtlas;
-    };
-
-    typedef SkTDynamicHash<AtlasEntry, GrTextureStripAtlas::Desc> AtlasHash;
-
-    AtlasHash fAtlasCache;
-};
-
-#endif
diff --git a/src/gpu/effects/GrDDLTextureStripAtlas.cpp b/src/gpu/effects/GrDDLTextureStripAtlas.cpp
deleted file mode 100644
index ac22df5..0000000
--- a/src/gpu/effects/GrDDLTextureStripAtlas.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrDDLTextureStripAtlas.h"
-
-#include "GrContextPriv.h"
-#include "GrTexture.h"
-#include "SkGr.h"
-#include "SkTSearch.h"
-
-GrDDLTextureStripAtlas::GrDDLTextureStripAtlas(const Desc& desc)
-        : INHERITED(desc)
-        , fAtlasBitmap(nullptr)
-        , fMaxNumRows(desc.fHeight / desc.fRowHeight)
-        , fCurRow(0)
-        , fRows(new AtlasRow[fMaxNumRows]) {
-    SkASSERT(fMaxNumRows * fDesc.fRowHeight == fDesc.fHeight);
-    SkDEBUGCODE(this->validate();)
-}
-
-GrDDLTextureStripAtlas::~GrDDLTextureStripAtlas() { delete[] fRows; }
-
-// Flush the current state of the atlas.
-void GrDDLTextureStripAtlas::finish(GrProxyProvider* proxyProvider) {
-    SkDEBUGCODE(this->validate();)
-
-    if (!fCurRow) {
-        SkASSERT(!fCurProxy && !fAtlasBitmap);
-        return;
-    }
-
-    int height = fCurRow * fDesc.fRowHeight;
-    SkASSERT(height <= fDesc.fHeight);
-
-    SkImageInfo ii = SkImageInfo::Make(fDesc.fWidth, height,
-                                       fDesc.fColorType, kPremul_SkAlphaType);
-    fAtlasBitmap->allocPixels(ii);
-
-    for (int i = 0; i < fCurRow; ++i) {
-        SkASSERT(fRows[i].fBitmap.height() == fDesc.fRowHeight);
-
-        int yPos = i * fDesc.fRowHeight;
-        fAtlasBitmap->writePixels(fRows[i].fBitmap.pixmap(), 0, yPos);
-    }
-
-    GrUniqueKey key;
-    {
-        static const GrUniqueKey::Domain kTextureStripAtlasDomain = GrUniqueKey::GenerateDomain();
-        GrUniqueKey::Builder builder(&key, kTextureStripAtlasDomain, fCurRow,
-                                     "DDL Texture Strip Atlas");
-        for (int i = 0; i < fCurRow; ++i) {
-            builder[i] = fRows[i].fBitmap.getGenerationID();
-        }
-        builder.finish();
-    }
-
-    sk_sp<GrTextureProxy> interloper = proxyProvider->findProxyByUniqueKey(key,
-                                                                           fCurProxy->origin());
-    if (!interloper) {
-        // In the unlikely event that there is already a proxy with this key (i.e., it has exactly
-        // the same strips in exactly the same order) we'll just let it keep the key.
-        proxyProvider->assignUniqueKeyToProxy(key, fCurProxy.get());
-    }
-
-    // reset the state for the next aggregate texture
-    for (int i = 0; i < fCurRow; ++i) {
-        fRows[i].fBitmap.reset();
-    }
-    fCurRow = 0;
-    fCurProxy = nullptr;
-    fAtlasBitmap = nullptr;
-    fKeyTable.rewind();
-    SkDEBUGCODE(this->validate();)
-}
-
-int GrDDLTextureStripAtlas::addStrip(GrContext* context, const SkBitmap& bitmap) {
-    SkDEBUGCODE(this->validate();)
-
-    const int key = bitmap.getGenerationID();
-    int index = this->searchByKey(key);
-
-    if (fCurRow >= fMaxNumRows && index < 0) {
-        // The current atlas is full and adding another strip would make it overflow. Calve it off
-        // and allow the next block to start a new one.
-        this->finish(context->contextPriv().proxyProvider());
-        index = this->searchByKey(key); // 'finish' cleared the table
-    }
-
-    if (!fCurProxy) {
-        SkASSERT(!fAtlasBitmap);
-
-        const GrCaps* caps = context->contextPriv().caps();
-        GrPixelConfig pixelConfig = SkColorType2GrPixelConfig(fDesc.fColorType);
-        SkASSERT(kUnknown_GrPixelConfig != pixelConfig);
-
-        SkBitmap* atlasBitmap = new SkBitmap();
-
-        fCurProxy = GrProxyProvider::MakeFullyLazyProxy(
-                [atlasBitmap, pixelConfig](GrResourceProvider* provider) -> sk_sp<GrSurface> {
-                        if (!provider) {
-                            delete atlasBitmap;
-                            return sk_sp<GrSurface>();
-                        }
-                        // When this is called 'atlasBitmap' should've been filled in and be
-                        // non-empty
-                        SkASSERT(atlasBitmap->width() && atlasBitmap->height());
-                        GrSurfaceDesc desc;
-                        desc.fFlags = kNone_GrSurfaceFlags;
-                        desc.fWidth = atlasBitmap->width();
-                        desc.fHeight = atlasBitmap->height();
-                        desc.fConfig = pixelConfig;
-
-                        GrMipLevel mipLevel = { atlasBitmap->getPixels(), atlasBitmap->rowBytes() };
-
-                        return provider->createTexture(desc, SkBudgeted::kYes,
-                                                       SkBackingFit::kExact, mipLevel);
-                },
-                GrProxyProvider::Renderable::kNo, kTopLeft_GrSurfaceOrigin, pixelConfig, *caps);
-
-        fAtlasBitmap = atlasBitmap;
-    }
-
-    SkASSERT(bitmap.width() == fDesc.fWidth);
-    SkASSERT(bitmap.height() == fDesc.fRowHeight);
-    SkASSERT(!context->contextPriv().resourceProvider());  // This atlas class is DDL specific
-    SkASSERT(fCurRow < fMaxNumRows);
-
-    int rowNumber = -1;
-
-    if (index >= 0) {
-        // We already have the data in a row, so we can just return that row
-        AtlasRow* row = fKeyTable[index];
-
-        // Since all the rows are always stored in a contiguous array, we can save the memory
-        // required for storing row numbers and just compute it with some pointer arithmetic
-        rowNumber = static_cast<int>(row - fRows);
-    } else {
-        // ~index is the index where we will insert the new key to keep things sorted
-        index = ~index;
-
-        rowNumber = fCurRow;
-        fRows[fCurRow].fBitmap = bitmap;
-
-        AtlasRow* row = &fRows[rowNumber];
-        fKeyTable.insert(index, 1, &row);
-
-        ++fCurRow;
-        SkASSERT(fCurRow <= fMaxNumRows);
-    }
-
-    SkASSERT(rowNumber >= 0);
-    SkDEBUGCODE(this->validate();)
-    return rowNumber;
-}
-
-int GrDDLTextureStripAtlas::searchByKey(uint32_t generationID) {
-    static struct AtlasRowLessFunctor {
-        bool operator()(const AtlasRow* row, const uint32_t& id) const {
-            return row->fBitmap.getGenerationID() < id;
-        }
-        bool operator()(const uint32_t& id, const AtlasRow* row) const {
-            return id < row->fBitmap.getGenerationID();
-        }
-    } functor;
-
-    return SkTSearch(fKeyTable.begin(), fKeyTable.count(), generationID, sizeof(AtlasRow*),
-                     functor);
-}
-
-#ifdef SK_DEBUG
-void GrDDLTextureStripAtlas::validate() {
-    static const int kBitmapInvalidGenID = 0;
-
-    // Our key table should be sorted
-    uint32_t prev = fKeyTable.count() >= 1 ? fKeyTable[0]->fBitmap.getGenerationID() : 0;
-    for (int i = 1; i < fKeyTable.count(); ++i) {
-        AtlasRow* row = fKeyTable[i];
-        SkASSERT(prev < row->fBitmap.getGenerationID());
-        SkASSERT(row->fBitmap.getGenerationID() != kBitmapInvalidGenID);
-        prev = row->fBitmap.getGenerationID();
-    }
-
-    for (int i = 0; i < fCurRow; ++i) {
-        // These should all have a valid bitmap and be in the search table
-        SkASSERT(fRows[i].fBitmap.getGenerationID() != kBitmapInvalidGenID);
-        SkASSERT(this->searchByKey(fRows[i].fBitmap.getGenerationID()) >= 0);
-    }
-    for (int i = fCurRow; i < fMaxNumRows; ++i) {
-        // These should all be empty
-        SkASSERT(fRows[i].fBitmap.getGenerationID() == kBitmapInvalidGenID);
-    }
-}
-#endif
diff --git a/src/gpu/effects/GrDDLTextureStripAtlas.h b/src/gpu/effects/GrDDLTextureStripAtlas.h
deleted file mode 100644
index 5fb5804..0000000
--- a/src/gpu/effects/GrDDLTextureStripAtlas.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrDDLTextureStripAtlas_DEFINED
-#define GrDDLTextureStripAtlas_DEFINED
-
-#include "GrTextureStripAtlas.h"
-
-#include "SkBitmap.h"
-#include "SkTDArray.h"
-
-/**
- * The DDL version of the texture strip atlas consolidates individual strips into a larger texture
- * until some limit is reached, at which point a new large texture is started.
- * This can lead to the same strip being duplicated in VRAM. This can happen if a strip appears once
- * early in a rendering (that has, say, a lot of gradients) and then again later in the rendering
- * when one of the large textures has been filled. The second, probably more common, case is
- * if the same strip is used in different DDL recordings. Since the texture strip atlases aren't
- * dedupped across threads, if the same strip is used in two different DDL recordings it will
- * be duplicated in both of the DDL recorders' atlases.
- * Note, one additional feature of the DDL texture strip atlases is that, if DDL recording is ended
- * before one of the large textures is full, the large texture will be "shrunk" to fit its
- * contents.
- */
-class GrDDLTextureStripAtlas final : public GrTextureStripAtlas {
-public:
-    ~GrDDLTextureStripAtlas() final;
-
-    // Overrides from GrTextureStripAtlas
-    void lockRow(int row) final { /* The DDL version doesn't lock & unlock individual rows */}
-    void unlockRow(int row) final { /* The DDL version doesn't lock & unlock individual rows */}
-
-    // Caution: this method will only return the appropriate proxy after a successful 'addStrip'
-    // call has been made. Additionally, the proxy return will be fully lazy (i.e., its final
-    // height will be unknown).
-    sk_sp<GrTextureProxy> asTextureProxyRef() const final {
-        SkASSERT(fCurProxy);
-        return fCurProxy;
-    }
-
-private:
-    friend class GrTextureStripAtlasManager; // for ctor
-
-    // Overrides from GrTextureStripAtlas
-    int addStrip(GrContext*, const SkBitmap&) final;
-    void finish(GrProxyProvider*) final;
-
-    /**
-     * The state of a single row in our cache. For the DDL texture strip atlas we hold onto all
-     * the individual strip bitmaps and, upon finish, combine them all into a single bitmap.
-     */
-    struct AtlasRow : ::SkNoncopyable {
-        AtlasRow() {}
-
-        SkBitmap fBitmap;
-    };
-
-    /**
-     * Only the GrTextureStripAtlasManager is allowed to create GrDDLTextureStripAtlas
-     */
-    GrDDLTextureStripAtlas(const Desc& desc);
-
-    /**
-     * Searches the key table for a key and returns the index if found; if not found, it returns
-     * the bitwise not of the index at which we could insert the key to maintain a sorted list.
-     **/
-    int searchByKey(uint32_t key);
-
-    SkDEBUGCODE(void validate();)
-
-    sk_sp<GrTextureProxy> fCurProxy;    // the lazy proxy that will be split off in the finish call
-    SkBitmap*             fAtlasBitmap; // the bitmap backing 'fCurProxy'
-
-    const uint16_t        fMaxNumRows;
-    uint16_t              fCurRow;
-
-    AtlasRow*             fRows;        // We just store the source bitmap for each row.
-
-    // A list of pointers to AtlasRows that currently contain cached images, sorted by key
-    SkTDArray<AtlasRow*> fKeyTable;
-
-    typedef GrTextureStripAtlas INHERITED;
-};
-
-#endif
diff --git a/src/gpu/effects/GrDynamicTextureStripAtlas.cpp b/src/gpu/effects/GrDynamicTextureStripAtlas.cpp
deleted file mode 100644
index 04683e1..0000000
--- a/src/gpu/effects/GrDynamicTextureStripAtlas.cpp
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrDynamicTextureStripAtlas.h"
-
-#include "GrContextPriv.h"
-#include "SkAtomics.h"
-#include "SkGr.h"
-#include "SkTSearch.h"
-
-#ifdef SK_DEBUG
-    #define VALIDATE this->validate()
-#else
-    #define VALIDATE
-#endif
-
-uint32_t GrDynamicTextureStripAtlas::CreateUniqueID() {
-    static int32_t gUniqueID = SK_InvalidUniqueID;
-    uint32_t id;
-    // Loop in case our global wraps around, as we never want to return a 0.
-    do {
-        id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
-    } while (id == SK_InvalidUniqueID);
-    return id;
-}
-
-GrDynamicTextureStripAtlas::GrDynamicTextureStripAtlas(const Desc& desc)
-        : INHERITED(desc)
-        , fCacheKey(CreateUniqueID())
-        , fLockedRows(0)
-        , fNumRows(desc.fHeight / desc.fRowHeight)
-        , fRows(new AtlasRow[fNumRows])
-        , fLRUFront(nullptr)
-        , fLRUBack(nullptr) {
-    SkASSERT(fNumRows * fDesc.fRowHeight == fDesc.fHeight);
-    this->initLRU();
-    fNormalizedYHeight = SK_Scalar1 / fDesc.fHeight;
-    VALIDATE;
-}
-
-GrDynamicTextureStripAtlas::~GrDynamicTextureStripAtlas() { delete[] fRows; }
-
-void GrDynamicTextureStripAtlas::lockRow(int row) {
-    // This should only be called on a row that is already locked.
-    SkASSERT(fRows[row].fLocks);
-    fRows[row].fLocks++;
-    ++fLockedRows;
-}
-
-int GrDynamicTextureStripAtlas::addStrip(GrContext* context, const SkBitmap& bitmap) {
-    VALIDATE;
-
-    if (!context->contextPriv().resourceProvider()) {
-        // DDL TODO: For DDL we need to schedule inline & ASAP uploads. However these systems
-        // currently use the flushState which we can't use for the opList-based DDL phase.
-        // For the opList-based solution every texture strip will get its own texture proxy.
-        // We will revisit this for the flushState-based solution.
-        return -1;
-    }
-
-    if (0 == fLockedRows) {
-        this->lockTexture(context);
-        if (!fTexContext) {
-            return -1;
-        }
-    }
-
-    int key = bitmap.getGenerationID();
-    int rowNumber = -1;
-    int index = this->searchByKey(key);
-
-    if (index >= 0) {
-        // We already have the data in a row, so we can just return that row
-        AtlasRow* row = fKeyTable[index];
-        if (0 == row->fLocks) {
-            this->removeFromLRU(row);
-        }
-        ++row->fLocks;
-        ++fLockedRows;
-
-        // Since all the rows are always stored in a contiguous array, we can save the memory
-        // required for storing row numbers and just compute it with some pointer arithmetic
-        rowNumber = static_cast<int>(row - fRows);
-    } else {
-        // ~index is the index where we will insert the new key to keep things sorted
-        index = ~index;
-
-        // We don't have this data cached, so pick the least recently used row to copy into
-        AtlasRow* row = this->getLRU();
-
-        ++fLockedRows;
-
-        if (nullptr == row) {
-            // force a flush, which should unlock all the rows; then try again
-            context->contextPriv().flush(nullptr); // tighten this up?
-            row = this->getLRU();
-            if (nullptr == row) {
-                --fLockedRows;
-                return -1;
-            }
-        }
-
-        this->removeFromLRU(row);
-
-        uint32_t oldKey = row->fKey;
-
-        // If we are writing into a row that already held bitmap data, we need to remove the
-        // reference to that genID which is stored in our sorted table of key values.
-        if (oldKey != kEmptyAtlasRowKey) {
-
-            // Find the entry in the list; if it's before the index where we plan on adding the new
-            // entry, we decrement since it will shift elements ahead of it back by one.
-            int oldIndex = this->searchByKey(oldKey);
-            if (oldIndex < index) {
-                --index;
-            }
-
-            fKeyTable.remove(oldIndex);
-        }
-
-        row->fKey = key;
-        row->fLocks = 1;
-        fKeyTable.insert(index, 1, &row);
-        rowNumber = static_cast<int>(row - fRows);
-
-        SkASSERT(bitmap.width() == fDesc.fWidth);
-        SkASSERT(bitmap.height() == fDesc.fRowHeight);
-
-        // Pass in the kDontFlush flag, since we know we're writing to a part of this texture
-        // that is not currently in use
-        fTexContext->writePixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(),
-                                 0, rowNumber * fDesc.fRowHeight,
-                                 GrContextPriv::kDontFlush_PixelOpsFlag);
-    }
-
-    SkASSERT(rowNumber >= 0);
-    VALIDATE;
-    return rowNumber;
-}
-
-sk_sp<GrTextureProxy> GrDynamicTextureStripAtlas::asTextureProxyRef() const {
-    return fTexContext->asTextureProxyRef();
-}
-
-void GrDynamicTextureStripAtlas::unlockRow(int row) {
-    VALIDATE;
-    --fRows[row].fLocks;
-    --fLockedRows;
-    SkASSERT(fRows[row].fLocks >= 0 && fLockedRows >= 0);
-    if (0 == fRows[row].fLocks) {
-        this->appendLRU(fRows + row);
-    }
-    if (0 == fLockedRows) {
-        this->unlockTexture();
-    }
-    VALIDATE;
-}
-
-GrDynamicTextureStripAtlas::AtlasRow* GrDynamicTextureStripAtlas::getLRU() {
-    // Front is least-recently-used
-    AtlasRow* row = fLRUFront;
-    return row;
-}
-
-void GrDynamicTextureStripAtlas::lockTexture(GrContext* context) {
-
-    static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
-    GrUniqueKey key;
-    GrUniqueKey::Builder builder(&key, kDomain, 1);
-    builder[0] = static_cast<uint32_t>(fCacheKey);
-    builder.finish();
-
-    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
-
-    sk_sp<GrTextureProxy> proxy = proxyProvider->findOrCreateProxyByUniqueKey(
-                                                                key, kTopLeft_GrSurfaceOrigin);
-    if (!proxy) {
-        GrPixelConfig pixelConfig = SkColorType2GrPixelConfig(fDesc.fColorType);
-
-        GrSurfaceDesc texDesc;
-        texDesc.fWidth  = fDesc.fWidth;
-        texDesc.fHeight = fDesc.fHeight;
-        texDesc.fConfig = pixelConfig;
-
-        proxy = proxyProvider->createProxy(texDesc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kExact,
-                                           SkBudgeted::kYes, GrInternalSurfaceFlags::kNoPendingIO);
-        if (!proxy) {
-            return;
-        }
-
-        SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
-        proxyProvider->assignUniqueKeyToProxy(key, proxy.get());
-        // This is a new texture, so all of our cache info is now invalid
-        this->initLRU();
-        fKeyTable.rewind();
-    }
-    SkASSERT(proxy);
-    fTexContext = context->contextPriv().makeWrappedSurfaceContext(std::move(proxy));
-}
-
-void GrDynamicTextureStripAtlas::unlockTexture() {
-    SkASSERT(fTexContext && 0 == fLockedRows);
-    fTexContext.reset();
-}
-
-void GrDynamicTextureStripAtlas::initLRU() {
-    fLRUFront = nullptr;
-    fLRUBack = nullptr;
-    // Initially all the rows are in the LRU list
-    for (int i = 0; i < fNumRows; ++i) {
-        fRows[i].fKey = kEmptyAtlasRowKey;
-        fRows[i].fNext = nullptr;
-        fRows[i].fPrev = nullptr;
-        this->appendLRU(fRows + i);
-    }
-    SkASSERT(nullptr == fLRUFront || nullptr == fLRUFront->fPrev);
-    SkASSERT(nullptr == fLRUBack || nullptr == fLRUBack->fNext);
-}
-
-void GrDynamicTextureStripAtlas::appendLRU(AtlasRow* row) {
-    SkASSERT(nullptr == row->fPrev && nullptr == row->fNext);
-    if (nullptr == fLRUFront && nullptr == fLRUBack) {
-        fLRUFront = row;
-        fLRUBack = row;
-    } else {
-        row->fPrev = fLRUBack;
-        fLRUBack->fNext = row;
-        fLRUBack = row;
-    }
-}
-
-void GrDynamicTextureStripAtlas::removeFromLRU(AtlasRow* row) {
-    SkASSERT(row);
-    if (row->fNext && row->fPrev) {
-        row->fPrev->fNext = row->fNext;
-        row->fNext->fPrev = row->fPrev;
-    } else {
-        if (nullptr == row->fNext) {
-            SkASSERT(row == fLRUBack);
-            fLRUBack = row->fPrev;
-            if (fLRUBack) {
-                fLRUBack->fNext = nullptr;
-            }
-        }
-        if (nullptr == row->fPrev) {
-            SkASSERT(row == fLRUFront);
-            fLRUFront = row->fNext;
-            if (fLRUFront) {
-                fLRUFront->fPrev = nullptr;
-            }
-        }
-    }
-    row->fNext = nullptr;
-    row->fPrev = nullptr;
-}
-
-int GrDynamicTextureStripAtlas::searchByKey(uint32_t key) {
-    AtlasRow target;
-    target.fKey = key;
-    return SkTSearch<const AtlasRow, KeyLess>((const AtlasRow**)fKeyTable.begin(),
-                                              fKeyTable.count(),
-                                              &target,
-                                              sizeof(AtlasRow*));
-}
-
-#ifdef SK_DEBUG
-void GrDynamicTextureStripAtlas::validate() {
-    // Our key table should be sorted
-    uint32_t prev = 1 > fKeyTable.count() ? 0 : fKeyTable[0]->fKey;
-    for (int i = 1; i < fKeyTable.count(); ++i) {
-        SkASSERT(prev < fKeyTable[i]->fKey);
-        SkASSERT(fKeyTable[i]->fKey != kEmptyAtlasRowKey);
-        prev = fKeyTable[i]->fKey;
-    }
-
-    int lruCount = 0;
-    // Validate LRU pointers, and count LRU entries
-    SkASSERT(nullptr == fLRUFront || nullptr == fLRUFront->fPrev);
-    SkASSERT(nullptr == fLRUBack  || nullptr == fLRUBack->fNext);
-    for (AtlasRow* r = fLRUFront; r != nullptr; r = r->fNext) {
-        if (nullptr == r->fNext) {
-            SkASSERT(r == fLRUBack);
-        } else {
-            SkASSERT(r->fNext->fPrev == r);
-        }
-        ++lruCount;
-    }
-
-    int rowLocks = 0;
-    int freeRows = 0;
-
-    for (int i = 0; i < fNumRows; ++i) {
-        rowLocks += fRows[i].fLocks;
-        if (0 == fRows[i].fLocks) {
-            ++freeRows;
-            bool inLRU = false;
-            // Step through the LRU and make sure it's present
-            for (AtlasRow* r = fLRUFront; r != nullptr; r = r->fNext) {
-                if (r == &fRows[i]) {
-                    inLRU = true;
-                    break;
-                }
-            }
-            SkASSERT(inLRU);
-        } else {
-            // If we are locked, we should have a key
-            SkASSERT(kEmptyAtlasRowKey != fRows[i].fKey);
-        }
-
-        // If we have a key != kEmptyAtlasRowKey, it should be in the key table
-        SkASSERT(fRows[i].fKey == kEmptyAtlasRowKey || this->searchByKey(fRows[i].fKey) >= 0);
-    }
-
-    // Our count of locks should equal the sum of row locks, unless we ran out of rows and flushed,
-    // in which case we'll have one more lock than recorded in the rows (to represent the pending
-    // lock of a row; which ensures we don't unlock the texture prematurely).
-    SkASSERT(rowLocks == fLockedRows || rowLocks + 1 == fLockedRows);
-
-    // We should have one lru entry for each free row
-    SkASSERT(freeRows == lruCount);
-
-    // If we have locked rows, we should have a locked texture, otherwise
-    // it should be unlocked
-    if (fLockedRows == 0) {
-        SkASSERT(!fTexContext);
-    } else {
-        SkASSERT(fTexContext);
-    }
-}
-#endif
diff --git a/src/gpu/effects/GrDynamicTextureStripAtlas.h b/src/gpu/effects/GrDynamicTextureStripAtlas.h
deleted file mode 100644
index 301617b..0000000
--- a/src/gpu/effects/GrDynamicTextureStripAtlas.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrDynamicTextureStripAtlas_DEFINED
-#define GrDynamicTextureStripAtlas_DEFINED
-
-#include "GrTextureStripAtlas.h"
-#include "SkTDArray.h"
-
-class GrSurfaceContext;
-
-/**
- * Maintains a single large texture whose rows store many textures of a small fixed height,
- * stored in rows across the x-axis such that we can safely wrap/repeat them horizontally.
- */
-class GrDynamicTextureStripAtlas final : public GrTextureStripAtlas {
-public:
-    ~GrDynamicTextureStripAtlas() final;
-
-    /**
-     * This is intended to be used when cloning a processor that already holds a lock. It is
-     * assumed that the row already has at least one lock.
-     */
-    void lockRow(int row) final;
-    void unlockRow(int row) final;
-
-    sk_sp<GrTextureProxy> asTextureProxyRef() const final;
-
-private:
-    friend class GrTextureStripAtlasManager; // for ctor
-
-    /**
-     * Only the GrTextureStripAtlasManager is allowed to create GrTextureStripAtlases
-     */
-    GrDynamicTextureStripAtlas(const Desc& desc);
-
-    /**
-     * Add a texture to the atlas
-     *  @param data Bitmap data to copy into the row
-     *  @return The row index we inserted into, or -1 if we failed to find an open row. The caller
-     *      is responsible for calling unlockRow() with this row index when it's done with it.
-     */
-    int addStrip(GrContext*, const SkBitmap&) final;
-
-    void finish(GrProxyProvider*) final { SkASSERT(0); }  // this is only called in DDL mode
-
-    static uint32_t CreateUniqueID();
-
-    // Key to indicate an atlas row without any meaningful data stored in it
-    const static uint32_t kEmptyAtlasRowKey = 0xffffffff;
-
-    /**
-     * The state of a single row in our cache, next/prev pointers allow these to be chained
-     * together to represent LRU status
-     */
-    struct AtlasRow : ::SkNoncopyable {
-        AtlasRow() : fKey(kEmptyAtlasRowKey), fLocks(0), fNext(nullptr), fPrev(nullptr) { }
-        // GenerationID of the bitmap that is represented by this row, 0xffffffff means "empty"
-        uint32_t fKey;
-        // How many times this has been locked (0 == unlocked)
-        int32_t fLocks;
-        // We maintain an LRU linked list between unlocked nodes with these pointers
-        AtlasRow* fNext;
-        AtlasRow* fPrev;
-    };
-
-    void lockTexture(GrContext*);
-    void unlockTexture();
-
-    /**
-     * Initialize our LRU list (if one already exists, clear it and start anew)
-     */
-    void initLRU();
-
-    /**
-     * Grabs the least recently used free row out of the LRU list, returns nullptr if no rows
-     * are free.
-     */
-    AtlasRow* getLRU();
-
-    void appendLRU(AtlasRow* row);
-    void removeFromLRU(AtlasRow* row);
-
-    /**
-     * Searches the key table for a key and returns the index if found; if not found, it returns
-     * the bitwise not of the index at which we could insert the key to maintain a sorted list.
-     **/
-    int searchByKey(uint32_t key);
-
-    /**
-     * Compare two atlas rows by key, so we can sort/search by key
-     */
-    static bool KeyLess(const AtlasRow& lhs, const AtlasRow& rhs) {
-        return lhs.fKey < rhs.fKey;
-    }
-
-#ifdef SK_DEBUG
-    void validate();
-#endif
-
-    // A unique ID for this atlas, so we can be sure that if we
-    // get a texture back from the texture cache, that it's the same one we last used.
-    const uint32_t fCacheKey;
-
-    // Total locks on all rows (when this reaches zero, we can unlock our texture)
-    int32_t fLockedRows;
-
-    const uint16_t fNumRows;
-    sk_sp<GrSurfaceContext> fTexContext;
-
-    SkScalar fNormalizedYHeight;
-
-    // Array of AtlasRows which store the state of all our rows. Stored in a contiguous array, in
-    // order that they appear in our texture, this means we can subtract this pointer from a row
-    // pointer to get its index in the texture, and can save storing a row number in AtlasRow.
-    AtlasRow* fRows;
-
-    // Head and tail for linked list of least-recently-used rows (front = least recently used).
-    // Note that when a texture is locked, it gets removed from this list until it is unlocked.
-    AtlasRow* fLRUFront;
-    AtlasRow* fLRUBack;
-
-    // A list of pointers to AtlasRows that currently contain cached images, sorted by key
-    SkTDArray<AtlasRow*> fKeyTable;
-
-    typedef GrTextureStripAtlas INHERITED;
-};
-
-#endif
diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp
deleted file mode 100644
index 42bbf9e..0000000
--- a/src/gpu/effects/GrTextureStripAtlas.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrTextureStripAtlas.h"
-#include "GrContext.h"
-#include "GrContextPriv.h"
-#include "GrDDLTextureStripAtlas.h"
-#include "GrDynamicTextureStripAtlas.h"
-#include "SkBitmap.h"
-
-GrTextureStripAtlasManager::~GrTextureStripAtlasManager() {
-    this->deleteAllAtlases();
-}
-
-void GrTextureStripAtlasManager::deleteAllAtlases() {
-    AtlasHash::Iter iter(&fAtlasCache);
-    while (!iter.done()) {
-        AtlasEntry* tmp = &(*iter);
-        ++iter;
-        delete tmp;
-    }
-    fAtlasCache.reset();
-}
-
-void GrTextureStripAtlasManager::abandon() {
-    this->deleteAllAtlases();
-}
-
-void GrTextureStripAtlasManager::finish(GrProxyProvider* proxyProvider) {
-    for (AtlasHash::Iter iter(&fAtlasCache); !iter.done(); ++iter) {
-        AtlasEntry* tmp = &(*iter);
-        tmp->fAtlas->finish(proxyProvider);
-    }
-}
-
-
-sk_sp<GrTextureStripAtlas> GrTextureStripAtlasManager::addStrip(
-                                                          GrContext* context,
-                                                          const GrTextureStripAtlas::Desc& desc,
-                                                          const SkBitmap& bitmap,
-                                                          int* row) {
-    SkASSERT(kPremul_SkAlphaType == bitmap.alphaType());
-
-    AtlasEntry* entry = fAtlasCache.find(desc);
-    if (!entry) {
-        sk_sp<GrTextureStripAtlas> atlas;
-
-        if (!context->contextPriv().resourceProvider()) {
-            atlas.reset(new GrDDLTextureStripAtlas(desc));
-        } else {
-            atlas.reset(new GrDynamicTextureStripAtlas(desc));
-        }
-
-        entry = new AtlasEntry(sk_sp<GrTextureStripAtlas>(std::move(atlas)));
-        fAtlasCache.add(entry);
-    }
-
-    *row = entry->fAtlas->addStrip(context, bitmap);
-    if (*row < 0) {
-        return nullptr;
-    }
-
-    return entry->fAtlas;
-}
-
diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp
index 073ac18..59ed6bc 100644
--- a/src/shaders/gradients/SkGradientShader.cpp
+++ b/src/shaders/gradients/SkGradientShader.cpp
@@ -920,7 +920,6 @@
 #include "GrContextPriv.h"
 #include "GrShaderCaps.h"
 #include "GrTexture.h"
-#include "GrTextureStripAtlas.h"
 #include "gl/GrGLContext.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
 #include "glsl/GrGLSLProgramDataManager.h"
@@ -945,8 +944,7 @@
                                                             ge.fIntervals.count());
             break;
         case GrGradientEffect::InterpolationStrategy::kTexture:
-            fFSYUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
-                                                 "GradientYCoordFS");
+            // No extra uniforms
             break;
     }
 }
@@ -966,11 +964,7 @@
                          reinterpret_cast<const float*>(e.fIntervals.begin()));
             break;
         case GrGradientEffect::InterpolationStrategy::kTexture:
-            if (e.fYCoord != fCachedYCoord) {
-                SkScalar yDelta = 1.0f / e.fTextureSampler.peekTexture()->height();
-                pdman.set1f(fFSYUni, e.fYCoord * yDelta);
-                fCachedYCoord = e.fYCoord;
-            }
+            // No additional uniform data beyond what is already managed by the samplers
             break;
     }
 }
@@ -1111,9 +1105,7 @@
         return;
     }
 
-    const char* fsyuni = uniformHandler->getUniformCStr(fFSYUni);
-
-    fragBuilder->codeAppendf("half2 coord = half2(%s, %s);", gradientTValue, fsyuni);
+    fragBuilder->codeAppendf("half2 coord = half2(%s, 0.5);", gradientTValue);
     fragBuilder->codeAppendf("%s = ", outputColor);
     fragBuilder->appendTextureLookupAndModulate(inputColor, texSamplers[0], "coord",
                                                 kFloat2_GrSLType);
@@ -1155,7 +1147,6 @@
 GrGradientEffect::GrGradientEffect(ClassID classID, const CreateArgs& args, bool isOpaque)
     : INHERITED(classID, OptFlags(isOpaque))
     , fWrapMode(args.fWrapMode)
-    , fRow(-1)
     , fIsOpaque(args.fShader->isOpaque())
     , fStrategy(InterpolationStrategy::kTexture)
     , fThreshold(0) {
@@ -1251,60 +1242,35 @@
         SkASSERT(kPremul_SkAlphaType == bitmap.alphaType());
         SkASSERT(bitmap.isImmutable());
 
-        auto atlasManager = args.fContext->contextPriv().textureStripAtlasManager();
-
-        GrTextureStripAtlas::Desc desc;
-        desc.fWidth  = bitmap.width();
-        desc.fHeight = 32;
-        desc.fRowHeight = bitmap.height(); // always 1 here
-        desc.fColorType = bitmap.colorType();
-
-        int row;
-        fAtlas = atlasManager->addStrip(args.fContext, desc, bitmap, &row);
-        if (!args.fContext->contextPriv().resourceProvider()) {
-            // In DDL mode we should always be able to atlas
-            SkASSERT(fAtlas && row >= 0);
-        }
-
         // We always filter the gradient table. Each table is one row of a texture, always
         // y-clamp.
         GrSamplerState samplerState(args.fWrapMode, GrSamplerState::Filter::kBilerp);
 
-        if (-1 != fRow) {
-            SkASSERT(fAtlas);
+        // We know the samplerState state is:
+        //   clampY, bilerp
+        // and the proxy is:
+        //   exact fit, power of two in both dimensions
+        // Only the x-tileMode is unknown. However, given all the other knowns we know
+        // that GrMakeCachedImageProxy is sufficient (i.e., it won't need to be
+        // extracted to a subset or mipmapped).
 
-            fYCoord = fAtlas->rowToTextureY(fRow);
-            // This is 1/2 places where auto-normalization is disabled bc the gradient T is 0..1
-            fCoordTransform.reset(*args.fMatrix, fAtlas->asTextureProxyRef().get(), false);
-            fTextureSampler.reset(fAtlas->asTextureProxyRef(), samplerState);
-        } else {
-            // In this instance we know the samplerState state is:
-            //   clampY, bilerp
-            // and the proxy is:
-            //   exact fit, power of two in both dimensions
-            // Only the x-tileMode is unknown. However, given all the other knowns we know
-            // that GrMakeCachedImageProxy is sufficient (i.e., it won't need to be
-            // extracted to a subset or mipmapped).
-
-            sk_sp<SkImage> srcImage = SkImage::MakeFromBitmap(bitmap);
-            if (!srcImage) {
-                return;
-            }
-
-            sk_sp<GrTextureProxy> proxy = GrMakeCachedImageProxy(
-                                                     args.fContext->contextPriv().proxyProvider(),
-                                                     std::move(srcImage));
-            if (!proxy) {
-                SkDebugf("Gradient won't draw. Could not create texture.");
-                return;
-            }
-            // This is 2/2 places where auto-normalization is disabled because the graient T is 0..1
-            fCoordTransform.reset(*args.fMatrix, proxy.get(), false);
-            fTextureSampler.reset(std::move(proxy), samplerState);
-            SkASSERT(1 == bitmap.height());
-            fYCoord = SK_ScalarHalf;
+        sk_sp<SkImage> srcImage = SkImage::MakeFromBitmap(bitmap);
+        if (!srcImage) {
+            return;
         }
 
+        sk_sp<GrTextureProxy> proxy = GrMakeCachedImageProxy(
+                                                 args.fContext->contextPriv().proxyProvider(),
+                                                 std::move(srcImage));
+        if (!proxy) {
+            SkDebugf("Gradient won't draw. Could not create texture.");
+            return;
+        }
+        // Auto-normalization is disabled because the gradient T is 0..1
+        fCoordTransform.reset(*args.fMatrix, proxy.get(), false);
+        fTextureSampler.reset(std::move(proxy), samplerState);
+        SkASSERT(1 == bitmap.height());
+
         this->setTextureSamplerCnt(1);
     }
 
@@ -1317,9 +1283,6 @@
         , fWrapMode(that.fWrapMode)
         , fCoordTransform(that.fCoordTransform)
         , fTextureSampler(that.fTextureSampler)
-        , fYCoord(that.fYCoord)
-        , fAtlas(that.fAtlas)
-        , fRow(that.fRow)
         , fIsOpaque(that.fIsOpaque)
         , fStrategy(that.fStrategy)
         , fThreshold(that.fThreshold)
@@ -1328,15 +1291,6 @@
     if (fStrategy == InterpolationStrategy::kTexture) {
         this->setTextureSamplerCnt(1);
     }
-    if (this->useAtlas()) {
-        fAtlas->lockRow(fRow);
-    }
-}
-
-GrGradientEffect::~GrGradientEffect() {
-    if (this->useAtlas()) {
-        fAtlas->unlockRow(fRow);
-    }
 }
 
 bool GrGradientEffect::onIsEqual(const GrFragmentProcessor& processor) const {
@@ -1346,9 +1300,8 @@
         return false;
     }
 
-    SkASSERT(this->useAtlas() == ge.useAtlas());
     if (fStrategy == InterpolationStrategy::kTexture) {
-        if (fYCoord != ge.fYCoord) {
+        if (fTextureSampler != ge.fTextureSampler) {
             return false;
         }
     } else {
diff --git a/src/shaders/gradients/SkGradientShaderPriv.h b/src/shaders/gradients/SkGradientShaderPriv.h
index f3e10d0..2c7a5e4 100644
--- a/src/shaders/gradients/SkGradientShaderPriv.h
+++ b/src/shaders/gradients/SkGradientShaderPriv.h
@@ -231,10 +231,6 @@
 
     class GLSLProcessor;
 
-    ~GrGradientEffect() override;
-
-    bool useAtlas() const { return SkToBool(-1 != fRow); }
-
     // Controls the implementation strategy for this effect.
     // NB: all entries need to be reflected in the key.
     enum class InterpolationStrategy : uint8_t {
@@ -313,9 +309,6 @@
 
     GrCoordTransform fCoordTransform;
     TextureSampler fTextureSampler;
-    SkScalar fYCoord;
-    sk_sp<GrTextureStripAtlas> fAtlas;
-    int fRow;
     bool fIsOpaque;
 
     InterpolationStrategy fStrategy;
@@ -333,10 +326,6 @@
 // Base class for GL gradient effects
 class GrGradientEffect::GLSLProcessor : public GrGLSLFragmentProcessor {
 public:
-    GLSLProcessor() {
-        fCachedYCoord = SK_ScalarMax;
-    }
-
     static uint32_t GenBaseGradientKey(const GrProcessor&);
 
 protected:
@@ -368,10 +357,8 @@
                              const char* outputColor,
                              const char* inputColor);
 
-    SkScalar fCachedYCoord;
     GrGLSLProgramDataManager::UniformHandle fIntervalsUni;
     GrGLSLProgramDataManager::UniformHandle fThresholdUni;
-    GrGLSLProgramDataManager::UniformHandle fFSYUni;
 
     typedef GrGLSLFragmentProcessor INHERITED;
 };