Re-arrange GrResourceProvider's texture creation methods

This is all in service of removing the last raw writeSurfacePixels (that we can do anything about)

Change-Id: Ic84f677b2440b20e5fcc23e787584db0cfaecd01
Reviewed-on: https://skia-review.googlesource.com/13584
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index d2ec204..6299264 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -22,6 +22,7 @@
 #include "GrSurfaceProxyPriv.h"
 #include "GrTexturePriv.h"
 #include "../private/GrSingleOwner.h"
+#include "SkGr.h"
 #include "SkMathPriv.h"
 
 GR_DECLARE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
@@ -54,7 +55,6 @@
                                                       SkBudgeted budgeted,
                                                       const GrMipLevel* texels,
                                                       int mipLevelCount,
-                                                      uint32_t flags,
                                                       SkDestinationSurfaceColorMode mipColorMode) {
     ASSERT_SINGLE_OWNER
 
@@ -63,17 +63,17 @@
             return nullptr;
         }
         return GrSurfaceProxy::MakeDeferred(this, desc, budgeted, nullptr, 0);
+    } else if (1 == mipLevelCount) {
+        if (!texels) {
+            return nullptr;
+        }
+        return this->createTextureProxy(desc, budgeted, texels[0]);
     }
 
     if (this->isAbandoned()) {
         return nullptr;
     }
 
-    for (int i = 0; i < mipLevelCount; ++i) {
-        if (!texels[i].fPixels) {
-            return nullptr;
-        }
-    }
     if (mipLevelCount > 1 && GrPixelConfigIsSint(desc.fConfig)) {
         return nullptr;
     }
@@ -81,28 +81,13 @@
         !fGpu->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
         return nullptr;
     }
-    if (!GrPixelConfigIsCompressed(desc.fConfig)) {
-        if (mipLevelCount < 2) {
-            flags |= kExact_Flag | kNoCreate_Flag;
-            sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags));
-            if (tex) {
-                sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(tex);
-
-                if (fGpu->getContext()->contextPriv().writeSurfacePixels(
-                                proxy.get(), nullptr, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
-                                nullptr, texels[0].fPixels, texels[0].fRowBytes)) {
-                    if (SkBudgeted::kNo == budgeted) {
-                        tex->resourcePriv().makeUnbudgeted();
-                    }
-                    tex->texturePriv().setMipColorMode(mipColorMode);
-                    return proxy;
-                }
-            }
-        }
-    }
 
     SkTArray<GrMipLevel> texelsShallowCopy(mipLevelCount);
     for (int i = 0; i < mipLevelCount; ++i) {
+        if (!texels[i].fPixels) {
+            return nullptr;
+        }
+
         texelsShallowCopy.push_back(texels[i]);
     }
     sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texelsShallowCopy));
@@ -113,6 +98,60 @@
     return GrSurfaceProxy::MakeWrapped(std::move(tex));
 }
 
+sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc,
+                                                     SkBudgeted budgeted, uint32_t flags) {
+
+    flags |= kExact_Flag | kNoCreate_Flag;
+    sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags));
+    if (tex && SkBudgeted::kNo == budgeted) {
+        tex->resourcePriv().makeUnbudgeted();
+    }
+
+    return tex;
+}
+
+static bool make_info(int w, int h, GrPixelConfig config, SkImageInfo* ii) {
+    SkColorType colorType;
+    if (!GrPixelConfigToColorType(config, &colorType)) {
+        return false;
+    }
+
+    *ii = SkImageInfo::Make(w, h, colorType, kUnknown_SkAlphaType, nullptr);
+    return true;
+}
+
+sk_sp<GrTextureProxy> GrResourceProvider::createTextureProxy(const GrSurfaceDesc& desc,
+                                                             SkBudgeted budgeted,
+                                                             const GrMipLevel& mipLevel) {
+    if (!mipLevel.fPixels) {
+        return nullptr;
+    }
+
+    GrContext* context = fGpu->getContext();
+
+    if (!GrPixelConfigIsCompressed(desc.fConfig)) {
+        SkImageInfo srcInfo;
+
+        if (make_info(desc.fWidth, desc.fHeight, desc.fConfig, &srcInfo)) {
+            sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, 0);
+            sk_sp<GrSurfaceContext> sContext =
+                                context->contextPriv().makeWrappedSurfaceContext(std::move(tex));
+            if (sContext) {
+                if (sContext->writePixels(srcInfo, mipLevel.fPixels, mipLevel.fRowBytes, 0, 0)) {
+                    return sContext->asTextureProxyRef();
+                }
+            }
+        }
+    }
+
+    SkTArray<GrMipLevel> texels(1);
+    texels.push_back(mipLevel);
+
+    sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texels));
+    return GrSurfaceProxy::MakeWrapped(std::move(tex));
+}
+
+
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
                                                    uint32_t flags) {
     ASSERT_SINGLE_OWNER
@@ -127,12 +166,8 @@
     }
 
     if (!GrPixelConfigIsCompressed(desc.fConfig)) {
-        flags |= kExact_Flag | kNoCreate_Flag;
-        sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags));
+        sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, flags);
         if (tex) {
-            if (SkBudgeted::kNo == budgeted) {
-                tex->resourcePriv().makeUnbudgeted();
-            }
             return tex;
         }
     }