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; | |
mtklein
2014/07/11 15:24:27
Removing this was intentional?
krajcevski
2014/07/11 16:11:47
Yes, it was the same as line 595 above, which I mo
| |
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 static class CompressionProcTable |
774 int width, int height, int rowBytes); | 770 { |
771 public: | |
772 CompressionProcTable() { | |
mtklein
2014/07/11 15:24:27
We try to avoid static initializers when possible.
krajcevski
2014/07/11 16:11:47
Done.
| |
773 memset(kProcMap, 0, sizeof(kProcMap)); | |
774 | |
775 kProcMap[kLATC_Format][kAlpha_8_SkColorType] = compress_a8_to_latc; | |
776 kProcMap[kR11_EAC_Format][kAlpha_8_SkColorType] = compress_a8_to_r11eac; | |
777 CompressionProc r11opt = SkTextureCompressorGetPlatformProc(kR11_EAC_For mat); | |
778 if (NULL != r11opt) { | |
779 kProcMap[kR11_EAC_Format][kAlpha_8_SkColorType] = r11opt; | |
780 } | |
781 } | |
782 | |
783 CompressionProc getProc(SkColorType colorType, Format fmt) const { | |
784 return kProcMap[fmt][colorType]; | |
785 } | |
786 | |
787 private: | |
788 CompressionProc kProcMap[kFormatCnt][kLastEnum_SkColorType + 1]; | |
789 } kCompressionProcTable; | |
775 | 790 |
776 bool CompressBufferToFormat(uint8_t* dst, const uint8_t* src, SkColorType srcCol orType, | 791 bool CompressBufferToFormat(uint8_t* dst, const uint8_t* src, SkColorType srcCol orType, |
777 int width, int height, int rowBytes, Format format) { | 792 int width, int height, int rowBytes, Format format) { |
778 | 793 CompressionProc proc = kCompressionProcTable.getProc(srcColorType, format); |
779 CompressBitmapProc kProcMap[kFormatCnt][kLastEnum_SkColorType + 1]; | |
780 memset(kProcMap, 0, sizeof(kProcMap)); | |
781 | |
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) { | 794 if (NULL != proc) { |
787 return proc(dst, src, width, height, rowBytes); | 795 return proc(dst, src, width, height, rowBytes); |
788 } | 796 } |
789 | 797 |
790 return false; | 798 return false; |
791 } | 799 } |
792 | 800 |
793 SkData *CompressBitmapToFormat(const SkBitmap &bitmap, Format format) { | 801 SkData *CompressBitmapToFormat(const SkBitmap &bitmap, Format format) { |
794 SkAutoLockPixels alp(bitmap); | 802 SkAutoLockPixels alp(bitmap); |
795 | 803 |
796 int compressedDataSize = get_compressed_data_size(format, bitmap.width(), bi tmap.height()); | 804 int compressedDataSize = get_compressed_data_size(format, bitmap.width(), bi tmap.height()); |
797 const uint8_t* src = reinterpret_cast<const uint8_t*>(bitmap.getPixels()); | 805 const uint8_t* src = reinterpret_cast<const uint8_t*>(bitmap.getPixels()); |
798 uint8_t* dst = reinterpret_cast<uint8_t*>(sk_malloc_throw(compressedDataSize )); | 806 uint8_t* dst = reinterpret_cast<uint8_t*>(sk_malloc_throw(compressedDataSize )); |
799 if (CompressBufferToFormat(dst, src, bitmap.colorType(), bitmap.width(), bit map.height(), | 807 if (CompressBufferToFormat(dst, src, bitmap.colorType(), bitmap.width(), bit map.height(), |
800 bitmap.rowBytes(), format)) { | 808 bitmap.rowBytes(), format)) { |
801 return SkData::NewFromMalloc(dst, compressedDataSize); | 809 return SkData::NewFromMalloc(dst, compressedDataSize); |
802 } | 810 } |
803 | 811 |
804 sk_free(dst); | 812 sk_free(dst); |
805 return NULL; | 813 return NULL; |
806 } | 814 } |
807 | 815 |
808 } // namespace SkTextureCompressor | 816 } // namespace SkTextureCompressor |
OLD | NEW |