Move GrMakeCachedBitmapProxy work in lazy mode

This basically wraps the bitmap in an SkImage and uses the GrMakeCachedImageProxy
call to create the proxy.

Bug: skia:
Change-Id: I648a9cac3a316231bfb1bcedaae2009b7de0356c
Reviewed-on: https://skia-review.googlesource.com/105360
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index b73d9244..0076a1a 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -341,8 +341,8 @@
     // In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap
     // even if its mutable. In ddl, if the bitmap is mutable then we must make a copy since the
     // upload of the data to the gpu can happen at anytime and the bitmap may change by then.
-    SkCopyPixelsMode copyMode = fResourceProvider ? kNever_SkCopyPixelsMode
-                                                  : kIfMutable_SkCopyPixelsMode;
+    SkCopyPixelsMode copyMode = this->mutableBitmapsNeedCopy() ? kIfMutable_SkCopyPixelsMode
+                                                               : kNever_SkCopyPixelsMode;
     sk_sp<SkImage> baseLevel = SkMakeImageFromRasterBitmap(bitmap, copyMode);
 
     if (!baseLevel) {
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index aa1d991..af661c1 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -228,6 +228,12 @@
 
     void removeAllUniqueKeys();
 
+    /**
+     * Helper function for callers who are wrapping a bitmap into an SkImage so they know whether or
+     * not that bitmap should be copied or not.
+     */
+    bool mutableBitmapsNeedCopy() const { return !SkToBool(fResourceProvider); }
+
 private:
     friend class GrAHardwareBufferImageGenerator; // for createWrapped
 
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 1d210c4..cf8b3ab 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -25,6 +25,7 @@
 #include "SkData.h"
 #include "SkImage_Base.h"
 #include "SkImageInfoPriv.h"
+#include "SkImagePriv.h"
 #include "SkMaskFilterBase.h"
 #include "SkMessageBus.h"
 #include "SkMipMap.h"
@@ -167,33 +168,24 @@
 }
 
 sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider* proxyProvider,
-                                              const SkBitmap& bitmap) {
-    GrUniqueKey originalKey;
-
-    if (!bitmap.isVolatile()) {
-        SkIPoint origin = bitmap.pixelRefOrigin();
-        SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bitmap.width(), bitmap.height());
-        GrMakeKeyFromImageID(&originalKey, bitmap.pixelRef()->getGenerationID(), subset);
+                                              const SkBitmap& bitmap,
+                                              SkBackingFit fit) {
+    if (!bitmap.peekPixels(nullptr)) {
+        return nullptr;
     }
 
-    sk_sp<GrTextureProxy> proxy;
+    // In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap
+    // even if its mutable. In ddl, if the bitmap is mutable then we must make a copy since the
+    // upload of the data to the gpu can happen at anytime and the bitmap may change by then.
+    SkCopyPixelsMode cpyMode = proxyProvider->mutableBitmapsNeedCopy() ? kIfMutable_SkCopyPixelsMode
+                                                                       : kNever_SkCopyPixelsMode;
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, cpyMode);
 
-    if (originalKey.isValid()) {
-        proxy = proxyProvider->findOrCreateProxyByUniqueKey(originalKey, kTopLeft_GrSurfaceOrigin);
-    }
-    if (!proxy) {
-        // Pass nullptr for |dstColorSpace|.  This is lenient - we allow a wider range of
-        // color spaces in legacy mode.  Unfortunately, we have to be lenient here, since
-        // we can't necessarily know the |dstColorSpace| at this time.
-        proxy = GrUploadBitmapToTextureProxy(proxyProvider, bitmap, nullptr);
-        if (proxy && originalKey.isValid()) {
-            SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
-            proxyProvider->assignUniqueKeyToProxy(originalKey, proxy.get());
-            GrInstallBitmapUniqueKeyInvalidator(originalKey, bitmap.pixelRef());
-        }
+    if (!image) {
+        return nullptr;
     }
 
-    return proxy;
+    return GrMakeCachedImageProxy(proxyProvider, std::move(image), fit);
 }
 
 static void create_unique_key_for_image(const SkImage* image, GrUniqueKey* result) {
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index 86f584c..ea32210 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -228,18 +228,12 @@
                                                    int mipLevelCount,
                                                    SkDestinationSurfaceColorMode colorMode);
 
