Change GrGpu::onCreateCompressedTexture signature

In the previous form there was some duplication between the backend format and the SkImage::CompressionType being passed around.

Bug: skia:9680
Change-Id: I04455b7a4289bec83d87be17b75b4e9d4d6ef2e0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/261184
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index 78e0e6c..7adc481 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -808,18 +808,8 @@
 /**
  * Returns the data size for the given SkImage::CompressionType
  */
-static inline size_t GrCompressedFormatDataSize(SkImage::CompressionType compressionType,
-                                                SkISize dimensions) {
-    switch (compressionType) {
-        case SkImage::CompressionType::kNone:
-            return 0;
-        case SkImage::CompressionType::kETC1:
-            SkASSERT((dimensions.width() & 3) == 0);
-            SkASSERT((dimensions.height() & 3) == 0);
-            return (dimensions.width() >> 2) * (dimensions.height() >> 2) * 8;
-    }
-    SkUNREACHABLE;
-}
+size_t GrCompressedFormatDataSize(SkImage::CompressionType, SkISize dimensions,
+                                  GrMipMapped = GrMipMapped::kNo);
 
 /**
  * Like SkColorType this describes a layout of pixel data in CPU memory. It specifies the channels,
diff --git a/src/gpu/GrDataUtils.cpp b/src/gpu/GrDataUtils.cpp
index 2c6b0a8..2b2d10d 100644
--- a/src/gpu/GrDataUtils.cpp
+++ b/src/gpu/GrDataUtils.cpp
@@ -159,6 +159,11 @@
     return totalSize;
 }
 
+size_t GrCompressedFormatDataSize(SkImage::CompressionType compressionType,
+                                  SkISize dimensions, GrMipMapped mipMapped) {
+    return GrCompressedDataSize(compressionType, dimensions, nullptr, mipMapped);
+}
+
 size_t GrCompressedRowBytes(SkImage::CompressionType type, int width) {
     switch (type) {
         case SkImage::CompressionType::kNone:
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index b648ce6..a96e340 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -269,19 +269,14 @@
     return tex;
 }
 
-sk_sp<GrTexture> GrGpu::createCompressedTexture(int width, int height,
+sk_sp<GrTexture> GrGpu::createCompressedTexture(SkISize dimensions,
                                                 const GrBackendFormat& format,
-                                                SkImage::CompressionType compressionType,
                                                 SkBudgeted budgeted,
                                                 const void* data,
                                                 size_t dataSize) {
-    // If we ever add a new CompressionType, we should add a check here to make sure the
-    // GrBackendFormat and CompressionType are compatible with eachother.
-    SkASSERT(compressionType == SkImage::CompressionType::kETC1);
-
     this->handleDirtyContext();
-    if (width  < 1 || width  > this->caps()->maxTextureSize() ||
-        height < 1 || height > this->caps()->maxTextureSize()) {
+    if (dimensions.width()  < 1 || dimensions.width()  > this->caps()->maxTextureSize() ||
+        dimensions.height() < 1 || dimensions.height() > this->caps()->maxTextureSize()) {
         return nullptr;
     }
     // Note if we relax the requirement that data must be provided then we must check
@@ -292,11 +287,15 @@
     if (!this->caps()->isFormatTexturable(format)) {
         return nullptr;
     }
-    if (dataSize < GrCompressedDataSize(compressionType, {width, height},
+
+    // TODO: expand CompressedDataIsCorrect to work here too
+    SkImage::CompressionType compressionType = this->caps()->compressionType(format);
+
+    if (dataSize < GrCompressedDataSize(compressionType, dimensions,
                                         nullptr, GrMipMapped::kNo)) {
         return nullptr;
     }
-    return this->onCreateCompressedTexture(width, height, format, compressionType, budgeted, data);
+    return this->onCreateCompressedTexture(dimensions, format, budgeted, data, dataSize);
 }
 
 sk_sp<GrTexture> GrGpu::wrapBackendTexture(const GrBackendTexture& backendTex,
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 227c07c..59716e7 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -132,9 +132,8 @@
                                    SkBudgeted budgeted,
                                    GrProtected isProtected);
 
-    sk_sp<GrTexture> createCompressedTexture(int width, int height, const GrBackendFormat&,
-                                             SkImage::CompressionType, SkBudgeted, const void* data,
-                                             size_t dataSize);
+    sk_sp<GrTexture> createCompressedTexture(SkISize dimensions, const GrBackendFormat&,
+                                             SkBudgeted, const void* data, size_t dataSize);
 
     /**
      * Implements GrResourceProvider::wrapBackendTexture
@@ -661,10 +660,10 @@
                                              GrProtected,
                                              int mipLevelCoont,
                                              uint32_t levelClearMask) = 0;
-    virtual sk_sp<GrTexture> onCreateCompressedTexture(int width, int height,
+    virtual sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions,
                                                        const GrBackendFormat&,
-                                                       SkImage::CompressionType, SkBudgeted,
-                                                       const void* data) = 0;
+                                                       SkBudgeted,
+                                                       const void* data, size_t dataSize) = 0;
     virtual sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrColorType,
                                                   GrWrapOwnership, GrWrapCacheable, GrIOType) = 0;
 
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index aa329ff..b51fc9e 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -483,13 +483,13 @@
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createCompressedTextureProxy(
-        int width, int height, SkBudgeted budgeted, SkImage::CompressionType compressionType,
+        SkISize dimensions, SkBudgeted budgeted, SkImage::CompressionType compressionType,
         sk_sp<SkData> data) {
 
     GrSurfaceDesc desc;
     desc.fConfig = GrCompressionTypeToPixelConfig(compressionType);
-    desc.fWidth = width;
-    desc.fHeight = height;
+    desc.fWidth = dimensions.width();
+    desc.fHeight = dimensions.height();
 
     GrBackendFormat format = this->caps()->getBackendFormatFromCompressionType(compressionType);
 
@@ -498,10 +498,10 @@
     }
 
     sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
-            [width, height, format, compressionType, budgeted,
+            [dimensions, format, budgeted,
              data](GrResourceProvider* resourceProvider) {
                 return LazyCallbackResult(resourceProvider->createCompressedTexture(
-                        width, height, format, compressionType, budgeted, data.get()));
+                    dimensions, format, budgeted, data.get()));
             },
             format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
             GrMipMapsStatus::kNotAllocated, GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact,
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index 1cb86b2..cf964c0 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -95,8 +95,8 @@
     /*
      * Create a texture proxy from compressed texture data.
      */
