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