-// This is intended to replace:
-//    SkAutoLockPixels alp(bitmap, true);
-//    if (!bitmap.readyToDraw()) {
-//        return nullptr;
-//    }
-//    sk_sp<GrTexture> texture = GrMakeCachedBitmapTexture(fContext.get(), bitmap,
-//                                                         GrSamplerState::ClampNearest(),
-//                                                         nullptr);
-//    if (!texture) {
-//        return nullptr;
-//    }
-sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider*, const SkBitmap& bitmap);
+/*
+ * Create a texture proxy from the provided bitmap by wrapping it in an image and calling
+ * GrMakeCachedImageProxy.
+ */
+sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider*, const SkBitmap& bitmap,
+                                              SkBackingFit fit = SkBackingFit::kExact);
 
 /*
  * Create a texture proxy from the provided 'srcImage' and add it to the texture cache
diff --git a/src/shaders/SkPerlinNoiseShader.cpp b/src/shaders/SkPerlinNoiseShader.cpp
index 5979a9b..e43fe01 100644
--- a/src/shaders/SkPerlinNoiseShader.cpp
+++ b/src/shaders/SkPerlinNoiseShader.cpp
@@ -12,10 +12,10 @@
 #include "SkColorFilter.h"
 #include "SkMakeUnique.h"
 #include "SkReadBuffer.h"
-#include "SkWriteBuffer.h"
 #include "SkShader.h"
-#include "SkUnPreMultiply.h"
 #include "SkString.h"
+#include "SkUnPreMultiply.h"
+#include "SkWriteBuffer.h"
 
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
@@ -107,16 +107,19 @@
             }
 
     #if SK_SUPPORT_GPU
-            fPermutationsBitmap.setInfo(SkImageInfo::MakeA8(kBlockSize, 1));
-            fPermutationsBitmap.setPixels(fLatticeSelector);
+            SkImageInfo info = SkImageInfo::MakeA8(kBlockSize, 1);
+            SkPixmap permutationsPixmap(info, fLatticeSelector, info.minRowBytes());
+            fPermutationsImage = SkImage::MakeFromRaster(permutationsPixmap, nullptr, nullptr);
 
-            fNoiseBitmap.setInfo(SkImageInfo::MakeN32Premul(kBlockSize, 4));
-            fNoiseBitmap.setPixels(fNoise[0][0]);
+            info = SkImageInfo::MakeN32Premul(kBlockSize, 4);
+            SkPixmap noisePixmap(info, fNoise[0][0], info.minRowBytes());
+            fNoiseImage = SkImage::MakeFromRaster(noisePixmap, nullptr, nullptr);
 
-            fImprovedPermutationsBitmap.setInfo(SkImageInfo::MakeA8(256, 1));
-            fImprovedPermutationsBitmap.setPixels(improved_noise_permutations);
+            info = SkImageInfo::MakeA8(256, 1);
+            SkPixmap impPermutationsPixmap(info, improved_noise_permutations, info.minRowBytes());
+            fImprovedPermutationsImage = SkImage::MakeFromRaster(impPermutationsPixmap, nullptr,
+                                                                 nullptr);
 
-            fGradientBitmap.setInfo(SkImageInfo::MakeN32Premul(16, 1));
             static uint8_t gradients[] = { 2, 2, 1, 0,
                                            0, 2, 1, 0,
                                            2, 0, 1, 0,
@@ -133,7 +136,9 @@
                                            1, 0, 2, 0,
                                            0, 2, 1, 0,
                                            1, 0, 0, 0 };
-            fGradientBitmap.setPixels(gradients);
+            info = SkImageInfo::MakeN32Premul(16, 1);
+            SkPixmap gradPixmap(info, gradients, info.minRowBytes());
+            fGradientImage = SkImage::MakeFromRaster(gradPixmap, nullptr, nullptr);
     #endif
         }
 
@@ -143,10 +148,10 @@
                 , fTileSize(that.fTileSize)
                 , fBaseFrequency(that.fBaseFrequency)
                 , fStitchDataInit(that.fStitchDataInit)
-                , fPermutationsBitmap(that.fPermutationsBitmap)
-                , fNoiseBitmap(that.fNoiseBitmap)
-                , fImprovedPermutationsBitmap(that.fImprovedPermutationsBitmap)
-                , fGradientBitmap(that.fGradientBitmap) {
+                , fPermutationsImage(that.fPermutationsImage)
+                , fNoiseImage(that.fNoiseImage)
+                , fImprovedPermutationsImage(that.fImprovedPermutationsImage)
+                , fGradientImage(that.fGradientImage) {
             memcpy(fLatticeSelector, that.fLatticeSelector, sizeof(fLatticeSelector));
             memcpy(fNoise, that.fNoise, sizeof(fNoise));
             memcpy(fGradient, that.fGradient, sizeof(fGradient));
@@ -164,10 +169,10 @@
     private:
 
     #if SK_SUPPORT_GPU
-        SkBitmap   fPermutationsBitmap;
-        SkBitmap   fNoiseBitmap;
-        SkBitmap   fImprovedPermutationsBitmap;
-        SkBitmap   fGradientBitmap;
+        sk_sp<SkImage> fPermutationsImage;
+        sk_sp<SkImage> fNoiseImage;
+        sk_sp<SkImage> fImprovedPermutationsImage;
+        sk_sp<SkImage> fGradientImage;
     #endif
 
         inline int random()  {
@@ -294,13 +299,15 @@
     public:
 
 #if SK_SUPPORT_GPU
-        const SkBitmap& getPermutationsBitmap() const { return fPermutationsBitmap; }
+        const sk_sp<SkImage> getPermutationsImage() const { return fPermutationsImage; }
 
-        const SkBitmap& getNoiseBitmap() const { return fNoiseBitmap; }
+        const sk_sp<SkImage> getNoiseImage() const { return fNoiseImage; }
 
-        const SkBitmap& getImprovedPermutationsBitmap() const { return fImprovedPermutationsBitmap; }
+        const sk_sp<SkImage> getImprovedPermutationsImage() const {
+            return fImprovedPermutationsImage;
+        }
 
-        const SkBitmap& getGradientBitmap() const { return fGradientBitmap; }
+        const sk_sp<SkImage> getGradientImage() const { return fGradientImage; }
 #endif
     };
 
@@ -1409,17 +1416,20 @@
     m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1);
     m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1);
 
+    auto proxyProvider = args.fContext->contextPriv().proxyProvider();
     if (fType == kImprovedNoise_Type) {
-        GrSamplerState textureParams(GrSamplerState::WrapMode::kRepeat,
-                                     GrSamplerState::Filter::kNearest);
+        // Need to assert that the textures we'll create are power of 2 so a copy isn't needed.
+        // We also know that we will not be using mipmaps. If things things weren't true we should
+        // go through GrBitmapTextureMaker to handle needed copies.
+        const sk_sp<SkImage> permutationsImage = paintingData->getImprovedPermutationsImage();
+        SkASSERT(SkIsPow2(permutationsImage->width()) && SkIsPow2(permutationsImage->height()));
         sk_sp<GrTextureProxy> permutationsTexture(
-            GrRefCachedBitmapTextureProxy(args.fContext,
-                                          paintingData->getImprovedPermutationsBitmap(),
-                                          textureParams, nullptr));
+                GrMakeCachedImageProxy(proxyProvider, std::move(permutationsImage)));
+
+        const sk_sp<SkImage> gradientImage = paintingData->getGradientImage();
+        SkASSERT(SkIsPow2(gradientImage->width()) && SkIsPow2(gradientImage->height()));
         sk_sp<GrTextureProxy> gradientTexture(
-            GrRefCachedBitmapTextureProxy(args.fContext,
-                                          paintingData->getGradientBitmap(),
-                                          textureParams, nullptr));
+                GrMakeCachedImageProxy(proxyProvider, std::move(gradientImage)));
         return GrImprovedPerlinNoiseEffect::Make(fNumOctaves, fSeed, std::move(paintingData),
                                                  std::move(permutationsTexture),
                                                  std::move(gradientTexture), m);
@@ -1441,12 +1451,18 @@
                                            GrConstColorProcessor::InputMode::kIgnore);
     }
 
-    sk_sp<GrTextureProxy> permutationsProxy = GrMakeCachedBitmapProxy(
-                                                    args.fContext->contextPriv().proxyProvider(),
-                                                    paintingData->getPermutationsBitmap());
-    sk_sp<GrTextureProxy> noiseProxy = GrMakeCachedBitmapProxy(
-                                                    args.fContext->contextPriv().proxyProvider(),
-                                                    paintingData->getNoiseBitmap());
+    // Need to assert that the textures we'll create are power of 2 so that now copy is needed. We
+    // also know that we will not be using mipmaps. If things things weren't true we should go
+    // through GrBitmapTextureMaker to handle needed copies.
+    const sk_sp<SkImage> permutationsImage = paintingData->getPermutationsImage();
+    SkASSERT(SkIsPow2(permutationsImage->width()) && SkIsPow2(permutationsImage->height()));
+    sk_sp<GrTextureProxy> permutationsProxy = GrMakeCachedImageProxy(proxyProvider,
+                                                                     std::move(permutationsImage));
+
+    const sk_sp<SkImage> noiseImage = paintingData->getNoiseImage();
+    SkASSERT(SkIsPow2(noiseImage->width()) && SkIsPow2(noiseImage->height()));
+    sk_sp<GrTextureProxy> noiseProxy = GrMakeCachedImageProxy(proxyProvider,
+                                                              std::move(noiseImage));
 
     if (permutationsProxy && noiseProxy) {
         auto inner = GrPerlinNoise2Effect::Make(fType,