-    sk_sp<GrTextureProxy> createCompressedTextureProxy(int width, int height, SkBudgeted budgeted,
-                                                       SkImage::CompressionType compressionType,
+    sk_sp<GrTextureProxy> createCompressedTextureProxy(SkISize dimensions, SkBudgeted,
+                                                       SkImage::CompressionType,
                                                        sk_sp<SkData> data);
 
     // These match the definitions in SkImage & GrTexture.h, for whence they came
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index 93ccc62..bd6b34d 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -144,16 +144,15 @@
     }
 }
 
-sk_sp<GrTexture> GrResourceProvider::createCompressedTexture(int width, int height,
+sk_sp<GrTexture> GrResourceProvider::createCompressedTexture(SkISize dimensions,
                                                              const GrBackendFormat& format,
-                                                             SkImage::CompressionType compression,
                                                              SkBudgeted budgeted, SkData* data) {
     ASSERT_SINGLE_OWNER
     if (this->isAbandoned()) {
         return nullptr;
     }
-    return fGpu->createCompressedTexture(width, height, format, compression, budgeted, data->data(),
-                                         data->size());
+    return fGpu->createCompressedTexture(dimensions, format, budgeted,
+                                         data->data(), data->size());
 }
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index 4ccd08e..17487f0 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -108,8 +108,8 @@
      * Creates a compressed texture. The GrGpu must support the SkImageImage::Compression type.
      * This does not currently support MIP maps. It will not be renderable.
      */
-    sk_sp<GrTexture> createCompressedTexture(int width, int height, const GrBackendFormat&,
-                                             SkImage::CompressionType, SkBudgeted, SkData* data);
+    sk_sp<GrTexture> createCompressedTexture(SkISize dimensions, const GrBackendFormat&,
+                                             SkBudgeted, SkData* data);
 
     ///////////////////////////////////////////////////////////////////////////
     // Wrapped Backend Surfaces
diff --git a/src/gpu/GrSurface.cpp b/src/gpu/GrSurface.cpp
index 2f1a8d3..b876991 100644
--- a/src/gpu/GrSurface.cpp
+++ b/src/gpu/GrSurface.cpp
@@ -35,7 +35,7 @@
 
     SkImage::CompressionType compressionType = caps.compressionType(format);
     if (compressionType != SkImage::CompressionType::kNone) {
-        colorSize = GrCompressedFormatDataSize(compressionType, dimensions);
+        colorSize = GrCompressedFormatDataSize(compressionType, dimensions, mipMapped);
     } else {
         colorSize = (size_t)dimensions.width() * dimensions.height() * caps.bytesPerPixel(format);
     }
diff --git a/src/gpu/dawn/GrDawnGpu.cpp b/src/gpu/dawn/GrDawnGpu.cpp
index d8fd061..4134d01 100644
--- a/src/gpu/dawn/GrDawnGpu.cpp
+++ b/src/gpu/dawn/GrDawnGpu.cpp
@@ -171,9 +171,9 @@
                                        mipMapsStatus);
 }
 
