diff options
Diffstat (limited to 'src/utils/SkTextureCompressor_LATC.cpp')
-rw-r--r-- | src/utils/SkTextureCompressor_LATC.cpp | 70 |
1 files changed, 53 insertions, 17 deletions
diff --git a/src/utils/SkTextureCompressor_LATC.cpp b/src/utils/SkTextureCompressor_LATC.cpp index c9bf89ea4c..1e5e142ddb 100644 --- a/src/utils/SkTextureCompressor_LATC.cpp +++ b/src/utils/SkTextureCompressor_LATC.cpp @@ -297,8 +297,27 @@ static uint64_t compress_latc_block(const uint8_t pixels[]) { #if COMPRESS_LATC_FAST -// Take the top three indices of each int and pack them into the low 12 +// Take the top three bits of each index and pack them into the low 12 // bits of the integer. +static inline uint32_t pack_index(uint32_t x) { + // Pack it in... +#if defined (SK_CPU_BENDIAN) + return + (x >> 24) | + ((x >> 13) & 0x38) | + ((x >> 2) & 0x1C0) | + ((x << 9) & 0xE00); +#else + return + (x & 0x7) | + ((x >> 5) & 0x38) | + ((x >> 10) & 0x1C0) | + ((x >> 15) & 0xE00); +#endif +} + +// Converts each 8-bit byte in the integer into an LATC index, and then packs +// the indices into the low 12 bits of the integer. static inline uint32_t convert_index(uint32_t x) { // Since the palette is // 255, 0, 219, 182, 146, 109, 73, 36 @@ -326,21 +345,8 @@ static inline uint32_t convert_index(uint32_t x) { // Mask out high bits: // 9 7 6 5 4 3 2 0 --> 1 7 6 5 4 3 2 0 x &= 0x07070707; - - // Pack it in... -#if defined (SK_CPU_BENDIAN) - return - (x >> 24) | - ((x >> 13) & 0x38) | - ((x >> 2) & 0x1C0) | - ((x << 9) & 0xE00); -#else - return - (x & 0x7) | - ((x >> 5) & 0x38) | - ((x >> 10) & 0x1C0) | - ((x >> 15) & 0xE00); -#endif + + return pack_index(x); } typedef uint64_t (*PackIndicesProc)(const uint8_t* alpha, int rowBytes); @@ -427,8 +433,38 @@ struct CompressorLATC { compress_a8_latc_block<PackRowMajor>(&dst, src, srcRowBytes); } - static inline void UpdateBlock(uint8_t* dst, const uint8_t* src) { +#if PEDANTIC_BLIT_RECT + static inline void UpdateBlock(uint8_t* dst, const uint8_t* src, int srcRowBytes, + const uint8_t* mask) { + // Pack the mask + uint64_t cmpMask = 0; + for (int i = 0; i < 4; ++i) { + const uint32_t idx = *(reinterpret_cast<const uint32_t*>(src + i*srcRowBytes)); + cmpMask |= static_cast<uint64_t>(pack_index(idx)) << 12*i; + } + cmpMask = SkEndian_SwapLE64(cmpMask << 16); // avoid header + + uint64_t cmpSrc; + uint8_t *cmpSrcPtr = reinterpret_cast<uint8_t*>(&cmpSrc); + compress_a8_latc_block<PackRowMajor>(&cmpSrcPtr, src, srcRowBytes); + + // Mask out header + cmpSrc = cmpSrc & cmpMask; + + // Read destination encoding + uint64_t *cmpDst = reinterpret_cast<uint64_t*>(dst); + + // If the destination is the encoding for a blank block, then we need + // to properly set the header + if (0 == cmpDst) { + *cmpDst = SkTEndian_SwapLE64(0x24924924924900FFULL); + } + + // Set the new indices + *cmpDst &= ~cmpMask; + *cmpDst |= cmpSrc; } +#endif // PEDANTIC_BLIT_RECT }; //////////////////////////////////////////////////////////////////////////////// |