Add ETC1 format to SkTextureCompressor

R=robertphillips@google.com

Author: krajcevski@google.com

Review URL: https://codereview.chromium.org/432143002
This commit is contained in:
krajcevski 2014-08-04 09:08:29 -07:00 committed by Commit bot
parent 9dc41a5100
commit 5d8b1b44ea
6 changed files with 60 additions and 16 deletions

View File

@ -8,6 +8,7 @@
'standalone_static_library': 1,
'dependencies': [
'core.gyp:*',
'etc1.gyp:libetc1',
],
'includes': [
'utils.gypi',

View File

@ -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];

View File

@ -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<etc1_byte *>(outRGBData.get());
uint8_t *outRGBDataPtr = reinterpret_cast<uint8_t *>(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;
}

View File

@ -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,6 +208,10 @@ 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;

View File

@ -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

View File

@ -132,11 +132,12 @@ DEF_TEST(CompressCheckerboard, reporter) {
for (int i = 0; i < SkTextureCompressor::kFormatCnt; ++i) {
const SkTextureCompressor::Format fmt = static_cast<SkTextureCompressor::Format>(i);
// ASTC is for RGBA data, and the decompressed buffer
// Ignore formats for RGBA data, since the decompressed buffer
// won't match the size and contents of the original.
// TODO: Create separate tests for RGB and RGBA data once
// ASTC decompression is implemented.
if (SkTextureCompressor::kASTC_12x12_Format == fmt) {
// ASTC and ETC1 decompression is implemented.
if (SkTextureCompressor::kASTC_12x12_Format == fmt ||
SkTextureCompressor::kETC1_Format == fmt) {
continue;
}