-sk_sp<GrTexture> GrDawnGpu::onCreateCompressedTexture(int width, int height, const GrBackendFormat&,
-                                                      SkImage::CompressionType, SkBudgeted,
-                                                      const void* data) {
+sk_sp<GrTexture> GrDawnGpu::onCreateCompressedTexture(SkISize dimensions, const GrBackendFormat&,
+                                                      SkBudgeted, const void* data,
+                                                      size_t dataSize) {
     SkASSERT(!"unimplemented");
     return nullptr;
 }
diff --git a/src/gpu/dawn/GrDawnGpu.h b/src/gpu/dawn/GrDawnGpu.h
index 86529e6..1b70928 100644
--- a/src/gpu/dawn/GrDawnGpu.h
+++ b/src/gpu/dawn/GrDawnGpu.h
@@ -119,9 +119,10 @@
                                      int mipLevelCount,
                                      uint32_t levelClearMask) override;
 
-    sk_sp<GrTexture> onCreateCompressedTexture(int width, int height, const GrBackendFormat&,
-                                               SkImage::CompressionType, SkBudgeted,
-                                               const void* data) override;
+    sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions,
+                                               const GrBackendFormat&,
+                                               SkBudgeted,
+                                               const void* data, size_t dataSize) override;
 
     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrColorType, GrWrapOwnership,
                                           GrWrapCacheable, GrIOType) override;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index e62b436..a408430 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1072,20 +1072,22 @@
 }
 
 bool GrGLGpu::uploadCompressedTexData(GrGLFormat format,
-                                      SkImage::CompressionType compressionType,
                                       SkISize dimensions,
                                       GrMipMapped mipMapped,
                                       GrGLenum target,
-                                      const void* data) {
+                                      const void* data, size_t dataSize) {
     SkASSERT(format != GrGLFormat::kUnknown);
     const GrGLCaps& caps = this->glCaps();
 
     // We only need the internal format for compressed 2D textures.
     GrGLenum internalFormat = caps.getTexImageOrStorageInternalFormat(format);
     if (!internalFormat) {
-        return 0;
+        return false;
     }
 
+    SkImage::CompressionType compressionType = GrGLFormatToCompressionType(format);
+    SkASSERT(compressionType != SkImage::CompressionType::kNone);
+
     bool useTexStorage = caps.formatSupportsTexStorage(format);
 
     int numMipLevels = 1;
@@ -1109,8 +1111,8 @@
         size_t offset = 0;
         for (int level = 0; level < numMipLevels; ++level) {
 
-            size_t dataSize = GrCompressedDataSize(compressionType, dimensions,
-                                                   nullptr, GrMipMapped::kNo);
+            size_t levelDataSize = GrCompressedDataSize(compressionType, dimensions,
+                                                        nullptr, GrMipMapped::kNo);
 
             GL_CALL(CompressedTexSubImage2D(target,
                                             level,
@@ -1119,7 +1121,7 @@
                                             dimensions.width(),
                                             dimensions.height(),
                                             internalFormat,
-                                            SkToInt(dataSize),
+                                            SkToInt(levelDataSize),
                                             &((char*)data)[offset]));
 
             GrGLenum error = CHECK_ALLOC_ERROR(this->glInterface());
@@ -1127,15 +1129,15 @@
                 return false;
             }
 
-            offset += dataSize;
+            offset += levelDataSize;
             dimensions = {SkTMax(1, dimensions.width()/2), SkTMax(1, dimensions.height()/2)};
         }
     } else {
         size_t offset = 0;
 
         for (int level = 0; level < numMipLevels; ++level) {
-            size_t dataSize = GrCompressedDataSize(compressionType, dimensions,
-                                                   nullptr, GrMipMapped::kNo);
+            size_t levelDataSize = GrCompressedDataSize(compressionType, dimensions,
+                                                        nullptr, GrMipMapped::kNo);
 
             const char* rawLevelData = &((char*)data)[offset];
             GL_ALLOC_CALL(this->glInterface(), CompressedTexImage2D(target,
@@ -1144,7 +1146,7 @@
                                                                     dimensions.width(),
                                                                     dimensions.height(),
                                                                     0,  // border
-                                                                    SkToInt(dataSize),
+                                                                    SkToInt(levelDataSize),
                                                                     rawLevelData));
 
             GrGLenum error = CHECK_ALLOC_ERROR(this->glInterface());
@@ -1152,7 +1154,7 @@
                 return false;
             }
 
-            offset += dataSize;
+            offset += levelDataSize;
             dimensions = {SkTMax(1, dimensions.width()/2), SkTMax(1, dimensions.height()/2)};
         }
     }
@@ -1407,20 +1409,20 @@
     return tex;
 }
 
