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 |
}; |
//////////////////////////////////////////////////////////////////////////////// |