aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/utils/SkTextureCompressor.cpp31
-rw-r--r--src/utils/SkTextureCompressor.h28
-rw-r--r--src/utils/SkTextureCompressor_LATC.cpp106
-rw-r--r--src/utils/SkTextureCompressor_LATC.h2
-rw-r--r--src/utils/SkTextureCompressor_R11EAC.cpp46
-rw-r--r--src/utils/SkTextureCompressor_R11EAC.h2
-rw-r--r--tests/TextureCompressionTest.cpp80
7 files changed, 46 insertions, 249 deletions
diff --git a/src/utils/SkTextureCompressor.cpp b/src/utils/SkTextureCompressor.cpp
index e0b751f3f7..30fd3072d5 100644
--- a/src/utils/SkTextureCompressor.cpp
+++ b/src/utils/SkTextureCompressor.cpp
@@ -20,16 +20,15 @@
namespace SkTextureCompressor {
-void GetBlockDimensions(Format format, int* dimX, int* dimY, bool matchSpec) {
+void GetBlockDimensions(Format format, int* dimX, int* dimY) {
if (NULL == dimX || NULL == dimY) {
return;
}
- if (!matchSpec && SkTextureCompressorGetPlatformDims(format, dimX, dimY)) {
+ if (SkTextureCompressorGetPlatformDims(format, dimX, dimY)) {
return;
}
- // No specialized arguments, return the dimensions as they are in the spec.
switch(format) {
// These formats are 64 bits per 4x4 block.
default:
@@ -160,30 +159,4 @@ SkBlitter* CreateBlitterForFormat(int width, int height, void* compressedBuffer,
return NULL;
}
-bool DecompressBufferFromFormat(uint8_t* dst, int dstRowBytes, const uint8_t* src,
- int width, int height, Format format) {
- int dimX, dimY;
- GetBlockDimensions(format, &dimX, &dimY, true);
-
- if (width < 0 || ((width % dimX) != 0) || height < 0 || ((height % dimY) != 0)) {
- return false;
- }
-
- switch(format) {
- case kLATC_Format:
- DecompressLATC(dst, dstRowBytes, src, width, height);
- return true;
-
- case kR11_EAC_Format:
- DecompressR11EAC(dst, dstRowBytes, src, width, height);
- return true;
-
- case kASTC_12x12_Format:
- // TODO(krajcevski) .. right now just fall through and return false.
- return false;
- }
-
- return false;
-}
-
} // namespace SkTextureCompressor
diff --git a/src/utils/SkTextureCompressor.h b/src/utils/SkTextureCompressor.h
index eac8c5eea3..c6305bab45 100644
--- a/src/utils/SkTextureCompressor.h
+++ b/src/utils/SkTextureCompressor.h
@@ -44,24 +44,6 @@ namespace SkTextureCompressor {
int width, int height, int rowBytes, Format format,
bool opt = true /* Use optimization if available */);
- // Decompresses the given src data from the format specified into the
- // 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
- //
- // Note, CompressBufferToFormat compresses A8 data into ASTC. However,
- // general ASTC data encodes RGBA data, so that is what the decompressor
- // operates on.
- //
- // Returns true if successfully decompresses the src data.
- bool DecompressBufferFromFormat(uint8_t* dst, int dstRowBytes, const uint8_t* src,
- int width, int height, Format format);
-
// This typedef defines what the nominal aspects of a compression function
// are. The typedef is not meant to be used by clients of the API, but rather
// allows SIMD optimized compression functions to be implemented.
@@ -75,12 +57,10 @@ namespace SkTextureCompressor {
Format format);
// Returns the desired dimensions of the block size for the given format. These dimensions
- // don't necessarily correspond to the specification's dimensions, since there may
- // be specialized algorithms that operate on multiple blocks at once. If the
- // flag 'matchSpec' is true, then the actual dimensions from the specification are
- // returned. If the flag is false, then these dimensions reflect the appropriate operable
- // dimensions of the compression functions.
- void GetBlockDimensions(Format format, int* dimX, int* dimY, bool matchSpec = false);
+ // don't necessarily correspond to the hardware-specified dimensions, since there may
+ // be specialized algorithms that operate on multiple blocks at once. These dimensions
+ // reflect that optimization and return the appropriate operable dimensions.
+ void GetBlockDimensions(Format format, int* dimX, int* dimY);
}
#endif
diff --git a/src/utils/SkTextureCompressor_LATC.cpp b/src/utils/SkTextureCompressor_LATC.cpp
index 5db0fc6c04..9d42b4f71d 100644
--- a/src/utils/SkTextureCompressor_LATC.cpp
+++ b/src/utils/SkTextureCompressor_LATC.cpp
@@ -17,46 +17,6 @@
////////////////////////////////////////////////////////////////////////////////
-// Generates an LATC palette. LATC constructs
-// a palette of eight colors from LUM0 and LUM1 using the algorithm:
-//
-// LUM0, if lum0 > lum1 and code(x,y) == 0
-// LUM1, if lum0 > lum1 and code(x,y) == 1
-// (6*LUM0+ LUM1)/7, if lum0 > lum1 and code(x,y) == 2
-// (5*LUM0+2*LUM1)/7, if lum0 > lum1 and code(x,y) == 3
-// (4*LUM0+3*LUM1)/7, if lum0 > lum1 and code(x,y) == 4
-// (3*LUM0+4*LUM1)/7, if lum0 > lum1 and code(x,y) == 5
-// (2*LUM0+5*LUM1)/7, if lum0 > lum1 and code(x,y) == 6
-// ( LUM0+6*LUM1)/7, if lum0 > lum1 and code(x,y) == 7
-//
-// LUM0, if lum0 <= lum1 and code(x,y) == 0
-// LUM1, if lum0 <= lum1 and code(x,y) == 1
-// (4*LUM0+ LUM1)/5, if lum0 <= lum1 and code(x,y) == 2
-// (3*LUM0+2*LUM1)/5, if lum0 <= lum1 and code(x,y) == 3
-// (2*LUM0+3*LUM1)/5, if lum0 <= lum1 and code(x,y) == 4
-// ( LUM0+4*LUM1)/5, if lum0 <= lum1 and code(x,y) == 5
-// 0, if lum0 <= lum1 and code(x,y) == 6
-// 255, if lum0 <= lum1 and code(x,y) == 7
-
-static const int kLATCPaletteSize = 8;
-static void generate_latc_palette(uint8_t palette[], uint8_t lum0, uint8_t lum1) {
- palette[0] = lum0;
- palette[1] = lum1;
- if (lum0 > lum1) {
- for (int i = 1; i < 7; i++) {
- palette[i+1] = ((7-i)*lum0 + i*lum1) / 7;
- }
- } else {
- for (int i = 1; i < 5; i++) {
- palette[i+1] = ((5-i)*lum0 + i*lum1) / 5;
- }
- palette[6] = 0;
- palette[7] = 255;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
#if COMPRESS_LATC_SLOW
////////////////////////////////////////////////////////////////////////////////
@@ -119,9 +79,47 @@ static bool compress_4x4_a8_to_64bit(uint8_t* dst, const uint8_t* src,
////////////////////////////////////////////////////////////////////////////////
// LATC compressed texels down into square 4x4 blocks
+static const int kLATCPaletteSize = 8;
static const int kLATCBlockSize = 4;
static const int kLATCPixelsPerBlock = kLATCBlockSize * kLATCBlockSize;
+// Generates an LATC palette. LATC constructs
+// a palette of eight colors from LUM0 and LUM1 using the algorithm:
+//
+// LUM0, if lum0 > lum1 and code(x,y) == 0
+// LUM1, if lum0 > lum1 and code(x,y) == 1
+// (6*LUM0+ LUM1)/7, if lum0 > lum1 and code(x,y) == 2
+// (5*LUM0+2*LUM1)/7, if lum0 > lum1 and code(x,y) == 3
+// (4*LUM0+3*LUM1)/7, if lum0 > lum1 and code(x,y) == 4
+// (3*LUM0+4*LUM1)/7, if lum0 > lum1 and code(x,y) == 5
+// (2*LUM0+5*LUM1)/7, if lum0 > lum1 and code(x,y) == 6
+// ( LUM0+6*LUM1)/7, if lum0 > lum1 and code(x,y) == 7
+//
+// LUM0, if lum0 <= lum1 and code(x,y) == 0
+// LUM1, if lum0 <= lum1 and code(x,y) == 1
+// (4*LUM0+ LUM1)/5, if lum0 <= lum1 and code(x,y) == 2
+// (3*LUM0+2*LUM1)/5, if lum0 <= lum1 and code(x,y) == 3
+// (2*LUM0+3*LUM1)/5, if lum0 <= lum1 and code(x,y) == 4
+// ( LUM0+4*LUM1)/5, if lum0 <= lum1 and code(x,y) == 5
+// 0, if lum0 <= lum1 and code(x,y) == 6
+// 255, if lum0 <= lum1 and code(x,y) == 7
+
+static void generate_latc_palette(uint8_t palette[], uint8_t lum0, uint8_t lum1) {
+ palette[0] = lum0;
+ palette[1] = lum1;
+ if (lum0 > lum1) {
+ for (int i = 1; i < 7; i++) {
+ palette[i+1] = ((7-i)*lum0 + i*lum1) / 7;
+ }
+ } else {
+ for (int i = 1; i < 5; i++) {
+ palette[i+1] = ((5-i)*lum0 + i*lum1) / 5;
+ }
+ palette[6] = 0;
+ palette[7] = 255;
+ }
+}
+
// Compress a block by using the bounding box of the pixels. It is assumed that
// there are no extremal pixels in this block otherwise we would have used
// compressBlockBBIgnoreExtremal.
@@ -395,24 +393,6 @@ void CompressA8LATCBlockVertical(uint8_t* dst, const uint8_t block[]) {
#endif // COMPRESS_LATC_FAST
-void decompress_latc_block(uint8_t* dst, int dstRowBytes, const uint8_t* src) {
- uint64_t block = SkEndian_SwapLE64(*(reinterpret_cast<const uint64_t *>(src)));
- uint8_t lum0 = block & 0xFF;
- uint8_t lum1 = (block >> 8) & 0xFF;
-
- uint8_t palette[kLATCPaletteSize];
- generate_latc_palette(palette, lum0, lum1);
-
- block >>= 16;
- for (int j = 0; j < 4; ++j) {
- for (int i = 0; i < 4; ++i) {
- dst[i] = palette[block & 0x7];
- block >>= 3;
- }
- dst += dstRowBytes;
- }
-}
-
////////////////////////////////////////////////////////////////////////////////
namespace SkTextureCompressor {
@@ -438,14 +418,4 @@ SkBlitter* CreateLATCBlitter(int width, int height, void* outputBuffer) {
#endif
}
-void DecompressLATC(uint8_t* dst, int dstRowBytes, const uint8_t* src, int width, int height) {
- for (int j = 0; j < height; j += 4) {
- for (int i = 0; i < width; i += 4) {
- decompress_latc_block(dst + i, dstRowBytes, src);
- src += 8;
- }
- dst += 4 * dstRowBytes;
- }
-}
-
} // SkTextureCompressor
diff --git a/src/utils/SkTextureCompressor_LATC.h b/src/utils/SkTextureCompressor_LATC.h
index 6ee2ff63e2..e3446b546d 100644
--- a/src/utils/SkTextureCompressor_LATC.h
+++ b/src/utils/SkTextureCompressor_LATC.h
@@ -16,8 +16,6 @@ namespace SkTextureCompressor {
int width, int height, int rowBytes);
SkBlitter* CreateLATCBlitter(int width, int height, void* outputBuffer);
-
- void DecompressLATC(uint8_t* dst, int dstRowBytes, const uint8_t* src, int width, int height);
}
#endif // SkTextureCompressor_LATC_DEFINED
diff --git a/src/utils/SkTextureCompressor_R11EAC.cpp b/src/utils/SkTextureCompressor_R11EAC.cpp
index 7baa219a28..982fb012ef 100644
--- a/src/utils/SkTextureCompressor_R11EAC.cpp
+++ b/src/utils/SkTextureCompressor_R11EAC.cpp
@@ -29,6 +29,8 @@
// If mul is zero, then we set mul = 1/8, so that the formula becomes
// clamp[0, 2047](base_cw * 8 + 4 + mod_val)
+#if COMPRESS_R11_EAC_SLOW
+
static const int kNumR11EACPalettes = 16;
static const int kR11EACPaletteSize = 8;
static const int kR11EACModifierPalettes[kNumR11EACPalettes][kR11EACPaletteSize] = {
@@ -50,8 +52,6 @@ static const int kR11EACModifierPalettes[kNumR11EACPalettes][kR11EACPaletteSize]
{-3, -5, -7, -9, 2, 4, 6, 8}
};
-#if COMPRESS_R11_EAC_SLOW
-
// Pack the base codeword, palette, and multiplier into the 64 bits necessary
// to decode it.
static uint64_t pack_r11eac_block(uint16_t base_cw, uint16_t palette, uint16_t multiplier,
@@ -557,38 +557,6 @@ inline void compress_block_vertical(uint8_t* dstPtr, const uint8_t *block) {
static_cast<uint64_t>(packedIndexColumn3));
}
-static inline int get_r11_eac_index(uint64_t block, int x, int y) {
- SkASSERT(x >= 0 && x < 4);
- SkASSERT(y >= 0 && y < 4);
- const int idx = x*4 + y;
- return (block >> ((15-idx)*3)) & 0x7;
-}
-
-static void decompress_r11_eac_block(uint8_t* dst, int dstRowBytes, const uint8_t* src) {
- const uint64_t block = SkEndian_SwapBE64(*(reinterpret_cast<const uint64_t *>(src)));
-
- const int base_cw = (block >> 56) & 0xFF;
- const int mod = (block >> 52) & 0xF;
- const int palette_idx = (block >> 48) & 0xF;
-
- const int* palette = kR11EACModifierPalettes[palette_idx];
-
- for (int j = 0; j < 4; ++j) {
- for (int i = 0; i < 4; ++i) {
- const int idx = get_r11_eac_index(block, i, j);
- const int val = base_cw*8 + 4 + palette[idx]*mod*8;
- if (val < 0) {
- dst[i] = 0;
- } else if (val > 2047) {
- dst[i] = 0xFF;
- } else {
- dst[i] = (val >> 3) & 0xFF;
- }
- }
- dst += dstRowBytes;
- }
-}
-
////////////////////////////////////////////////////////////////////////////////
namespace SkTextureCompressor {
@@ -614,14 +582,4 @@ SkBlitter* CreateR11EACBlitter(int width, int height, void* outputBuffer) {
(width, height, outputBuffer);
}
-void DecompressR11EAC(uint8_t* dst, int dstRowBytes, const uint8_t* src, int width, int height) {
- for (int j = 0; j < height; j += 4) {
- for (int i = 0; i < width; i += 4) {
- decompress_r11_eac_block(dst + i, dstRowBytes, src);
- src += 8;
- }
- dst += 4 * dstRowBytes;
- }
-}
-
} // namespace SkTextureCompressor
diff --git a/src/utils/SkTextureCompressor_R11EAC.h b/src/utils/SkTextureCompressor_R11EAC.h
index 1dd8e395a8..5f981ef46f 100644
--- a/src/utils/SkTextureCompressor_R11EAC.h
+++ b/src/utils/SkTextureCompressor_R11EAC.h
@@ -16,8 +16,6 @@ namespace SkTextureCompressor {
int width, int height, int rowBytes);
SkBlitter* CreateR11EACBlitter(int width, int height, void* outputBuffer);
-
- void DecompressR11EAC(uint8_t* dst, int dstRB, const uint8_t* src, int width, int height);
}
#endif // SkTextureCompressor_R11EAC_DEFINED
diff --git a/tests/TextureCompressionTest.cpp b/tests/TextureCompressionTest.cpp
index 7313487ffc..503605b003 100644
--- a/tests/TextureCompressionTest.cpp
+++ b/tests/TextureCompressionTest.cpp
@@ -75,86 +75,6 @@ DEF_TEST(CompressAlphaFailColorType, reporter) {
}
/**
- * Make sure that if you compress a texture with alternating black/white pixels, and
- * then decompress it, you get what you started with.
- */
-DEF_TEST(CompressCheckerboard, reporter) {
- SkBitmap bitmap;
- static const int kWidth = 12;
- static const int kHeight = 12;
- SkImageInfo info = SkImageInfo::MakeA8(kWidth, kHeight);
-
- // ASTC is at most 12x12, and any dimension divisible by 12 is also divisible
- // by 4, which is the dimensions of R11_EAC and LATC. In the future, we might
- // support additional variants of ASTC, such as 5x6 and 8x8, in which case this would
- // need to be updated.
- REPORTER_ASSERT(reporter, kWidth % 12 == 0);
- REPORTER_ASSERT(reporter, kHeight % 12 == 0);
-
- bool setInfoSuccess = bitmap.setInfo(info);
- REPORTER_ASSERT(reporter, setInfoSuccess);
-
- bool allocPixelsSuccess = bitmap.allocPixels(info);
- REPORTER_ASSERT(reporter, allocPixelsSuccess);
-
- bitmap.lockPixels();
- uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap.getPixels());
- REPORTER_ASSERT(reporter, NULL != pixels);
-
- for (int y = 0; y < kHeight; ++y) {
- for (int x = 0; x < kWidth; ++x) {
- if ((x ^ y) & 1) {
- pixels[x] = 0xFF;
- } else {
- pixels[x] = 0;
- }
- }
- pixels += bitmap.rowBytes();
- }
- bitmap.unlockPixels();
-
- SkAutoMalloc decompMemory(kWidth*kHeight);
- uint8_t* decompBuffer = reinterpret_cast<uint8_t*>(decompMemory.get());
- REPORTER_ASSERT(reporter, NULL != decompBuffer);
- if (NULL == decompBuffer) {
- return;
- }
-
- 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
- // 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) {
- continue;
- }
-
- SkAutoDataUnref data(SkTextureCompressor::CompressBitmapToFormat(bitmap, fmt));
- REPORTER_ASSERT(reporter, NULL != data);
-
- bool decompResult =
- SkTextureCompressor::DecompressBufferFromFormat(
- decompBuffer, kWidth,
- data->bytes(),
- kWidth, kHeight, fmt);
- REPORTER_ASSERT(reporter, decompResult);
-
- bitmap.lockPixels();
- pixels = reinterpret_cast<uint8_t*>(bitmap.getPixels());
- REPORTER_ASSERT(reporter, NULL != pixels);
-
- for (int y = 0; y < kHeight; ++y) {
- for (int x = 0; x < kWidth; ++x) {
- bool ok = pixels[y*bitmap.rowBytes() + x] == decompBuffer[y*kWidth + x];
- REPORTER_ASSERT(reporter, ok);
- }
- }
- }
-}
-
-/**
* Make sure that if we pass in a solid color bitmap that we get the appropriate results
*/
DEF_TEST(CompressLATC, reporter) {