SkPMFloat.h revision f94fa7112f67af6fc5db19f86d8397307ba17105
1a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein#ifndef SkPM_DEFINED
2a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein#define SkPM_DEFINED
3a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein
4a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein#include "SkTypes.h"
5a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein#include "SkColor.h"
6f94fa7112f67af6fc5db19f86d8397307ba17105mtklein#include "SkColorPriv.h"
7870b9ea38672276a3e8506a0101dc559fa04583amtklein#include "Sk4x.h"
8a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein
9f94fa7112f67af6fc5db19f86d8397307ba17105mtklein#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
10f94fa7112f67af6fc5db19f86d8397307ba17105mtklein    #include <immintrin.h>
11f94fa7112f67af6fc5db19f86d8397307ba17105mtklein#elif defined(__ARM_NEON__)
12f94fa7112f67af6fc5db19f86d8397307ba17105mtklein    #include <arm_neon.h>
13f94fa7112f67af6fc5db19f86d8397307ba17105mtklein#endif
14f94fa7112f67af6fc5db19f86d8397307ba17105mtklein
154e644f5d5020a6ec904734a3f521bfad173cb450mtklein// A pre-multiplied color storing each component in the same order as SkPMColor,
164e644f5d5020a6ec904734a3f521bfad173cb450mtklein// but as a float in the range [0, 255].
177ab42771859145884e1b28c8c45f0a5a728b22acmtkleinclass SK_STRUCT_ALIGN(16) SkPMFloat {
187ab42771859145884e1b28c8c45f0a5a728b22acmtkleinpublic:
194e644f5d5020a6ec904734a3f521bfad173cb450mtklein    static SkPMFloat FromPMColor(SkPMColor c) { return SkPMFloat(c); }
204e644f5d5020a6ec904734a3f521bfad173cb450mtklein    static SkPMFloat FromARGB(float a, float r, float g, float b) { return SkPMFloat(a,r,g,b); }
214e644f5d5020a6ec904734a3f521bfad173cb450mtklein
22548bf38b28986fab6770350b72247d7114d98184mtklein    // May be more efficient than one at a time.  No special alignment assumed for SkPMColors.
2391fd7371ec80724ec53aae8f2d5a6753499d8963mtklein    static void From4PMColors(SkPMFloat[4], const SkPMColor[4]);
24548bf38b28986fab6770350b72247d7114d98184mtklein
254e644f5d5020a6ec904734a3f521bfad173cb450mtklein    explicit SkPMFloat(SkPMColor);
264e644f5d5020a6ec904734a3f521bfad173cb450mtklein    SkPMFloat(float a, float r, float g, float b) {
274e644f5d5020a6ec904734a3f521bfad173cb450mtklein        // TODO: faster when specialized?
284e644f5d5020a6ec904734a3f521bfad173cb450mtklein        fColor[SK_A32_SHIFT / 8] = a;
294e644f5d5020a6ec904734a3f521bfad173cb450mtklein        fColor[SK_R32_SHIFT / 8] = r;
304e644f5d5020a6ec904734a3f521bfad173cb450mtklein        fColor[SK_G32_SHIFT / 8] = g;
314e644f5d5020a6ec904734a3f521bfad173cb450mtklein        fColor[SK_B32_SHIFT / 8] = b;
324e644f5d5020a6ec904734a3f521bfad173cb450mtklein    }
334e644f5d5020a6ec904734a3f521bfad173cb450mtklein
344e644f5d5020a6ec904734a3f521bfad173cb450mtklein    // Uninitialized.
354e644f5d5020a6ec904734a3f521bfad173cb450mtklein    SkPMFloat() {}
364e644f5d5020a6ec904734a3f521bfad173cb450mtklein
37f94fa7112f67af6fc5db19f86d8397307ba17105mtklein    SkPMFloat(const SkPMFloat& that) { *this = that; }
38f94fa7112f67af6fc5db19f86d8397307ba17105mtklein    SkPMFloat& operator=(const SkPMFloat& that);
39870b9ea38672276a3e8506a0101dc559fa04583amtklein
40f94fa7112f67af6fc5db19f86d8397307ba17105mtklein    // Freely autoconvert between SkPMFloat and Sk4f.  They're always byte-for-byte identical.
41f94fa7112f67af6fc5db19f86d8397307ba17105mtklein    /*implicit*/ SkPMFloat(const Sk4f& fs) { *(Sk4f*)this = fs; }
42f94fa7112f67af6fc5db19f86d8397307ba17105mtklein    /*implicit*/ operator Sk4f() const     { return *(const Sk4f*)this;    }
43870b9ea38672276a3e8506a0101dc559fa04583amtklein
44a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein    float a() const { return fColor[SK_A32_SHIFT / 8]; }
45a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein    float r() const { return fColor[SK_R32_SHIFT / 8]; }
46a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein    float g() const { return fColor[SK_G32_SHIFT / 8]; }
47a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein    float b() const { return fColor[SK_B32_SHIFT / 8]; }
48a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein
490aebf5d0d3a2aef38a71885c85303583fdeaad57mtklein    // get() and clamped() round component values to the nearest integer.
507ab42771859145884e1b28c8c45f0a5a728b22acmtklein    SkPMColor     get() const;  // May SkASSERT(this->isValid()).  Some implementations may clamp.
5160d2a32b2dbbaabf4a0c133c8d3ff5ad888b8e5emtklein    SkPMColor clamped() const;  // Will clamp all values to [0, 255].  Then may assert isValid().
52a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein
53548bf38b28986fab6770350b72247d7114d98184mtklein    // 4-at-a-time versions of get() and clamped().  Like From4PMColors(), no alignment assumed.
5491fd7371ec80724ec53aae8f2d5a6753499d8963mtklein    static void To4PMColors(SkPMColor[4], const SkPMFloat[4]);
5591fd7371ec80724ec53aae8f2d5a6753499d8963mtklein    static void ClampTo4PMColors(SkPMColor[4], const SkPMFloat[4]);
56548bf38b28986fab6770350b72247d7114d98184mtklein
57a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein    bool isValid() const {
5860d2a32b2dbbaabf4a0c133c8d3ff5ad888b8e5emtklein        return this->a() >= 0 && this->a() <= 255
59a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein            && this->r() >= 0 && this->r() <= this->a()
60a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein            && this->g() >= 0 && this->g() <= this->a()
61a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein            && this->b() >= 0 && this->b() <= this->a();
62a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein    }
637ab42771859145884e1b28c8c45f0a5a728b22acmtklein
647ab42771859145884e1b28c8c45f0a5a728b22acmtkleinprivate:
65f94fa7112f67af6fc5db19f86d8397307ba17105mtklein    union {
66f94fa7112f67af6fc5db19f86d8397307ba17105mtklein        float fColor[4];
67f94fa7112f67af6fc5db19f86d8397307ba17105mtklein#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
68f94fa7112f67af6fc5db19f86d8397307ba17105mtklein        __m128 fColors;
69f94fa7112f67af6fc5db19f86d8397307ba17105mtklein#elif defined(__ARM_NEON__)
70f94fa7112f67af6fc5db19f86d8397307ba17105mtklein        float32x4_t fColors;
71f94fa7112f67af6fc5db19f86d8397307ba17105mtklein#endif
72f94fa7112f67af6fc5db19f86d8397307ba17105mtklein    };
73a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein};
74a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein
758c7ba092a68836c5db95c2a80b74d4f9cb475cc2mtklein#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
768c7ba092a68836c5db95c2a80b74d4f9cb475cc2mtklein    #include "../opts/SkPMFloat_SSSE3.h"
778c7ba092a68836c5db95c2a80b74d4f9cb475cc2mtklein#elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
78a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein    #include "../opts/SkPMFloat_SSE2.h"
79a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein#elif defined(__ARM_NEON__)
80a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein    #include "../opts/SkPMFloat_neon.h"
81a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein#else
82a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein    #include "../opts/SkPMFloat_none.h"
83a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein#endif
84a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein
85a2f4be76a9d453f1fdfd55b0cec6a683f23ffe0fmtklein#endif//SkPM_DEFINED
86