diff options
-rw-r--r-- | gm/astcbitmap.cpp | 104 | ||||
-rw-r--r-- | gyp/gmslides.gypi | 1 | ||||
-rw-r--r-- | gyp/images.gyp | 1 | ||||
-rw-r--r-- | include/core/SkImageDecoder.h | 2 | ||||
-rw-r--r-- | src/gpu/GrSWMaskHelper.cpp | 38 | ||||
-rw-r--r-- | src/images/SkForceLinking.cpp | 1 | ||||
-rw-r--r-- | src/images/SkImageDecoder.cpp | 2 | ||||
-rw-r--r-- | src/images/SkImageDecoder_astc.cpp | 209 | ||||
-rw-r--r-- | src/utils/SkTextureCompressor.cpp | 76 | ||||
-rw-r--r-- | src/utils/SkTextureCompressor.h | 13 | ||||
-rw-r--r-- | src/utils/SkTextureCompressor_ASTC.cpp | 15 | ||||
-rw-r--r-- | tests/ImageDecodingTest.cpp | 5 | ||||
-rw-r--r-- | tests/TextureCompressionTest.cpp | 37 | ||||
-rw-r--r-- | third_party/ktx/ktx.cpp | 32 |
14 files changed, 491 insertions, 45 deletions
diff --git a/gm/astcbitmap.cpp b/gm/astcbitmap.cpp new file mode 100644 index 0000000000..3c9079cfa8 --- /dev/null +++ b/gm/astcbitmap.cpp @@ -0,0 +1,104 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm.h" + +#include "Resources.h" +#include "SkCanvas.h" +#include "SkData.h" +#include "SkDecodingImageGenerator.h" +#include "SkImageDecoder.h" +#include "SkOSFile.h" +#include "SkTextureCompressor.h" + +static const char *kASTCFilenames[] = { + "mandrill_128x128_4x4.astc", // kASTC_4x4_Format + "mandrill_130x128_5x4.astc", // kASTC_5x4_Format + "mandrill_130x130_5x5.astc", // kASTC_5x5_Format + "mandrill_132x130_6x5.astc", // kASTC_6x5_Format + "mandrill_132x132_6x6.astc", // kASTC_6x6_Format + "mandrill_128x130_8x5.astc", // kASTC_8x5_Format + "mandrill_128x132_8x6.astc", // kASTC_8x6_Format + "mandrill_128x128_8x8.astc", // kASTC_8x8_Format + "mandrill_130x130_10x5.astc", // kASTC_10x5_Format + "mandrill_130x132_10x6.astc", // kASTC_10x6_Format + "mandrill_130x128_10x8.astc", // kASTC_10x8_Format + "mandrill_130x130_10x10.astc", // kASTC_10x10_Format + "mandrill_132x130_12x10.astc", // kASTC_12x10_Format + "mandrill_132x132_12x12.astc", // kASTC_12x12_Format +}; + +static const int kNumASTCFilenames = SK_ARRAY_COUNT(kASTCFilenames); + +static inline const char *get_astc_filename(int idx) { + if (idx < 0 || kNumASTCFilenames <= idx) { + return ""; + } + + return kASTCFilenames[idx]; +} + +namespace skiagm { + +/** + * Test decoding an image from an ASTC file and then from compressed ASTC data. + */ +class ASTCBitmapGM : public GM { +public: + ASTCBitmapGM() { } + virtual ~ASTCBitmapGM() { } + +protected: + virtual SkString onShortName() SK_OVERRIDE { + return SkString("astcbitmap"); + } + + virtual SkISize onISize() SK_OVERRIDE { + return SkISize::Make(kGMDimension, kGMDimension); + } + + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { + for (int j = 0; j < 4; ++j) { + for (int i = 0; i < 4; ++i) { + SkString filename = GetResourcePath(get_astc_filename(j*4+i)); + if (filename == GetResourcePath("")) { + continue; + } + + SkAutoTUnref<SkData> fileData(SkData::NewFromFileName(filename.c_str())); + if (NULL == fileData) { + SkDebugf("Could not open the file. Did you forget to set the resourcePath?\n"); + return; + } + + SkBitmap bm; + if (!SkInstallDiscardablePixelRef( + SkDecodingImageGenerator::Create( + fileData, SkDecodingImageGenerator::Options()), &bm)) { + SkDebugf("Could not install discardable pixel ref.\n"); + return; + } + + const SkScalar bmX = static_cast<SkScalar>(i*kBitmapDimension); + const SkScalar bmY = static_cast<SkScalar>(j*kBitmapDimension); + canvas->drawBitmap(bm, bmX, bmY); + } + } + } + +private: + static const int kGMDimension = 600; + static const int kBitmapDimension = kGMDimension/4; + + typedef GM INHERITED; +}; + +} // namespace skiagm + +////////////////////////////////////////////////////////////////////////////// + +DEF_GM( return SkNEW(skiagm::ASTCBitmapGM); ) diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi index d9c18722b1..c55da892f8 100644 --- a/gyp/gmslides.gypi +++ b/gyp/gmslides.gypi @@ -18,6 +18,7 @@ '../gm/alphagradients.cpp', '../gm/arcofzorro.cpp', '../gm/arithmode.cpp', + '../gm/astcbitmap.cpp', '../gm/beziereffects.cpp', '../gm/bigblurs.cpp', '../gm/bigmatrix.cpp', diff --git a/gyp/images.gyp b/gyp/images.gyp index ee1840bd3f..3cc66a0adb 100644 --- a/gyp/images.gyp +++ b/gyp/images.gyp @@ -59,6 +59,7 @@ '../src/images/SkImageDecoder_wbmp.cpp', '../src/images/SkImageDecoder_pkm.cpp', '../src/images/SkImageDecoder_ktx.cpp', + '../src/images/SkImageDecoder_astc.cpp', '../src/images/SkImageDecoder_libbmp.cpp', '../src/images/SkImageDecoder_libgif.cpp', '../src/images/SkImageDecoder_libico.cpp', diff --git a/include/core/SkImageDecoder.h b/include/core/SkImageDecoder.h index b258afedce..2b9108025e 100644 --- a/include/core/SkImageDecoder.h +++ b/include/core/SkImageDecoder.h @@ -37,6 +37,7 @@ public: kWEBP_Format, kPKM_Format, kKTX_Format, + kASTC_Format, kLastKnownFormat = kKTX_Format, }; @@ -525,6 +526,7 @@ DECLARE_DECODER_CREATOR(WBMPImageDecoder); DECLARE_DECODER_CREATOR(WEBPImageDecoder); DECLARE_DECODER_CREATOR(PKMImageDecoder); DECLARE_DECODER_CREATOR(KTXImageDecoder); +DECLARE_DECODER_CREATOR(ASTCImageDecoder); // Typedefs to make registering decoder and formatter callbacks easier. // These have to be defined outside SkImageDecoder. :( diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index 2863739161..69dc0b5319 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -37,19 +37,33 @@ SkXfermode::Mode op_to_mode(SkRegion::Op op) { } 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::kETC1_Format); - GR_STATIC_ASSERT(3 == SkTextureCompressor::kASTC_12x12_Format); - GR_STATIC_ASSERT(SK_ARRAY_COUNT(configMap) == SkTextureCompressor::kFormatCnt); - return configMap[fmt]; + GrPixelConfig config; + switch (fmt) { + case SkTextureCompressor::kLATC_Format: + config = kLATC_GrPixelConfig; + break; + + case SkTextureCompressor::kR11_EAC_Format: + config = kR11_EAC_GrPixelConfig; + break; + + case SkTextureCompressor::kASTC_12x12_Format: + config = kASTC_12x12_GrPixelConfig; + break; + + case SkTextureCompressor::kETC1_Format: + config = kETC1_GrPixelConfig; + break; + + default: + SkDEBUGFAIL("No GrPixelConfig for compression format!"); + // Best guess + config = kAlpha_8_GrPixelConfig; + break; + } + + return config; } #if GR_COMPRESS_ALPHA_MASK diff --git a/src/images/SkForceLinking.cpp b/src/images/SkForceLinking.cpp index 442f0f77c0..6cc0704e83 100644 --- a/src/images/SkForceLinking.cpp +++ b/src/images/SkForceLinking.cpp @@ -20,6 +20,7 @@ int SkForceLinking(bool doNotPassTrue) { CreateICOImageDecoder(); CreatePKMImageDecoder(); CreateKTXImageDecoder(); + CreateASTCImageDecoder(); CreateWBMPImageDecoder(); // Only link GIF and PNG on platforms that build them. See images.gyp #if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_WIN) && !defined(SK_BUILD_FOR_NACL) \ diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp index fcba91069a..0e2018c117 100644 --- a/src/images/SkImageDecoder.cpp +++ b/src/images/SkImageDecoder.cpp @@ -86,6 +86,8 @@ const char* SkImageDecoder::GetFormatName(Format format) { return "PKM"; case kKTX_Format: return "KTX"; + case kASTC_Format: + return "ASTC"; case kJPEG_Format: return "JPEG"; case kPNG_Format: diff --git a/src/images/SkImageDecoder_astc.cpp b/src/images/SkImageDecoder_astc.cpp new file mode 100644 index 0000000000..79e98047d6 --- /dev/null +++ b/src/images/SkImageDecoder_astc.cpp @@ -0,0 +1,209 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkEndian.h" +#include "SkColorPriv.h" +#include "SkImageDecoder.h" +#include "SkScaledBitmapSampler.h" +#include "SkStream.h" +#include "SkStreamPriv.h" +#include "SkTypes.h" + +#include "SkTextureCompressor.h" + +class SkASTCImageDecoder : public SkImageDecoder { +public: + SkASTCImageDecoder() { } + + virtual Format getFormat() const SK_OVERRIDE { + return kASTC_Format; + } + +protected: + virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; + +private: + typedef SkImageDecoder INHERITED; +}; + +///////////////////////////////////////////////////////////////////////////////////////// + +static const uint32_t kASTCMagicNumber = 0x5CA1AB13; + +static inline int read_24bit(const uint8_t* buf) { + // Assume everything is little endian... + return + static_cast<int>(buf[0]) | + (static_cast<int>(buf[1]) << 8) | + (static_cast<int>(buf[2]) << 16); +} + +bool SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { + SkAutoMalloc autoMal; + const size_t length = SkCopyStreamToStorage(&autoMal, stream); + if (0 == length) { + return false; + } + + unsigned char* buf = (unsigned char*)autoMal.get(); + + // Make sure that the magic header is there... + SkASSERT(SkEndian_SwapLE32(*(reinterpret_cast<uint32_t*>(buf))) == kASTCMagicNumber); + + // Advance past the magic header + buf += 4; + + const int blockDimX = buf[0]; + const int blockDimY = buf[1]; + const int blockDimZ = buf[2]; + + if (1 != blockDimZ) { + // We don't support decoding 3D + return false; + } + + // Choose the proper ASTC format + SkTextureCompressor::Format astcFormat; + if (4 == blockDimX && 4 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_4x4_Format; + } else if (5 == blockDimX && 4 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_5x4_Format; + } else if (5 == blockDimX && 5 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_5x5_Format; + } else if (6 == blockDimX && 5 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_6x5_Format; + } else if (6 == blockDimX && 6 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_6x6_Format; + } else if (8 == blockDimX && 5 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_8x5_Format; + } else if (8 == blockDimX && 6 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_8x6_Format; + } else if (8 == blockDimX && 8 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_8x8_Format; + } else if (10 == blockDimX && 5 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_10x5_Format; + } else if (10 == blockDimX && 6 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_10x6_Format; + } else if (10 == blockDimX && 8 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_10x8_Format; + } else if (10 == blockDimX && 10 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_10x10_Format; + } else if (12 == blockDimX && 10 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_12x10_Format; + } else if (12 == blockDimX && 12 == blockDimY) { + astcFormat = SkTextureCompressor::kASTC_12x12_Format; + } else { + // We don't support any other block dimensions.. + return false; + } + + // Advance buf past the block dimensions + buf += 3; + + // Read the width/height/depth from the buffer... + const int width = read_24bit(buf); + const int height = read_24bit(buf + 3); + const int depth = read_24bit(buf + 6); + + if (1 != depth) { + // We don't support decoding 3D. + return false; + } + + // Advance the buffer past the image dimensions + buf += 9; + +#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER + // should we allow the Chooser (if present) to pick a config for us??? + if (!this->chooseFromOneChoice(kN32_SkColorType, width, height)) { + return false; + } +#endif + + // Setup the sampler... + SkScaledBitmapSampler sampler(width, height, this->getSampleSize()); + + // Determine the alpha of the bitmap... + SkAlphaType alphaType = kOpaque_SkAlphaType; + if (this->getRequireUnpremultipliedColors()) { + alphaType = kUnpremul_SkAlphaType; + } else { + alphaType = kPremul_SkAlphaType; + } + + // Set the config... + bm->setInfo(SkImageInfo::MakeN32(sampler.scaledWidth(), sampler.scaledHeight(), alphaType)); + + if (SkImageDecoder::kDecodeBounds_Mode == mode) { + return true; + } + + if (!this->allocPixelRef(bm, NULL)) { + return false; + } + + // Lock the pixels, since we're about to write to them... + SkAutoLockPixels alp(*bm); + + if (!sampler.begin(bm, SkScaledBitmapSampler::kRGBA, *this)) { + return false; + } + + // ASTC Data is encoded as RGBA pixels, so we should extract it as such + int nPixels = width * height; + SkAutoMalloc outRGBAData(nPixels * 4); + uint8_t *outRGBADataPtr = reinterpret_cast<uint8_t *>(outRGBAData.get()); + + // Decode ASTC + if (!SkTextureCompressor::DecompressBufferFromFormat( + outRGBADataPtr, width*4, buf, width, height, astcFormat)) { + } + + // Set each of the pixels... + const int srcRowBytes = width * 4; + const int dstHeight = sampler.scaledHeight(); + const uint8_t *srcRow = reinterpret_cast<uint8_t *>(outRGBADataPtr); + srcRow += sampler.srcY0() * srcRowBytes; + for (int y = 0; y < dstHeight; ++y) { + sampler.next(srcRow); + srcRow += sampler.srcDY() * srcRowBytes; + } + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////// +DEFINE_DECODER_CREATOR(ASTCImageDecoder); +///////////////////////////////////////////////////////////////////////////////////////// + +static bool is_astc(SkStreamRewindable* stream) { + // Read the ASTC header and make sure it's valid. + uint32_t magic; + if (stream->read((void*)&magic, 4) != 4) { + return false; + } + + return kASTCMagicNumber == SkEndian_SwapLE32(magic); +} + +static SkImageDecoder* sk_libastc_dfactory(SkStreamRewindable* stream) { + if (is_astc(stream)) { + return SkNEW(SkASTCImageDecoder); + } + return NULL; +} + +static SkImageDecoder_DecodeReg gReg(sk_libastc_dfactory); + +static SkImageDecoder::Format get_format_astc(SkStreamRewindable* stream) { + if (is_astc(stream)) { + return SkImageDecoder::kASTC_Format; + } + return SkImageDecoder::kUnknown_Format; +} + +static SkImageDecoder_FormatReg gFormatReg(get_format_astc); diff --git a/src/utils/SkTextureCompressor.cpp b/src/utils/SkTextureCompressor.cpp index 4ced9a0b57..0dfc229193 100644 --- a/src/utils/SkTextureCompressor.cpp +++ b/src/utils/SkTextureCompressor.cpp @@ -45,24 +45,31 @@ void GetBlockDimensions(Format format, int* dimX, int* dimY, bool matchSpec) { } // No specialized arguments, return the dimensions as they are in the spec. - switch(format) { - // These formats are 64 bits per 4x4 block. - default: - SkDEBUGFAIL("Unknown compression format!"); - // fall through - case kLATC_Format: - case kR11_EAC_Format: - case kETC1_Format: - *dimX = 4; - *dimY = 4; - break; - - // This format is 12x12 blocks to 128 bits. - case kASTC_12x12_Format: - *dimX = 12; - *dimY = 12; - break; - } + static const struct FormatDimensions { + const int fBlockSizeX; + const int fBlockSizeY; + } kFormatDimensions[kFormatCnt] = { + { 4, 4 }, // kLATC_Format + { 4, 4 }, // kR11_EAC_Format + { 4, 4 }, // kETC1_Format + { 4, 4 }, // kASTC_4x4_Format + { 5, 4 }, // kASTC_5x4_Format + { 5, 5 }, // kASTC_5x5_Format + { 6, 5 }, // kASTC_6x5_Format + { 6, 6 }, // kASTC_6x6_Format + { 8, 5 }, // kASTC_8x5_Format + { 8, 6 }, // kASTC_8x6_Format + { 8, 8 }, // kASTC_8x8_Format + { 10, 5 }, // kASTC_10x5_Format + { 10, 6 }, // kASTC_10x6_Format + { 10, 8 }, // kASTC_10x8_Format + { 10, 10 }, // kASTC_10x10_Format + { 12, 10 }, // kASTC_12x10_Format + { 12, 12 }, // kASTC_12x12_Format + }; + + *dimX = kFormatDimensions[format].fBlockSizeX; + *dimY = kFormatDimensions[format].fBlockSizeY; } int GetCompressedDataSize(Format fmt, int width, int height) { @@ -79,7 +86,20 @@ int GetCompressedDataSize(Format fmt, int width, int height) { encodedBlockSize = 8; break; - // This format is 12x12 blocks to 128 bits. + // This format is 128 bits. + case kASTC_4x4_Format: + case kASTC_5x4_Format: + case kASTC_5x5_Format: + case kASTC_6x5_Format: + case kASTC_6x6_Format: + case kASTC_8x5_Format: + case kASTC_8x6_Format: + case kASTC_8x8_Format: + case kASTC_10x5_Format: + case kASTC_10x6_Format: + case kASTC_10x8_Format: + case kASTC_10x10_Format: + case kASTC_12x10_Format: case kASTC_12x12_Format: encodedBlockSize = 16; break; @@ -214,9 +234,23 @@ bool DecompressBufferFromFormat(uint8_t* dst, int dstRowBytes, const uint8_t* sr case kETC1_Format: return 0 == etc1_decode_image(src, dst, width, height, 3, dstRowBytes); #endif + + case kASTC_4x4_Format: + case kASTC_5x4_Format: + case kASTC_5x5_Format: + case kASTC_6x5_Format: + case kASTC_6x6_Format: + case kASTC_8x5_Format: + case kASTC_8x6_Format: + case kASTC_8x8_Format: + case kASTC_10x5_Format: + case kASTC_10x6_Format: + case kASTC_10x8_Format: + case kASTC_10x10_Format: + case kASTC_12x10_Format: case kASTC_12x12_Format: - // TODO(krajcevski) .. right now just fall through and return false. - return false; + DecompressASTC(dst, dstRowBytes, src, width, height, dimX, dimY); + return true; default: // Do nothing... diff --git a/src/utils/SkTextureCompressor.h b/src/utils/SkTextureCompressor.h index d82bf07a1e..d5c1d2557e 100644 --- a/src/utils/SkTextureCompressor.h +++ b/src/utils/SkTextureCompressor.h @@ -30,6 +30,19 @@ namespace SkTextureCompressor { // bitmap to insert alphas. // Multi-purpose formats + kASTC_4x4_Format, // 4x4 blocks, no compression, decompresses RGBA + kASTC_5x4_Format, // 5x4 blocks, no compression, decompresses RGBA + kASTC_5x5_Format, // 5x5 blocks, no compression, decompresses RGBA + kASTC_6x5_Format, // 6x5 blocks, no compression, decompresses RGBA + kASTC_6x6_Format, // 6x6 blocks, no compression, decompresses RGBA + kASTC_8x5_Format, // 8x5 blocks, no compression, decompresses RGBA + kASTC_8x6_Format, // 8x6 blocks, no compression, decompresses RGBA + kASTC_8x8_Format, // 8x8 blocks, no compression, decompresses RGBA + kASTC_10x5_Format, // 10x5 blocks, no compression, decompresses RGBA + kASTC_10x6_Format, // 10x6 blocks, no compression, decompresses RGBA + kASTC_10x8_Format, // 10x8 blocks, no compression, decompresses RGBA + kASTC_10x10_Format, // 10x10 blocks, no compression, decompresses RGBA + kASTC_12x10_Format, // 12x10 blocks, no compression, decompresses RGBA kASTC_12x12_Format, // 12x12 blocks, compresses A8, decompresses RGBA kLast_Format = kASTC_12x12_Format diff --git a/src/utils/SkTextureCompressor_ASTC.cpp b/src/utils/SkTextureCompressor_ASTC.cpp index 25d87fd28e..029f7f2426 100644 --- a/src/utils/SkTextureCompressor_ASTC.cpp +++ b/src/utils/SkTextureCompressor_ASTC.cpp @@ -793,7 +793,11 @@ static bool decode_integer_sequence( endBlockBit = endBit; } - decode_trit_block(dst, nBits, read_astc_bits(src, startBit, endBlockBit)); + // Trit blocks are three values large. + int trits[5]; + decode_trit_block(trits, nBits, read_astc_bits(src, startBit, endBlockBit)); + memcpy(dst, trits, SkMin32(nVals, 5)*sizeof(int)); + dst += 5; nVals -= 5; startBit = endBlockBit; @@ -806,7 +810,11 @@ static bool decode_integer_sequence( endBlockBit = endBit; } - decode_quint_block(dst, nBits, read_astc_bits(src, startBit, endBlockBit)); + // Quint blocks are three values large + int quints[3]; + decode_quint_block(quints, nBits, read_astc_bits(src, startBit, endBlockBit)); + memcpy(dst, quints, SkMin32(nVals, 3)*sizeof(int)); + dst += 3; nVals -= 3; startBit = endBlockBit; @@ -1708,7 +1716,8 @@ struct ASTCDecompressionData { // The rest of the CEM config will be between the dual plane bit selector // and the texel weight grid. const int lowCEM = static_cast<int>(read_astc_bits(fBlock, 23, 29)); - SkASSERT(lastWeight - dualPlaneBitLoc > 31); + SkASSERT(lastWeight >= dualPlaneBitLoc); + SkASSERT(lastWeight - dualPlaneBitLoc < 31); int fullCEM = static_cast<int>(read_astc_bits(fBlock, dualPlaneBitLoc, lastWeight)); // Attach the config at the end of the weight grid to the CEM values diff --git a/tests/ImageDecodingTest.cpp b/tests/ImageDecodingTest.cpp index 5e63611348..8838e75566 100644 --- a/tests/ImageDecodingTest.cpp +++ b/tests/ImageDecodingTest.cpp @@ -55,9 +55,10 @@ static bool skip_image_format(SkImageDecoder::Format format) { // decoders do not, so skip them as well. case SkImageDecoder::kICO_Format: case SkImageDecoder::kBMP_Format: - // KTX is a Texture format so it's not particularly clear how to - // decode the alpha from it. + // KTX and ASTC are texture formats so it's not particularly clear how to + // decode the alpha from them. case SkImageDecoder::kKTX_Format: + case SkImageDecoder::kASTC_Format: // The rest of these are opaque. case SkImageDecoder::kPKM_Format: case SkImageDecoder::kWBMP_Format: diff --git a/tests/TextureCompressionTest.cpp b/tests/TextureCompressionTest.cpp index 8694389fe7..da7a87bd41 100644 --- a/tests/TextureCompressionTest.cpp +++ b/tests/TextureCompressionTest.cpp @@ -12,6 +12,32 @@ #include "SkTextureCompressor.h" #include "Test.h" +// TODO: Create separate tests for RGB and RGBA data once +// ASTC and ETC1 decompression is implemented. + +static bool decompresses_a8(SkTextureCompressor::Format fmt) { + switch (fmt) { + case SkTextureCompressor::kLATC_Format: + case SkTextureCompressor::kR11_EAC_Format: + return true; + + default: + return false; + } +} + +static bool compresses_a8(SkTextureCompressor::Format fmt) { + switch (fmt) { + case SkTextureCompressor::kLATC_Format: + case SkTextureCompressor::kR11_EAC_Format: + case SkTextureCompressor::kASTC_12x12_Format: + return true; + + default: + return false; + } +} + /** * Make sure that we properly fail when we don't have multiple of four image dimensions. */ @@ -38,6 +64,9 @@ DEF_TEST(CompressAlphaFailDimensions, reporter) { for (int i = 0; i < SkTextureCompressor::kFormatCnt; ++i) { const SkTextureCompressor::Format fmt = static_cast<SkTextureCompressor::Format>(i); + if (!compresses_a8(fmt)) { + continue; + } SkAutoDataUnref data(SkTextureCompressor::CompressBitmapToFormat(bitmap, fmt)); REPORTER_ASSERT(reporter, NULL == data); } @@ -69,6 +98,9 @@ DEF_TEST(CompressAlphaFailColorType, reporter) { for (int i = 0; i < SkTextureCompressor::kFormatCnt; ++i) { const SkTextureCompressor::Format fmt = static_cast<SkTextureCompressor::Format>(i); + if (!compresses_a8(fmt)) { + continue; + } SkAutoDataUnref data(SkTextureCompressor::CompressBitmapToFormat(bitmap, fmt)); REPORTER_ASSERT(reporter, NULL == data); } @@ -134,10 +166,7 @@ DEF_TEST(CompressCheckerboard, reporter) { // 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 and ETC1 decompression is implemented. - if (SkTextureCompressor::kASTC_12x12_Format == fmt || - SkTextureCompressor::kETC1_Format == fmt) { + if (!decompresses_a8(fmt) || !compresses_a8(fmt)) { continue; } diff --git a/third_party/ktx/ktx.cpp b/third_party/ktx/ktx.cpp index ebcc5eb187..d62833fac4 100644 --- a/third_party/ktx/ktx.cpp +++ b/third_party/ktx/ktx.cpp @@ -19,15 +19,41 @@ static inline uint32_t compressed_fmt_to_gl_define(SkTextureCompressor::Format fmt) { static const uint32_t kGLDefineMap[SkTextureCompressor::kFormatCnt] = { GR_GL_COMPRESSED_LUMINANCE_LATC1, // kLATC_Format - GR_GL_COMPRESSED_R11, // kR11_EAC_Format - GR_GL_COMPRESSED_RGB8_ETC1, // kETC1_Format + GR_GL_COMPRESSED_R11, // kR11_EAC_Format + GR_GL_COMPRESSED_RGB8_ETC1, // kETC1_Format + GR_GL_COMPRESSED_RGBA_ASTC_4x4, // kASTC_4x4_Format + GR_GL_COMPRESSED_RGBA_ASTC_5x4, // kASTC_5x4_Format + GR_GL_COMPRESSED_RGBA_ASTC_5x5, // kASTC_5x5_Format + GR_GL_COMPRESSED_RGBA_ASTC_6x5, // kASTC_6x5_Format + GR_GL_COMPRESSED_RGBA_ASTC_6x6, // kASTC_6x6_Format + GR_GL_COMPRESSED_RGBA_ASTC_8x5, // kASTC_8x5_Format + GR_GL_COMPRESSED_RGBA_ASTC_8x6, // kASTC_8x6_Format + GR_GL_COMPRESSED_RGBA_ASTC_8x8, // kASTC_8x8_Format + GR_GL_COMPRESSED_RGBA_ASTC_10x5, // kASTC_10x5_Format + GR_GL_COMPRESSED_RGBA_ASTC_10x6, // kASTC_10x6_Format + GR_GL_COMPRESSED_RGBA_ASTC_10x8, // kASTC_10x8_Format + GR_GL_COMPRESSED_RGBA_ASTC_10x10, // kASTC_10x10_Format + GR_GL_COMPRESSED_RGBA_ASTC_12x10, // kASTC_12x10_Format GR_GL_COMPRESSED_RGBA_ASTC_12x12, // kASTC_12x12_Format }; GR_STATIC_ASSERT(0 == SkTextureCompressor::kLATC_Format); GR_STATIC_ASSERT(1 == SkTextureCompressor::kR11_EAC_Format); GR_STATIC_ASSERT(2 == SkTextureCompressor::kETC1_Format); - GR_STATIC_ASSERT(3 == SkTextureCompressor::kASTC_12x12_Format); + GR_STATIC_ASSERT(3 == SkTextureCompressor::kASTC_4x4_Format); + GR_STATIC_ASSERT(4 == SkTextureCompressor::kASTC_5x4_Format); + GR_STATIC_ASSERT(5 == SkTextureCompressor::kASTC_5x5_Format); + GR_STATIC_ASSERT(6 == SkTextureCompressor::kASTC_6x5_Format); + GR_STATIC_ASSERT(7 == SkTextureCompressor::kASTC_6x6_Format); + GR_STATIC_ASSERT(8 == SkTextureCompressor::kASTC_8x5_Format); + GR_STATIC_ASSERT(9 == SkTextureCompressor::kASTC_8x6_Format); + GR_STATIC_ASSERT(10 == SkTextureCompressor::kASTC_8x8_Format); + GR_STATIC_ASSERT(11 == SkTextureCompressor::kASTC_10x5_Format); + GR_STATIC_ASSERT(12 == SkTextureCompressor::kASTC_10x6_Format); + GR_STATIC_ASSERT(13 == SkTextureCompressor::kASTC_10x8_Format); + GR_STATIC_ASSERT(14 == SkTextureCompressor::kASTC_10x10_Format); + GR_STATIC_ASSERT(15 == SkTextureCompressor::kASTC_12x10_Format); + GR_STATIC_ASSERT(16 == SkTextureCompressor::kASTC_12x12_Format); GR_STATIC_ASSERT(SK_ARRAY_COUNT(kGLDefineMap) == SkTextureCompressor::kFormatCnt); return kGLDefineMap[fmt]; |