-sk_sp<GrTexture> GrGLGpu::onCreateCompressedTexture(int width, int height,
+sk_sp<GrTexture> GrGLGpu::onCreateCompressedTexture(SkISize dimensions,
                                                     const GrBackendFormat& format,
-                                                    SkImage::CompressionType compression,
-                                                    SkBudgeted budgeted, const void* data) {
+                                                    SkBudgeted budgeted,
+                                                    const void* data, size_t dataSize) {
     GrGLTextureParameters::SamplerOverriddenState initialState;
     GrGLTexture::Desc desc;
-    desc.fSize = {width, height};
+    desc.fSize = dimensions;
     desc.fTarget = GR_GL_TEXTURE_2D;
-    desc.fConfig = GrCompressionTypeToPixelConfig(compression);
+    desc.fConfig = this->glCaps().getConfigFromCompressedBackendFormat(format);
     desc.fOwnership = GrBackendObjectOwnership::kOwned;
     desc.fFormat = format.asGLFormat();
-    desc.fID = this->createCompressedTexture2D(desc.fSize, desc.fFormat, compression,
+    desc.fID = this->createCompressedTexture2D(desc.fSize, desc.fFormat,
                                                GrMipMapped::kNo, &initialState,
-                                               data);
+                                               data, dataSize);
     if (!desc.fID) {
         return nullptr;
     }
@@ -1452,23 +1454,21 @@
         return {};
     }
 
-    SkImage::CompressionType compression = GrGLFormatToCompressionType(glFormat);
-    if (compression == SkImage::CompressionType::kNone) {
-        // Un-compressed formats go through onCreateBackendTexture
-        return {};
-    }
-
     const char* rawData = nullptr;
+    size_t rawDataSize = 0;
     SkAutoMalloc am;
 
     SkASSERT(!data || data->type() != BackendTextureData::Type::kPixmaps);
     if (data && data->type() == BackendTextureData::Type::kCompressed) {
         rawData = (const char*) data->compressedData();
+        rawDataSize = data->compressedSize();
     } else if (data && data->type() == BackendTextureData::Type::kColor) {
-        size_t requiredSize = GrCompressedDataSize(compression, dimensions,
-                                                   nullptr, mipMapped);
+        SkImage::CompressionType compression = GrGLFormatToCompressionType(glFormat);
+        SkASSERT(compression != SkImage::CompressionType::kNone);
 
-        am.reset(requiredSize);
+        rawDataSize = GrCompressedDataSize(compression, dimensions, nullptr, mipMapped);
+
+        am.reset(rawDataSize);
 
         GrFillInCompressedData(compression, dimensions, mipMapped, (char*)am.get(), data->color());
 
@@ -1481,8 +1481,8 @@
     info.fTarget = GR_GL_TEXTURE_2D;
     info.fFormat = GrGLFormatToEnum(glFormat);
     info.fID = this->createCompressedTexture2D(dimensions, glFormat,
-                                               compression, mipMapped, &initialState,
-                                               rawData);
+                                               mipMapped, &initialState,
+                                               rawData, rawDataSize);
     if (!info.fID) {
         return {};
     }
@@ -1606,10 +1606,9 @@
 GrGLuint GrGLGpu::createCompressedTexture2D(
         const SkISize& dimensions,
         GrGLFormat format,
-        SkImage::CompressionType compression,
         GrMipMapped mipMapped,
         GrGLTextureParameters::SamplerOverriddenState* initialState,
-        const void* data) {
+        const void* data, size_t dataSize) {
     if (format == GrGLFormat::kUnknown) {
         return 0;
     }
@@ -1624,8 +1623,8 @@
     *initialState = set_initial_texture_params(this->glInterface(), GR_GL_TEXTURE_2D);
 
     if (data) {
-        if (!this->uploadCompressedTexData(format, compression, dimensions, mipMapped,
-                                           GR_GL_TEXTURE_2D, data)) {
+        if (!this->uploadCompressedTexData(format, dimensions, mipMapped,
+                                           GR_GL_TEXTURE_2D, data, dataSize)) {
             GL_CALL(DeleteTextures(1, &id));
             return 0;
         }
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 8186256..45b6d8d 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -206,9 +206,10 @@
                                      GrProtected,
                                      int mipLevelCount,
                                      uint32_t levelClearMask) override;
-    sk_sp<GrTexture> onCreateCompressedTexture(int width, int height, const GrBackendFormat&,
-                                               SkImage::CompressionType compression, SkBudgeted,
-                                               const void* data) override;
+    sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions,
+                                               const GrBackendFormat&,
+                                               SkBudgeted,
+                                               const void* data, size_t dataSize) override;
 
     sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType intendedType, GrAccessPattern,
                                       const void* data) override;
@@ -242,9 +243,9 @@
                              int mipLevelCount);
 
     GrGLuint createCompressedTexture2D(const SkISize& dimensions, GrGLFormat,
-                                       SkImage::CompressionType, GrMipMapped,
+                                       GrMipMapped,
                                        GrGLTextureParameters::SamplerOverriddenState* initialState,
-                                       const void* data);
+                                       const void* data, size_t dataSize);
 
     bool onReadPixels(GrSurface*, int left, int top, int width, int height,
                       GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
@@ -388,11 +389,10 @@
     // Helper for onCreateCompressedTexture. Compressed textures are read-only so we only use this
     // to populate a new texture. Returns false if we failed to create and upload the texture.
     bool uploadCompressedTexData(GrGLFormat,
-                                 SkImage::CompressionType,
                                  SkISize dimensions,
                                  GrMipMapped,
                                  GrGLenum target,
-                                 const void* data);
+                                 const void* data, size_t dataSize);
 
     bool createRenderTargetObjects(const GrGLTexture::Desc&,
                                    int sampleCount,
diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp
index df59f17..50f0e6b 100644
--- a/src/gpu/mock/GrMockGpu.cpp
+++ b/src/gpu/mock/GrMockGpu.cpp
@@ -163,11 +163,10 @@
 }
 
 // TODO: why no 'isProtected' ?!
