aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/opts
diff options
context:
space:
mode:
Diffstat (limited to 'src/opts')
-rw-r--r--src/opts/SkBlurImageFilter_opts.h56
-rw-r--r--src/opts/SkMorphologyImageFilter_opts.h137
-rw-r--r--src/opts/SkMorphology_opts.h22
-rw-r--r--src/opts/SkMorphology_opts_SSE2.cpp81
-rw-r--r--src/opts/SkMorphology_opts_SSE2.h22
-rw-r--r--src/opts/SkMorphology_opts_arm.cpp34
-rw-r--r--src/opts/SkMorphology_opts_neon.cpp80
-rw-r--r--src/opts/SkMorphology_opts_neon.h15
-rw-r--r--src/opts/SkMorphology_opts_none.cpp12
-rw-r--r--src/opts/SkOpts_neon.cpp13
-rw-r--r--src/opts/SkOpts_sse2.cpp13
-rw-r--r--src/opts/SkOpts_sse41.cpp7
-rw-r--r--src/opts/opts_check_x86.cpp22
13 files changed, 188 insertions, 326 deletions
diff --git a/src/opts/SkBlurImageFilter_opts.h b/src/opts/SkBlurImageFilter_opts.h
index fb3fc19c0d..31d9d5fdbc 100644
--- a/src/opts/SkBlurImageFilter_opts.h
+++ b/src/opts/SkBlurImageFilter_opts.h
@@ -13,10 +13,10 @@
namespace SK_OPTS_NS {
-enum Direction { kX, kY };
+enum class BlurDirection { kX, kY };
#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
-template<Direction srcDirection, Direction dstDirection>
+template<BlurDirection srcDirection, BlurDirection dstDirection>
void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int kernelSize,
int leftOffset, int rightOffset, int width, int height) {
#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE41
@@ -57,10 +57,10 @@ void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int kernelSiz
};
#endif
const int rightBorder = SkMin32(rightOffset + 1, width);
- const int srcStrideX = srcDirection == kX ? 1 : srcStride;
- const int dstStrideX = dstDirection == kX ? 1 : height;
- const int srcStrideY = srcDirection == kX ? srcStride : 1;
- const int dstStrideY = dstDirection == kX ? width : 1;
+ const int srcStrideX = srcDirection == BlurDirection::kX ? 1 : srcStride;
+ const int dstStrideX = dstDirection == BlurDirection::kX ? 1 : height;
+ const int srcStrideY = srcDirection == BlurDirection::kX ? srcStride : 1;
+ const int dstStrideY = dstDirection == BlurDirection::kX ? width : 1;
const __m128i scale = _mm_set1_epi32((1 << 24) / kernelSize);
const __m128i half = _mm_set1_epi32(1 << 23);
for (int y = 0; y < height; ++y) {
@@ -93,7 +93,7 @@ void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int kernelSiz
sum = _mm_add_epi32(sum, expand(r));
}
sptr += srcStrideX;
- if (srcDirection == kY) {
+ if (srcDirection == BlurDirection::kY) {
// TODO(mtklein): experiment with moving this prefetch forward
_mm_prefetch(reinterpret_cast<const char*>(sptr + (rightOffset + 1) * srcStrideX),
_MM_HINT_T0);
@@ -108,12 +108,12 @@ void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int kernelSiz
#elif defined(SK_ARM_HAS_NEON)
// Fast path for kernel sizes between 2 and 127, working on two rows at a time.
-template<Direction srcDirection, Direction dstDirection>
+template<BlurDirection srcDirection, BlurDirection dstDirection>
void box_blur_double(const SkPMColor** src, int srcStride, SkPMColor** dst, int kernelSize,
int leftOffset, int rightOffset, int width, int* height) {
// Load 2 pixels from adjacent rows.
auto load_2_pixels = [&](const SkPMColor* s) {
- if (srcDirection == kX) {
+ if (srcDirection == BlurDirection::kX) {
// 10% faster by adding these 2 prefetches
SK_PREFETCH(s + 16);
SK_PREFETCH(s + 16 + srcStride);
@@ -125,10 +125,10 @@ void box_blur_double(const SkPMColor** src, int srcStride, SkPMColor** dst, int
}
};
const int rightBorder = SkMin32(rightOffset + 1, width);
- const int srcStrideX = srcDirection == kX ? 1 : srcStride;
- const int dstStrideX = dstDirection == kX ? 1 : *height;
- const int srcStrideY = srcDirection == kX ? srcStride : 1;
- const int dstStrideY = dstDirection == kX ? width : 1;
+ const int srcStrideX = srcDirection == BlurDirection::kX ? 1 : srcStride;
+ const int dstStrideX = dstDirection == BlurDirection::kX ? 1 : *height;
+ const int srcStrideY = srcDirection == BlurDirection::kX ? srcStride : 1;
+ const int dstStrideY = dstDirection == BlurDirection::kX ? width : 1;
const uint16x8_t scale = vdupq_n_u16((1 << 15) / kernelSize);
for (; *height >= 2; *height -= 2) {
@@ -145,7 +145,7 @@ void box_blur_double(const SkPMColor** src, int srcStride, SkPMColor** dst, int
// val = (sum * scale * 2 + 0x8000) >> 16
uint16x8_t resultPixels = vreinterpretq_u16_s16(vqrdmulhq_s16(
vreinterpretq_s16_u16(sum), vreinterpretq_s16_u16(scale)));
- if (dstDirection == kX) {
+ if (dstDirection == BlurDirection::kX) {
uint32x2_t px2 = vreinterpret_u32_u8(vmovn_u16(resultPixels));
vst1_lane_u32(dptr + 0, px2, 0);
vst1_lane_u32(dptr + width, px2, 1);
@@ -167,7 +167,7 @@ void box_blur_double(const SkPMColor** src, int srcStride, SkPMColor** dst, int
}
}
-template<Direction srcDirection, Direction dstDirection>
+template<BlurDirection srcDirection, BlurDirection dstDirection>
void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int kernelSize,
int leftOffset, int rightOffset, int width, int height) {
// ARGB -> 0A0R 0G0B
@@ -175,10 +175,10 @@ void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int kernelSiz
return vget_low_u16(vmovl_u8(vreinterpret_u8_u32(vdup_n_u32(p))));
};
const int rightBorder = SkMin32(rightOffset + 1, width);
- const int srcStrideX = srcDirection == kX ? 1 : srcStride;
- const int dstStrideX = dstDirection == kX ? 1 : height;
- const int srcStrideY = srcDirection == kX ? srcStride : 1;
- const int dstStrideY = dstDirection == kX ? width : 1;
+ const int srcStrideX = srcDirection == BlurDirection::kX ? 1 : srcStride;
+ const int dstStrideX = dstDirection == BlurDirection::kX ? 1 : height;
+ const int srcStrideY = srcDirection == BlurDirection::kX ? srcStride : 1;
+ const int dstStrideY = dstDirection == BlurDirection::kX ? width : 1;
const uint32x4_t scale = vdupq_n_u32((1 << 24) / kernelSize);
const uint32x4_t half = vdupq_n_u32(1 << 23);
@@ -222,7 +222,7 @@ void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int kernelSiz
sum = vaddw_u16(sum, expand(*r));
}
sptr += srcStrideX;
- if (srcDirection == kX) {
+ if (srcDirection == BlurDirection::kX) {
SK_PREFETCH(sptr + (rightOffset + 16) * srcStrideX);
}
dptr += dstStrideX;
@@ -234,14 +234,14 @@ void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int kernelSiz
#else // Neither NEON nor >=SSE2.
-template<Direction srcDirection, Direction dstDirection>
+template<BlurDirection srcDirection, BlurDirection dstDirection>
static void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int kernelSize,
int leftOffset, int rightOffset, int width, int height) {
int rightBorder = SkMin32(rightOffset + 1, width);
- int srcStrideX = srcDirection == kX ? 1 : srcStride;
- int dstStrideX = dstDirection == kX ? 1 : height;
- int srcStrideY = srcDirection == kX ? srcStride : 1;
- int dstStrideY = dstDirection == kX ? width : 1;
+ int srcStrideX = srcDirection == BlurDirection::kX ? 1 : srcStride;
+ int dstStrideX = dstDirection == BlurDirection::kX ? 1 : height;
+ int srcStrideY = srcDirection == BlurDirection::kX ? srcStride : 1;
+ int dstStrideY = dstDirection == BlurDirection::kX ? width : 1;
uint32_t scale = (1 << 24) / kernelSize;
uint32_t half = 1 << 23;
for (int y = 0; y < height; ++y) {
@@ -277,7 +277,7 @@ static void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int ke
sumB += SkGetPackedB32(r);
}
sptr += srcStrideX;
- if (srcDirection == kY) {
+ if (srcDirection == BlurDirection::kY) {
SK_PREFETCH(sptr + (rightOffset + 1) * srcStrideX);
}
dptr += dstStrideX;
@@ -289,6 +289,10 @@ static void box_blur(const SkPMColor* src, int srcStride, SkPMColor* dst, int ke
#endif
+static auto box_blur_xx = &box_blur<BlurDirection::kX, BlurDirection::kX>,
+ box_blur_xy = &box_blur<BlurDirection::kX, BlurDirection::kY>,
+ box_blur_yx = &box_blur<BlurDirection::kY, BlurDirection::kX>;
+
} // namespace SK_OPTS_NS
#endif
diff --git a/src/opts/SkMorphologyImageFilter_opts.h b/src/opts/SkMorphologyImageFilter_opts.h
new file mode 100644
index 0000000000..e30a9e4973
--- /dev/null
+++ b/src/opts/SkMorphologyImageFilter_opts.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkMorphologyImageFilter_opts_DEFINED
+#define SkMorphologyImageFilter_opts_DEFINED
+
+namespace SK_OPTS_NS {
+
+enum MorphType { kDilate, kErode };
+enum class MorphDirection { kX, kY };
+
+#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
+template<MorphType type, MorphDirection direction>
+static void morph(const SkPMColor* src, SkPMColor* dst,
+ int radius, int width, int height, int srcStride, int dstStride) {
+ const int srcStrideX = direction == MorphDirection::kX ? 1 : srcStride;
+ const int dstStrideX = direction == MorphDirection::kX ? 1 : dstStride;
+ const int srcStrideY = direction == MorphDirection::kX ? srcStride : 1;
+ const int dstStrideY = direction == MorphDirection::kX ? dstStride : 1;
+ radius = SkMin32(radius, width - 1);
+ const SkPMColor* upperSrc = src + radius * srcStrideX;
+ for (int x = 0; x < width; ++x) {
+ const SkPMColor* lp = src;
+ const SkPMColor* up = upperSrc;
+ SkPMColor* dptr = dst;
+ for (int y = 0; y < height; ++y) {
+ __m128i extreme = (type == kDilate) ? _mm_setzero_si128()
+ : _mm_set1_epi32(0xFFFFFFFF);
+ for (const SkPMColor* p = lp; p <= up; p += srcStrideX) {
+ __m128i src_pixel = _mm_cvtsi32_si128(*p);
+ extreme = (type == kDilate) ? _mm_max_epu8(src_pixel, extreme)
+ : _mm_min_epu8(src_pixel, extreme);
+ }
+ *dptr = _mm_cvtsi128_si32(extreme);
+ dptr += dstStrideY;
+ lp += srcStrideY;
+ up += srcStrideY;
+ }
+ if (x >= radius) { src += srcStrideX; }
+ if (x + radius < width - 1) { upperSrc += srcStrideX; }
+ dst += dstStrideX;
+ }
+}
+
+#elif defined(SK_ARM_HAS_NEON)
+template<MorphType type, MorphDirection direction>
+static void morph(const SkPMColor* src, SkPMColor* dst,
+ int radius, int width, int height, int srcStride, int dstStride) {
+ const int srcStrideX = direction == MorphDirection::kX ? 1 : srcStride;
+ const int dstStrideX = direction == MorphDirection::kX ? 1 : dstStride;
+ const int srcStrideY = direction == MorphDirection::kX ? srcStride : 1;
+ const int dstStrideY = direction == MorphDirection::kX ? dstStride : 1;
+ radius = SkMin32(radius, width - 1);
+ const SkPMColor* upperSrc = src + radius * srcStrideX;
+ for (int x = 0; x < width; ++x) {
+ const SkPMColor* lp = src;
+ const SkPMColor* up = upperSrc;
+ SkPMColor* dptr = dst;
+ for (int y = 0; y < height; ++y) {
+ uint8x8_t extreme = vdup_n_u8(type == kDilate ? 0 : 255);
+ for (const SkPMColor* p = lp; p <= up; p += srcStrideX) {
+ uint8x8_t src_pixel = vreinterpret_u8_u32(vdup_n_u32(*p));
+ extreme = (type == kDilate) ? vmax_u8(src_pixel, extreme)
+ : vmin_u8(src_pixel, extreme);
+ }
+ *dptr = vget_lane_u32(vreinterpret_u32_u8(extreme), 0);
+ dptr += dstStrideY;
+ lp += srcStrideY;
+ up += srcStrideY;
+ }
+ if (x >= radius) src += srcStrideX;
+ if (x + radius < width - 1) upperSrc += srcStrideX;
+ dst += dstStrideX;
+ }
+}
+
+#else
+template<MorphType type, MorphDirection direction>
+static void morph(const SkPMColor* src, SkPMColor* dst,
+ int radius, int width, int height, int srcStride, int dstStride) {
+ const int srcStrideX = direction == MorphDirection::kX ? 1 : srcStride;
+ const int dstStrideX = direction == MorphDirection::kX ? 1 : dstStride;
+ const int srcStrideY = direction == MorphDirection::kX ? srcStride : 1;
+ const int dstStrideY = direction == MorphDirection::kX ? dstStride : 1;
+ radius = SkMin32(radius, width - 1);
+ const SkPMColor* upperSrc = src + radius * srcStrideX;
+ for (int x = 0; x < width; ++x) {
+ const SkPMColor* lp = src;
+ const SkPMColor* up = upperSrc;
+ SkPMColor* dptr = dst;
+ for (int y = 0; y < height; ++y) {
+ // If we're maxing (dilate), start from 0; if minning (erode), start from 255.
+ const int start = (type == kDilate) ? 0 : 255;
+ int B = start, G = start, R = start, A = start;
+ for (const SkPMColor* p = lp; p <= up; p += srcStrideX) {
+ int b = SkGetPackedB32(*p),
+ g = SkGetPackedG32(*p),
+ r = SkGetPackedR32(*p),
+ a = SkGetPackedA32(*p);
+ if (type == kDilate) {
+ B = SkTMax(b, B);
+ G = SkTMax(g, G);
+ R = SkTMax(r, R);
+ A = SkTMax(a, A);
+ } else {
+ B = SkTMin(b, B);
+ G = SkTMin(g, G);
+ R = SkTMin(r, R);
+ A = SkTMin(a, A);
+ }
+ }
+ *dptr = SkPackARGB32(A, R, G, B);
+ dptr += dstStrideY;
+ lp += srcStrideY;
+ up += srcStrideY;
+ }
+ if (x >= radius) { src += srcStrideX; }
+ if (x + radius < width - 1) { upperSrc += srcStrideX; }
+ dst += dstStrideX;
+ }
+}
+
+#endif
+
+static auto dilate_x = &morph<kDilate, MorphDirection::kX>,
+ dilate_y = &morph<kDilate, MorphDirection::kY>,
+ erode_x = &morph<kErode, MorphDirection::kX>,
+ erode_y = &morph<kErode, MorphDirection::kY>;
+
+} // namespace SK_OPTS_NS
+
+#endif//SkMorphologyImageFilter_opts_DEFINED
+
diff --git a/src/opts/SkMorphology_opts.h b/src/opts/SkMorphology_opts.h
deleted file mode 100644
index 7813efb191..0000000000
--- a/src/opts/SkMorphology_opts.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkMorphology_opts_DEFINED
-#define SkMorphology_opts_DEFINED
-
-#include "SkMorphologyImageFilter.h"
-
-enum SkMorphologyProcType {
- kDilateX_SkMorphologyProcType,
- kDilateY_SkMorphologyProcType,
- kErodeX_SkMorphologyProcType,
- kErodeY_SkMorphologyProcType
-};
-
-SkMorphologyImageFilter::Proc SkMorphologyGetPlatformProc(SkMorphologyProcType type);
-
-#endif
diff --git a/src/opts/SkMorphology_opts_SSE2.cpp b/src/opts/SkMorphology_opts_SSE2.cpp
deleted file mode 100644
index e782950956..0000000000
--- a/src/opts/SkMorphology_opts_SSE2.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <emmintrin.h>
-#include "SkColorPriv.h"
-#include "SkMorphology_opts_SSE2.h"
-
-/* SSE2 version of dilateX, dilateY, erodeX, erodeY.
- * portable versions are in src/effects/SkMorphologyImageFilter.cpp.
- */
-
-enum MorphType {
- kDilate, kErode
-};
-
-enum MorphDirection {
- kX, kY
-};
-
-template<MorphType type, MorphDirection direction>
-static void SkMorph_SSE2(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride)
-{
- const int srcStrideX = direction == kX ? 1 : srcStride;
- const int dstStrideX = direction == kX ? 1 : dstStride;
- const int srcStrideY = direction == kX ? srcStride : 1;
- const int dstStrideY = direction == kX ? dstStride : 1;
- radius = SkMin32(radius, width - 1);
- const SkPMColor* upperSrc = src + radius * srcStrideX;
- for (int x = 0; x < width; ++x) {
- const SkPMColor* lp = src;
- const SkPMColor* up = upperSrc;
- SkPMColor* dptr = dst;
- for (int y = 0; y < height; ++y) {
- __m128i max = type == kDilate ? _mm_setzero_si128() : _mm_set1_epi32(0xFFFFFFFF);
- for (const SkPMColor* p = lp; p <= up; p += srcStrideX) {
- __m128i src_pixel = _mm_cvtsi32_si128(*p);
- max = type == kDilate ? _mm_max_epu8(src_pixel, max) : _mm_min_epu8(src_pixel, max);
- }
- *dptr = _mm_cvtsi128_si32(max);
- dptr += dstStrideY;
- lp += srcStrideY;
- up += srcStrideY;
- }
- if (x >= radius) {
- src += srcStrideX;
- }
- if (x + radius < width - 1) {
- upperSrc += srcStrideX;
- }
- dst += dstStrideX;
- }
-}
-
-void SkDilateX_SSE2(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride)
-{
- SkMorph_SSE2<kDilate, kX>(src, dst, radius, width, height, srcStride, dstStride);
-}
-
-void SkErodeX_SSE2(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride)
-{
- SkMorph_SSE2<kErode, kX>(src, dst, radius, width, height, srcStride, dstStride);
-}
-
-void SkDilateY_SSE2(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride)
-{
- SkMorph_SSE2<kDilate, kY>(src, dst, radius, width, height, srcStride, dstStride);
-}
-
-void SkErodeY_SSE2(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride)
-{
- SkMorph_SSE2<kErode, kY>(src, dst, radius, width, height, srcStride, dstStride);
-}
diff --git a/src/opts/SkMorphology_opts_SSE2.h b/src/opts/SkMorphology_opts_SSE2.h
deleted file mode 100644
index bf5aa03b09..0000000000
--- a/src/opts/SkMorphology_opts_SSE2.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkMorphology_opts_SSE2_DEFINED
-#define SkMorphology_opts_SSE2_DEFINED
-
-#include "SkColor.h"
-
-void SkDilateX_SSE2(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride);
-void SkDilateY_SSE2(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride);
-void SkErodeX_SSE2(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride);
-void SkErodeY_SSE2(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride);
-
-#endif
diff --git a/src/opts/SkMorphology_opts_arm.cpp b/src/opts/SkMorphology_opts_arm.cpp
deleted file mode 100644
index 2bba4929c2..0000000000
--- a/src/opts/SkMorphology_opts_arm.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2014 ARM Ltd.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkMorphology_opts.h"
-#include "SkMorphology_opts_neon.h"
-#include "SkUtilsArm.h"
-
-SkMorphologyImageFilter::Proc SkMorphologyGetPlatformProc(SkMorphologyProcType type) {
-#if SK_ARM_NEON_IS_NONE
- return NULL;
-#else
-#if SK_ARM_NEON_IS_DYNAMIC
- if (!sk_cpu_arm_has_neon()) {
- return NULL;
- }
-#endif
- switch (type) {
- case kDilateX_SkMorphologyProcType:
- return SkDilateX_neon;
- case kDilateY_SkMorphologyProcType:
- return SkDilateY_neon;
- case kErodeX_SkMorphologyProcType:
- return SkErodeX_neon;
- case kErodeY_SkMorphologyProcType:
- return SkErodeY_neon;
- default:
- return NULL;
- }
-#endif
-}
diff --git a/src/opts/SkMorphology_opts_neon.cpp b/src/opts/SkMorphology_opts_neon.cpp
deleted file mode 100644
index 571b5c8b17..0000000000
--- a/src/opts/SkMorphology_opts_neon.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#include "SkColorPriv.h"
-#include "SkMorphology_opts.h"
-#include "SkMorphology_opts_neon.h"
-
-#include <arm_neon.h>
-
-/* neon version of dilateX, dilateY, erodeX, erodeY.
- * portable versions are in src/effects/SkMorphologyImageFilter.cpp.
- */
-
-enum MorphType {
- kDilate, kErode
-};
-
-enum MorphDirection {
- kX, kY
-};
-
-template<MorphType type, MorphDirection direction>
-static void SkMorph_neon(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride)
-{
- const int srcStrideX = direction == kX ? 1 : srcStride;
- const int dstStrideX = direction == kX ? 1 : dstStride;
- const int srcStrideY = direction == kX ? srcStride : 1;
- const int dstStrideY = direction == kX ? dstStride : 1;
- radius = SkMin32(radius, width - 1);
- const SkPMColor* upperSrc = src + radius * srcStrideX;
- for (int x = 0; x < width; ++x) {
- const SkPMColor* lp = src;
- const SkPMColor* up = upperSrc;
- SkPMColor* dptr = dst;
- for (int y = 0; y < height; ++y) {
- uint8x8_t max = vdup_n_u8(type == kDilate ? 0 : 255);
- for (const SkPMColor* p = lp; p <= up; p += srcStrideX) {
- uint8x8_t src_pixel = vreinterpret_u8_u32(vdup_n_u32(*p));
- max = type == kDilate ? vmax_u8(src_pixel, max) : vmin_u8(src_pixel, max);
- }
- *dptr = vget_lane_u32(vreinterpret_u32_u8(max), 0);
- dptr += dstStrideY;
- lp += srcStrideY;
- up += srcStrideY;
- }
- if (x >= radius) src += srcStrideX;
- if (x + radius < width - 1) upperSrc += srcStrideX;
- dst += dstStrideX;
- }
-}
-
-void SkDilateX_neon(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride)
-{
- SkMorph_neon<kDilate, kX>(src, dst, radius, width, height, srcStride, dstStride);
-}
-
-void SkErodeX_neon(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride)
-{
- SkMorph_neon<kErode, kX>(src, dst, radius, width, height, srcStride, dstStride);
-}
-
-void SkDilateY_neon(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride)
-{
- SkMorph_neon<kDilate, kY>(src, dst, radius, width, height, srcStride, dstStride);
-}
-
-void SkErodeY_neon(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride)
-{
- SkMorph_neon<kErode, kY>(src, dst, radius, width, height, srcStride, dstStride);
-}
diff --git a/src/opts/SkMorphology_opts_neon.h b/src/opts/SkMorphology_opts_neon.h
deleted file mode 100644
index 0b962bdad6..0000000000
--- a/src/opts/SkMorphology_opts_neon.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-void SkDilateX_neon(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride);
-void SkDilateY_neon(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride);
-void SkErodeX_neon(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride);
-void SkErodeY_neon(const SkPMColor* src, SkPMColor* dst, int radius,
- int width, int height, int srcStride, int dstStride);
diff --git a/src/opts/SkMorphology_opts_none.cpp b/src/opts/SkMorphology_opts_none.cpp
deleted file mode 100644
index ade261fc7d..0000000000
--- a/src/opts/SkMorphology_opts_none.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkMorphology_opts.h"
-
-SkMorphologyImageFilter::Proc SkMorphologyGetPlatformProc(SkMorphologyProcType) {
- return NULL;
-}
diff --git a/src/opts/SkOpts_neon.cpp b/src/opts/SkOpts_neon.cpp
index 2db976d5c9..f75dc7c55c 100644
--- a/src/opts/SkOpts_neon.cpp
+++ b/src/opts/SkOpts_neon.cpp
@@ -10,6 +10,7 @@
#define SK_OPTS_NS neon
#include "SkBlurImageFilter_opts.h"
#include "SkFloatingPoint_opts.h"
+#include "SkMorphologyImageFilter_opts.h"
#include "SkUtils_opts.h"
#include "SkXfermode_opts.h"
@@ -20,9 +21,13 @@ namespace SkOpts {
memset32 = neon::memset32;
create_xfermode = SkCreate4pxXfermode;
- static const auto x = neon::kX, y = neon::kY;
- box_blur_xx = neon::box_blur<x,x>;
- box_blur_xy = neon::box_blur<x,y>;
- box_blur_yx = neon::box_blur<y,x>;
+ box_blur_xx = neon::box_blur_xx;
+ box_blur_xy = neon::box_blur_xy;
+ box_blur_yx = neon::box_blur_yx;
+
+ dilate_x = neon::dilate_x;
+ dilate_y = neon::dilate_y;
+ erode_x = neon::erode_x;
+ erode_y = neon::erode_y;
}
}
diff --git a/src/opts/SkOpts_sse2.cpp b/src/opts/SkOpts_sse2.cpp
index ef0f96a0a1..8837efee55 100644
--- a/src/opts/SkOpts_sse2.cpp
+++ b/src/opts/SkOpts_sse2.cpp
@@ -9,6 +9,7 @@
#define SK_OPTS_NS sse2
#include "SkBlurImageFilter_opts.h"
+#include "SkMorphologyImageFilter_opts.h"
#include "SkUtils_opts.h"
#include "SkXfermode_opts.h"
@@ -18,9 +19,13 @@ namespace SkOpts {
memset32 = sse2::memset32;
create_xfermode = SkCreate4pxXfermode;
- static const auto x = sse2::kX, y = sse2::kY;
- box_blur_xx = sse2::box_blur<x,x>;
- box_blur_xy = sse2::box_blur<x,y>;
- box_blur_yx = sse2::box_blur<y,x>;
+ box_blur_xx = sse2::box_blur_xx;
+ box_blur_xy = sse2::box_blur_xy;
+ box_blur_yx = sse2::box_blur_yx;
+
+ dilate_x = sse2::dilate_x;
+ dilate_y = sse2::dilate_y;
+ erode_x = sse2::erode_x;
+ erode_y = sse2::erode_y;
}
}
diff --git a/src/opts/SkOpts_sse41.cpp b/src/opts/SkOpts_sse41.cpp
index 189810c11e..938b2f9e83 100644
--- a/src/opts/SkOpts_sse41.cpp
+++ b/src/opts/SkOpts_sse41.cpp
@@ -12,9 +12,8 @@
namespace SkOpts {
void Init_sse41() {
- static const auto x = sse41::kX, y = sse41::kY;
- box_blur_xx = sse41::box_blur<x,x>;
- box_blur_xy = sse41::box_blur<x,y>;
- box_blur_yx = sse41::box_blur<y,x>;
+ box_blur_xx = sse41::box_blur_xx;
+ box_blur_xy = sse41::box_blur_xy;
+ box_blur_yx = sse41::box_blur_yx;
}
}
diff --git a/src/opts/opts_check_x86.cpp b/src/opts/opts_check_x86.cpp
index d0423377a1..c560b914f9 100644
--- a/src/opts/opts_check_x86.cpp
+++ b/src/opts/opts_check_x86.cpp
@@ -14,8 +14,6 @@
#include "SkBlitRow_opts_SSE2.h"
#include "SkBlitRow_opts_SSE4.h"
#include "SkLazyPtr.h"
-#include "SkMorphology_opts.h"
-#include "SkMorphology_opts_SSE2.h"
#include "SkRTConf.h"
#if defined(_MSC_VER) && defined(_WIN64)
@@ -294,23 +292,3 @@ SkBlitMask::BlitLCD16RowProc SkBlitMask::PlatformBlitRowProcs16(bool isOpaque) {
SkBlitMask::RowProc SkBlitMask::PlatformRowProcs(SkColorType, SkMask::Format, RowFlags) {
return NULL;
}
-
-////////////////////////////////////////////////////////////////////////////////
-
-SkMorphologyImageFilter::Proc SkMorphologyGetPlatformProc(SkMorphologyProcType type) {
- if (!supports_simd(SK_CPU_SSE_LEVEL_SSE2)) {
- return NULL;
- }
- switch (type) {
- case kDilateX_SkMorphologyProcType:
- return SkDilateX_SSE2;
- case kDilateY_SkMorphologyProcType:
- return SkDilateY_SSE2;
- case kErodeX_SkMorphologyProcType:
- return SkErodeX_SSE2;
- case kErodeY_SkMorphologyProcType:
- return SkErodeY_SSE2;
- default:
- return NULL;
- }
-}