Revert "Defer mip-mapping until lazy proxy instantiation"

This reverts commit 475819cab73082c7ff33c3bf5c56b3871cdc1280.

Reason for revert: No, let's not defer.

Original change's description:
> Defer mip-mapping until lazy proxy instantiation
> 
> - Remove some checks for truly impossible failures (levelCount < 0)
> - Use helper method to predict number of mips, then verify correct
>   results in the lambda.
> - Split up SkMipMap::Build with a CanBuild helper, so GPU code can
>   predict success/failure accurately.
> - This is going to simplify the case where we need to change the
>   config for unsupported formats.
> 
> Bug: skia:8375
> Change-Id: Ied523ab55c38b8c8e7e2ae983744ed400497939b
> Reviewed-on: https://skia-review.googlesource.com/154080
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Robert Phillips <robertphillips@google.com>

TBR=bsalomon@google.com,robertphillips@google.com,brianosman@google.com,reed@google.com

Change-Id: I04dbc458103f7bb5a7c28da28b0256d7a2b8b3d3
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:8375
Reviewed-on: https://skia-review.googlesource.com/154304
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp
index adc1aae..7dbe319 100644
--- a/src/core/SkMipMap.cpp
+++ b/src/core/SkMipMap.cpp
@@ -312,168 +312,148 @@
     return SkTo<int32_t>(size);
 }
 
