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