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/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