OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 #ifndef SkColorPriv_DEFINED | 8 #ifndef SkColorPriv_DEFINED |
9 #define SkColorPriv_DEFINED | 9 #define SkColorPriv_DEFINED |
10 | 10 |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], | 299 static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], |
300 int srcScale, int count) { | 300 int srcScale, int count) { |
301 SkASSERT(count > 0); | 301 SkASSERT(count > 0); |
302 SkASSERT((unsigned)srcScale <= 256); | 302 SkASSERT((unsigned)srcScale <= 256); |
303 | 303 |
304 srcScale >>= 3; | 304 srcScale >>= 3; |
305 | 305 |
306 do { | 306 do { |
307 uint32_t src32 = SkExpand_rgb_16(*src++); | 307 uint32_t src32 = SkExpand_rgb_16(*src++); |
308 uint32_t dst32 = SkExpand_rgb_16(*dst); | 308 uint32_t dst32 = SkExpand_rgb_16(*dst); |
309 *dst++ = SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5)); | 309 *dst++ = static_cast<uint16_t>( |
| 310 SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5))); |
310 } while (--count > 0); | 311 } while (--count > 0); |
311 } | 312 } |
312 | 313 |
313 #ifdef SK_DEBUG | 314 #ifdef SK_DEBUG |
314 static inline U16CPU SkRGB16Add(U16CPU a, U16CPU b) { | 315 static inline U16CPU SkRGB16Add(U16CPU a, U16CPU b) { |
315 SkASSERT(SkGetPackedR16(a) + SkGetPackedR16(b) <= SK_R16_MASK); | 316 SkASSERT(SkGetPackedR16(a) + SkGetPackedR16(b) <= SK_R16_MASK); |
316 SkASSERT(SkGetPackedG16(a) + SkGetPackedG16(b) <= SK_G16_MASK); | 317 SkASSERT(SkGetPackedG16(a) + SkGetPackedG16(b) <= SK_G16_MASK); |
317 SkASSERT(SkGetPackedB16(a) + SkGetPackedB16(b) <= SK_B16_MASK); | 318 SkASSERT(SkGetPackedB16(a) + SkGetPackedB16(b) <= SK_B16_MASK); |
318 | 319 |
319 return a + b; | 320 return a + b; |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 unsigned g, unsigned b) { | 779 unsigned g, unsigned b) { |
779 SkASSERT(a <= 0xF); | 780 SkASSERT(a <= 0xF); |
780 SkASSERT(r <= a); | 781 SkASSERT(r <= a); |
781 SkASSERT(g <= a); | 782 SkASSERT(g <= a); |
782 SkASSERT(b <= a); | 783 SkASSERT(b <= a); |
783 | 784 |
784 return (SkPMColor16)((a << SK_A4444_SHIFT) | (r << SK_R4444_SHIFT) | | 785 return (SkPMColor16)((a << SK_A4444_SHIFT) | (r << SK_R4444_SHIFT) | |
785 (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT)); | 786 (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT)); |
786 } | 787 } |
787 | 788 |
788 static inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) { | 789 static inline SkPMColor16 SkAlphaMulQ4(SkPMColor16 c, int scale) { |
789 SkASSERT(scale <= 16); | 790 SkASSERT(scale <= 16); |
790 | 791 |
791 const unsigned mask = 0xF0F; //gMask_0F0F; | 792 const unsigned mask = 0xF0F; //gMask_0F0F; |
792 | 793 |
793 #if 0 | 794 #if 0 |
794 unsigned rb = ((c & mask) * scale) >> 4; | 795 unsigned rb = ((c & mask) * scale) >> 4; |
795 unsigned ag = ((c >> 4) & mask) * scale; | 796 unsigned ag = ((c >> 4) & mask) * scale; |
796 return (rb & mask) | (ag & ~mask); | 797 return (rb & mask) | (ag & ~mask); |
797 #else | 798 #else |
798 c = (c & mask) | ((c & (mask << 4)) << 12); | 799 unsigned expanded_c = (c & mask) | ((c & (mask << 4)) << 12); |
799 c = c * scale >> 4; | 800 unsigned scaled_c = (expanded_c * scale) >> 4; |
800 return (c & mask) | ((c >> 12) & (mask << 4)); | 801 return (scaled_c & mask) | ((scaled_c >> 12) & (mask << 4)); |
801 #endif | 802 #endif |
802 } | 803 } |
803 | 804 |
804 /** Expand the SkPMColor16 color into a 32bit value that can be scaled all at | 805 /** Expand the SkPMColor16 color into a 32bit value that can be scaled all at |
805 once by a value up to 16. Used in conjunction with SkCompact_4444. | 806 once by a value up to 16. |
806 */ | 807 */ |
807 static inline uint32_t SkExpand_4444(U16CPU c) { | 808 static inline uint32_t SkExpand_4444(U16CPU c) { |
808 SkASSERT(c == (uint16_t)c); | 809 SkASSERT(c == (uint16_t)c); |
809 | 810 |
810 const unsigned mask = 0xF0F; //gMask_0F0F; | 811 const unsigned mask = 0xF0F; //gMask_0F0F; |
811 return (c & mask) | ((c & ~mask) << 12); | 812 return (c & mask) | ((c & ~mask) << 12); |
812 } | 813 } |
813 | 814 |
814 /** Compress an expanded value (from SkExpand_4444) back down to a SkPMColor16. | |
815 NOTE: this explicitly does not clean the top 16 bits (which may be garbage). | |
816 It does this for speed, since if it is being written directly to 16bits of | |
817 memory, the top 16bits will be ignored. Casting the result to uint16_t here | |
818 would add 2 more instructions, slow us down. It is up to the caller to | |
819 perform the cast if needed. | |
820 */ | |
821 static inline U16CPU SkCompact_4444(uint32_t c) { | |
822 const unsigned mask = 0xF0F; //gMask_0F0F; | |
823 return (c & mask) | ((c >> 12) & ~mask); | |
824 } | |
825 | |
826 static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) { | 815 static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) { |
827 unsigned sa = SkGetPackedA4444(s); | 816 unsigned sa = SkGetPackedA4444(s); |
828 unsigned sr = SkR4444ToR565(SkGetPackedR4444(s)); | 817 unsigned sr = SkR4444ToR565(SkGetPackedR4444(s)); |
829 unsigned sg = SkG4444ToG565(SkGetPackedG4444(s)); | 818 unsigned sg = SkG4444ToG565(SkGetPackedG4444(s)); |
830 unsigned sb = SkB4444ToB565(SkGetPackedB4444(s)); | 819 unsigned sb = SkB4444ToB565(SkGetPackedB4444(s)); |
831 | 820 |
832 // To avoid overflow, we have to clear the low bit of the synthetic sg | 821 // To avoid overflow, we have to clear the low bit of the synthetic sg |
833 // if the src alpha is <= 7. | 822 // if the src alpha is <= 7. |
834 // to see why, try blending 0x4444 on top of 565-white and watch green | 823 // to see why, try blending 0x4444 on top of 565-white and watch green |
835 // overflow (sum == 64) | 824 // overflow (sum == 64) |
(...skipping 11 matching lines...) Expand all Loading... |
847 #endif | 836 #endif |
848 return SkPackRGB16(sr + dr, sg + dg, sb + db); | 837 return SkPackRGB16(sr + dr, sg + dg, sb + db); |
849 } | 838 } |
850 | 839 |
851 static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale1
6) { | 840 static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale1
6) { |
852 SkASSERT((unsigned)scale16 <= 16); | 841 SkASSERT((unsigned)scale16 <= 16); |
853 | 842 |
854 return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst); | 843 return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst); |
855 } | 844 } |
856 | 845 |
857 static inline uint16_t SkBlend4444(SkPMColor16 src, SkPMColor16 dst, int scale16
) { | |
858 SkASSERT((unsigned)scale16 <= 16); | |
859 | |
860 uint32_t src32 = SkExpand_4444(src) * scale16; | |
861 // the scaled srcAlpha is the bottom byte | |
862 #ifdef SK_DEBUG | |
863 { | |
864 unsigned srcA = SkGetPackedA4444(src) * scale16; | |
865 SkASSERT(srcA == (src32 & 0xFF)); | |
866 } | |
867 #endif | |
868 unsigned dstScale = SkAlpha255To256(255 - (src32 & 0xFF)) >> 4; | |
869 uint32_t dst32 = SkExpand_4444(dst) * dstScale; | |
870 return SkCompact_4444((src32 + dst32) >> 4); | |
871 } | |
872 | |
873 static inline SkPMColor SkPixel4444ToPixel32(U16CPU c) { | 846 static inline SkPMColor SkPixel4444ToPixel32(U16CPU c) { |
874 uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) | | 847 uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) | |
875 (SkGetPackedR4444(c) << SK_R32_SHIFT) | | 848 (SkGetPackedR4444(c) << SK_R32_SHIFT) | |
876 (SkGetPackedG4444(c) << SK_G32_SHIFT) | | 849 (SkGetPackedG4444(c) << SK_G32_SHIFT) | |
877 (SkGetPackedB4444(c) << SK_B32_SHIFT); | 850 (SkGetPackedB4444(c) << SK_B32_SHIFT); |
878 return d | (d << 4); | 851 return d | (d << 4); |
879 } | 852 } |
880 | 853 |
881 static inline SkPMColor16 SkPixel32ToPixel4444(SkPMColor c) { | 854 static inline SkPMColor16 SkPixel32ToPixel4444(SkPMColor c) { |
882 return (((c >> (SK_A32_SHIFT + 4)) & 0xF) << SK_A4444_SHIFT) | | 855 return (((c >> (SK_A32_SHIFT + 4)) & 0xF) << SK_A4444_SHIFT) | |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 int srcG = SkColorGetG(src); | 1021 int srcG = SkColorGetG(src); |
1049 int srcB = SkColorGetB(src); | 1022 int srcB = SkColorGetB(src); |
1050 | 1023 |
1051 for (int i = 0; i < width; i++) { | 1024 for (int i = 0; i < width; i++) { |
1052 dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], mask[i], | 1025 dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], mask[i], |
1053 opaqueDst); | 1026 opaqueDst); |
1054 } | 1027 } |
1055 } | 1028 } |
1056 | 1029 |
1057 #endif | 1030 #endif |
OLD | NEW |