-struct SkMipMap::BuildParams {
-    typedef void (*FilterProc)(void*, const void* srcPtr, size_t srcRB, int count);
-    FilterProc fProc_1_2 = nullptr;
-    FilterProc fProc_1_3 = nullptr;
-    FilterProc fProc_2_1 = nullptr;
-    FilterProc fProc_2_2 = nullptr;
-    FilterProc fProc_2_3 = nullptr;
-    FilterProc fProc_3_1 = nullptr;
-    FilterProc fProc_3_2 = nullptr;
-    FilterProc fProc_3_3 = nullptr;
-
-    int    fCountLevels = 0;
-    size_t fSize = 0;
-    size_t fStorageSize = 0;
-};
-
-bool SkMipMap::CanBuild(const SkImageInfo& info, SkMipMap::BuildParams* outParams) {
-    BuildParams params;
-
-    const SkColorType ct = info.colorType();
-
-    switch (ct) {
-        case kRGBA_8888_SkColorType:
-        case kBGRA_8888_SkColorType:
-            params.fProc_1_2 = downsample_1_2<ColorTypeFilter_8888>;
-            params.fProc_1_3 = downsample_1_3<ColorTypeFilter_8888>;
-            params.fProc_2_1 = downsample_2_1<ColorTypeFilter_8888>;
-            params.fProc_2_2 = downsample_2_2<ColorTypeFilter_8888>;
-            params.fProc_2_3 = downsample_2_3<ColorTypeFilter_8888>;
-            params.fProc_3_1 = downsample_3_1<ColorTypeFilter_8888>;
-            params.fProc_3_2 = downsample_3_2<ColorTypeFilter_8888>;
-            params.fProc_3_3 = downsample_3_3<ColorTypeFilter_8888>;
-            break;
-        case kRGB_565_SkColorType:
-            params.fProc_1_2 = downsample_1_2<ColorTypeFilter_565>;
-            params.fProc_1_3 = downsample_1_3<ColorTypeFilter_565>;
-            params.fProc_2_1 = downsample_2_1<ColorTypeFilter_565>;
-            params.fProc_2_2 = downsample_2_2<ColorTypeFilter_565>;
-            params.fProc_2_3 = downsample_2_3<ColorTypeFilter_565>;
-            params.fProc_3_1 = downsample_3_1<ColorTypeFilter_565>;
-            params.fProc_3_2 = downsample_3_2<ColorTypeFilter_565>;
-            params.fProc_3_3 = downsample_3_3<ColorTypeFilter_565>;
-            break;
-        case kARGB_4444_SkColorType:
-            params.fProc_1_2 = downsample_1_2<ColorTypeFilter_4444>;
-            params.fProc_1_3 = downsample_1_3<ColorTypeFilter_4444>;
-            params.fProc_2_1 = downsample_2_1<ColorTypeFilter_4444>;
-            params.fProc_2_2 = downsample_2_2<ColorTypeFilter_4444>;
-            params.fProc_2_3 = downsample_2_3<ColorTypeFilter_4444>;
-            params.fProc_3_1 = downsample_3_1<ColorTypeFilter_4444>;
-            params.fProc_3_2 = downsample_3_2<ColorTypeFilter_4444>;
-            params.fProc_3_3 = downsample_3_3<ColorTypeFilter_4444>;
-            break;
-        case kAlpha_8_SkColorType:
-        case kGray_8_SkColorType:
-            params.fProc_1_2 = downsample_1_2<ColorTypeFilter_8>;
-            params.fProc_1_3 = downsample_1_3<ColorTypeFilter_8>;
-            params.fProc_2_1 = downsample_2_1<ColorTypeFilter_8>;
-            params.fProc_2_2 = downsample_2_2<ColorTypeFilter_8>;
-            params.fProc_2_3 = downsample_2_3<ColorTypeFilter_8>;
-            params.fProc_3_1 = downsample_3_1<ColorTypeFilter_8>;
-            params.fProc_3_2 = downsample_3_2<ColorTypeFilter_8>;
-            params.fProc_3_3 = downsample_3_3<ColorTypeFilter_8>;
-            break;
-        case kRGBA_F16_SkColorType:
-            params.fProc_1_2 = downsample_1_2<ColorTypeFilter_F16>;
-            params.fProc_1_3 = downsample_1_3<ColorTypeFilter_F16>;
-            params.fProc_2_1 = downsample_2_1<ColorTypeFilter_F16>;
-            params.fProc_2_2 = downsample_2_2<ColorTypeFilter_F16>;
-            params.fProc_2_3 = downsample_2_3<ColorTypeFilter_F16>;
-            params.fProc_3_1 = downsample_3_1<ColorTypeFilter_F16>;
-            params.fProc_3_2 = downsample_3_2<ColorTypeFilter_F16>;
-            params.fProc_3_3 = downsample_3_3<ColorTypeFilter_F16>;
-            break;
-        default:
-            return false;
-    }
-
-    if (info.width() <= 1 && info.height() <= 1) {
-        return false;
-    }
-    // whip through our loop to compute the exact size needed
-    params.fCountLevels = ComputeLevelCount(info.width(), info.height());
-    for (int currentMipLevel = params.fCountLevels; currentMipLevel >= 0; currentMipLevel--) {
-        SkISize mipSize = ComputeLevelSize(info.width(), info.height(), currentMipLevel);
-        params.fSize += SkColorTypeMinRowBytes(ct, mipSize.fWidth) * mipSize.fHeight;
-    }
-
-    params.fStorageSize = SkMipMap::AllocLevelsSize(params.fCountLevels, params.fSize);
-    if (0 == params.fStorageSize) {
-        return false;
-    }
-
-    if (outParams) {
-        *outParams = params;
-    }
-    return true;
-}
-
 SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) {
-    BuildParams params;
-    if (!CanBuild(src.info(), &params)) {
-        return nullptr;
-    }
+    typedef void FilterProc(void*, const void* srcPtr, size_t srcRB, int count);
+
+    FilterProc* proc_1_2 = nullptr;
+    FilterProc* proc_1_3 = nullptr;
+    FilterProc* proc_2_1 = nullptr;
+    FilterProc* proc_2_2 = nullptr;
+    FilterProc* proc_2_3 = nullptr;
+    FilterProc* proc_3_1 = nullptr;
+    FilterProc* proc_3_2 = nullptr;
+    FilterProc* proc_3_3 = nullptr;
 
     const SkColorType ct = src.colorType();
     const SkAlphaType at = src.alphaType();
 
+    switch (ct) {
+        case kRGBA_8888_SkColorType:
+        case kBGRA_8888_SkColorType:
+            proc_1_2 = downsample_1_2<ColorTypeFilter_8888>;
+            proc_1_3 = downsample_1_3<ColorTypeFilter_8888>;
+            proc_2_1 = downsample_2_1<ColorTypeFilter_8888>;
+            proc_2_2 = downsample_2_2<ColorTypeFilter_8888>;
+            proc_2_3 = downsample_2_3<ColorTypeFilter_8888>;
+            proc_3_1 = downsample_3_1<ColorTypeFilter_8888>;
+            proc_3_2 = downsample_3_2<ColorTypeFilter_8888>;
+            proc_3_3 = downsample_3_3<ColorTypeFilter_8888>;
+            break;
+        case kRGB_565_SkColorType:
+            proc_1_2 = downsample_1_2<ColorTypeFilter_565>;
+            proc_1_3 = downsample_1_3<ColorTypeFilter_565>;
+            proc_2_1 = downsample_2_1<ColorTypeFilter_565>;
+            proc_2_2 = downsample_2_2<ColorTypeFilter_565>;
+            proc_2_3 = downsample_2_3<ColorTypeFilter_565>;
+            proc_3_1 = downsample_3_1<ColorTypeFilter_565>;
+            proc_3_2 = downsample_3_2<ColorTypeFilter_565>;
+            proc_3_3 = downsample_3_3<ColorTypeFilter_565>;
+            break;
+        case kARGB_4444_SkColorType:
+            proc_1_2 = downsample_1_2<ColorTypeFilter_4444>;
+            proc_1_3 = downsample_1_3<ColorTypeFilter_4444>;
+            proc_2_1 = downsample_2_1<ColorTypeFilter_4444>;
+            proc_2_2 = downsample_2_2<ColorTypeFilter_4444>;
+            proc_2_3 = downsample_2_3<ColorTypeFilter_4444>;
+            proc_3_1 = downsample_3_1<ColorTypeFilter_4444>;
+            proc_3_2 = downsample_3_2<ColorTypeFilter_4444>;
+            proc_3_3 = downsample_3_3<ColorTypeFilter_4444>;
+            break;
+        case kAlpha_8_SkColorType:
+        case kGray_8_SkColorType:
+            proc_1_2 = downsample_1_2<ColorTypeFilter_8>;
+            proc_1_3 = downsample_1_3<ColorTypeFilter_8>;
+            proc_2_1 = downsample_2_1<ColorTypeFilter_8>;
+            proc_2_2 = downsample_2_2<ColorTypeFilter_8>;
+            proc_2_3 = downsample_2_3<ColorTypeFilter_8>;
+            proc_3_1 = downsample_3_1<ColorTypeFilter_8>;
+            proc_3_2 = downsample_3_2<ColorTypeFilter_8>;
+            proc_3_3 = downsample_3_3<ColorTypeFilter_8>;
+            break;
+        case kRGBA_F16_SkColorType:
+            proc_1_2 = downsample_1_2<ColorTypeFilter_F16>;
+            proc_1_3 = downsample_1_3<ColorTypeFilter_F16>;
+            proc_2_1 = downsample_2_1<ColorTypeFilter_F16>;
+            proc_2_2 = downsample_2_2<ColorTypeFilter_F16>;
+            proc_2_3 = downsample_2_3<ColorTypeFilter_F16>;
+            proc_3_1 = downsample_3_1<ColorTypeFilter_F16>;
+            proc_3_2 = downsample_3_2<ColorTypeFilter_F16>;
+            proc_3_3 = downsample_3_3<ColorTypeFilter_F16>;
+            break;
+        default:
+            return nullptr;
+    }
+
+    if (src.width() <= 1 && src.height() <= 1) {
+        return nullptr;
+    }
+    // whip through our loop to compute the exact size needed
+    size_t size = 0;
+    int countLevels = ComputeLevelCount(src.width(), src.height());
+    for (int currentMipLevel = countLevels; currentMipLevel >= 0; currentMipLevel--) {
+        SkISize mipSize = ComputeLevelSize(src.width(), src.height(), currentMipLevel);
+        size += SkColorTypeMinRowBytes(ct, mipSize.fWidth) * mipSize.fHeight;
+    }
+
+    size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size);
+    if (0 == storageSize) {
+        return nullptr;
+    }
+
     SkMipMap* mipmap;
     if (fact) {
-        SkDiscardableMemory* dm = fact(params.fStorageSize);
+        SkDiscardableMemory* dm = fact(storageSize);
         if (nullptr == dm) {
             return nullptr;
         }
-        mipmap = new SkMipMap(params.fStorageSize, dm);
+        mipmap = new SkMipMap(storageSize, dm);
     } else {
-        mipmap = new SkMipMap(sk_malloc_throw(params.fStorageSize), params.fStorageSize);
+        mipmap = new SkMipMap(sk_malloc_throw(storageSize), storageSize);
     }
 
     // init
     mipmap->fCS = sk_ref_sp(src.info().colorSpace());
