blob: 28aa90bf29fd8d4913417f8111d92f1bc9b23448 [file] [log] [blame]
mtkleine9a3e3c2015-06-25 08:56:28 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8namespace { // See SkPMFloat.h
9
10inline SkPMFloat::SkPMFloat(SkPMColor c) {
11 SkPMColorAssert(c);
12#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
13 const int _ = 255; // Zero these bytes.
14 __m128i fix8 = _mm_cvtsi32_si128((int)c),
15 fix8_32 = _mm_shuffle_epi8(fix8, _mm_setr_epi8(0,_,_,_, 1,_,_,_, 2,_,_,_, 3,_,_,_));
16#else
17 __m128i fix8 = _mm_cvtsi32_si128((int)c),
18 fix8_16 = _mm_unpacklo_epi8 (fix8, _mm_setzero_si128()),
19 fix8_32 = _mm_unpacklo_epi16(fix8_16, _mm_setzero_si128());
20#endif
21 fVec = _mm_mul_ps(_mm_cvtepi32_ps(fix8_32), _mm_set1_ps(1.0f / 255));
22 SkASSERT(this->isValid());
23}
24
25inline SkPMColor SkPMFloat::round() const {
26 // We don't use _mm_cvtps_epi32, because we want precise control over how 0.5 rounds (up).
27 __m128 scaled = _mm_mul_ps(_mm_set1_ps(255), fVec);
28 __m128i fix8_32 = _mm_cvttps_epi32(_mm_add_ps(_mm_set1_ps(0.5f), scaled)),
29 fix8_16 = _mm_packus_epi16(fix8_32, fix8_32),
30 fix8 = _mm_packus_epi16(fix8_16, fix8_16);
31 SkPMColor c = _mm_cvtsi128_si32(fix8);
32 SkPMColorAssert(c);
33 return c;
34}
35
mtklein2aab22a2015-06-26 10:46:31 -070036inline Sk4f SkPMFloat::alphas() const {
37 static_assert(SK_A32_SHIFT == 24, "");
38 return _mm_shuffle_ps(fVec, fVec, 0xff); // Read as 11 11 11 11, copying lane 3 to all lanes.
39}
40
mtkleine9a3e3c2015-06-25 08:56:28 -070041} // namespace