Plumbing mipmaps to the point of creation.

When creating a DeferredTextureImage we may create mipmaps.
Those mipmaps need to then be passed along for when the texture is
actually created.

R=bsalomon@google.com
BUG=578304
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2031273002

Review-Url: https://codereview.chromium.org/2031273002
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index c9579b6..50a9f57 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -396,7 +396,7 @@
      *  to empty.
      */
     bool asLegacyBitmap(SkBitmap*, LegacyBitmapMode) const;
-    
+
     /**
      *  Returns true if the image is backed by an image-generator or other src that creates
      *  (and caches) its pixels / texture on-demand.
@@ -443,6 +443,10 @@
     SkImage(int width, int height, uint32_t uniqueID);
 
 private:
+    static sk_sp<SkImage> MakeTextureFromMipMap(GrContext*, const SkImageInfo&,
+                                                const GrMipLevel* texels, int mipLevelCount,
+                                                SkBudgeted);
+
     const int       fWidth;
     const int       fHeight;
     const uint32_t  fUniqueID;
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 2127c36..60736da 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -394,6 +394,14 @@
                                                           mipLevelCount);
 }
 
+GrTexture* GrUploadMipMapToTexture(GrContext* ctx, const SkImageInfo& info,
+                                   const GrMipLevel* texels, int mipLevelCount) {
+    const GrCaps* caps = ctx->caps();
+    return ctx->textureProvider()->createMipMappedTexture(GrImageInfoToSurfaceDesc(info, *caps),
+                                                          SkBudgeted::kYes, texels,
+                                                          mipLevelCount);
+}
+
 GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,
                                     const GrTextureParams& params) {
     if (bitmap.getTexture()) {
diff --git a/src/gpu/SkGrPriv.h b/src/gpu/SkGrPriv.h
index 46be3a5..ac21669 100644
--- a/src/gpu/SkGrPriv.h
+++ b/src/gpu/SkGrPriv.h
@@ -131,6 +131,12 @@
  */
 GrTexture* GrUploadPixmapToTexture(GrContext*, const SkPixmap&, SkBudgeted budgeted);
 
+/**
+ * Creates a new texture populated with the mipmap levels.
+ */
+GrTexture* GrUploadMipMapToTexture(GrContext*, const SkImageInfo&, const GrMipLevel* texels,
+                                   int mipLevelCount);
+
 //////////////////////////////////////////////////////////////////////////////
 
 GR_STATIC_ASSERT((int)kZero_GrBlendCoeff == (int)SkXfermode::kZero_Coeff);
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index 8bf1f24..1c1b311 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -499,3 +499,8 @@
     return MakeFromDeferredTextureImageData(ctx, data, budgeted).release();
 }
 #endif
+
+sk_sp<SkImage> MakeTextureFromMipMap(GrContext*, const SkImageInfo&, const GrMipLevel* texels,
+                                     int mipLevelCount, SkBudgeted) {
+    return nullptr;
+}
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index f67d7aa..a728c3d 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -468,3 +468,16 @@
     return dst;
 }
 
+sk_sp<SkImage> SkImage::MakeTextureFromMipMap(GrContext* ctx, const SkImageInfo& info,
+                                              const GrMipLevel* texels, int mipLevelCount,
+                                              SkBudgeted budgeted) {
+    if (!ctx) {
+        return nullptr;
+    }
+    SkAutoTUnref<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, mipLevelCount));
+    if (!texture) {
+        return nullptr;
+    }
+    return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNewImageUniqueID,
+                                   info.alphaType(), texture, budgeted);
+}