Add srcData version of createBackendTexture API

Change-Id: I9679774d69e087a4ceb24de78e98585382bf8593
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/218553
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrContextPriv.cpp b/src/gpu/GrContextPriv.cpp
index 093acbf..174de02 100644
--- a/src/gpu/GrContextPriv.cpp
+++ b/src/gpu/GrContextPriv.cpp
@@ -367,3 +367,60 @@
 
     return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToPremul);
 }
+
+//////////////////////////////////////////////////////////////////////////////
+
+#include "src/core/SkMipMap.h"
+
+GrBackendTexture GrContextPriv::createBackendTexture(const SkPixmap srcData[], int numLevels,
+                                                     GrRenderable renderable) {
+    if (!fContext->asDirectContext()) {
+        return {};
+    }
+
+    if (this->abandoned()) {
+        return {};
+    }
+
+    if (!srcData || !numLevels) {
+        return {};
+    }
+
+    int baseWidth = srcData[0].width();
+    int baseHeight = srcData[0].height();
+    SkColorType colorType = srcData[0].colorType();
+
+    if (numLevels > 1) {
+        if (numLevels != SkMipMap::ComputeLevelCount(baseWidth, baseHeight) + 1) {
+            return {};
+        }
+
+        int currentWidth = baseWidth;
+        int currentHeight = baseHeight;
+        for (int i = 1; i < numLevels; ++i) {
+            currentWidth = SkTMax(1, currentWidth / 2);
+            currentHeight = SkTMax(1, currentHeight / 2);
+
+            if (srcData[i].colorType() != colorType) {
+                return {};
+            }
+
+            if (srcData[i].width() != currentWidth || srcData[i].height() != currentHeight) {
+                return {};
+            }
+        }
+    }
+
+    GrBackendFormat backendFormat = this->caps()->getBackendFormatFromColorType(colorType);
+    if (!backendFormat.isValid()) {
+        return {};
+    }
+
+    GrGpu* gpu = fContext->fGpu.get();
+
+    // TODO: propagate the array of pixmaps interface to GrGpu
+    return gpu->createBackendTexture(baseWidth, baseHeight, backendFormat,
+                                     GrMipMapped::kNo, // TODO: use real mipmap setting here
+                                     renderable, srcData[0].addr(), srcData[0].rowBytes(),
+                                     nullptr);
+}
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index 700a50a..6e261e3 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -253,6 +253,14 @@
     void testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject*);
 #endif
 
+    // If possible, create a backend texture initialized with the provided pixmap data. The client
+    // should ensure that the returned backend texture is valid.
+    // If successful, the created backend texture will be compatible with the provided
+    // pixmap(s).
+    // If numLevels is 1 a non-mipMapped texture will result. If a mipMapped texture is desired
+    // the data for all the mipmap levels must be provided.
+    GrBackendTexture createBackendTexture(const SkPixmap srcData[], int numLevels, GrRenderable);
+
 private:
     explicit GrContextPriv(GrContext* context) : fContext(context) {}
     GrContextPriv(const GrContextPriv&); // unimpl
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 7efd5cc..caa17d3 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -450,20 +450,6 @@
 void GrGpu::dumpJSON(SkJSONWriter* writer) const { }
 #endif
 
-GrBackendTexture GrGpu::createTestingOnlyBackendTexture(int w, int h, SkColorType colorType,
-                                                        GrMipMapped mipMapped,
-                                                        GrRenderable renderable,
-                                                        const void* pixels, size_t rowBytes,
-                                                        const SkColor4f* color) {
-    GrBackendFormat format = this->caps()->getBackendFormatFromColorType(colorType);
-    if (!format.isValid()) {
-        return GrBackendTexture();
-    }
-
-    return this->createBackendTexture(w, h, format, mipMapped, renderable,
-                                      pixels, rowBytes, color);
-}
-
 #if GR_TEST_UTILS
 
 #if GR_GPU_STATS
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index ac3b687..025273d 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -378,13 +378,6 @@
     Stats* stats() { return &fStats; }
     void dumpJSON(SkJSONWriter*) const;
 
-    // TODO: remove this method
-    GrBackendTexture createTestingOnlyBackendTexture(int w, int h, SkColorType,
-                                                     GrMipMapped, GrRenderable,
-                                                     const void* pixels,
-                                                     size_t rowBytes,
-                                                     const SkColor4f* color);
-
     /**
      * Creates a texture directly in the backend API without wrapping it in a GrTexture.
      * Must be matched with a call to deleteBackendTexture().