| Index: src/opts/SkBlurImageFilter_opts.h
|
| diff --git a/src/opts/SkBlurImageFilter_opts.h b/src/opts/SkBlurImageFilter_opts.h
|
| index fb3fc19c0d3f319bcab80c68e00e00893b4f8d6e..31d9d5fdbc166e5fedab16638f6c353ed8608969 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
|
|
|