-sk_sp<GrTexture> GrMockGpu::onCreateCompressedTexture(int width, int height,
+sk_sp<GrTexture> GrMockGpu::onCreateCompressedTexture(SkISize dimensions,
                                                       const GrBackendFormat& format,
-                                                      SkImage::CompressionType compressionType,
                                                       SkBudgeted budgeted,
-                                                      const void* data) {
+                                                      const void* data, size_t dataSize) {
     if (fMockOptions.fFailTextureAllocations) {
         return nullptr;
     }
@@ -175,11 +174,10 @@
     // Uncompressed formats should go through onCreateTexture
     SkImage::CompressionType compression = format.asMockCompressionType();
     SkASSERT(compression != SkImage::CompressionType::kNone);
-    SkASSERT(compression == compressionType);
 
     GrSurfaceDesc desc;
-    desc.fWidth = width;
-    desc.fHeight = height;
+    desc.fWidth = dimensions.width();
+    desc.fHeight = dimensions.height();
     desc.fConfig = GrCompressionTypeToPixelConfig(compression);
 
     GrMipMapsStatus mipMapsStatus = GrMipMapsStatus::kNotAllocated;
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index 22995bb..dc4162c 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -71,9 +71,9 @@
                                      int mipLevelCount,
                                      uint32_t levelClearMask) override;
 
-    sk_sp<GrTexture> onCreateCompressedTexture(int width, int height, const GrBackendFormat&,
-                                               SkImage::CompressionType, SkBudgeted,
-                                               const void* data) override;
+    sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions, const GrBackendFormat&,
+                                               SkBudgeted, const void* data,
+                                               size_t dataSize) override;
 
     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrColorType, GrWrapOwnership,
                                           GrWrapCacheable, GrIOType) override;
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index 3ea549c..61dda2c 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -147,9 +147,9 @@
                                      GrProtected,
                                      int mipLevelCount,
                                      uint32_t levelClearMask) override;
-    sk_sp<GrTexture> onCreateCompressedTexture(int width, int height, const GrBackendFormat&,
-                                               SkImage::CompressionType, SkBudgeted,
-                                               const void* data) override;
+    sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions, const GrBackendFormat&,
+                                               SkBudgeted, const void* data,
+                                               size_t dataSize) override;
 
     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrColorType,
                                           GrWrapOwnership, GrWrapCacheable, GrIOType) override;
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index 9339555..d643630 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -502,14 +502,15 @@
     return tex;
 }
 
