From e90c900ed7b2be3d0f9c7134d7fcd5f820b0464c Mon Sep 17 00:00:00 2001 From: krajcevski Date: Tue, 5 Aug 2014 07:37:26 -0700 Subject: Add ETC1 format to SkTextureCompressor R=robertphillips@google.com Author: krajcevski@google.com Review URL: https://codereview.chromium.org/432143002 --- src/gpu/GrSWMaskHelper.cpp | 4 +++- src/images/SkImageDecoder_pkm.cpp | 6 ++++-- src/utils/SkTextureCompressor.cpp | 41 +++++++++++++++++++++++++++++++++++++-- src/utils/SkTextureCompressor.h | 21 ++++++++++++-------- 4 files changed, 59 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index be6eb034b4..744fa1db8f 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -40,11 +40,13 @@ static inline GrPixelConfig fmt_to_config(SkTextureCompressor::Format fmt) { static const GrPixelConfig configMap[] = { kLATC_GrPixelConfig, // kLATC_Format, kR11_EAC_GrPixelConfig, // kR11_EAC_Format, + kETC1_GrPixelConfig, // kETC1_Format, kASTC_12x12_GrPixelConfig // kASTC_12x12_Format, }; GR_STATIC_ASSERT(0 == SkTextureCompressor::kLATC_Format); GR_STATIC_ASSERT(1 == SkTextureCompressor::kR11_EAC_Format); - GR_STATIC_ASSERT(2 == SkTextureCompressor::kASTC_12x12_Format); + GR_STATIC_ASSERT(2 == SkTextureCompressor::kETC1_Format); + GR_STATIC_ASSERT(3 == SkTextureCompressor::kASTC_12x12_Format); GR_STATIC_ASSERT(SK_ARRAY_COUNT(configMap) == SkTextureCompressor::kFormatCnt); return configMap[fmt]; diff --git a/src/images/SkImageDecoder_pkm.cpp b/src/images/SkImageDecoder_pkm.cpp index 738d98ec29..f5fd4b3fbc 100644 --- a/src/images/SkImageDecoder_pkm.cpp +++ b/src/images/SkImageDecoder_pkm.cpp @@ -10,6 +10,7 @@ #include "SkScaledBitmapSampler.h" #include "SkStream.h" #include "SkStreamPriv.h" +#include "SkTextureCompressor.h" #include "SkTypes.h" #include "etc1.h" @@ -80,10 +81,11 @@ bool SkPKMImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { // ETC1 Data is encoded as RGB pixels, so we should extract it as such int nPixels = width * height; SkAutoMalloc outRGBData(nPixels * 3); - etc1_byte *outRGBDataPtr = reinterpret_cast(outRGBData.get()); + uint8_t *outRGBDataPtr = reinterpret_cast(outRGBData.get()); // Decode ETC1 - if (etc1_decode_image(buf, outRGBDataPtr, width, height, 3, width*3)) { + if (!SkTextureCompressor::DecompressBufferFromFormat( + outRGBDataPtr, width*3, buf, width, height, SkTextureCompressor::kETC1_Format)) { return false; } diff --git a/src/utils/SkTextureCompressor.cpp b/src/utils/SkTextureCompressor.cpp index 801328642f..4034615b37 100644 --- a/src/utils/SkTextureCompressor.cpp +++ b/src/utils/SkTextureCompressor.cpp @@ -16,6 +16,20 @@ #include "SkTextureCompression_opts.h" +#ifndef SK_IGNORE_ETC1_SUPPORT +# include "etc1.h" +#endif + +// Convert ETC1 functions to our function signatures +static bool compress_etc1_565(uint8_t* dst, const uint8_t* src, + int width, int height, int rowBytes) { +#ifndef SK_IGNORE_ETC1_SUPPORT + return 0 == etc1_encode_image(src, width, height, 2, rowBytes, dst); +#else + return false; +#endif +} + //////////////////////////////////////////////////////////////////////////////// namespace SkTextureCompressor { @@ -35,8 +49,9 @@ void GetBlockDimensions(Format format, int* dimX, int* dimY, bool matchSpec) { default: SkDEBUGFAIL("Unknown compression format!"); // fall through - case kR11_EAC_Format: case kLATC_Format: + case kR11_EAC_Format: + case kETC1_Format: *dimX = 4; *dimY = 4; break; @@ -57,8 +72,9 @@ int GetCompressedDataSize(Format fmt, int width, int height) { switch (fmt) { // These formats are 64 bits per 4x4 block. - case kR11_EAC_Format: case kLATC_Format: + case kR11_EAC_Format: + case kETC1_Format: encodedBlockSize = 8; break; @@ -110,6 +126,19 @@ bool CompressBufferToFormat(uint8_t* dst, const uint8_t* src, SkColorType srcCol } break; + case kRGB_565_SkColorType: + { + switch (format) { + case kETC1_Format: + proc = compress_etc1_565; + break; + default: + // Do nothing... + break; + } + } + break; + default: // Do nothing... break; @@ -179,9 +208,17 @@ bool DecompressBufferFromFormat(uint8_t* dst, int dstRowBytes, const uint8_t* sr DecompressR11EAC(dst, dstRowBytes, src, width, height); return true; +#ifndef SK_IGNORE_ETC1_SUPPORT + case kETC1_Format: + return 0 == etc1_decode_image(src, dst, width, height, 3, dstRowBytes); +#endif case kASTC_12x12_Format: // TODO(krajcevski) .. right now just fall through and return false. return false; + + default: + // Do nothing... + break; } return false; diff --git a/src/utils/SkTextureCompressor.h b/src/utils/SkTextureCompressor.h index eac8c5eea3..4254ae76fb 100644 --- a/src/utils/SkTextureCompressor.h +++ b/src/utils/SkTextureCompressor.h @@ -18,9 +18,18 @@ namespace SkTextureCompressor { // Various texture compression formats that we support. enum Format { // Alpha only formats. - kLATC_Format, // 4x4 blocks, compresses A8 - kR11_EAC_Format, // 4x4 blocks, compresses A8 - kASTC_12x12_Format, // 12x12 blocks, compresses A8 + kLATC_Format, // 4x4 blocks, (de)compresses A8 + kR11_EAC_Format, // 4x4 blocks, (de)compresses A8 + + // RGB only formats + kETC1_Format, // 4x4 blocks, compresses RGB 565, decompresses 8-bit RGB + // NOTE: ETC1 supports 8-bit RGB compression, but we + // currently don't have any RGB8 SkColorTypes. We could + // support 8-bit RGBA but we would have to preprocess the + // bitmap to insert alphas. + + // Multi-purpose formats + kASTC_12x12_Format, // 12x12 blocks, compresses A8, decompresses RGBA kLast_Format = kASTC_12x12_Format }; @@ -48,11 +57,7 @@ namespace SkTextureCompressor { // destination buffer. The width and height of the data passed corresponds // to the width and height of the uncompressed image. The destination buffer (dst) // is assumed to be large enough to hold the entire decompressed image. The - // decompressed image colors are determined based on the passed format: - // - // LATC -> Alpha 8 - // R11_EAC -> Alpha 8 - // ASTC -> RGBA + // decompressed image colors are determined based on the passed format. // // Note, CompressBufferToFormat compresses A8 data into ASTC. However, // general ASTC data encodes RGBA data, so that is what the decompressor -- cgit v1.2.3