OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 #ifndef Sk4fGradientPriv_DEFINED | 8 #ifndef Sk4fGradientPriv_DEFINED |
9 #define Sk4fGradientPriv_DEFINED | 9 #define Sk4fGradientPriv_DEFINED |
10 | 10 |
11 #include "SkColor.h" | 11 #include "SkColor.h" |
| 12 #include "SkHalf.h" |
| 13 #include "SkImageInfo.h" |
12 #include "SkNx.h" | 14 #include "SkNx.h" |
13 #include "SkPM4f.h" | 15 #include "SkPM4f.h" |
| 16 #include "SkPM4fPriv.h" |
14 | 17 |
15 // Templates shared by various 4f gradient flavors. | 18 // Templates shared by various 4f gradient flavors. |
16 | 19 |
17 namespace { | 20 namespace { |
18 | 21 |
| 22 enum class ApplyPremul { True, False }; |
| 23 |
19 inline Sk4f premul_4f(const Sk4f& c) { | 24 inline Sk4f premul_4f(const Sk4f& c) { |
20 const float alpha = c[SkPM4f::A]; | 25 const float alpha = c[SkPM4f::A]; |
21 // FIXME: portable swizzle? | 26 // FIXME: portable swizzle? |
22 return c * Sk4f(alpha, alpha, alpha, 1); | 27 return c * Sk4f(alpha, alpha, alpha, 1); |
23 } | 28 } |
24 | 29 |
25 template <bool do_premul> | 30 template <ApplyPremul premul> |
26 inline SkPMColor trunc_from_255(const Sk4f& c) { | 31 inline SkPMColor trunc_from_4f_255(const Sk4f& c) { |
27 SkPMColor pmc; | 32 SkPMColor pmc; |
28 SkNx_cast<uint8_t>(c).store(&pmc); | 33 SkNx_cast<uint8_t>(c).store(&pmc); |
29 if (do_premul) { | 34 if (premul == ApplyPremul::True) { |
30 pmc = SkPreMultiplyARGB(SkGetPackedA32(pmc), SkGetPackedR32(pmc), | 35 pmc = SkPreMultiplyARGB(SkGetPackedA32(pmc), SkGetPackedR32(pmc), |
31 SkGetPackedG32(pmc), SkGetPackedB32(pmc)); | 36 SkGetPackedG32(pmc), SkGetPackedB32(pmc)); |
32 } | 37 } |
33 return pmc; | 38 return pmc; |
34 } | 39 } |
35 | 40 |
36 template<typename DstType, bool do_premul> | 41 template<typename DstType, SkColorProfileType, ApplyPremul premul> |
37 void store(const Sk4f& color, DstType* dst); | 42 void store(const Sk4f& color, DstType* dst); |
38 | 43 |
39 template<> | 44 template<> |
40 inline void store<SkPM4f, false>(const Sk4f& c, SkPM4f* dst) { | 45 inline void store<SkPM4f, kLinear_SkColorProfileType, ApplyPremul::False> |
| 46 (const Sk4f& c, SkPM4f* dst) { |
41 c.store(dst); | 47 c.store(dst); |
42 } | 48 } |
43 | 49 |
44 template<> | 50 template<> |
45 inline void store<SkPM4f, true>(const Sk4f& c, SkPM4f* dst) { | 51 inline void store<SkPM4f, kLinear_SkColorProfileType, ApplyPremul::True> |
46 store<SkPM4f, false>(premul_4f(c), dst); | 52 (const Sk4f& c, SkPM4f* dst) { |
| 53 premul_4f(c).store(dst); |
47 } | 54 } |
48 | 55 |
49 template<> | 56 template<> |
50 inline void store<SkPMColor, false>(const Sk4f& c, SkPMColor* dst) { | 57 inline void store<SkPMColor, kLinear_SkColorProfileType, ApplyPremul::False> |
51 *dst = trunc_from_255<false>(c); | 58 (const Sk4f& c, SkPMColor* dst) { |
| 59 *dst = trunc_from_4f_255<ApplyPremul::False>(c); |
52 } | 60 } |
53 | 61 |
54 template<> | 62 template<> |
55 inline void store<SkPMColor, true>(const Sk4f& c, SkPMColor* dst) { | 63 inline void store<SkPMColor, kLinear_SkColorProfileType, ApplyPremul::True> |
56 *dst = trunc_from_255<true>(c); | 64 (const Sk4f& c, SkPMColor* dst) { |
| 65 *dst = trunc_from_4f_255<ApplyPremul::True>(c); |
57 } | 66 } |
58 | 67 |
59 template<typename DstType, bool do_premul> | 68 template<> |
| 69 inline void store<SkPMColor, kSRGB_SkColorProfileType, ApplyPremul::False> |
| 70 (const Sk4f& c, SkPMColor* dst) { |
| 71 // FIXME: this assumes opaque colors. Handle unpremultiplication. |
| 72 *dst = Sk4f_toS32(c); |
| 73 } |
| 74 |
| 75 template<> |
| 76 inline void store<SkPMColor, kSRGB_SkColorProfileType, ApplyPremul::True> |
| 77 (const Sk4f& c, SkPMColor* dst) { |
| 78 *dst = Sk4f_toS32(premul_4f(c)); |
| 79 } |
| 80 |
| 81 template<> |
| 82 inline void store<uint64_t, kLinear_SkColorProfileType, ApplyPremul::False> |
| 83 (const Sk4f& c, uint64_t* dst) { |
| 84 *dst = SkFloatToHalf_01(c); |
| 85 } |
| 86 |
| 87 template<> |
| 88 inline void store<uint64_t, kLinear_SkColorProfileType, ApplyPremul::True> |
| 89 (const Sk4f& c, uint64_t* dst) { |
| 90 *dst = SkFloatToHalf_01(premul_4f(c)); |
| 91 } |
| 92 |
| 93 template<typename DstType, SkColorProfileType profile, ApplyPremul premul> |
60 inline void store4x(const Sk4f& c0, | 94 inline void store4x(const Sk4f& c0, |
61 const Sk4f& c1, | 95 const Sk4f& c1, |
62 const Sk4f& c2, | 96 const Sk4f& c2, |
63 const Sk4f& c3, | 97 const Sk4f& c3, |
64 DstType* dst) { | 98 DstType* dst) { |
65 store<DstType, do_premul>(c0, dst++); | 99 store<DstType, profile, premul>(c0, dst++); |
66 store<DstType, do_premul>(c1, dst++); | 100 store<DstType, profile, premul>(c1, dst++); |
67 store<DstType, do_premul>(c2, dst++); | 101 store<DstType, profile, premul>(c2, dst++); |
68 store<DstType, do_premul>(c3, dst++); | 102 store<DstType, profile, premul>(c3, dst++); |
69 } | 103 } |
70 | 104 |
71 template<> | 105 template<> |
72 inline void store4x<SkPMColor, false>(const Sk4f& c0, | 106 inline void store4x<SkPMColor, kLinear_SkColorProfileType, ApplyPremul::False> |
73 const Sk4f& c1, | 107 (const Sk4f& c0, const Sk4f& c1, |
74 const Sk4f& c2, | 108 const Sk4f& c2, const Sk4f& c3, |
75 const Sk4f& c3, | 109 SkPMColor* dst) { |
76 SkPMColor* dst) { | |
77 Sk4f_ToBytes((uint8_t*)dst, c0, c1, c2, c3); | 110 Sk4f_ToBytes((uint8_t*)dst, c0, c1, c2, c3); |
78 } | 111 } |
79 | 112 |
80 template<typename DstType> | 113 template<typename DstType, SkColorProfileType> |
81 float dst_component_scale(); | 114 Sk4f scale_for_dest(const Sk4f& c) { |
82 | 115 return c; |
83 template<> | |
84 inline float dst_component_scale<SkPM4f>() { | |
85 return 1; | |
86 } | 116 } |
87 | 117 |
88 template<> | 118 template<> |
89 inline float dst_component_scale<SkPMColor>() { | 119 inline Sk4f scale_for_dest<SkPMColor, kLinear_SkColorProfileType>(const Sk4f& c)
{ |
90 return 255; | 120 return c * 255; |
91 } | 121 } |
92 | 122 |
93 template<typename DstType> | 123 template<typename DstType> |
94 Sk4f dst_swizzle(const SkPM4f&); | 124 Sk4f dst_swizzle(const SkPM4f&); |
95 | 125 |
96 template<> | 126 template<> |
97 inline Sk4f dst_swizzle<SkPM4f>(const SkPM4f& c) { | 127 inline Sk4f dst_swizzle<SkPM4f>(const SkPM4f& c) { |
98 return c.to4f(); | 128 return c.to4f(); |
99 } | 129 } |
100 | 130 |
101 template<> | 131 template<> |
102 inline Sk4f dst_swizzle<SkPMColor>(const SkPM4f& c) { | 132 inline Sk4f dst_swizzle<SkPMColor>(const SkPM4f& c) { |
103 return c.to4f_pmorder(); | 133 return c.to4f_pmorder(); |
104 } | 134 } |
105 | 135 |
| 136 template<> |
| 137 inline Sk4f dst_swizzle<uint64_t>(const SkPM4f& c) { |
| 138 return c.to4f(); |
| 139 } |
| 140 |
106 } | 141 } |
107 | 142 |
108 #endif // Sk4fGradientPriv_DEFINED | 143 #endif // Sk4fGradientPriv_DEFINED |
OLD | NEW |