| Index: src/utils/SkTextureCompressor_LATC.cpp
|
| diff --git a/src/utils/SkTextureCompressor_LATC.cpp b/src/utils/SkTextureCompressor_LATC.cpp
|
| index c9bf89ea4c1bc648a194a1ad5ccc3517ccd0cf41..1e5e142ddb8d9911eb5de3f419b8f379f978a70f 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
|
| };
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|