| 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.h" | 8 #include "SkTextureCompressor.h" |
| 9 | 9 |
| 10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
| 11 #include "SkData.h" | 11 #include "SkData.h" |
| 12 #include "SkEndian.h" | 12 #include "SkEndian.h" |
| 13 | 13 |
| 14 #include "SkTextureCompression_opts.h" | |
| 15 | |
| 16 //////////////////////////////////////////////////////////////////////////////// | 14 //////////////////////////////////////////////////////////////////////////////// |
| 17 // | 15 // |
| 18 // Utility Functions | 16 // Utility Functions |
| 19 // | 17 // |
| 20 //////////////////////////////////////////////////////////////////////////////// | 18 //////////////////////////////////////////////////////////////////////////////// |
| 21 | 19 |
| 22 // Absolute difference between two values. More correct than SkTAbs(a - b) | 20 // Absolute difference between two values. More correct than SkTAbs(a - b) |
| 23 // because it works on unsigned values. | 21 // because it works on unsigned values. |
| 24 template <typename T> inline T abs_diff(const T &a, const T &b) { | 22 template <typename T> inline T abs_diff(const T &a, const T &b) { |
| 25 return (a > b) ? (a - b) : (b - a); | 23 return (a > b) ? (a - b) : (b - a); |
| (...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 // using a shuffle and a few shift-rotates... | 579 // using a shuffle and a few shift-rotates... |
| 582 uint64_t x = (static_cast<uint64_t>(topRows) << 32) | static_cast<uint64_t>(
bottomRows); | 580 uint64_t x = (static_cast<uint64_t>(topRows) << 32) | static_cast<uint64_t>(
bottomRows); |
| 583 | 581 |
| 584 // x: 00 a e 00 b f 00 c g 00 d h 00 i m 00 j n 00 k o 00 l p | 582 // x: 00 a e 00 b f 00 c g 00 d h 00 i m 00 j n 00 k o 00 l p |
| 585 | 583 |
| 586 uint64_t t = (x ^ (x >> 10)) & 0x3FC0003FC00000ULL; | 584 uint64_t t = (x ^ (x >> 10)) & 0x3FC0003FC00000ULL; |
| 587 x = x ^ t ^ (t << 10); | 585 x = x ^ t ^ (t << 10); |
| 588 | 586 |
| 589 // x: b f 00 00 00 a e c g i m 00 00 00 d h j n 00 k o 00 l p | 587 // x: b f 00 00 00 a e c g i m 00 00 00 d h j n 00 k o 00 l p |
| 590 | 588 |
| 591 x = (x | ((x << 52) & (0x3FULL << 52)) | ((x << 20) & (0x3FULL << 28))) >> 1
6; | 589 x |= ((x << 52) & (0x3FULL << 52)); |
| 590 x = (x | ((x << 20) & (0x3FULL << 28))) >> 16; |
| 592 | 591 |
| 592 #if defined (SK_CPU_BENDIAN) |
| 593 // x: 00 00 00 00 00 00 00 00 b f l p a e c g i m k o d h j n | 593 // x: 00 00 00 00 00 00 00 00 b f l p a e c g i m k o d h j n |
| 594 | 594 |
| 595 t = (x ^ (x >> 6)) & 0xFC0000ULL; | 595 t = (x ^ (x >> 6)) & 0xFC0000ULL; |
| 596 x = x ^ t ^ (t << 6); | 596 x = x ^ t ^ (t << 6); |
| 597 | 597 |
| 598 #if defined (SK_CPU_BENDIAN) | |
| 599 // x: 00 00 00 00 00 00 00 00 b f l p a e i m c g k o d h j n | 598 // x: 00 00 00 00 00 00 00 00 b f l p a e i m c g k o d h j n |
| 600 | 599 |
| 601 t = (x ^ (x >> 36)) & 0x3FULL; | 600 t = (x ^ (x >> 36)) & 0x3FULL; |
| 602 x = x ^ t ^ (t << 36); | 601 x = x ^ t ^ (t << 36); |
| 603 | 602 |
| 604 // x: 00 00 00 00 00 00 00 00 b f j n a e i m c g k o d h l p | 603 // x: 00 00 00 00 00 00 00 00 b f j n a e i m c g k o d h l p |
| 605 | 604 |
| 606 t = (x ^ (x >> 12)) & 0xFFF000000ULL; | 605 t = (x ^ (x >> 12)) & 0xFFF000000ULL; |
| 607 x = x ^ t ^ (t << 12); | 606 x = x ^ t ^ (t << 12); |
| 608 | 607 |
| 609 // x: 00 00 00 00 00 00 00 00 a e i m b f j n c g k o d h l p | 608 // x: 00 00 00 00 00 00 00 00 a e i m b f j n c g k o d h l p |
| 610 return x; | 609 return x; |
| 611 #else | 610 #else |
| 612 // If our CPU is little endian, then the above logic will | 611 // If our CPU is little endian, then the above logic will |
| 613 // produce the following indices: | 612 // produce the following indices: |
| 613 // x: 00 00 00 00 00 00 00 00 c g i m d h b f l p j n a e k o |
| 614 |
| 615 t = (x ^ (x >> 6)) & 0xFC0000ULL; |
| 616 x = x ^ t ^ (t << 6); |
| 617 |
| 614 // x: 00 00 00 00 00 00 00 00 c g i m d h l p b f j n a e k o | 618 // x: 00 00 00 00 00 00 00 00 c g i m d h l p b f j n a e k o |
| 615 | 619 |
| 616 t = (x ^ (x >> 36)) & 0xFC0ULL; | 620 t = (x ^ (x >> 36)) & 0xFC0ULL; |
| 617 x = x ^ t ^ (t << 36); | 621 x = x ^ t ^ (t << 36); |
| 618 | 622 |
| 619 // x: 00 00 00 00 00 00 00 00 a e i m d h l p b f j n c g k o | 623 // x: 00 00 00 00 00 00 00 00 a e i m d h l p b f j n c g k o |
| 620 | 624 |
| 621 x = (x & (0xFFFULL << 36)) | ((x & 0xFFFFFFULL) << 12) | ((x >> 24) & 0xFFFU
LL); | 625 x = (x & (0xFFFULL << 36)) | ((x & 0xFFFFFFULL) << 12) | ((x >> 24) & 0xFFFU
LL); |
| 622 | 626 |
| 623 // x: 00 00 00 00 00 00 00 00 a e i m b f j n c g k o d h l p | 627 // x: 00 00 00 00 00 00 00 00 a e i m b f j n c g k o d h l p |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 | 763 |
| 760 return blocksX * blocksY * kLATCEncodedBlockSize; | 764 return blocksX * blocksY * kLATCEncodedBlockSize; |
| 761 } | 765 } |
| 762 | 766 |
| 763 default: | 767 default: |
| 764 SkFAIL("Unknown compressed format!"); | 768 SkFAIL("Unknown compressed format!"); |
| 765 return 0; | 769 return 0; |
| 766 } | 770 } |
| 767 } | 771 } |
| 768 | 772 |
| 773 typedef bool (*CompressBitmapProc)(uint8_t* dst, const uint8_t* src, |
| 774 int width, int height, int rowBytes); |
| 775 |
| 769 bool CompressBufferToFormat(uint8_t* dst, const uint8_t* src, SkColorType srcCol
orType, | 776 bool CompressBufferToFormat(uint8_t* dst, const uint8_t* src, SkColorType srcCol
orType, |
| 770 int width, int height, int rowBytes, Format format,
bool opt) { | 777 int width, int height, int rowBytes, Format format)
{ |
| 771 CompressionProc proc = NULL; | |
| 772 if (opt) { | |
| 773 proc = SkTextureCompressorGetPlatformProc(srcColorType, format); | |
| 774 } | |
| 775 | 778 |
| 776 if (NULL == proc) { | 779 CompressBitmapProc kProcMap[kFormatCnt][kLastEnum_SkColorType + 1]; |
| 777 switch (srcColorType) { | 780 memset(kProcMap, 0, sizeof(kProcMap)); |
| 778 case kAlpha_8_SkColorType: | |
| 779 { | |
| 780 switch (format) { | |
| 781 case kLATC_Format: | |
| 782 proc = compress_a8_to_latc; | |
| 783 break; | |
| 784 case kR11_EAC_Format: | |
| 785 proc = compress_a8_to_r11eac; | |
| 786 break; | |
| 787 default: | |
| 788 // Do nothing... | |
| 789 break; | |
| 790 } | |
| 791 } | |
| 792 break; | |
| 793 | 781 |
| 794 default: | 782 kProcMap[kLATC_Format][kAlpha_8_SkColorType] = compress_a8_to_latc; |
| 795 // Do nothing... | 783 kProcMap[kR11_EAC_Format][kAlpha_8_SkColorType] = compress_a8_to_r11eac; |
| 796 break; | |
| 797 } | |
| 798 } | |
| 799 | 784 |
| 785 CompressBitmapProc proc = kProcMap[format][srcColorType]; |
| 800 if (NULL != proc) { | 786 if (NULL != proc) { |
| 801 return proc(dst, src, width, height, rowBytes); | 787 return proc(dst, src, width, height, rowBytes); |
| 802 } | 788 } |
| 803 | 789 |
| 804 return false; | 790 return false; |
| 805 } | 791 } |
| 806 | 792 |
| 807 SkData *CompressBitmapToFormat(const SkBitmap &bitmap, Format format) { | 793 SkData *CompressBitmapToFormat(const SkBitmap &bitmap, Format format) { |
| 808 SkAutoLockPixels alp(bitmap); | 794 SkAutoLockPixels alp(bitmap); |
| 809 | 795 |
| 810 int compressedDataSize = get_compressed_data_size(format, bitmap.width(), bi
tmap.height()); | 796 int compressedDataSize = get_compressed_data_size(format, bitmap.width(), bi
tmap.height()); |
| 811 const uint8_t* src = reinterpret_cast<const uint8_t*>(bitmap.getPixels()); | 797 const uint8_t* src = reinterpret_cast<const uint8_t*>(bitmap.getPixels()); |
| 812 uint8_t* dst = reinterpret_cast<uint8_t*>(sk_malloc_throw(compressedDataSize
)); | 798 uint8_t* dst = reinterpret_cast<uint8_t*>(sk_malloc_throw(compressedDataSize
)); |
| 813 if (CompressBufferToFormat(dst, src, bitmap.colorType(), bitmap.width(), bit
map.height(), | 799 if (CompressBufferToFormat(dst, src, bitmap.colorType(), bitmap.width(), bit
map.height(), |
| 814 bitmap.rowBytes(), format)) { | 800 bitmap.rowBytes(), format)) { |
| 815 return SkData::NewFromMalloc(dst, compressedDataSize); | 801 return SkData::NewFromMalloc(dst, compressedDataSize); |
| 816 } | 802 } |
| 817 | 803 |
| 818 sk_free(dst); | 804 sk_free(dst); |
| 819 return NULL; | 805 return NULL; |
| 820 } | 806 } |
| 821 | 807 |
| 822 } // namespace SkTextureCompressor | 808 } // namespace SkTextureCompressor |
| OLD | NEW |