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 |