-sk_sp<GrTexture> GrMtlGpu::onCreateCompressedTexture(int width, int height,
+sk_sp<GrTexture> GrMtlGpu::onCreateCompressedTexture(SkISize dimensions,
                                                      const GrBackendFormat& format,
-                                                     SkImage::CompressionType compressionType,
-                                                     SkBudgeted budgeted, const void* data) {
+                                                     SkBudgeted budgeted,
+                                                     const void* data,
+                                                     size_t dataSize) {
     SkASSERT(this->caps()->isFormatTexturable(format));
     SkASSERT(data);
 
-    if (!check_max_blit_width(width)) {
+    if (!check_max_blit_width(dimensions.width())) {
         return nullptr;
     }
 
@@ -522,8 +523,8 @@
     MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init];
     texDesc.textureType = MTLTextureType2D;
     texDesc.pixelFormat = mtlPixelFormat;
-    texDesc.width = width;
-    texDesc.height = height;
+    texDesc.width = dimensions.width();
+    texDesc.height = dimensions.height();
     texDesc.depth = 1;
     texDesc.mipmapLevelCount = 1;
     texDesc.sampleCount = 1;
@@ -536,9 +537,9 @@
     }
 
     GrSurfaceDesc desc;
-    desc.fConfig = GrCompressionTypeToPixelConfig(compressionType);
-    desc.fWidth = width;
-    desc.fHeight = height;
+    desc.fConfig = this->caps()->getConfigFromCompressedBackendFormat(format);
+    desc.fWidth = dimensions.width();
+    desc.fHeight = dimensions.height();
     auto tex = GrMtlTexture::MakeNewTexture(this, budgeted, desc, texDesc,
                                             GrMipMapsStatus::kNotAllocated);
     if (!tex) {
@@ -549,15 +550,8 @@
     id<MTLTexture> mtlTexture = tex->mtlTexture();
     SkASSERT(mtlTexture);
 
-    SkImage::CompressionType textureCompressionType;
-    if (!GrMtlFormatToCompressionType(mtlTexture.pixelFormat, &textureCompressionType) ||
-        textureCompressionType != compressionType) {
-        return nullptr;
-    }
-
-    size_t dataSize = GrCompressedDataSize(compressionType, {width, height},
-                                           nullptr, GrMipMapped::kNo);
-    SkASSERT(dataSize);
+    auto compressionType = GrMtlFormatToCompressionType(mtlTexture.pixelFormat);
+    SkASSERT(compressionType != SkImage::CompressionType::kNone);
 
     size_t bufferOffset;
     id<MTLBuffer> transferBuffer = this->resourceProvider().getDynamicBuffer(dataSize,
@@ -570,7 +564,7 @@
     MTLOrigin origin = MTLOriginMake(0, 0, 0);
 
     id<MTLBlitCommandEncoder> blitCmdEncoder = this->commandBuffer()->getBlitCommandEncoder();
-    const size_t rowBytes = GrCompressedRowBytes(compressionType, width);
+    const size_t rowBytes = GrCompressedRowBytes(compressionType, dimensions.width());
 
     // copy data into the buffer, skipping any trailing bytes
     memcpy(buffer, data, dataSize);
@@ -578,7 +572,7 @@
                       sourceOffset: bufferOffset
                  sourceBytesPerRow: rowBytes
                sourceBytesPerImage: dataSize
-                        sourceSize: MTLSizeMake(width, height, 1)
+                        sourceSize: MTLSizeMake(dimensions.width(), dimensions.height(), 1)
                          toTexture: mtlTexture
                   destinationSlice: 0
                   destinationLevel: 0
diff --git a/src/gpu/mtl/GrMtlUtil.h b/src/gpu/mtl/GrMtlUtil.h
index 87b8201..70a732e 100644
--- a/src/gpu/mtl/GrMtlUtil.h
+++ b/src/gpu/mtl/GrMtlUtil.h
@@ -110,6 +110,6 @@
 /**
  * Maps a MTLPixelFormat into the CompressionType enum if applicable.
  */
-bool GrMtlFormatToCompressionType(MTLPixelFormat mtlFormat,
-                                  SkImage::CompressionType* compressionType);
+SkImage::CompressionType GrMtlFormatToCompressionType(MTLPixelFormat mtlFormat);
+
 #endif
diff --git a/src/gpu/mtl/GrMtlUtil.mm b/src/gpu/mtl/GrMtlUtil.mm
index d831a2e..45f3852 100644
--- a/src/gpu/mtl/GrMtlUtil.mm
+++ b/src/gpu/mtl/GrMtlUtil.mm
@@ -303,17 +303,15 @@
     }
 }
 
-bool GrMtlFormatToCompressionType(MTLPixelFormat mtlFormat,
-                                  SkImage::CompressionType* compressionType) {
+SkImage::CompressionType GrMtlFormatToCompressionType(MTLPixelFormat mtlFormat) {
     switch (mtlFormat) {
 #ifdef SK_BUILD_FOR_IOS
-        case MTLPixelFormatETC2_RGB8:
-            *compressionType = SkImage::CompressionType::kETC1;
-            return true;
+        case MTLPixelFormatETC2_RGB8: return SkImage::CompressionType::kETC1;
 #endif
-        default:
-            return false;
+        default:                      return SkImage::CompressionType::kNone;
     }
+
+    SkUNREACHABLE;
 }
 
 #if GR_TEST_UTILS
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 8c4b9d6..5c1cd7a 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -1440,8 +1440,7 @@
             return SurfaceReadPixelsSupport::kCopyToTexture2D;
         }
         // We can't directly read from a compressed format
-        SkImage::CompressionType compressionType;
-        if (GrVkFormatToCompressionType(tex->imageFormat(), &compressionType)) {
+        if (GrVkFormatIsCompressed(tex->imageFormat())) {
             return SurfaceReadPixelsSupport::kCopyToTexture2D;
         }
     }
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 5ec0589..508e637 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -871,7 +871,7 @@
 // It's probably possible to roll this into uploadTexDataOptimal,
 // but for now it's easier to maintain as a separate entity.
 bool GrVkGpu::uploadTexDataCompressed(GrVkTexture* tex, int left, int top, int width, int height,
-                                      SkImage::CompressionType compressionType, const void* data) {
+                                      const void* data, size_t dataSize) {
     SkASSERT(data);
     SkASSERT(!tex->isLinearTiled());
     // For now the assumption is that our rect is the entire texture.
@@ -882,17 +882,8 @@
         return false;
     }
 
-    SkImage::CompressionType textureCompressionType;
-    if (!GrVkFormatToCompressionType(tex->imageFormat(), &textureCompressionType) ||
-        textureCompressionType != compressionType) {
-        return false;
-    }
-
     SkASSERT(this->vkCaps().isVkFormatTexturable(tex->imageFormat()));
 
-    size_t dataSize = GrCompressedDataSize(compressionType, {width, height},
-                                           nullptr, GrMipMapped::kNo);
-
     // allocate buffer to hold our mip data
     sk_sp<GrVkTransferBuffer> transferBuffer =
             GrVkTransferBuffer::Make(this, dataSize, GrVkBuffer::kCopyRead_Type);
@@ -1024,10 +1015,10 @@
     return tex;
 }
 
