OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2015 Google Inc. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. |
| 6 */ |
| 7 |
| 8 #ifndef Sk4px_DEFINED |
| 9 #define Sk4px_DEFINED |
| 10 |
| 11 #include "SkNx.h" |
| 12 #include "SkColor.h" |
| 13 |
| 14 // 1, 2 or 4 SkPMColors, generally vectorized. |
| 15 class Sk4px : public Sk16b { |
| 16 public: |
| 17 Sk4px(SkPMColor); // Duplicate 4x. |
| 18 Sk4px(const Sk16b& v) : Sk16b(v) {} |
| 19 |
| 20 // When loading or storing fewer than 4 SkPMColors, we use the low lanes. |
| 21 static Sk4px Load4(const SkPMColor[4]); |
| 22 static Sk4px Load2(const SkPMColor[2]); |
| 23 static Sk4px Load1(const SkPMColor[1]); |
| 24 |
| 25 void store4(SkPMColor[4]) const; |
| 26 void store2(SkPMColor[2]) const; |
| 27 void store1(SkPMColor[1]) const; |
| 28 |
| 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(). |
| 31 class Wide : public Sk16h { |
| 32 public: |
| 33 Wide(const Sk16h& v) : Sk16h(v) {} |
| 34 |
| 35 // Pack the top byte of each component back down into 4 SkPMColors. |
| 36 Sk4px addNarrowHi(const Sk16h&) const; |
| 37 private: |
| 38 typedef Sk16h INHERITED; |
| 39 }; |
| 40 |
| 41 Wide widenLo() const; // ARGB -> 0A 0R 0G 0B |
| 42 Wide widenHi() const; // ARGB -> A0 R0 G0 B0 |
| 43 Wide mulWiden(const Sk16b&) const; // 8-bit x 8-bit -> 16-bit components. |
| 44 |
| 45 // 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)
. |
| 47 template <typename Fn> |
| 48 static void MapSrc(int count, SkPMColor* dst, const SkPMColor* src, Fn fn) { |
| 49 // This looks a bit odd, but it helps loop-invariant hoisting across dif
ferent calls to fn. |
| 50 // Basically, we need to make sure we keep things inside a single loop. |
| 51 while (count > 0) { |
| 52 if (count >= 8) { |
| 53 Sk4px dst0 = fn(Load4(src+0)), |
| 54 dst4 = fn(Load4(src+4)); |
| 55 dst0.store4(dst+0); |
| 56 dst4.store4(dst+4); |
| 57 dst += 8; src += 8; count -= 8; |
| 58 continue; // Keep our stride at 8 pixels as long as possible. |
| 59 } |
| 60 SkASSERT(count <= 7); |
| 61 if (count >= 4) { |
| 62 fn(Load4(src)).store4(dst); |
| 63 dst += 4; src += 4; count -= 4; |
| 64 } |
| 65 if (count >= 2) { |
| 66 fn(Load2(src)).store2(dst); |
| 67 dst += 2; src += 2; count -= 2; |
| 68 } |
| 69 if (count >= 1) { |
| 70 fn(Load1(src)).store1(dst); |
| 71 } |
| 72 break; |
| 73 } |
| 74 } |
| 75 |
| 76 private: |
| 77 typedef Sk16b INHERITED; |
| 78 }; |
| 79 |
| 80 #ifdef SKNX_NO_SIMD |
| 81 #include "../opts/Sk4px_none.h" |
| 82 #else |
| 83 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 |
| 84 #include "../opts/Sk4px_SSE2.h" |
| 85 #elif defined(SK_ARM_HAS_NEON) |
| 86 #include "../opts/Sk4px_NEON.h" |
| 87 #else |
| 88 #include "../opts/Sk4px_none.h" |
| 89 #endif |
| 90 #endif |
| 91 |
| 92 #endif//Sk4px_DEFINED |
OLD | NEW |