diff options
author | mtklein <mtklein@chromium.org> | 2015-02-23 09:39:27 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-23 09:39:27 -0800 |
commit | 50d2b3114b3e59dc84811881591bf25b2c1ecb9f (patch) | |
tree | 29833d04dfc2c575bfabb7a0b561b7e88260fdc4 /src/opts/SkPMFloat_SSE2.h | |
parent | 259656779334689ab1624ec4e2e234b35fe4024b (diff) |
Sketch SkPMFloat
BUG=skia:
Review URL: https://codereview.chromium.org/936633002
Diffstat (limited to 'src/opts/SkPMFloat_SSE2.h')
-rw-r--r-- | src/opts/SkPMFloat_SSE2.h | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/opts/SkPMFloat_SSE2.h b/src/opts/SkPMFloat_SSE2.h new file mode 100644 index 0000000000..7bacf56af7 --- /dev/null +++ b/src/opts/SkPMFloat_SSE2.h @@ -0,0 +1,36 @@ +#include "SkColorPriv.h" +#include "SkPMFloat.h" +#include <emmintrin.h> + +// For set(), we widen our 8 bit components (fix8) to 8-bit components in 16 bits (fix8_16), +// then widen those to 8-bit-in-32-bits (fix8_32), convert those to floats (scaled), +// then finally scale those down from [0.0f, 255.0f] to [0.0f, 1.0f] into fColor. + +// get() and clamped() do the opposite, working from [0.0f, 1.0f] floats to [0.0f, 255.0f], +// to 8-bit-in-32-bit, to 8-bit-in-16-bit, back down to 8-bit components. +// _mm_packus_epi16() gives us clamping for free while narrowing. + +inline void SkPMFloat::set(SkPMColor c) { + SkPMColorAssert(c); + __m128i fix8 = _mm_set_epi32(0,0,0,c), + fix8_16 = _mm_unpacklo_epi8 (fix8, _mm_setzero_si128()), + fix8_32 = _mm_unpacklo_epi16(fix8_16, _mm_setzero_si128()); + __m128 scaled = _mm_cvtepi32_ps(fix8_32); + _mm_store_ps(fColor, _mm_mul_ps(scaled, _mm_set1_ps(1.0f/255.0f))); + SkASSERT(this->isValid()); +} + +inline SkPMColor SkPMFloat::get() const { + SkASSERT(this->isValid()); + return this->clamped(); // At the moment, we don't know anything faster. +} + +inline SkPMColor SkPMFloat::clamped() const { + __m128 scaled = _mm_mul_ps(_mm_load_ps(fColor), _mm_set1_ps(255.0f)); + __m128i fix8_32 = _mm_cvtps_epi32(scaled), + fix8_16 = _mm_packus_epi16(fix8_32, fix8_32), + fix8 = _mm_packus_epi16(fix8_16, fix8_16); + SkPMColor c = _mm_cvtsi128_si32(fix8); + SkPMColorAssert(c); + return c; +} |