aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils/SkTextureCompressor_LATC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/SkTextureCompressor_LATC.cpp')
-rw-r--r--src/utils/SkTextureCompressor_LATC.cpp70
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
};
////////////////////////////////////////////////////////////////////////////////