OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 Sk4px_DEFINED | 8 #ifndef Sk4px_DEFINED |
9 #define Sk4px_DEFINED | 9 #define Sk4px_DEFINED |
10 | 10 |
(...skipping 16 matching lines...) Expand all Loading... |
27 void store1(SkPMColor[1]) const; | 27 void store1(SkPMColor[1]) const; |
28 | 28 |
29 // 1, 2, or 4 SkPMColors with 16-bit components. | 29 // 1, 2, or 4 SkPMColors with 16-bit components. |
30 // This is most useful as the result of a multiply, e.g. from mulWiden(). | 30 // This is most useful as the result of a multiply, e.g. from mulWiden(). |
31 class Wide : public Sk16h { | 31 class Wide : public Sk16h { |
32 public: | 32 public: |
33 Wide(const Sk16h& v) : Sk16h(v) {} | 33 Wide(const Sk16h& v) : Sk16h(v) {} |
34 | 34 |
35 // Pack the top byte of each component back down into 4 SkPMColors. | 35 // Pack the top byte of each component back down into 4 SkPMColors. |
36 Sk4px addNarrowHi(const Sk16h&) const; | 36 Sk4px addNarrowHi(const Sk16h&) const; |
| 37 |
| 38 Sk4px div255TruncNarrow() const { return this->addNarrowHi(*this >> 8);
} |
| 39 Sk4px div255RoundNarrow() const { |
| 40 return Sk4px::Wide(*this + Sk16h(128)).div255TruncNarrow(); |
| 41 } |
| 42 |
37 private: | 43 private: |
38 typedef Sk16h INHERITED; | 44 typedef Sk16h INHERITED; |
39 }; | 45 }; |
40 | 46 |
41 Wide widenLo() const; // ARGB -> 0A 0R 0G 0B | 47 Wide widenLo() const; // ARGB -> 0A 0R 0G 0B |
42 Wide widenHi() const; // ARGB -> A0 R0 G0 B0 | 48 Wide widenHi() const; // ARGB -> A0 R0 G0 B0 |
43 Wide mulWiden(const Sk16b&) const; // 8-bit x 8-bit -> 16-bit components. | 49 Wide mulWiden(const Sk16b&) const; // 8-bit x 8-bit -> 16-bit components. |
44 | 50 |
45 // A generic driver that maps fn over a src array into a dst array. | 51 // A generic driver that maps fn over a src array into a dst array. |
46 // fn should take an Sk4px (4 src pixels) and return an Sk4px (4 dst pixels)
. | 52 // fn should take an Sk4px (4 src pixels) and return an Sk4px (4 dst pixels)
. |
(...skipping 19 matching lines...) Expand all Loading... |
66 fn(Load2(src)).store2(dst); | 72 fn(Load2(src)).store2(dst); |
67 dst += 2; src += 2; count -= 2; | 73 dst += 2; src += 2; count -= 2; |
68 } | 74 } |
69 if (count >= 1) { | 75 if (count >= 1) { |
70 fn(Load1(src)).store1(dst); | 76 fn(Load1(src)).store1(dst); |
71 } | 77 } |
72 break; | 78 break; |
73 } | 79 } |
74 } | 80 } |
75 | 81 |
| 82 // As above, but with dst4' = fn(dst4, src4). |
| 83 template <typename Fn> |
| 84 static void MapDstSrc(int count, SkPMColor* dst, const SkPMColor* src, Fn fn
) { |
| 85 while (count > 0) { |
| 86 if (count >= 8) { |
| 87 Sk4px dst0 = fn(Load4(dst+0), Load4(src+0)), |
| 88 dst4 = fn(Load4(dst+4), Load4(src+4)); |
| 89 dst0.store4(dst+0); |
| 90 dst4.store4(dst+4); |
| 91 dst += 8; src += 8; count -= 8; |
| 92 continue; // Keep our stride at 8 pixels as long as possible. |
| 93 } |
| 94 SkASSERT(count <= 7); |
| 95 if (count >= 4) { |
| 96 fn(Load4(dst), Load4(src)).store4(dst); |
| 97 dst += 4; src += 4; count -= 4; |
| 98 } |
| 99 if (count >= 2) { |
| 100 fn(Load2(dst), Load2(src)).store2(dst); |
| 101 dst += 2; src += 2; count -= 2; |
| 102 } |
| 103 if (count >= 1) { |
| 104 fn(Load1(dst), Load1(src)).store1(dst); |
| 105 } |
| 106 break; |
| 107 } |
| 108 } |
| 109 |
| 110 // As above, but with dst4' = fn(dst4, src4, alpha4). |
| 111 template <typename Fn> |
| 112 static void MapDstSrcAlpha( |
| 113 int count, SkPMColor* dst, const SkPMColor* src, const SkAlpha* a, F
n fn) { |
| 114 // TODO: find a terser / faster way to construct Sk16b alphas. |
| 115 while (count > 0) { |
| 116 if (count >= 8) { |
| 117 Sk16b alpha0(a[0],a[0],a[0],a[0], a[1],a[1],a[1],a[1], |
| 118 a[2],a[2],a[2],a[2], a[3],a[3],a[3],a[3]), |
| 119 alpha4(a[4],a[4],a[4],a[4], a[5],a[5],a[5],a[5], |
| 120 a[6],a[6],a[6],a[6], a[7],a[7],a[7],a[7]); |
| 121 Sk4px dst0 = fn(Load4(dst+0), Load4(src+0), alpha0), |
| 122 dst4 = fn(Load4(dst+4), Load4(src+4), alpha4); |
| 123 dst0.store4(dst+0); |
| 124 dst4.store4(dst+4); |
| 125 dst += 8; src += 8; a += 8; count -= 8; |
| 126 continue; // Keep our stride at 8 pixels as long as possible. |
| 127 } |
| 128 SkASSERT(count <= 7); |
| 129 if (count >= 4) { |
| 130 Sk16b alpha(a[0],a[0],a[0],a[0], a[1],a[1],a[1],a[1], |
| 131 a[2],a[2],a[2],a[2], a[3],a[3],a[3],a[3]); |
| 132 fn(Load4(dst), Load4(src), alpha).store4(dst); |
| 133 dst += 4; src += 4; a += 4; count -= 4; |
| 134 } |
| 135 if (count >= 2) { |
| 136 Sk16b alpha(a[0],a[0],a[0],a[0], a[1],a[1],a[1],a[1], 0,0,0,0, 0
,0,0,0); |
| 137 fn(Load2(dst), Load2(src), alpha).store2(dst); |
| 138 dst += 2; src += 2; a += 2; count -= 2; |
| 139 } |
| 140 if (count >= 1) { |
| 141 Sk16b alpha(a[0],a[0],a[0],a[0], 0,0,0,0, 0,0,0,0, 0,0,0,0); |
| 142 fn(Load1(dst), Load1(src), alpha).store1(dst); |
| 143 } |
| 144 break; |
| 145 } |
| 146 } |
| 147 |
76 private: | 148 private: |
77 typedef Sk16b INHERITED; | 149 typedef Sk16b INHERITED; |
78 }; | 150 }; |
79 | 151 |
80 #ifdef SKNX_NO_SIMD | 152 #ifdef SKNX_NO_SIMD |
81 #include "../opts/Sk4px_none.h" | 153 #include "../opts/Sk4px_none.h" |
82 #else | 154 #else |
83 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 | 155 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 |
84 #include "../opts/Sk4px_SSE2.h" | 156 #include "../opts/Sk4px_SSE2.h" |
85 #elif defined(SK_ARM_HAS_NEON) | 157 #elif defined(SK_ARM_HAS_NEON) |
86 #include "../opts/Sk4px_NEON.h" | 158 #include "../opts/Sk4px_NEON.h" |
87 #else | 159 #else |
88 #include "../opts/Sk4px_none.h" | 160 #include "../opts/Sk4px_none.h" |
89 #endif | 161 #endif |
90 #endif | 162 #endif |
91 | 163 |
92 #endif//Sk4px_DEFINED | 164 #endif//Sk4px_DEFINED |
OLD | NEW |