Switch GrTextureStripAtlas over to GrTextureProxies

This is split out of: https://skia-review.googlesource.com/c/8823/ (Remove GrFragmentProcessor-derived class' GrTexture-based ctors)

Change-Id: I9f602985b6010fc58b595e2be6d4e67e50179747
Reviewed-on: https://skia-review.googlesource.com/8881
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/include/gpu/GrProcessor.h b/include/gpu/GrProcessor.h
index 388bd54..1fee5a3 100644
--- a/include/gpu/GrProcessor.h
+++ b/include/gpu/GrProcessor.h
@@ -205,23 +205,26 @@
     TextureSampler();
 
     TextureSampler(GrTexture*, const GrSamplerParams&);
-
     explicit TextureSampler(GrTexture*,
                             GrSamplerParams::FilterMode = GrSamplerParams::kNone_FilterMode,
                             SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode,
                             GrShaderFlags visibility = kFragment_GrShaderFlag);
-
-    TextureSampler(GrTextureProvider*, sk_sp<GrTextureProxy>, const GrSamplerParams&);
+    void reset(GrTexture*, const GrSamplerParams&,
+               GrShaderFlags visibility = kFragment_GrShaderFlag);
+    void reset(GrTexture*,
+               GrSamplerParams::FilterMode = GrSamplerParams::kNone_FilterMode,
+               SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode,
+               GrShaderFlags visibility = kFragment_GrShaderFlag);
 
     // MDB TODO: ultimately we shouldn't need the texProvider parameter
+    TextureSampler(GrTextureProvider*, sk_sp<GrTextureProxy>, const GrSamplerParams&);
     explicit TextureSampler(GrTextureProvider*, sk_sp<GrTextureProxy>,
                             GrSamplerParams::FilterMode = GrSamplerParams::kNone_FilterMode,
                             SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode,
                             GrShaderFlags visibility = kFragment_GrShaderFlag);
-
-    void reset(GrTexture*, const GrSamplerParams&,
+    void reset(GrTextureProvider*, sk_sp<GrTextureProxy>, const GrSamplerParams&,
                GrShaderFlags visibility = kFragment_GrShaderFlag);
-    void reset(GrTexture*,
+    void reset(GrTextureProvider*, sk_sp<GrTextureProxy>,
                GrSamplerParams::FilterMode = GrSamplerParams::kNone_FilterMode,
                SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode,
                GrShaderFlags visibility = kFragment_GrShaderFlag);
diff --git a/include/gpu/GrRenderTargetContext.h b/include/gpu/GrRenderTargetContext.h
index 466424e..ed8ac04 100644
--- a/include/gpu/GrRenderTargetContext.h
+++ b/include/gpu/GrRenderTargetContext.h
@@ -433,7 +433,8 @@
     friend class GrStencilAndCoverPathRenderer;  // for access to addDrawOp
     friend class GrTessellatingPathRenderer;     // for access to addDrawOp
     // for a unit test
-    friend void test_draw_op(GrRenderTargetContext*, sk_sp<GrFragmentProcessor>, GrTexture*);
+    friend void test_draw_op(GrContext*, GrRenderTargetContext*,
+                             sk_sp<GrFragmentProcessor>, sk_sp<GrTextureProxy>);
 
     void internalClear(const GrFixedClip&, const GrColor, bool canIgnoreClip);
 
@@ -469,7 +470,7 @@
     bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
                       size_t dstRowBytes, int x, int y) override;
     bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
-                       size_t srcRowBytes, int x, int y) override;
+                       size_t srcRowBytes, int x, int y, uint32_t flags) override;
 
     // This entry point allows the GrTextContext-derived classes to add their ops to the GrOpList.
     void addDrawOp(const GrPipelineBuilder&, const GrClip&, std::unique_ptr<GrDrawOp>);
