Clean update ETC1 data utilities (take 2)

Change-Id: Idb84867cf1a701bd2f0ffff863fd78c3caf0739e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/217376
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrDataUtils.cpp b/src/gpu/GrDataUtils.cpp
index 4815714..b03a79a 100644
--- a/src/gpu/GrDataUtils.cpp
+++ b/src/gpu/GrDataUtils.cpp
@@ -10,6 +10,11 @@
 #include "include/private/GrColor.h"
 #include "src/core/SkUtils.h"
 
+struct ETC1Block {
+    uint32_t fHigh;
+    uint32_t fLow;
+};
+
 static const int kNumModifierTables = 8;
 static const int kNumPixelIndices = 4;
 
@@ -88,7 +93,7 @@
     }
 }
 
-int GrNumETC1Blocks(int w, int h) {
+static int num_ETC1_blocks(int w, int h) {
     if (w < 4) {
         w = 1;
     } else {
@@ -106,12 +111,20 @@
     return w * h;
 }
 
-void GrFillInETC1WithColor(const SkColor4f& colorf, void* dest, int numBlocks) {
+size_t GrETC1CompressedDataSize(int width, int height) {
+    int numBlocks = num_ETC1_blocks(width, height);
+
+    return numBlocks * sizeof(ETC1Block);
+}
+
+void GrFillInETC1WithColor(int width, int height, const SkColor4f& colorf, void* dest) {
     SkColor color = colorf.toSkColor();
 
     ETC1Block block;
     create_etc1_block(color, &block);
 
+    int numBlocks = num_ETC1_blocks(width, height);
+
     for (int i = 0; i < numBlocks; ++i) {
         ((ETC1Block*)dest)[i] = block;
     }
diff --git a/src/gpu/GrDataUtils.h b/src/gpu/GrDataUtils.h
index a3e0e34..bdcbd66 100644
--- a/src/gpu/GrDataUtils.h
+++ b/src/gpu/GrDataUtils.h
@@ -15,14 +15,11 @@
 bool GrFillBufferWithColor(GrPixelConfig config, int width, int height,
                            const SkColor4f& color, void* dest);
 
-struct ETC1Block {
-    uint32_t fHigh;
-    uint32_t fLow;
-};
+// TODO: consolidate all the backend-specific flavors of this method to this
+size_t GrETC1CompressedDataSize(int w, int h);
 
-int GrNumETC1Blocks(int w, int h);
-
-// Fill in 'blocks' with ETC1 blocks derived from 'color'
-void GrFillInETC1WithColor(const SkColor4f& color, void* blocks, int numBlocks);
+// Fill in 'dest' with ETC1 blocks derived from 'color'
+void GrFillInETC1WithColor(int width, int height,
+                           const SkColor4f& color, void* dest);
 
 #endif
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index a9a8615..2a9b0f4 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1097,7 +1097,7 @@
                                                      const GrMipLevel texels[], int mipLevelCount,
                                                      int baseWidth, int baseHeight) {
     CLEAR_ERROR_BEFORE_ALLOC(&interface);
-    SkASSERT(GrPixelConfigIsCompressed(config));
+    SkASSERT(GrGLFormatIsCompressed(internalFormat));
 
     bool useTexStorage = caps.isConfigTexSupportEnabled(config);
     // We can only use TexStorage if we know we will not later change the storage requirements.
@@ -1131,7 +1131,8 @@
 
                 // Make sure that the width and height that we pass to OpenGL
                 // is a multiple of the block size.
-                size_t dataSize = GrCompressedFormatDataSize(config, currentWidth, currentHeight);
+                size_t dataSize = GrGLFormatCompressedDataSize(internalFormat,
+                                                               currentWidth, currentHeight);
                 GR_GL_CALL(&interface, CompressedTexSubImage2D(target,
                                                                currentMipLevel,
                                                                0, // left
@@ -1157,7 +1158,7 @@
 
             // Make sure that the width and height that we pass to OpenGL
             // is a multiple of the block size.
-            size_t dataSize = GrCompressedFormatDataSize(config, baseWidth, baseHeight);
+            size_t dataSize = GrGLFormatCompressedDataSize(internalFormat, baseWidth, baseHeight);
 
             GL_ALLOC_CALL(&interface,
                           CompressedTexImage2D(target,
@@ -1609,7 +1610,8 @@
         case GR_GL_RGBA32F:
             return 16;
 
-        case GR_GL_COMPRESSED_RGB8_ETC2:
+        case GR_GL_COMPRESSED_RGB8_ETC2: // fall through
+        case GR_GL_COMPRESSED_ETC1_RGB8:
             return 0;
     }
 
@@ -1630,7 +1632,7 @@
     GrGLenum glFormat = this->glCaps().configSizedInternalFormat(desc.fConfig);
 
     bool performClear = (desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
-                        !GrPixelConfigIsCompressed(desc.fConfig);
+                        !GrGLFormatIsCompressed(glFormat);
 
     GrMipLevel zeroLevel;
     std::unique_ptr<uint8_t[]> zeros;
@@ -1851,6 +1853,8 @@
         return false;
     }
 
+    info->fFormat = this->glCaps().configSizedInternalFormat(desc.fConfig);
+
     this->bindTextureToScratchUnit(info->fTarget, info->fID);
 
     if (GrRenderable::kYes == renderable && this->glCaps().textureUsageSupport()) {
@@ -1863,7 +1867,7 @@
     *initialTexParams = set_initial_texture_params(this->glInterface(), *info);
 
     bool success = false;
-    if (GrPixelConfigIsCompressed(desc.fConfig)) {
+    if (GrGLFormatIsCompressed(info->fFormat)) {
         SkASSERT(GrRenderable::kNo == renderable);
 
         success = this->uploadCompressedTexData(desc.fConfig, desc.fWidth, desc.fHeight,
@@ -1878,7 +1882,6 @@
         GL_CALL(DeleteTextures(1, &(info->fID)));
         return false;
     }
-    info->fFormat = this->glCaps().configSizedInternalFormat(desc.fConfig);
     return true;
 }
 
@@ -4042,7 +4045,8 @@
         case GR_GL_RGBA16F:
             *config = kRGBA_half_GrPixelConfig;
             return true;
-        case GR_GL_COMPRESSED_RGB8_ETC2:
+        case GR_GL_COMPRESSED_RGB8_ETC2: // fall through
+        case GR_GL_COMPRESSED_ETC1_RGB8:
             *config = kRGB_ETC1_GrPixelConfig;
             return true;
         case GR_GL_R16F:
@@ -4099,14 +4103,14 @@
 
     SkAutoMalloc pixelStorage;
 
-    if (GrPixelConfigIsCompressed(config)) {
+    if (GrGLFormatIsCompressed(*glFormat)) {
         // we have to do something special for compressed textures
         SkASSERT(0 == rowBytes);
 
         if (!pixels) {
-            int numBlocks = GrNumETC1Blocks(w, h);
-            pixelStorage.reset(numBlocks * sizeof(ETC1Block));
-            GrFillInETC1WithColor(colorf, pixelStorage.get(), numBlocks);
+            size_t etc1Size = GrGLFormatCompressedDataSize(*glFormat, w, h);
+            pixelStorage.reset(etc1Size);
+            GrFillInETC1WithColor(w, h, colorf, pixelStorage.get());
             pixels = pixelStorage.get();
             rowBytes = 0;
         }
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 9989cff..2c67f70 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -8,6 +8,7 @@
 
 #include "include/core/SkMatrix.h"
 #include "include/private/GrTypesPriv.h"
+#include "src/gpu/GrDataUtils.h"
 #include "src/gpu/gl/GrGLUtil.h"
 #include <stdio.h>
 
@@ -559,3 +560,32 @@
 
     return gTable[(int)test];
 }
+
+bool GrGLFormatIsCompressed(GrGLenum glFormat) {
+    switch (glFormat) {
+        case GR_GL_COMPRESSED_RGB8_ETC2: // fall through
+        case GR_GL_COMPRESSED_ETC1_RGB8:
+            return true;
+        default:
+            return false;
+    }
+    SK_ABORT("Invalid format");
+    return false;
+}
+
+size_t GrGLFormatCompressedDataSize(GrGLenum glFormat, int width, int height) {
+    SkASSERT(GrGLFormatIsCompressed(glFormat));
+
+    switch (glFormat) {
+        case GR_GL_COMPRESSED_RGB8_ETC2:  // fall through
+        case GR_GL_COMPRESSED_ETC1_RGB8:
+            return GrETC1CompressedDataSize(width, height);
+        default:
+            SK_ABORT("Unknown compressed format");
+            return 4 * width * height;
+    }
+
+    SK_ABORT("Unknown compressed format");
+    return 4 * width * height;
+}
+
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index dd25823..d820b9d 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -259,4 +259,14 @@
 
 GrGLenum GrToGLStencilFunc(GrStencilTest test);
 
+/**
+ * Returns true if the format is compressed.
+ */
+bool GrGLFormatIsCompressed(GrGLenum glFormat);
+
+/**
+ * Returns the data size for the given compressed format
+ */
+size_t GrGLFormatCompressedDataSize(GrGLenum glFormat, int width, int height);
+
 #endif
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp
index 98136ec..7d3ee65 100644
--- a/src/gpu/vk/GrVkUtil.cpp
+++ b/src/gpu/vk/GrVkUtil.cpp
@@ -8,6 +8,7 @@
 #include "src/gpu/vk/GrVkUtil.h"
 
 #include "src/gpu/GrContextPriv.h"
+#include "src/gpu/GrDataUtils.h"
 #include "src/gpu/vk/GrVkGpu.h"
 #include "src/sksl/SkSLCompiler.h"
 
@@ -309,28 +310,18 @@
     return false;
 }
 
-size_t GrVkFormatCompressedDataSize(VkFormat format, int width, int height) {
-    SkASSERT(GrVkFormatIsCompressed(format));
+size_t GrVkFormatCompressedDataSize(VkFormat vkFormat, int width, int height) {
+    SkASSERT(GrVkFormatIsCompressed(vkFormat));
 
-    switch (format) {
+    switch (vkFormat) {
         case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
-            if (width < 4) {
-                SkASSERT(width == 1 || width == 2);
-                width = 4;
-            }
-            if (height < 4) {
-                SkASSERT(height == 1 || height == 2);
-                height = 4;
-            }
-            SkASSERT((width & 3) == 0);
-            SkASSERT((height & 3) == 0);
-            return (width >> 2) * (height >> 2) * 8;
+            return GrETC1CompressedDataSize(width, height);
         default:
             SK_ABORT("Unknown compressed format");
             return 4 * width * height;
     }
 
-    SK_ABORT("Invalid format");
+    SK_ABORT("Unknown compressed format");
     return 4 * width * height;
 }