| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkTextureCompressor_LATC.h" | 8 #include "SkTextureCompressor_LATC.h" |
| 9 #include "SkTextureCompressor_Blitter.h" | 9 #include "SkTextureCompressor_Blitter.h" |
| 10 | 10 |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 return compress_latc_block_bb_ignore_extremal(pixels); | 290 return compress_latc_block_bb_ignore_extremal(pixels); |
| 291 } | 291 } |
| 292 } | 292 } |
| 293 | 293 |
| 294 #endif // COMPRESS_LATC_SLOW | 294 #endif // COMPRESS_LATC_SLOW |
| 295 | 295 |
| 296 //////////////////////////////////////////////////////////////////////////////// | 296 //////////////////////////////////////////////////////////////////////////////// |
| 297 | 297 |
| 298 #if COMPRESS_LATC_FAST | 298 #if COMPRESS_LATC_FAST |
| 299 | 299 |
| 300 // Take the top three indices of each int and pack them into the low 12 | 300 // Take the top three bits of each index and pack them into the low 12 |
| 301 // bits of the integer. | 301 // bits of the integer. |
| 302 static inline uint32_t pack_index(uint32_t x) { |
| 303 // Pack it in... |
| 304 #if defined (SK_CPU_BENDIAN) |
| 305 return |
| 306 (x >> 24) | |
| 307 ((x >> 13) & 0x38) | |
| 308 ((x >> 2) & 0x1C0) | |
| 309 ((x << 9) & 0xE00); |
| 310 #else |
| 311 return |
| 312 (x & 0x7) | |
| 313 ((x >> 5) & 0x38) | |
| 314 ((x >> 10) & 0x1C0) | |
| 315 ((x >> 15) & 0xE00); |
| 316 #endif |
| 317 } |
| 318 |
| 319 // Converts each 8-bit byte in the integer into an LATC index, and then packs |
| 320 // the indices into the low 12 bits of the integer. |
| 302 static inline uint32_t convert_index(uint32_t x) { | 321 static inline uint32_t convert_index(uint32_t x) { |
| 303 // Since the palette is | 322 // Since the palette is |
| 304 // 255, 0, 219, 182, 146, 109, 73, 36 | 323 // 255, 0, 219, 182, 146, 109, 73, 36 |
| 305 // we need to map the high three bits of each byte in the integer | 324 // we need to map the high three bits of each byte in the integer |
| 306 // from | 325 // from |
| 307 // 0 1 2 3 4 5 6 7 | 326 // 0 1 2 3 4 5 6 7 |
| 308 // to | 327 // to |
| 309 // 1 7 6 5 4 3 2 0 | 328 // 1 7 6 5 4 3 2 0 |
| 310 // | 329 // |
| 311 // This first operation takes the mapping from | 330 // This first operation takes the mapping from |
| 312 // 0 1 2 3 4 5 6 7 --> 7 6 5 4 3 2 1 0 | 331 // 0 1 2 3 4 5 6 7 --> 7 6 5 4 3 2 1 0 |
| 313 x = 0x07070707 - ((x >> 5) & 0x07070707); | 332 x = 0x07070707 - ((x >> 5) & 0x07070707); |
| 314 | 333 |
| 315 // mask is 1 if index is non-zero | 334 // mask is 1 if index is non-zero |
| 316 const uint32_t mask = (x | (x >> 1) | (x >> 2)) & 0x01010101; | 335 const uint32_t mask = (x | (x >> 1) | (x >> 2)) & 0x01010101; |
| 317 | 336 |
| 318 // add mask: | 337 // add mask: |
| 319 // 7 6 5 4 3 2 1 0 --> 8 7 6 5 4 3 2 0 | 338 // 7 6 5 4 3 2 1 0 --> 8 7 6 5 4 3 2 0 |
| 320 x = (x + mask); | 339 x = (x + mask); |
| 321 | 340 |
| 322 // Handle overflow: | 341 // Handle overflow: |
| 323 // 8 7 6 5 4 3 2 0 --> 9 7 6 5 4 3 2 0 | 342 // 8 7 6 5 4 3 2 0 --> 9 7 6 5 4 3 2 0 |
| 324 x |= (x >> 3) & 0x01010101; | 343 x |= (x >> 3) & 0x01010101; |
| 325 | 344 |
| 326 // Mask out high bits: | 345 // Mask out high bits: |
| 327 // 9 7 6 5 4 3 2 0 --> 1 7 6 5 4 3 2 0 | 346 // 9 7 6 5 4 3 2 0 --> 1 7 6 5 4 3 2 0 |
| 328 x &= 0x07070707; | 347 x &= 0x07070707; |
| 329 | 348 |
| 330 // Pack it in... | 349 return pack_index(x); |
| 331 #if defined (SK_CPU_BENDIAN) | |
| 332 return | |
| 333 (x >> 24) | | |
| 334 ((x >> 13) & 0x38) | | |
| 335 ((x >> 2) & 0x1C0) | | |
| 336 ((x << 9) & 0xE00); | |
| 337 #else | |
| 338 return | |
| 339 (x & 0x7) | | |
| 340 ((x >> 5) & 0x38) | | |
| 341 ((x >> 10) & 0x1C0) | | |
| 342 ((x >> 15) & 0xE00); | |
| 343 #endif | |
| 344 } | 350 } |
| 345 | 351 |
| 346 typedef uint64_t (*PackIndicesProc)(const uint8_t* alpha, int rowBytes); | 352 typedef uint64_t (*PackIndicesProc)(const uint8_t* alpha, int rowBytes); |
| 347 template<PackIndicesProc packIndicesProc> | 353 template<PackIndicesProc packIndicesProc> |
| 348 static void compress_a8_latc_block(uint8_t** dstPtr, const uint8_t* src, int row
Bytes) { | 354 static void compress_a8_latc_block(uint8_t** dstPtr, const uint8_t* src, int row
Bytes) { |
| 349 *(reinterpret_cast<uint64_t*>(*dstPtr)) = | 355 *(reinterpret_cast<uint64_t*>(*dstPtr)) = |
| 350 SkEndian_SwapLE64(0xFF | (packIndicesProc(src, rowBytes) << 16)); | 356 SkEndian_SwapLE64(0xFF | (packIndicesProc(src, rowBytes) << 16)); |
| 351 *dstPtr += 8; | 357 *dstPtr += 8; |
| 352 } | 358 } |
| 353 | 359 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 struct CompressorLATC { | 426 struct CompressorLATC { |
| 421 static inline void CompressA8Vertical(uint8_t* dst, const uint8_t block[]) { | 427 static inline void CompressA8Vertical(uint8_t* dst, const uint8_t block[]) { |
| 422 compress_a8_latc_block<PackColumnMajor>(&dst, block, 4); | 428 compress_a8_latc_block<PackColumnMajor>(&dst, block, 4); |
| 423 } | 429 } |
| 424 | 430 |
| 425 static inline void CompressA8Horizontal(uint8_t* dst, const uint8_t* src, | 431 static inline void CompressA8Horizontal(uint8_t* dst, const uint8_t* src, |
| 426 int srcRowBytes) { | 432 int srcRowBytes) { |
| 427 compress_a8_latc_block<PackRowMajor>(&dst, src, srcRowBytes); | 433 compress_a8_latc_block<PackRowMajor>(&dst, src, srcRowBytes); |
| 428 } | 434 } |
| 429 | 435 |
| 430 static inline void UpdateBlock(uint8_t* dst, const uint8_t* src) { | 436 #if PEDANTIC_BLIT_RECT |
| 437 static inline void UpdateBlock(uint8_t* dst, const uint8_t* src, int srcRowB
ytes, |
| 438 const uint8_t* mask) { |
| 439 // Pack the mask |
| 440 uint64_t cmpMask = 0; |
| 441 for (int i = 0; i < 4; ++i) { |
| 442 const uint32_t idx = *(reinterpret_cast<const uint32_t*>(src + i*src
RowBytes)); |
| 443 cmpMask |= static_cast<uint64_t>(pack_index(idx)) << 12*i; |
| 444 } |
| 445 cmpMask = SkEndian_SwapLE64(cmpMask << 16); // avoid header |
| 446 |
| 447 uint64_t cmpSrc; |
| 448 uint8_t *cmpSrcPtr = reinterpret_cast<uint8_t*>(&cmpSrc); |
| 449 compress_a8_latc_block<PackRowMajor>(&cmpSrcPtr, src, srcRowBytes); |
| 450 |
| 451 // Mask out header |
| 452 cmpSrc = cmpSrc & cmpMask; |
| 453 |
| 454 // Read destination encoding |
| 455 uint64_t *cmpDst = reinterpret_cast<uint64_t*>(dst); |
| 456 |
| 457 // If the destination is the encoding for a blank block, then we need |
| 458 // to properly set the header |
| 459 if (0 == cmpDst) { |
| 460 *cmpDst = SkTEndian_SwapLE64(0x24924924924900FFULL); |
| 461 } |
| 462 |
| 463 // Set the new indices |
| 464 *cmpDst &= ~cmpMask; |
| 465 *cmpDst |= cmpSrc; |
| 431 } | 466 } |
| 467 #endif // PEDANTIC_BLIT_RECT |
| 432 }; | 468 }; |
| 433 | 469 |
| 434 //////////////////////////////////////////////////////////////////////////////// | 470 //////////////////////////////////////////////////////////////////////////////// |
| 435 | 471 |
| 436 namespace SkTextureCompressor { | 472 namespace SkTextureCompressor { |
| 437 | 473 |
| 438 bool CompressA8ToLATC(uint8_t* dst, const uint8_t* src, int width, int height, i
nt rowBytes) { | 474 bool CompressA8ToLATC(uint8_t* dst, const uint8_t* src, int width, int height, i
nt rowBytes) { |
| 439 #if COMPRESS_LATC_FAST | 475 #if COMPRESS_LATC_FAST |
| 440 return compress_4x4_a8_latc(dst, src, width, height, rowBytes); | 476 return compress_4x4_a8_latc(dst, src, width, height, rowBytes); |
| 441 #elif COMPRESS_LATC_SLOW | 477 #elif COMPRESS_LATC_SLOW |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 for (int j = 0; j < height; j += 4) { | 509 for (int j = 0; j < height; j += 4) { |
| 474 for (int i = 0; i < width; i += 4) { | 510 for (int i = 0; i < width; i += 4) { |
| 475 decompress_latc_block(dst + i, dstRowBytes, src); | 511 decompress_latc_block(dst + i, dstRowBytes, src); |
| 476 src += 8; | 512 src += 8; |
| 477 } | 513 } |
| 478 dst += 4 * dstRowBytes; | 514 dst += 4 * dstRowBytes; |
| 479 } | 515 } |
| 480 } | 516 } |
| 481 | 517 |
| 482 } // SkTextureCompressor | 518 } // SkTextureCompressor |
| OLD | NEW |