Revert "Revert "Restore GL_UNPACK_ROW_LENGTH to 0 between MIP levles""

This reverts commit abb5a315af45cdfc13fbe71265e8630041f8d845.

Two fixes:
  1) GMs pass valid rowBytes when calling directly to GrGpu.
  2) Check for non-null data before trying to set UNPACK_ROW_LENGTH

Bug: chromium:981254

Change-Id: I24e46b0d2b14562d6b84a29fefe3410ce5c06c94
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/226498
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/gm/asyncrescaleandread.cpp b/gm/asyncrescaleandread.cpp
index cc2abac..723212a 100644
--- a/gm/asyncrescaleandread.cpp
+++ b/gm/asyncrescaleandread.cpp
@@ -101,14 +101,14 @@
     GrBackendFormat format =
             gr->priv().caps()->getBackendFormatFromColorType(GrColorType::kAlpha_8);
     backendTextures[0] = gr->priv().getGpu()->createBackendTexture(
-            dstW, dstH, format, GrMipMapped::kNo, GrRenderable::kNo, yData.get(), 0, nullptr,
+            dstW, dstH, format, GrMipMapped::kNo, GrRenderable::kNo, yData.get(), dstW, nullptr,
             GrProtected::kNo);
     backendTextures[1] = gr->priv().getGpu()->createBackendTexture(
             dstW / 2, dstH / 2, format, GrMipMapped::kNo, GrRenderable::kNo,
-            uData.get(), 0, nullptr, GrProtected::kNo);
+            uData.get(), dstW / 2, nullptr, GrProtected::kNo);
     backendTextures[2] = gr->priv().getGpu()->createBackendTexture(
             dstW / 2, dstH / 2, format, GrMipMapped::kNo, GrRenderable::kNo,
-            vData.get(), 0, nullptr, GrProtected::kNo);
+            vData.get(), dstW / 2, nullptr, GrProtected::kNo);
     auto config = gr->priv().caps()->getConfigFromBackendFormat(format, GrColorType::kAlpha_8);
     SkColorChannel channel;
     if (config == kAlpha_8_as_Red_GrPixelConfig) {
diff --git a/gm/wacky_yuv_formats.cpp b/gm/wacky_yuv_formats.cpp
index 37b174c..d7c9682 100644
--- a/gm/wacky_yuv_formats.cpp
+++ b/gm/wacky_yuv_formats.cpp
@@ -917,11 +917,12 @@
 static void make_RG_88(const GrCaps* caps,
                        const SkBitmap& bm, YUVFormat yuvFormat,
                        SkAutoTMalloc<uint8_t>* pixels,
-                       GrBackendFormat* format) {
+                       GrBackendFormat* format, size_t* rowBytes) {
     SkASSERT(kNV12_YUVFormat == yuvFormat || kNV21_YUVFormat == yuvFormat);
     SkASSERT(kRGBA_8888_SkColorType == bm.colorType());     // uv stored in rg
 
-    pixels->reset(2 * sizeof(uint8_t) * bm.width() * bm.height());
+    *rowBytes = bm.width() * 2 * sizeof(uint8_t);
+    pixels->reset(*rowBytes * bm.height());
     uint8_t* currPixel = pixels->get();
     for (int y = 0; y < bm.height(); ++y) {
         for (int x = 0; x < bm.width(); ++x) {
@@ -940,12 +941,13 @@
 static void make_RG_1616(const GrCaps* caps,
                          const SkBitmap& bm, YUVFormat yuvFormat,
                          SkAutoTMalloc<uint8_t>* pixels,
-                         GrBackendFormat* format) {
+                         GrBackendFormat* format, size_t* rowBytes) {
     SkASSERT(kP016_YUVFormat == yuvFormat || kP010_YUVFormat == yuvFormat);
     SkASSERT(kRGBA_8888_SkColorType == bm.colorType());     // uv stored in rg
 
     uint16_t u16, v16;
-    pixels->reset(2 * sizeof(uint16_t) * bm.width() * bm.height());
+    *rowBytes = bm.width() * 2 * sizeof(uint16_t);
+    pixels->reset(*rowBytes * bm.height());
     uint16_t* currPixel = (uint16_t*) pixels->get();
     for (int y = 0; y < bm.height(); ++y) {
         for (int x = 0; x < bm.width(); ++x) {
@@ -974,12 +976,14 @@
                          const SkBitmap& bm,
                          YUVFormat yuvFormat,
                          SkAutoTMalloc<uint8_t>* pixels,
-                         GrBackendFormat* format) {
+                         GrBackendFormat* format,
+                         size_t* rowBytes) {
     SkASSERT(kY416_YUVFormat == yuvFormat);
     SkASSERT(kRGBA_8888_SkColorType == bm.colorType());
 
     uint16_t y16, u16, v16, a16;
-    pixels->reset(4 * sizeof(uint16_t) * bm.width() * bm.height());
+    *rowBytes = 4 * sizeof(uint16_t) * bm.width();
+    pixels->reset(*rowBytes * bm.height());
     uint16_t* currPixel = (uint16_t*) pixels->get();
     for (int y = 0; y < bm.height(); ++y) {
         for (int x = 0; x < bm.width(); ++x) {
@@ -1006,12 +1010,14 @@
                       const SkBitmap& bm,
                       YUVFormat yuvFormat,
                       SkAutoTMalloc<uint8_t>* pixels,
-                      GrBackendFormat* format) {
+                      GrBackendFormat* format,
+                      size_t* rowBytes) {
     SkASSERT(kP016_YUVFormat == yuvFormat || kP010_YUVFormat == yuvFormat);
     SkASSERT(kAlpha_8_SkColorType == bm.colorType());
 
     uint16_t y16;
-    pixels->reset(sizeof(uint16_t) * bm.width() * bm.height());
+    *rowBytes = sizeof(uint16_t) * bm.width();
+    pixels->reset(*rowBytes * bm.height());
     uint16_t* currPixel = (uint16_t*) pixels->get();
     for (int y = 0; y < bm.height(); ++y) {
         for (int x = 0; x < bm.width(); ++x) {
@@ -1052,24 +1058,25 @@
 
         SkAutoTMalloc<uint8_t> pixels;
         GrBackendFormat format;
+        size_t rowBytes;
 
         if (2 == channelCount) {
             if (format_uses_16_bpp(yuvFormat)) {
-                make_RG_1616(caps, bm, yuvFormat, &pixels, &format);
+                make_RG_1616(caps, bm, yuvFormat, &pixels, &format, &rowBytes);
             } else {
-                make_RG_88(caps, bm, yuvFormat, &pixels, &format);
+                make_RG_88(caps, bm, yuvFormat, &pixels, &format, &rowBytes);
             }
         } else {
             if (kRGBA_8888_SkColorType == bm.colorType()) {
-                make_RGBA_16(caps, bm, yuvFormat, &pixels, &format);
+                make_RGBA_16(caps, bm, yuvFormat, &pixels, &format, &rowBytes);
             } else {
-                make_R_16(caps, bm, yuvFormat, &pixels, &format);
+                make_R_16(caps, bm, yuvFormat, &pixels, &format, &rowBytes);
             }
         }
 
         tex = gpu->createBackendTexture(bm.width(), bm.height(), format,
                                         GrMipMapped::kNo, GrRenderable::kNo,
-                                        pixels, 0, nullptr, GrProtected::kNo);
+                                        pixels, rowBytes, nullptr, GrProtected::kNo);
     } else {
         tex = context->priv().createBackendTexture(&bm.pixmap(), 1,
                                                    GrRenderable::kNo, GrProtected::kNo);
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 72425aa..ad94098 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -113,7 +113,6 @@
         fWritePixelsRowBytesSupport = version >= GR_GL_VER(2, 0);
         fReadPixelsRowBytesSupport = version >= GR_GL_VER(2, 0);
     }
-
     if (fDriverBugWorkarounds.pack_parameters_workaround_with_pack_buffer) {
         // In some cases drivers handle copying the last row incorrectly
         // when using GL_PACK_ROW_LENGTH.  Chromium handles this by iterating
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index cad7f79..621f16f 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1010,7 +1010,7 @@
                                           int mipLevelCount,
                                           int baseWidth,
                                           int baseHeight,
-                                          bool* changedUpackRowLength) {
+                                          bool* changedUnpackRowLength) {
     CLEAR_ERROR_BEFORE_ALLOC(&interface);
 
     if (caps.configSupportsTexStorage(config)) {
@@ -1031,13 +1031,20 @@
                 int twoToTheMipLevel = 1 << currentMipLevel;
                 const int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
                 const int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
-                const size_t trimRowBytes = currentWidth * bpp;
-                const size_t rowBytes = texels[currentMipLevel].fRowBytes;
 
-                if (caps.writePixelsRowBytesSupport() && rowBytes != trimRowBytes) {
-                    GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
-                    GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength));
-                    *changedUpackRowLength = true;
+                if (texels[currentMipLevel].fPixels) {
+                    const size_t trimRowBytes = currentWidth * bpp;
+                    const size_t rowBytes = texels[currentMipLevel].fRowBytes;
+                    if (rowBytes != trimRowBytes) {
+                        SkASSERT(caps.writePixelsRowBytesSupport());
+                        GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
+                        GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength));
+                        *changedUnpackRowLength = true;
+                    } else if (*changedUnpackRowLength) {
+                        SkASSERT(caps.writePixelsRowBytesSupport());
+                        GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
+                        *changedUnpackRowLength = false;
+                    }
                 }
 
                 GR_GL_CALL(&interface,
@@ -1073,13 +1080,20 @@
                 int twoToTheMipLevel = 1 << currentMipLevel;
                 const int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
                 const int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
-                const size_t trimRowBytes = currentWidth * bpp;
-                const size_t rowBytes = texels[currentMipLevel].fRowBytes;
 
-                if (caps.writePixelsRowBytesSupport() && rowBytes != trimRowBytes) {
-                    GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
-                    GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength));
-                    *changedUpackRowLength = true;
+                if (texels[currentMipLevel].fPixels) {
+                    const size_t trimRowBytes = currentWidth * bpp;
+                    const size_t rowBytes = texels[currentMipLevel].fRowBytes;
+                    if (rowBytes != trimRowBytes) {
+                        SkASSERT(caps.writePixelsRowBytesSupport());
+                        GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
+                        GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength));
+                        *changedUnpackRowLength = true;
+                    } else if (*changedUnpackRowLength) {
+                        SkASSERT(caps.writePixelsRowBytesSupport());
+                        GR_GL_CALL(&interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
+                        *changedUnpackRowLength = false;
+                    }
                 }
 
                 const void* currentMipData = texels[currentMipLevel].fPixels;