-    mipmap->fCount = params.fCountLevels;
+    mipmap->fCount = countLevels;
     mipmap->fLevels = (Level*)mipmap->writable_data();
     SkASSERT(mipmap->fLevels);
 
     Level* levels = mipmap->fLevels;
-    uint8_t*    baseAddr = (uint8_t*)&levels[params.fCountLevels];
+    uint8_t*    baseAddr = (uint8_t*)&levels[countLevels];
     uint8_t*    addr = baseAddr;
     int         width = src.width();
     int         height = src.height();
     uint32_t    rowBytes;
     SkPixmap    srcPM(src);
 
-    for (int i = 0; i < params.fCountLevels; ++i) {
-        BuildParams::FilterProc proc;
+    for (int i = 0; i < countLevels; ++i) {
+        FilterProc* proc;
         if (height & 1) {
             if (height == 1) {        // src-height is 1
                 if (width & 1) {      // src-width is 3
-                    proc = params.fProc_3_1;
+                    proc = proc_3_1;
                 } else {              // src-width is 2
-                    proc = params.fProc_2_1;
+                    proc = proc_2_1;
                 }
             } else {                  // src-height is 3
                 if (width & 1) {
                     if (width == 1) { // src-width is 1
-                        proc = params.fProc_1_3;
+                        proc = proc_1_3;
                     } else {          // src-width is 3
-                        proc = params.fProc_3_3;
+                        proc = proc_3_3;
                     }
                 } else {              // src-width is 2
-                    proc = params.fProc_2_3;
+                    proc = proc_2_3;
                 }
             }
         } else {                      // src-height is 2
             if (width & 1) {
                 if (width == 1) {     // src-width is 1
-                    proc = params.fProc_1_2;
+                    proc = proc_1_2;
                 } else {              // src-width is 3
-                    proc = params.fProc_3_2;
+                    proc = proc_3_2;
                 }
             } else {                  // src-width is 2
-                proc = params.fProc_2_2;
+                proc = proc_2_2;
             }
         }
         width = SkTMax(1, width >> 1);
@@ -500,7 +480,7 @@
         srcPM = dstPM;
         addr += height * rowBytes;
     }
-    SkASSERT(addr == baseAddr + params.fSize);
+    SkASSERT(addr == baseAddr + size);
 
     SkASSERT(mipmap->fLevels);
     return mipmap;
diff --git a/src/core/SkMipMap.h b/src/core/SkMipMap.h
index d35439c..c6fc24d 100644
--- a/src/core/SkMipMap.h
+++ b/src/core/SkMipMap.h
@@ -29,10 +29,6 @@
  */
 class SkMipMap : public SkCachedData {
 public:
-    struct BuildParams;
-
-    static bool CanBuild(const SkImageInfo& info, BuildParams*);
-
     static SkMipMap* Build(const SkPixmap& src, SkDiscardableFactoryProc);
     static SkMipMap* Build(const SkBitmap& src, SkDiscardableFactoryProc);
 
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 77fc632..d09a1a2 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -279,7 +279,20 @@
         return nullptr;
     }
 
-    ATRACE_ANDROID_FRAMEWORK("Upload MipMap Texture [%ux%u]", bitmap.width(), bitmap.height());
+    SkPixmap pixmap;
+    if (!bitmap.peekPixels(&pixmap)) {
+        return nullptr;
+    }
+
+    ATRACE_ANDROID_FRAMEWORK("Upload MipMap Texture [%ux%u]", pixmap.width(), pixmap.height());
+    sk_sp<SkMipMap> mipmaps(SkMipMap::Build(pixmap, nullptr));
+    if (!mipmaps) {
+        return nullptr;
+    }
+
+    if (mipmaps->countLevels() < 0) {
+        return nullptr;
+    }
 
     // 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
@@ -287,39 +300,30 @@
     SkCopyPixelsMode copyMode = this->recordingDDL() ? kIfMutable_SkCopyPixelsMode
                                                      : kNever_SkCopyPixelsMode;
     sk_sp<SkImage> baseLevel = SkMakeImageFromRasterBitmap(bitmap, copyMode);
+
     if (!baseLevel) {
         return nullptr;
     }
 
-    // This was never going to have mips anyway
-    if (0 == SkMipMap::ComputeLevelCount(baseLevel->width(), baseLevel->height())) {
+    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info());
+
+    if (0 == mipmaps->countLevels()) {
         return this->createTextureProxy(baseLevel, kNone_GrSurfaceFlags, 1, SkBudgeted::kYes,
                                         SkBackingFit::kExact);
     }
 
-    if (!SkMipMap::CanBuild(bitmap.info(), nullptr)) {
-        return nullptr;
-    }
-
-    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info());
-
     sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
-            [desc, baseLevel](GrResourceProvider* resourceProvider) {
+            [desc, baseLevel, mipmaps](GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
                     return sk_sp<GrTexture>();
                 }
 
+                const int mipLevelCount = mipmaps->countLevels() + 1;
+                std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
+
                 SkPixmap pixmap;
                 SkAssertResult(baseLevel->peekPixels(&pixmap));
 
-                int mipLevelCount = 1;
-                sk_sp<SkMipMap> mipmaps(SkMipMap::Build(pixmap, nullptr));
-                if (mipmaps) {
-                    mipLevelCount += mipmaps->countLevels();
-                }
-
-                std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
-
                 // DDL TODO: Instead of copying all this info into GrMipLevels we should just plumb
                 // the use of SkMipMap down through Ganesh.
                 texels[0].fPixels = pixmap.addr();