Reland "Make GrDirectContext::updateBackendTexture handle pixmaps with non-type row bytes."

This is a reland of 07d8c0d11cae593c46b2fbc0507b8c07cff9000f

Original change's description:
> Make GrDirectContext::updateBackendTexture handle pixmaps with non-type row bytes.
>
> Some GL contexts don't support GL_UNPACK_ROW_LENGTH and we must
> copy the src data to a pixmap with tight row bytes.
>
> Bug: chromium:1170392
>
> Change-Id: I4590f20dbc80cb792f30f0059536716cf106f6c3
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/361717
> Reviewed-by: Robert Phillips <robertphillips@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>

Bug: chromium:1170392
Change-Id: I6fb759c35f86d816b16694b00edaa1116a446d15
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/363099
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrDirectContext.cpp b/src/gpu/GrDirectContext.cpp
index ab5c6cf..6e393e7 100644
--- a/src/gpu/GrDirectContext.cpp
+++ b/src/gpu/GrDirectContext.cpp
@@ -505,26 +505,34 @@
                                         const GrBackendTexture& backendTexture,
                                         GrSurfaceOrigin textureOrigin,
                                         sk_sp<GrRefCntedCallback> finishedCallback) {
+    bool flip = textureOrigin == kBottomLeft_GrSurfaceOrigin;
+    bool mustBeTight = !gpu->caps()->writePixelsRowBytesSupport();
+
+    size_t size = 0;
+    for (int i = 0; i < numLevels; ++i) {
+        size_t minRowBytes = srcData[i].info().minRowBytes();
+        if (flip || (mustBeTight && srcData[i].rowBytes() != minRowBytes)) {
+            size += minRowBytes * srcData[i].height();
+        }
+    }
+
     std::unique_ptr<char[]> tempStorage;
-    SkAutoSTArray<15, GrPixmap> tempPixmaps(numLevels);
-    if (textureOrigin == kBottomLeft_GrSurfaceOrigin) {
-        size_t size = 0;
-        for (int i = 0; i < numLevels; ++i) {
-            size += srcData[i].info().minRowBytes()*srcData[i].height();
-        }
+    if (size) {
         tempStorage.reset(new char[size]);
-        size = 0;
-        for (int i = 0; i < numLevels; ++i) {
-            size_t tempRB = srcData[i].info().minRowBytes();
-            tempPixmaps[i] = {srcData[i].info(), tempStorage.get() + size, tempRB};
-            SkAssertResult(GrConvertPixels(tempPixmaps[i], srcData[i], /*flip*/ true));
-            size += tempRB*srcData[i].height();
-        }
-    } else {
-        for (int i = 0; i < numLevels; ++i) {
+    }
+    size = 0;
+    SkAutoSTArray<15, GrPixmap> tempPixmaps(numLevels);
+    for (int i = 0; i < numLevels; ++i) {
+        size_t minRowBytes = srcData[i].info().minRowBytes();
+        if (flip || (mustBeTight && srcData[i].rowBytes() != minRowBytes)) {
+            tempPixmaps[i] = {srcData[i].info(), tempStorage.get() + size, minRowBytes};
+            SkAssertResult(GrConvertPixels(tempPixmaps[i], srcData[i], flip));
+            size += minRowBytes*srcData[i].height();
+        } else {
             tempPixmaps[i] = srcData[i];
         }
     }
+
     GrGpu::BackendTextureData data(tempPixmaps.get());
     return gpu->updateBackendTexture(backendTexture, std::move(finishedCallback), &data);
 }