aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkPMFloat.h
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2015-03-30 10:50:27 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-03-30 10:50:27 -0700
commitc9adb05b64fa0bfadf9d1a782afcda470da68c9e (patch)
tree6413cc149b70ae36181e9f0789246b9db24447f0 /src/core/SkPMFloat.h
parent23ac62c83a49d675a38f1c20462b5537f3c8af01 (diff)
Refactor Sk2x<T> + Sk4x<T> into SkNf<N,T> and SkNi<N,T>
The primary feature this delivers is SkNf and SkNd for arbitrary power-of-two N. Non-specialized types or types larger than 128 bits should now Just Work (and we can drop in a specialization to make them faster). Sk4s is now just a typedef for SkNf<4, SkScalar>; Sk4d is SkNf<4, double>, Sk2f SkNf<2, float>, etc. This also makes implementing new specializations easier and more encapsulated. We're now using template specialization, which means the specialized versions don't have to leak out so much from SkNx_sse.h and SkNx_neon.h. This design leaves us room to grow up, e.g to SkNf<8, SkScalar> == Sk8s, and to grown down too, to things like SkNi<8, uint16_t> == Sk8h. To simplify things, I've stripped away most APIs (swizzles, casts, reinterpret_casts) that no one's using yet. I will happily add them back if they seem useful. You shouldn't feel bad about using any of the typedef Sk4s, Sk4f, Sk4d, Sk2s, Sk2f, Sk2d, Sk4i, etc. Here's how you should feel: - Sk4f, Sk4s, Sk2d: feel awesome - Sk2f, Sk2s, Sk4d: feel pretty good No public API changes. TBR=reed@google.com BUG=skia:3592 Review URL: https://codereview.chromium.org/1048593002
Diffstat (limited to 'src/core/SkPMFloat.h')
-rw-r--r--src/core/SkPMFloat.h68
1 files changed, 28 insertions, 40 deletions
diff --git a/src/core/SkPMFloat.h b/src/core/SkPMFloat.h
index 66262a8916..27f6f78f26 100644
--- a/src/core/SkPMFloat.h
+++ b/src/core/SkPMFloat.h
@@ -11,13 +11,7 @@
#include "SkTypes.h"
#include "SkColor.h"
#include "SkColorPriv.h"
-#include "Sk4x.h"
-
-#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
- #include <immintrin.h>
-#elif defined(SK_ARM_HAS_NEON)
- #include <arm_neon.h>
-#endif
+#include "SkNx.h"
// A pre-multiplied color storing each component in the same order as SkPMColor,
// but as a float in the range [0, 255].
@@ -29,29 +23,25 @@ public:
// May be more efficient than one at a time. No special alignment assumed for SkPMColors.
static void From4PMColors(const SkPMColor[4], SkPMFloat*, SkPMFloat*, SkPMFloat*, SkPMFloat*);
- explicit SkPMFloat(SkPMColor);
- SkPMFloat(float a, float r, float g, float b) {
- // TODO: faster when specialized?
- fColor[SK_A32_SHIFT / 8] = a;
- fColor[SK_R32_SHIFT / 8] = r;
- fColor[SK_G32_SHIFT / 8] = g;
- fColor[SK_B32_SHIFT / 8] = b;
- }
-
// Uninitialized.
SkPMFloat() {}
+ explicit SkPMFloat(SkPMColor);
+ SkPMFloat(float a, float r, float g, float b)
+ #ifdef SK_PMCOLOR_IS_RGBA
+ : fColors(r,g,b,a) {}
+ #else
+ : fColors(b,g,r,a) {}
+ #endif
- SkPMFloat(const SkPMFloat& that) { *this = that; }
- SkPMFloat& operator=(const SkPMFloat& that);
- // Freely autoconvert between SkPMFloat and Sk4f. They're always byte-for-byte identical.
- /*implicit*/ SkPMFloat(const Sk4f& fs) { fs.storeAligned(fColor); }
- /*implicit*/ operator Sk4f() const { return Sk4f::LoadAligned(fColor); }
+ // Freely autoconvert between SkPMFloat and Sk4s.
+ /*implicit*/ SkPMFloat(const Sk4s& fs) { fColors = fs; }
+ /*implicit*/ operator Sk4s() const { return fColors; }
- float a() const { return fColor[SK_A32_SHIFT / 8]; }
- float r() const { return fColor[SK_R32_SHIFT / 8]; }
- float g() const { return fColor[SK_G32_SHIFT / 8]; }
- float b() const { return fColor[SK_B32_SHIFT / 8]; }
+ float a() const { return fColors[SK_A32_SHIFT / 8]; }
+ float r() const { return fColors[SK_R32_SHIFT / 8]; }
+ float g() const { return fColors[SK_G32_SHIFT / 8]; }
+ float b() const { return fColors[SK_B32_SHIFT / 8]; }
// get() and clamped() round component values to the nearest integer.
SkPMColor get() const; // May SkASSERT(this->isValid()). Some implementations may clamp.
@@ -75,24 +65,22 @@ public:
}
private:
- union {
- float fColor[4];
-#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
- __m128 fColors;
-#elif defined(SK_ARM_HAS_NEON)
- float32x4_t fColors;
-#endif
- };
+ Sk4s fColors;
};
-#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
- #include "../opts/SkPMFloat_SSSE3.h"
-#elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
- #include "../opts/SkPMFloat_SSE2.h"
-#elif defined(SK_ARM_HAS_NEON)
- #include "../opts/SkPMFloat_neon.h"
-#else
+#ifdef SKNX_NO_SIMD
+ // Platform implementations of SkPMFloat assume Sk4s uses SSE or NEON. _none is generic.
#include "../opts/SkPMFloat_none.h"
+#else
+ #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
+ #include "../opts/SkPMFloat_SSSE3.h"
+ #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
+ #include "../opts/SkPMFloat_SSE2.h"
+ #elif defined(SK_ARM_HAS_NEON)
+ #include "../opts/SkPMFloat_neon.h"
+ #else
+ #include "../opts/SkPMFloat_none.h"
+ #endif
#endif
#endif//SkPM_DEFINED