-sk_sp<GrTexture> GrVkGpu::onCreateCompressedTexture(int width, int height,
+sk_sp<GrTexture> GrVkGpu::onCreateCompressedTexture(SkISize dimensions,
                                                     const GrBackendFormat& format,
-                                                    SkImage::CompressionType compressionType,
-                                                    SkBudgeted budgeted, const void* data) {
+                                                    SkBudgeted budgeted,
+                                                    const void* data, size_t dataSize) {
     VkFormat pixelFormat;
     SkAssertResult(format.asVkFormat(&pixelFormat));
     SkASSERT(GrVkFormatIsCompressed(pixelFormat));
@@ -1046,8 +1037,8 @@
     GrVkImage::ImageDesc imageDesc;
     imageDesc.fImageType = VK_IMAGE_TYPE_2D;
     imageDesc.fFormat = pixelFormat;
-    imageDesc.fWidth = width;
-    imageDesc.fHeight = height;
+    imageDesc.fWidth = dimensions.width();
+    imageDesc.fHeight = dimensions.height();
     imageDesc.fLevels = 1;
     imageDesc.fSamples = 1;
     imageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
@@ -1055,17 +1046,17 @@
     imageDesc.fIsProtected = GrProtected::kNo;
 
     GrSurfaceDesc desc;
-    desc.fConfig = GrCompressionTypeToPixelConfig(compressionType);
-    desc.fWidth = width;
-    desc.fHeight = height;
+    desc.fConfig = this->vkCaps().getConfigFromCompressedBackendFormat(format);
+    desc.fWidth = dimensions.width();
+    desc.fHeight = dimensions.height();
     auto tex = GrVkTexture::MakeNewTexture(this, budgeted, desc, imageDesc,
                                            GrMipMapsStatus::kNotAllocated);
     if (!tex) {
         return nullptr;
     }
 
-    if (!this->uploadTexDataCompressed(tex.get(), 0, 0, desc.fWidth, desc.fHeight, compressionType,
-                                       data)) {
+    if (!this->uploadTexDataCompressed(tex.get(), 0, 0, desc.fWidth, desc.fHeight,
+                                       data, dataSize)) {
         return nullptr;
     }
 
@@ -1531,14 +1522,15 @@
     return true;
 }
 
-bool generate_compressed_data(GrVkGpu* gpu, const GrVkAlloc& alloc, SkISize dimensions,
+bool generate_compressed_data(GrVkGpu* gpu, const GrVkAlloc& alloc,
+                              SkImage::CompressionType compression, SkISize dimensions,
                               GrMipMapped mipMapped, const SkColor4f& color) {
     char* mapPtr = (char*) GrVkMemory::MapAlloc(gpu, alloc);
     if (!mapPtr) {
         return false;
     }
 
-    GrFillInCompressedData(SkImage::CompressionType::kETC1, dimensions, mipMapped, mapPtr, color);
+    GrFillInCompressedData(compression, dimensions, mipMapped, mapPtr, color);
 
     GrVkMemory::FlushMappedAlloc(gpu, alloc, 0, alloc.fSize);
     GrVkMemory::UnmapAlloc(gpu, alloc);
@@ -1677,6 +1669,8 @@
     set_image_layout(this->vkInterface(), cmdBuffer, info, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                      numMipLevels, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
 
+    SkImage::CompressionType compression = GrVkFormatToCompressionType(vkFormat);
+
     // Unfortunately, CmdClearColorImage doesn't work for compressed formats
     bool fastPath = data->type() == BackendTextureData::Type::kColor &&
                     !GrVkFormatIsCompressed(vkFormat);
@@ -1694,9 +1688,8 @@
                                                                   &individualMipOffsets,
                                                                   numMipLevels);
         } else {
-            combinedBufferSize = GrCompressedDataSize(SkImage::CompressionType::kETC1,
-                                                      dimensions, &individualMipOffsets,
-                                                      mipMapped);
+            combinedBufferSize = GrCompressedDataSize(compression, dimensions,
+                                                      &individualMipOffsets, mipMapped);
         }
         SkASSERT(individualMipOffsets.count() == numMipLevels);
 
@@ -1736,8 +1729,8 @@
                                           data->compressedData(), data->compressedSize());
         } else {
             SkASSERT(data->type() == BackendTextureData::Type::kColor);
-            result = generate_compressed_data(this, bufferAlloc, dimensions, mipMapped,
-                                              data->color());
+            result = generate_compressed_data(this, bufferAlloc, compression, dimensions,
+                                              mipMapped, data->color());
         }
 
         if (!result) {
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 95c3efe..9721cec 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -193,9 +193,9 @@
                                      GrProtected,
                                      int mipLevelCount,
                                      uint32_t levelClearMask) override;
-    sk_sp<GrTexture> onCreateCompressedTexture(int width, int height, const GrBackendFormat&,
-                                               SkImage::CompressionType, SkBudgeted,
-                                               const void* data) override;
+    sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions, const GrBackendFormat&,
+                                               SkBudgeted, const void* data,
+                                               size_t dataSize) override;
 
     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrColorType, GrWrapOwnership,
                                           GrWrapCacheable, GrIOType) override;
