aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2015-09-10 14:16:07 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-09-10 14:16:07 -0700
commita1c0ee40040fa8bb06f5f68ba4bcb3a68f789924 (patch)
tree5dc5cb538490e254f4fab6f88fe459dd0c5d7ec4 /src
parente66fec23afb0e7c02a49baecb2be678abf3a8a63 (diff)
SkNx_shuffle
This allows us to express shuffles more directly in code while also giving us a convenient point to platform-specify particular shuffles for particular types. No specializations yet. Everyone just uses the (pretty good) default option. BUG=skia: Review URL: https://codereview.chromium.org/1301413006
Diffstat (limited to 'src')
-rw-r--r--src/core/SkNx.h19
-rw-r--r--src/effects/SkColorMatrixFilter.cpp8
-rw-r--r--src/opts/SkColorCubeFilter_opts.h2
-rw-r--r--src/opts/SkXfermode_opts.h2
4 files changed, 25 insertions, 6 deletions
diff --git a/src/core/SkNx.h b/src/core/SkNx.h
index ff94e05458..f8b27fc1ed 100644
--- a/src/core/SkNx.h
+++ b/src/core/SkNx.h
@@ -266,8 +266,27 @@ protected:
T fVal;
};
+// This default implementation can be specialized by ../opts/SkNx_foo.h
+// if there's a better platform-specific shuffle strategy.
+template <typename SkNx, int... Ix>
+inline SkNx SkNx_shuffle_impl(const SkNx& src) { return SkNx( src.template kth<Ix>()... ); }
+
+// This generic shuffle can be called on either SkNi or SkNf with 1 or N indices:
+// Sk4f f(a,b,c,d);
+// SkNx_shuffle<3>(f); // ~~~> Sk4f(d,d,d,d)
+// SkNx_shuffle<2,1,0,3>(f); // ~~~> Sk4f(c,b,a,d)
+template <int... Ix, typename SkNx>
+inline SkNx SkNx_shuffle(const SkNx& src) { return SkNx_shuffle_impl<SkNx, Ix...>(src); }
+
+// A reminder alias that shuffles can be used to duplicate a single index across a vector.
+template <int Ix, typename SkNx>
+inline SkNx SkNx_dup(const SkNx& src) { return SkNx_shuffle<Ix>(src); }
+
} // namespace
+
+
+
// Include platform specific specializations if available.
#ifndef SKNX_NO_SIMD
#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index d7f0a74295..1eedef1343 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -302,10 +302,10 @@ void SkColorMatrixFilter::filterSpan(const SkPMColor src[], int count, SkPMColor
srcf = unpremul(srcf);
}
- Sk4f r4 = Sk4f(srcf.kth<SK_R32_SHIFT/8>());
- Sk4f g4 = Sk4f(srcf.kth<SK_G32_SHIFT/8>());
- Sk4f b4 = Sk4f(srcf.kth<SK_B32_SHIFT/8>());
- Sk4f a4 = Sk4f(srcf.kth<SK_A32_SHIFT/8>());
+ Sk4f r4 = SkNx_dup<SK_R32_SHIFT/8>(srcf);
+ Sk4f g4 = SkNx_dup<SK_G32_SHIFT/8>(srcf);
+ Sk4f b4 = SkNx_dup<SK_B32_SHIFT/8>(srcf);
+ Sk4f a4 = SkNx_dup<SK_A32_SHIFT/8>(srcf);
// apply matrix
Sk4f dst4 = c0 * r4 + c1 * g4 + c2 * b4 + c3 * a4 + c4;
diff --git a/src/opts/SkColorCubeFilter_opts.h b/src/opts/SkColorCubeFilter_opts.h
index 3eb243de55..4c394051bb 100644
--- a/src/opts/SkColorCubeFilter_opts.h
+++ b/src/opts/SkColorCubeFilter_opts.h
@@ -71,7 +71,7 @@ void color_cube_filter_span(const SkPMColor src[],
// color is BGRA (SkColor order), dst is SkPMColor order, so may need to swap R+B.
#if defined(SK_PMCOLOR_IS_RGBA)
- color = Sk4f(color.kth<2>(), color.kth<1>(), color.kth<0>(), color.kth<3>());
+ color = SkNx_shuffle<2,1,0,3>(color);
#endif
uint8_t* dstBytes = (uint8_t*)(dst+i);
color.toBytes(dstBytes);
diff --git a/src/opts/SkXfermode_opts.h b/src/opts/SkXfermode_opts.h
index 50bef6ac46..69f2b420f5 100644
--- a/src/opts/SkXfermode_opts.h
+++ b/src/opts/SkXfermode_opts.h
@@ -117,7 +117,7 @@ static inline Sk4f a_rgb(const Sk4f& a, const Sk4f& rgb) {
return a * Sk4f(0,0,0,1) + rgb * Sk4f(1,1,1,0);
}
static inline Sk4f alphas(const Sk4f& f) {
- return Sk4f(f.kth<SK_A32_SHIFT/8>());
+ return SkNx_dup<SK_A32_SHIFT/8>(f);
}
XFERMODE(ColorDodge) {