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;
}
diff --git a/tests/BackendAllocationTest.cpp b/tests/BackendAllocationTest.cpp
index 52262a3..a62561a 100644
--- a/tests/BackendAllocationTest.cpp
+++ b/tests/BackendAllocationTest.cpp
@@ -359,12 +359,23 @@
kAlpha_half_as_Red_GrPixelConfig, { 1.0f, 0, 0, 0.5f }},
{ kUnknown_SkColorType, GR_GL_COMPRESSED_RGB8_ETC2,
kRGB_ETC1_GrPixelConfig, SkColors::kRed },
+ { kUnknown_SkColorType, GR_GL_COMPRESSED_ETC1_RGB8,
+ kRGB_ETC1_GrPixelConfig, SkColors::kRed },
};
for (auto combo : combinations) {
+ if (kRGB_ETC1_GrPixelConfig == combo.fConfig) {
+ // RGB8_ETC2/ETC1_RGB8 is an either/or situation
+ GrGLenum supportedETC1Format = glCaps->configSizedInternalFormat(combo.fConfig);
+ if (supportedETC1Format != combo.fFormat) {
+ continue;
+ }
+ }
+
GrBackendFormat format = GrBackendFormat::MakeGL(combo.fFormat, GR_GL_TEXTURE_2D);
- if (GR_GL_COMPRESSED_RGB8_ETC2 == combo.fFormat) {
+ if (GR_GL_COMPRESSED_RGB8_ETC2 == combo.fFormat ||
+ GR_GL_COMPRESSED_ETC1_RGB8 == combo.fFormat) {
// We current disallow uninitialized ETC1 textures in the GL backend
continue;
}