@@ -265,7 +265,7 @@
     bool uploadTexDataOptimal(GrVkTexture* tex, int left, int top, int width, int height,
                               GrColorType colorType, const GrMipLevel texels[], int mipLevelCount);
     bool uploadTexDataCompressed(GrVkTexture* tex, int left, int top, int width, int height,
-                                 SkImage::CompressionType, const void* data);
+                                 const void* data, size_t dataSize);
     void resolveImage(GrSurface* dst, GrVkRenderTarget* src, const SkIRect& srcRect,
                       const SkIPoint& dstPoint);
 
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp
index cd4d3a9..9fd513f 100644
--- a/src/gpu/vk/GrVkUtil.cpp
+++ b/src/gpu/vk/GrVkUtil.cpp
@@ -177,14 +177,13 @@
         default:
             return false;
     }
+    SkUNREACHABLE;
 }
 
-bool GrVkFormatToCompressionType(VkFormat vkFormat, SkImage::CompressionType* compressionType) {
+SkImage::CompressionType GrVkFormatToCompressionType(VkFormat vkFormat) {
     switch (vkFormat) {
-        case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
-            *compressionType = SkImage::CompressionType::kETC1;
-            return true;
-        default:
-            return false;
+        case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: return SkImage::CompressionType::kETC1;
+        default:                                return SkImage::CompressionType::kNone;
     }
+    SkUNREACHABLE;
 }
diff --git a/src/gpu/vk/GrVkUtil.h b/src/gpu/vk/GrVkUtil.h
index 940d7c4..3536ade 100644
--- a/src/gpu/vk/GrVkUtil.h
+++ b/src/gpu/vk/GrVkUtil.h
@@ -83,7 +83,7 @@
 /**
  * Maps a vk format into the CompressionType enum if applicable.
  */
-bool GrVkFormatToCompressionType(VkFormat vkFormat, SkImage::CompressionType* compressionType);
+SkImage::CompressionType GrVkFormatToCompressionType(VkFormat vkFormat);
 
 #if GR_TEST_UTILS
 static constexpr const char* GrVkFormatToStr(VkFormat vkFormat) {
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 795c149..1a561af 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -221,7 +221,7 @@
                                            int width, int height, CompressionType type) {
     GrProxyProvider* proxyProvider = context->priv().proxyProvider();
     sk_sp<GrTextureProxy> proxy = proxyProvider->createCompressedTextureProxy(
-            width, height, SkBudgeted::kYes, type, std::move(data));
+            {width, height}, SkBudgeted::kYes, type, std::move(data));
     if (!proxy) {
         return nullptr;
     }
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index 804508c..8d04bfa 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -95,9 +95,7 @@
             SkColor4f color = {0, 0, 0, 0};
             GrFillInCompressedData(compression, dimensions, GrMipMapped::kNo,
                                    (char*)data->writable_data(), color);
-            return rp->createCompressedTexture(dimensions.width(), dimensions.height(),
-                                               format, compression,
-                                               SkBudgeted::kNo, data.get());
+            return rp->createCompressedTexture(dimensions, format, SkBudgeted::kNo, data.get());
         } else {
             GrPixelConfig config = rp->caps()->getConfigFromBackendFormat(format, colorType);