diff --git a/include/gpu/GrSurfaceContext.h b/include/gpu/GrSurfaceContext.h
index 8be63ab..24041e8 100644
--- a/include/gpu/GrSurfaceContext.h
+++ b/include/gpu/GrSurfaceContext.h
@@ -91,8 +91,8 @@
      *              unsupported pixel config.
      */
     bool writePixels(const SkImageInfo& srcInfo, const void* srcBuffer, size_t srcRowBytes,
-                     int x, int y) {
-        return this->onWritePixels(srcInfo, srcBuffer, srcRowBytes, x, y);
+                     int x, int y, uint32_t flags = 0) {
+        return this->onWritePixels(srcInfo, srcBuffer, srcRowBytes, x, y, flags);
     }
 
     // TODO: this is virtual b.c. this object doesn't have a pointer to the wrapped GrSurfaceProxy?
@@ -139,7 +139,7 @@
     virtual bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
                               size_t dstRowBytes, int x, int y) = 0;
     virtual bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
-                               size_t srcRowBytes, int x, int y) = 0;
+                               size_t srcRowBytes, int x, int y, uint32_t flags) = 0;
 
     GrDrawingManager*     fDrawingManager;
 
diff --git a/include/gpu/GrTextureContext.h b/include/gpu/GrTextureContext.h
index 48a2e48..6b2f0e3 100644
--- a/include/gpu/GrTextureContext.h
+++ b/include/gpu/GrTextureContext.h
@@ -50,7 +50,7 @@
     bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
                       size_t dstRowBytes, int x, int y) override;
     bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
-                       size_t srcRowBytes, int x, int y) override;
+                       size_t srcRowBytes, int x, int y, uint32_t flags) override;
 
     GrTextureOpList* getOpList();
 
diff --git a/include/private/GrTextureStripAtlas.h b/include/private/GrTextureStripAtlas.h
index 5b90a34..5658b16 100644
--- a/include/private/GrTextureStripAtlas.h
+++ b/include/private/GrTextureStripAtlas.h
@@ -15,6 +15,9 @@
 #include "SkTDynamicHash.h"
 #include "SkTypes.h"
 
