aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/SkNx.h9
-rw-r--r--src/opts/SkColorXform_opts.h18
-rw-r--r--src/opts/SkNx_neon.h9
-rw-r--r--src/opts/SkNx_sse.h8
4 files changed, 35 insertions, 9 deletions
diff --git a/src/core/SkNx.h b/src/core/SkNx.h
index 374a0fc57c..dec63f8d89 100644
--- a/src/core/SkNx.h
+++ b/src/core/SkNx.h
@@ -300,6 +300,15 @@ typedef SkNx<4, int> Sk4i;
#include "../opts/SkNx_sse.h"
#elif !defined(SKNX_NO_SIMD) && defined(SK_ARM_HAS_NEON)
#include "../opts/SkNx_neon.h"
+#else
+
+SI Sk4i Sk4f_round(const Sk4f& x) {
+ return { (int) lrintf (x[0]),
+ (int) lrintf (x[1]),
+ (int) lrintf (x[2]),
+ (int) lrintf (x[3]), };
+}
+
#endif
SI void Sk4f_ToBytes(uint8_t p[16], const Sk4f& a, const Sk4f& b, const Sk4f& c, const Sk4f& d) {
diff --git a/src/opts/SkColorXform_opts.h b/src/opts/SkColorXform_opts.h
index 30bf164cbe..72ef35381e 100644
--- a/src/opts/SkColorXform_opts.h
+++ b/src/opts/SkColorXform_opts.h
@@ -84,19 +84,19 @@ static void color_xform_RGB1(uint32_t* dst, const uint32_t* src, int len,
dstGreens = clamp_0_to_255(dstGreens);
dstBlues = clamp_0_to_255(dstBlues);
- auto rgba = (SkNx_cast<int>(dstReds) )
- | (SkNx_cast<int>(dstGreens) << 8)
- | (SkNx_cast<int>(dstBlues) << 16)
- | (Sk4i{ 0xFF << 24});
+ auto rgba = (Sk4f_round(dstReds) )
+ | (Sk4f_round(dstGreens) << 8)
+ | (Sk4f_round(dstBlues) << 16)
+ | (Sk4i{ 0xFF << 24});
rgba.store(dst);
} else {
Sk4f scaledReds = Sk4f::Min(Sk4f::Max(1023.0f * dstReds, 0.0f), 1023.0f);
Sk4f scaledGreens = Sk4f::Min(Sk4f::Max(1023.0f * dstGreens, 0.0f), 1023.0f);
Sk4f scaledBlues = Sk4f::Min(Sk4f::Max(1023.0f * dstBlues, 0.0f), 1023.0f);
- Sk4i indicesReds = SkNx_cast<int>(scaledReds + 0.5f);
- Sk4i indicesGreens = SkNx_cast<int>(scaledGreens + 0.5f);
- Sk4i indicesBlues = SkNx_cast<int>(scaledBlues + 0.5f);
+ Sk4i indicesReds = Sk4f_round(scaledReds);
+ Sk4i indicesGreens = Sk4f_round(scaledGreens);
+ Sk4i indicesBlues = Sk4f_round(scaledBlues);
dst[0] = dstTables[0][indicesReds [0]]
| dstTables[1][indicesGreens[0]] << 8
@@ -149,13 +149,13 @@ static void color_xform_RGB1(uint32_t* dst, const uint32_t* src, int len,
dstPixel = clamp_0_to_255(dstPixel);
uint32_t rgba;
- SkNx_cast<uint8_t>(dstPixel).store(&rgba);
+ SkNx_cast<uint8_t>(Sk4f_round(dstPixel)).store(&rgba);
rgba |= 0xFF000000;
*dst = rgba;
} else {
Sk4f scaledPixel = Sk4f::Min(Sk4f::Max(1023.0f * dstPixel, 0.0f), 1023.0f);
- Sk4i indices = SkNx_cast<int>(scaledPixel + 0.5f);
+ Sk4i indices = Sk4f_round(scaledPixel);
*dst = dstTables[0][indices[0]]
| dstTables[1][indices[1]] << 8
diff --git a/src/opts/SkNx_neon.h b/src/opts/SkNx_neon.h
index bb81cded18..6d4cade12e 100644
--- a/src/opts/SkNx_neon.h
+++ b/src/opts/SkNx_neon.h
@@ -450,4 +450,13 @@ template<> inline Sk4b SkNx_cast<uint8_t, uint16_t>(const Sk4h& src) {
return vmovn_u16(vcombine_u16(src.fVec, src.fVec));
}
+template<> inline Sk4b SkNx_cast<uint8_t, int>(const Sk4i& src) {
+ uint16x4_t _16 = vqmovun_s32(src.fVec);
+ return vqmovn_u16(vcombine_u16(_16, _16));
+}
+
+static inline Sk4i Sk4f_round(const Sk4f& x) {
+ return vcvtq_s32_f32((x + 0.5f).fVec);
+}
+
#endif//SkNx_neon_DEFINED
diff --git a/src/opts/SkNx_sse.h b/src/opts/SkNx_sse.h
index 65d9873c5c..8952ff77f7 100644
--- a/src/opts/SkNx_sse.h
+++ b/src/opts/SkNx_sse.h
@@ -371,4 +371,12 @@ template<> /*static*/ inline Sk4b SkNx_cast<uint8_t, uint16_t>(const Sk4h& src)
return _mm_packus_epi16(src.fVec, src.fVec);
}
+template<> inline Sk4b SkNx_cast<uint8_t, int>(const Sk4i& src) {
+ return _mm_packus_epi16(_mm_packus_epi16(src.fVec, src.fVec), src.fVec);
+}
+
+static inline Sk4i Sk4f_round(const Sk4f& x) {
+ return _mm_cvtps_epi32(x.fVec);
+}
+
#endif//SkNx_sse_DEFINED