OLD | NEW |
1 #ifndef SkPM_DEFINED | 1 #ifndef SkPM_DEFINED |
2 #define SkPM_DEFINED | 2 #define SkPM_DEFINED |
3 | 3 |
4 #include "SkTypes.h" | 4 #include "SkTypes.h" |
5 #include "SkColor.h" | 5 #include "SkColor.h" |
| 6 #include "SkColorPriv.h" |
6 #include "Sk4x.h" | 7 #include "Sk4x.h" |
7 | 8 |
| 9 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 |
| 10 #include <immintrin.h> |
| 11 #elif defined(__ARM_NEON__) |
| 12 #include <arm_neon.h> |
| 13 #endif |
| 14 |
8 // A pre-multiplied color storing each component in the same order as SkPMColor, | 15 // A pre-multiplied color storing each component in the same order as SkPMColor, |
9 // but as a float in the range [0, 255]. | 16 // but as a float in the range [0, 255]. |
10 class SK_STRUCT_ALIGN(16) SkPMFloat { | 17 class SK_STRUCT_ALIGN(16) SkPMFloat { |
11 public: | 18 public: |
12 static SkPMFloat FromPMColor(SkPMColor c) { return SkPMFloat(c); } | 19 static SkPMFloat FromPMColor(SkPMColor c) { return SkPMFloat(c); } |
13 static SkPMFloat FromARGB(float a, float r, float g, float b) { return SkPMF
loat(a,r,g,b); } | 20 static SkPMFloat FromARGB(float a, float r, float g, float b) { return SkPMF
loat(a,r,g,b); } |
14 | 21 |
15 // May be more efficient than one at a time. No special alignment assumed f
or SkPMColors. | 22 // May be more efficient than one at a time. No special alignment assumed f
or SkPMColors. |
16 static void From4PMColors(SkPMFloat[4], const SkPMColor[4]); | 23 static void From4PMColors(SkPMFloat[4], const SkPMColor[4]); |
17 | 24 |
18 explicit SkPMFloat(SkPMColor); | 25 explicit SkPMFloat(SkPMColor); |
19 SkPMFloat(float a, float r, float g, float b) { | 26 SkPMFloat(float a, float r, float g, float b) { |
20 // TODO: faster when specialized? | 27 // TODO: faster when specialized? |
21 fColor[SK_A32_SHIFT / 8] = a; | 28 fColor[SK_A32_SHIFT / 8] = a; |
22 fColor[SK_R32_SHIFT / 8] = r; | 29 fColor[SK_R32_SHIFT / 8] = r; |
23 fColor[SK_G32_SHIFT / 8] = g; | 30 fColor[SK_G32_SHIFT / 8] = g; |
24 fColor[SK_B32_SHIFT / 8] = b; | 31 fColor[SK_B32_SHIFT / 8] = b; |
25 } | 32 } |
26 | 33 |
27 // Uninitialized. | 34 // Uninitialized. |
28 SkPMFloat() {} | 35 SkPMFloat() {} |
29 | 36 |
30 // Copy and assign are fastest if we remind the compiler we work best as Sk4
f. | 37 SkPMFloat(const SkPMFloat& that) { *this = that; } |
31 SkPMFloat(const SkPMFloat& that) { Sk4f(that).storeAligned(fColor); } | 38 SkPMFloat& operator=(const SkPMFloat& that); |
32 SkPMFloat& operator=(const SkPMFloat& that) { | |
33 Sk4f(that).storeAligned(fColor); | |
34 return *this; | |
35 } | |
36 | 39 |
37 // Freely autoconvert between SkPMFloat and Sk4f. | 40 // Freely autoconvert between SkPMFloat and Sk4f. They're always byte-for-b
yte identical. |
38 /*implicit*/ SkPMFloat(const Sk4f& fs) { fs.storeAligned(fColor); } | 41 /*implicit*/ SkPMFloat(const Sk4f& fs) { *(Sk4f*)this = fs; } |
39 /*implicit*/ operator Sk4f() const { return Sk4f::LoadAligned(fColor); } | 42 /*implicit*/ operator Sk4f() const { return *(const Sk4f*)this; } |
40 | 43 |
41 float a() const { return fColor[SK_A32_SHIFT / 8]; } | 44 float a() const { return fColor[SK_A32_SHIFT / 8]; } |
42 float r() const { return fColor[SK_R32_SHIFT / 8]; } | 45 float r() const { return fColor[SK_R32_SHIFT / 8]; } |
43 float g() const { return fColor[SK_G32_SHIFT / 8]; } | 46 float g() const { return fColor[SK_G32_SHIFT / 8]; } |
44 float b() const { return fColor[SK_B32_SHIFT / 8]; } | 47 float b() const { return fColor[SK_B32_SHIFT / 8]; } |
45 | 48 |
46 // get() and clamped() round component values to the nearest integer. | 49 // get() and clamped() round component values to the nearest integer. |
47 SkPMColor get() const; // May SkASSERT(this->isValid()). Some implemen
tations may clamp. | 50 SkPMColor get() const; // May SkASSERT(this->isValid()). Some implemen
tations may clamp. |
48 SkPMColor clamped() const; // Will clamp all values to [0, 255]. Then may
assert isValid(). | 51 SkPMColor clamped() const; // Will clamp all values to [0, 255]. Then may
assert isValid(). |
49 | 52 |
50 // 4-at-a-time versions of get() and clamped(). Like From4PMColors(), no al
ignment assumed. | 53 // 4-at-a-time versions of get() and clamped(). Like From4PMColors(), no al
ignment assumed. |
51 static void To4PMColors(SkPMColor[4], const SkPMFloat[4]); | 54 static void To4PMColors(SkPMColor[4], const SkPMFloat[4]); |
52 static void ClampTo4PMColors(SkPMColor[4], const SkPMFloat[4]); | 55 static void ClampTo4PMColors(SkPMColor[4], const SkPMFloat[4]); |
53 | 56 |
54 bool isValid() const { | 57 bool isValid() const { |
55 return this->a() >= 0 && this->a() <= 255 | 58 return this->a() >= 0 && this->a() <= 255 |
56 && this->r() >= 0 && this->r() <= this->a() | 59 && this->r() >= 0 && this->r() <= this->a() |
57 && this->g() >= 0 && this->g() <= this->a() | 60 && this->g() >= 0 && this->g() <= this->a() |
58 && this->b() >= 0 && this->b() <= this->a(); | 61 && this->b() >= 0 && this->b() <= this->a(); |
59 } | 62 } |
60 | 63 |
61 private: | 64 private: |
62 float fColor[4]; | 65 union { |
| 66 float fColor[4]; |
| 67 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 |
| 68 __m128 fColors; |
| 69 #elif defined(__ARM_NEON__) |
| 70 float32x4_t fColors; |
| 71 #endif |
| 72 }; |
63 }; | 73 }; |
64 | 74 |
65 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3 | 75 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3 |
66 #include "../opts/SkPMFloat_SSSE3.h" | 76 #include "../opts/SkPMFloat_SSSE3.h" |
67 #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 | 77 #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 |
68 #include "../opts/SkPMFloat_SSE2.h" | 78 #include "../opts/SkPMFloat_SSE2.h" |
69 #elif defined(__ARM_NEON__) | 79 #elif defined(__ARM_NEON__) |
70 #include "../opts/SkPMFloat_neon.h" | 80 #include "../opts/SkPMFloat_neon.h" |
71 #else | 81 #else |
72 #include "../opts/SkPMFloat_none.h" | 82 #include "../opts/SkPMFloat_none.h" |
73 #endif | 83 #endif |
74 | 84 |
75 #endif//SkPM_DEFINED | 85 #endif//SkPM_DEFINED |
OLD | NEW |