+class GrSurfaceContext;
+class GrTextureProxy;
+
 /**
  * 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.
@@ -71,7 +74,8 @@
     SkScalar getNormalizedTexelHeight() const { return fNormalizedYHeight; }
 
     GrContext* getContext() const { return fDesc.fContext; }
-    GrTexture* getTexture() const { return fTexture; }
+
+    sk_sp<GrTextureProxy> asTextureProxyRef() const;
 
 private:
 
@@ -168,7 +172,7 @@
 
     const Desc fDesc;
     const uint16_t fNumRows;
-    GrTexture* fTexture;
+    sk_sp<GrSurfaceContext> fTexContext;
 
     SkScalar fNormalizedYHeight;
 
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 98016e0..b63ed47 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -375,7 +375,7 @@
                                            const SkBitmap& bitmap,
                                            unsigned flags);
 
-    virtual ~ColorTableEffect();
+    ~ColorTableEffect() override;
 
     const char* name() const override { return "ColorTable"; }
 
@@ -389,7 +389,8 @@
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
 
-    ColorTableEffect(GrTexture* texture, GrTextureStripAtlas* atlas, int row, unsigned flags);
+    ColorTableEffect(GrContext* context, sk_sp<GrTextureProxy> proxy,
+                     GrTextureStripAtlas* atlas, int row, unsigned flags);
 
     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
@@ -494,29 +495,27 @@
     desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *context->caps());
     GrTextureStripAtlas* atlas = GrTextureStripAtlas::GetAtlas(desc);
     int row = atlas->lockRow(bitmap);
-    sk_sp<GrTexture> texture;
+    sk_sp<GrTextureProxy> proxy;
     if (-1 == row) {
         atlas = nullptr;
 
-        sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(context, bitmap);
-        if (proxy) {
-            texture.reset(proxy->instantiate(context->textureProvider()));
-        }
+        proxy = GrMakeCachedBitmapProxy(context, bitmap);
     } else {
-        texture.reset(SkRef(atlas->getTexture()));
+        proxy = atlas->asTextureProxyRef();
     }
 
-    if (!texture) {
+    if (!proxy) {
         return nullptr;
     }
 
-    return sk_sp<GrFragmentProcessor>(new ColorTableEffect(texture.get(), atlas, row, flags));
+    return sk_sp<GrFragmentProcessor>(new ColorTableEffect(context, std::move(proxy),
+                                                           atlas, row, flags));
 }
 
-ColorTableEffect::ColorTableEffect(GrTexture* texture, GrTextureStripAtlas* atlas, int row,
-                                   unsigned flags)
+ColorTableEffect::ColorTableEffect(GrContext* context, sk_sp<GrTextureProxy> proxy,
+                                   GrTextureStripAtlas* atlas, int row, unsigned flags)
         : INHERITED(kNone_OptimizationFlags)  // Not bothering with table-specific optimizations.
-        , fTextureSampler(texture)
+        , fTextureSampler(context->textureProvider(), std::move(proxy))
         , fAtlas(atlas)
         , fRow(row) {
     this->initClassID<ColorTableEffect>();
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index cd5eda3..b8b6d63 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -8,6 +8,7 @@
 #include "Sk4fLinearGradient.h"
 #include "SkColorSpace_XYZ.h"
 #include "SkGradientShaderPriv.h"
+#include "SkGrPriv.h"
 #include "SkHalf.h"
 #include "SkLinearGradient.h"
 #include "SkRadialGradient.h"
@@ -1674,6 +1675,8 @@
 
             SkBitmap bitmap;
             shader.getGradientTableBitmap(&bitmap, bitmapType);
+            SkASSERT(1 == bitmap.height() && SkIsPow2(bitmap.width()));
+
 
             GrTextureStripAtlas::Desc desc;
             desc.fWidth  = bitmap.width();
@@ -1694,18 +1697,28 @@
             if (-1 != fRow) {
                 fYCoord = fAtlas->getYOffset(fRow)+SK_ScalarHalf*fAtlas->getNormalizedTexelHeight();
                 // This is 1/2 places where auto-normalization is disabled
-                fCoordTransform.reset(*args.fMatrix, fAtlas->getTexture(),
+                fCoordTransform.reset(args.fContext, *args.fMatrix,
+                                      fAtlas->asTextureProxyRef().get(),
                                       params.filterMode(), false);
-                fTextureSampler.reset(fAtlas->getTexture(), params);
+                fTextureSampler.reset(args.fContext->textureProvider(),
+                                      fAtlas->asTextureProxyRef(), params);
             } else {
-                sk_sp<GrTexture> texture(GrRefCachedBitmapTexture(args.fContext, bitmap,
-                                                                  params, nullptr));
-                if (!texture) {
+                // In this instance we know the params are:
+                //   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 GrMakeCachedBitmapProxy is sufficient (i.e., it won't need to be
+                // extracted to a subset or mipmapped).
+                sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(args.fContext, bitmap);
+                if (!proxy) {
                     return;
                 }
                 // This is 2/2 places where auto-normalization is disabled
-                fCoordTransform.reset(*args.fMatrix, texture.get(), params.filterMode(), false);
-                fTextureSampler.reset(texture.get(), params);
+                fCoordTransform.reset(args.fContext, *args.fMatrix,
+                                      proxy.get(), params.filterMode(), false);
+                fTextureSampler.reset(args.fContext->textureProvider(),
+                                      std::move(proxy), params);
                 fYCoord = SK_ScalarHalf;
             }
 
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 663527e..8214d2c 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -211,9 +211,7 @@
 GrProcessor::TextureSampler::TextureSampler(GrTextureProvider* texProvider,
                                             sk_sp<GrTextureProxy> proxy,
                                             const GrSamplerParams& params) {
-    // For now, end the deferral at this time. Once all the TextureSamplers are swapped over
-    // to taking a GrSurfaceProxy just use the IORefs on the proxy
-    this->reset(proxy->instantiate(texProvider), params);
+    this->reset(texProvider, std::move(proxy), params);
 }
 
 GrProcessor::TextureSampler::TextureSampler(GrTextureProvider* texProvider,
@@ -221,9 +219,7 @@
                                             GrSamplerParams::FilterMode filterMode,
                                             SkShader::TileMode tileXAndY,
                                             GrShaderFlags visibility) {
-    // For now, end the deferral at this time. Once all the TextureSamplers are swapped over
-    // to taking a GrSurfaceProxy just use the IORefs on the proxy
-    this->reset(proxy->instantiate(texProvider), filterMode, tileXAndY, visibility);
+    this->reset(texProvider, std::move(proxy), filterMode, tileXAndY, visibility);
 }
 
 void GrProcessor::TextureSampler::reset(GrTexture* texture,
@@ -247,6 +243,35 @@
     fVisibility = visibility;
 }
 
+void GrProcessor::TextureSampler::reset(GrTextureProvider* texProvider,
+                                        sk_sp<GrTextureProxy> proxy,
+                                        const GrSamplerParams& params,
+                                        GrShaderFlags visibility) {
+    // For now, end the deferral at this time. Once all the TextureSamplers are swapped over
+    // to taking a GrSurfaceProxy just use the IORefs on the proxy
+    GrTexture* texture = proxy->instantiate(texProvider);
+    SkASSERT(texture);
+    fTexture.set(SkRef(texture), kRead_GrIOType);
+    fParams = params;
+    fParams.setFilterMode(SkTMin(params.filterMode(), texture->texturePriv().highestFilterMode()));
+    fVisibility = visibility;
+}
+
+void GrProcessor::TextureSampler::reset(GrTextureProvider* texProvider,
+                                        sk_sp<GrTextureProxy> proxy,
+                                        GrSamplerParams::FilterMode filterMode,
+                                        SkShader::TileMode tileXAndY,
+                                        GrShaderFlags visibility) {
+    // For now, end the deferral at this time. Once all the TextureSamplers are swapped over
+    // to taking a GrSurfaceProxy just use the IORefs on the proxy
+    GrTexture* texture = proxy->instantiate(texProvider);
+    SkASSERT(texture);
+    fTexture.set(SkRef(texture), kRead_GrIOType);
+    filterMode = SkTMin(filterMode, texture->texturePriv().highestFilterMode());
+    fParams.reset(tileXAndY, filterMode);
+    fVisibility = visibility;
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 GrProcessor::ImageStorageAccess::ImageStorageAccess(sk_sp<GrTexture> texture, GrIOType ioType,
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index c2197e3..a980818 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -186,15 +186,14 @@
 
 // TODO: move this (and GrTextureContext::onReadPixels) to GrSurfaceContext?
 bool GrRenderTargetContext::onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
-                                          size_t srcRowBytes, int x, int y) {
+                                          size_t srcRowBytes, int x, int y, uint32_t flags) {
     // TODO: teach GrRenderTarget to take ImageInfo directly to specify the src pixels
     GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps());
     if (kUnknown_GrPixelConfig == config) {
         return false;
     }
-    uint32_t flags = 0;
     if (kUnpremul_SkAlphaType == srcInfo.alphaType()) {
-        flags = GrContext::kUnpremul_PixelOpsFlag;
+        flags |= GrContext::kUnpremul_PixelOpsFlag;
     }
 
     // Deferral of the VRAM resources must end in this instance anyway
diff --git a/src/gpu/GrTextureContext.cpp b/src/gpu/GrTextureContext.cpp
index 7e90695..75c9e30 100644
--- a/src/gpu/GrTextureContext.cpp
+++ b/src/gpu/GrTextureContext.cpp
@@ -133,15 +133,15 @@
 
 // TODO: move this (and GrRenderTargetContext::onReadPixels) to GrSurfaceContext?
 bool GrTextureContext::onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
-                                     size_t srcRowBytes, int x, int y) {
+                                     size_t srcRowBytes, int x, int y,
+                                     uint32_t flags) {
     // TODO: teach GrTexture to take ImageInfo directly to specify the src pixels
     GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps());
     if (kUnknown_GrPixelConfig == config) {
         return false;
     }
-    uint32_t flags = 0;
     if (kUnpremul_SkAlphaType == srcInfo.alphaType()) {
-        flags = GrContext::kUnpremul_PixelOpsFlag;
+        flags |= GrContext::kUnpremul_PixelOpsFlag;
     }
 
     // Deferral of the VRAM resources must end in this instance anyway
diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp
index 2c88250..2de7076 100644
--- a/src/gpu/effects/GrTextureStripAtlas.cpp
+++ b/src/gpu/effects/GrTextureStripAtlas.cpp
@@ -7,7 +7,8 @@
 
 #include "GrTextureStripAtlas.h"
 #include "GrContext.h"
-#include "GrTexture.h"
+#include "GrContextPriv.h"
+#include "GrSurfaceContext.h"
 #include "SkGr.h"
 #include "SkPixelRef.h"
 #include "SkTSearch.h"
@@ -73,7 +74,6 @@
     , fLockedRows(0)
     , fDesc(desc)
     , fNumRows(desc.fHeight / desc.fRowHeight)
-    , fTexture(nullptr)
     , fRows(new AtlasRow[fNumRows])
     , fLRUFront(nullptr)
     , fLRUBack(nullptr) {
@@ -85,16 +85,16 @@
 
 GrTextureStripAtlas::~GrTextureStripAtlas() { delete[] fRows; }
 
-int GrTextureStripAtlas::lockRow(const SkBitmap& data) {
+int GrTextureStripAtlas::lockRow(const SkBitmap& bitmap) {
     VALIDATE;
     if (0 == fLockedRows) {
         this->lockTexture();
-        if (!fTexture) {
+        if (!fTexContext) {
             return -1;
         }
     }
 
-    int key = data.getGenerationID();
+    int key = bitmap.getGenerationID();
     int rowNumber = -1;
     int index = this->searchByKey(key);
 
@@ -152,16 +152,16 @@
         fKeyTable.insert(index, 1, &row);
         rowNumber = static_cast<int>(row - fRows);
 
-        SkAutoLockPixels lock(data);
+        SkAutoLockPixels lock(bitmap);
+
+        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
-        fTexture->writePixels(0,  rowNumber * fDesc.fRowHeight,
-                              fDesc.fWidth, fDesc.fRowHeight,
-                              SkImageInfo2GrPixelConfig(data.info(), *this->getContext()->caps()),
-                              data.getPixels(),
-                              data.rowBytes(),
-                              GrContext::kDontFlush_PixelOpsFlag);
+        fTexContext->writePixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(),
+                                 0, rowNumber * fDesc.fRowHeight,
+                                 GrContext::kDontFlush_PixelOpsFlag);
     }
 
     SkASSERT(rowNumber >= 0);
@@ -169,6 +169,10 @@
     return rowNumber;
 }
 
+sk_sp<GrTextureProxy> GrTextureStripAtlas::asTextureProxyRef() const {
+    return fTexContext->asTextureProxyRef();
+}
+
 void GrTextureStripAtlas::unlockRow(int row) {
     VALIDATE;
     --fRows[row].fLocks;
@@ -202,29 +206,30 @@
     builder[0] = static_cast<uint32_t>(fCacheKey);
     builder.finish();
 
-    fTexture = fDesc.fContext->textureProvider()->findAndRefTextureByUniqueKey(key);
-    if (nullptr == fTexture) {
-        fTexture = fDesc.fContext->textureProvider()->createTexture(texDesc, SkBudgeted::kYes,
-                                                                    nullptr, 0);
-        if (!fTexture) {
+    // MDB TODO (caching): this side-steps the issue of proxies with unique IDs
+    GrTexture* texture = fDesc.fContext->textureProvider()->findAndRefTextureByUniqueKey(key);
+    if (!texture) {
+        texture = fDesc.fContext->textureProvider()->createTexture(texDesc, SkBudgeted::kYes,
+                                                                   nullptr, 0);
+        if (!texture) {
             return;
         }
 
         // We will be issuing writes to the surface using kDontFlush_PixelOpsFlag, so we
         // need to make sure any existing IO is flushed
-        fDesc.fContext->flushSurfaceIO(fTexture);
-        fDesc.fContext->textureProvider()->assignUniqueKeyToTexture(key, fTexture);
+        fDesc.fContext->flushSurfaceIO(texture);
+        fDesc.fContext->textureProvider()->assignUniqueKeyToTexture(key, texture);
         // This is a new texture, so all of our cache info is now invalid
         this->initLRU();
         fKeyTable.rewind();
     }
-    SkASSERT(fTexture);
+    SkASSERT(texture);
+    fTexContext = fDesc.fContext->contextPriv().makeWrappedSurfaceContext(sk_ref_sp(texture));
 }
 
 void GrTextureStripAtlas::unlockTexture() {
-    SkASSERT(fTexture && 0 == fLockedRows);
-    fTexture->unref();
-    fTexture = nullptr;
+    SkASSERT(fTexContext && 0 == fLockedRows);
+    fTexContext.reset();
 }
 
 void GrTextureStripAtlas::initLRU() {
@@ -348,9 +353,9 @@
     // If we have locked rows, we should have a locked texture, otherwise
     // it should be unlocked
     if (fLockedRows == 0) {
-        SkASSERT(nullptr == fTexture);
+        SkASSERT(!fTexContext);
     } else {
-        SkASSERT(fTexture);
+        SkASSERT(fTexContext);
     }
 }
 #endif
diff --git a/tests/GrTextureStripAtlasTest.cpp b/tests/GrTextureStripAtlasTest.cpp
index 5b1a14e..13d5d92 100644
--- a/tests/GrTextureStripAtlasTest.cpp
+++ b/tests/GrTextureStripAtlasTest.cpp
@@ -52,6 +52,8 @@
         }
 
         srcSurface = srcProxy->instantiate(context->textureProvider());
+        // TODO: maybe add an assert here on srcSurface's ref state to ensure it is what we
+        // expect.
         srcProxy.reset();
     }
 
@@ -64,7 +66,7 @@
         atlasDesc.fConfig = desc.fConfig;
         atlasDesc.fWidth = desc.fWidth;
         atlasDesc.fHeight = desc.fHeight;
-        atlasDesc.fRowHeight = 1;
+        atlasDesc.fRowHeight = desc.fHeight;
         atlas = GrTextureStripAtlas::GetAtlas(atlasDesc);
     }
 
@@ -73,10 +75,9 @@
 
     {
         SkImageInfo info = SkImageInfo::MakeN32(desc.fWidth, desc.fHeight, kPremul_SkAlphaType);
-        size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig);
         SkBitmap bitmap;
-        bitmap.allocPixels(info, rowBytes);
-        memset(bitmap.getPixels(), 1, rowBytes * desc.fHeight);
+        bitmap.allocPixels(info);
+        bitmap.eraseColor(SK_ColorBLACK);
         lockedRow = atlas->lockRow(bitmap);
     }
 
@@ -103,8 +104,11 @@
     }
 
     if (!context->caps()->preferVRAMUseOverFlushes()) {
+        sk_sp<GrTextureProxy> proxy = atlas->asTextureProxyRef();
+        GrTexture* tex = proxy->instantiate(context->textureProvider());
+
         // This is kindof dodgy since we released it!
-        REPORTER_ASSERT(reporter, srcSurface == atlas->getTexture());
+        REPORTER_ASSERT(reporter, srcSurface == tex);
     }
 
     atlas->unlockRow(lockedRow);
diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp
index 8801a34..bb9a3da 100644
--- a/tests/ProcessorTest.cpp
+++ b/tests/ProcessorTest.cpp
@@ -50,10 +50,11 @@
     static sk_sp<GrFragmentProcessor> Make(sk_sp<GrFragmentProcessor> child) {
         return sk_sp<GrFragmentProcessor>(new TestFP(std::move(child)));
     }
-    static sk_sp<GrFragmentProcessor> Make(const SkTArray<sk_sp<GrTexture>>& textures,
+    static sk_sp<GrFragmentProcessor> Make(GrContext* context,
+                                           const SkTArray<sk_sp<GrTextureProxy>>& proxies,
                                            const SkTArray<sk_sp<GrBuffer>>& buffers,
                                            const SkTArray<Image>& images) {
-        return sk_sp<GrFragmentProcessor>(new TestFP(textures, buffers, images));
+        return sk_sp<GrFragmentProcessor>(new TestFP(context, proxies, buffers, images));
     }
 
     const char* name() const override { return "test"; }
@@ -65,11 +66,13 @@
     }
 
 private:
-    TestFP(const SkTArray<sk_sp<GrTexture>>& textures, const SkTArray<sk_sp<GrBuffer>>& buffers,
+    TestFP(GrContext* context,
+           const SkTArray<sk_sp<GrTextureProxy>>& proxies,
+           const SkTArray<sk_sp<GrBuffer>>& buffers,
            const SkTArray<Image>& images)
             : INHERITED(kNone_OptimizationFlags), fSamplers(4), fBuffers(4), fImages(4) {
-        for (const auto& texture : textures) {
-            this->addTextureSampler(&fSamplers.emplace_back(texture.get()));
+        for (const auto& proxy : proxies) {
+            this->addTextureSampler(&fSamplers.emplace_back(context->textureProvider(), proxy));
         }
         for (const auto& buffer : buffers) {
             this->addBufferAccess(&fBuffers.emplace_back(kRGBA_8888_GrPixelConfig, buffer.get()));
@@ -115,6 +118,12 @@
     *writeCnt = resource->fPendingWrites;
 }
 
+void testingOnly_getIORefCnts(GrSurfaceProxy* proxy, int* refCnt, int* readCnt, int* writeCnt) {
+    *refCnt = proxy->getBackingRefCnt_TestOnly();
+    *readCnt = proxy->getPendingReadCnt_TestOnly();
+    *writeCnt = proxy->getPendingWriteCnt_TestOnly();
+}
+
 DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) {
     GrContext* context = ctxInfo.grContext();
 
@@ -129,8 +138,9 @@
         {
             bool texelBufferSupport = context->caps()->shaderCaps()->texelBufferSupport();
             bool imageLoadStoreSupport = context->caps()->shaderCaps()->imageLoadStoreSupport();
-            sk_sp<GrTexture> texture1(
-                    context->resourceProvider()->createTexture(desc, SkBudgeted::kYes));
+            sk_sp<GrSurfaceProxy> proxy1(GrSurfaceProxy::MakeDeferred(*context->caps(), desc,
+                                                                      SkBackingFit::kExact,
+                                                                      SkBudgeted::kYes));
             sk_sp<GrTexture> texture2(
                     context->resourceProvider()->createTexture(desc, SkBudgeted::kYes));
             sk_sp<GrTexture> texture3(
@@ -143,10 +153,10 @@
                                                      GrAccessPattern::kStatic_GrAccessPattern, 0)
                                            : nullptr);
             {
-                SkTArray<sk_sp<GrTexture>> textures;
+                SkTArray<sk_sp<GrTextureProxy>> proxies;
                 SkTArray<sk_sp<GrBuffer>> buffers;
                 SkTArray<TestFP::Image> images;
-                textures.push_back(texture1);
+                proxies.push_back(sk_ref_sp(proxy1->asTextureProxy()));
                 if (texelBufferSupport) {
                     buffers.push_back(buffer);
                 }
@@ -157,7 +167,8 @@
                 }
                 std::unique_ptr<GrDrawOp> op(TestOp::Make());
                 GrPaint paint;
-                auto fp = TestFP::Make(std::move(textures), std::move(buffers), std::move(images));
+                auto fp = TestFP::Make(context,
+                                       std::move(proxies), std::move(buffers), std::move(images));
                 for (int i = 0; i < parentCnt; ++i) {
                     fp = TestFP::Make(std::move(fp));
                 }
@@ -167,7 +178,7 @@
             }
             int refCnt, readCnt, writeCnt;
 
-            testingOnly_getIORefCnts(texture1.get(), &refCnt, &readCnt, &writeCnt);
+            testingOnly_getIORefCnts(proxy1.get(), &refCnt, &readCnt, &writeCnt);
             REPORTER_ASSERT(reporter, 1 == refCnt);
             REPORTER_ASSERT(reporter, 1 == readCnt);
             REPORTER_ASSERT(reporter, 0 == writeCnt);
@@ -198,7 +209,7 @@
 
             context->flush();
 
-            testingOnly_getIORefCnts(texture1.get(), &refCnt, &readCnt, &writeCnt);
+            testingOnly_getIORefCnts(proxy1.get(), &refCnt, &readCnt, &writeCnt);
             REPORTER_ASSERT(reporter, 1 == refCnt);
             REPORTER_ASSERT(reporter, 0 == readCnt);
             REPORTER_ASSERT(reporter, 0 == writeCnt);
@@ -241,10 +252,10 @@
 
 static GrColor4f texel_color4f(int i, int j) { return GrColor4f::FromGrColor(texel_color(i, j)); }
 
-void test_draw_op(GrRenderTargetContext* rtc, sk_sp<GrFragmentProcessor> fp,
-                  GrTexture* inputDataTexture) {
+void test_draw_op(GrContext* context, GrRenderTargetContext* rtc, sk_sp<GrFragmentProcessor> fp,
+                  sk_sp<GrTextureProxy> inputDataProxy) {
     GrPaint paint;
-    paint.addColorTextureProcessor(inputDataTexture, nullptr, SkMatrix::I());
+    paint.addColorTextureProcessor(context, std::move(inputDataProxy), nullptr, SkMatrix::I());
     paint.addColorFragmentProcessor(std::move(fp));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
     GrPipelineBuilder pb(std::move(paint), GrAAType::kNone);
@@ -299,8 +310,12 @@
         }
     }
     desc.fConfig = kRGBA_8888_GrPixelConfig;
-    sk_sp<GrTexture> dataTexture(context->textureProvider()->createTexture(
-            desc, SkBudgeted::kYes, rgbaData.get(), 256 * sizeof(GrColor)));
+
+    sk_sp<GrSurfaceProxy> dataProxy = GrSurfaceProxy::MakeDeferred(*context->caps(),
+                                                                   context->textureProvider(),
+                                                                   desc, SkBudgeted::kYes,
+                                                                   rgbaData.get(),
+                                                                   256 * sizeof(GrColor));
 
     // Because processors factories configure themselves in random ways, this is not exhaustive.
     for (int i = 0; i < FPFactory::Count(); ++i) {
@@ -319,7 +334,7 @@
                 !fp->compatibleWithCoverageAsAlpha()) {
                 continue;
             }
-            test_draw_op(rtc.get(), fp, dataTexture.get());
+            test_draw_op(context, rtc.get(), fp, sk_ref_sp(dataProxy->asTextureProxy()));
             memset(rgbaData.get(), 0x0, sizeof(GrColor) * 256 * 256);
             rtc->readPixels(
                     SkImageInfo::Make(256, 256, kRGBA_8888_SkColorType, kPremul_SkAlphaType),