[M63 cherrypick] Do not always allocate temp space in GrGLGpu::uploadTexData

The always allocate behavior (which is being changed here) was introduced in:

https://codereview.chromium.org/1249543003/ (Creating functions for uploading a mipmapped texture)

I have also created skbug.com/7258 (Improve GrGLGpu::uploadTexData memory behavior) to drive future improvments.

No-Tree-Checks: true
No-Try: true
No-Presubmit: true
Bug: 780766
Change-Id: I201f4f9117fb09eb235bbf41ffd57ac42badba67
Reviewed-on: https://skia-review.googlesource.com/70101
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index bef1f19..d7a49f2 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1081,8 +1081,11 @@
         *wasFullMipMapDataProvided = true;
     }
 
+    const bool usesMips = mipLevelCount > 1;
+
     // find the combined size of all the mip levels and the relative offset of
     // each into the collective buffer
+    bool willNeedData = false;
     size_t combinedBufferSize = 0;
     SkTArray<size_t> individualMipOffsets(mipLevelCount);
     for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
@@ -1090,7 +1093,19 @@
             int twoToTheMipLevel = 1 << currentMipLevel;
             int currentWidth = SkTMax(1, width / twoToTheMipLevel);
             int currentHeight = SkTMax(1, height / twoToTheMipLevel);
-            const size_t trimmedSize = currentWidth * bpp * currentHeight;
+            const size_t trimRowBytes = currentWidth * bpp;
+            const size_t trimmedSize = trimRowBytes * currentHeight;
+
+            const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes
+                    ? texelsShallowCopy[currentMipLevel].fRowBytes
+                    : trimRowBytes;
+
+
+            if (((!caps.unpackRowLengthSupport() || usesMips) && trimRowBytes != rowBytes) ||
+                swFlipY) {
+                willNeedData = true;
+            }
+
             individualMipOffsets.push_back(combinedBufferSize);
             combinedBufferSize += trimmedSize;
         } else {
@@ -1101,7 +1116,10 @@
         }
 
     }
-    char* buffer = (char*)tempStorage.reset(combinedBufferSize);
+    char* buffer = nullptr;
+    if (willNeedData) {
+        buffer = (char*)tempStorage.reset(combinedBufferSize);
+    }
 
     for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
         if (!texelsShallowCopy[currentMipLevel].fPixels) {
@@ -1127,7 +1145,6 @@
         // TODO: This optimization should be enabled with or without mips.
         // For use with mips, we must set GR_GL_UNPACK_ROW_LENGTH once per
         // mip level, before calling glTexImage2D.
-        const bool usesMips = mipLevelCount > 1;
         if (caps.unpackRowLengthSupport() && !swFlipY && !usesMips) {
             // can't use this for flipping, only non-neg values allowed. :(
             if (rowBytes != trimRowBytes) {