Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(339)

Side by Side Diff: src/opts/SkMorphologyImageFilter_opts.h

Issue 1267343004: Port morphology to SkOpts. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/opts/SkBlurImageFilter_opts.h ('k') | src/opts/SkMorphology_opts.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
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
8 #ifndef SkMorphologyImageFilter_opts_DEFINED
9 #define SkMorphologyImageFilter_opts_DEFINED
10
11 namespace SK_OPTS_NS {
12
13 enum MorphType { kDilate, kErode };
14 enum class MorphDirection { kX, kY };
15
16 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
17 template<MorphType type, MorphDirection direction>
18 static void morph(const SkPMColor* src, SkPMColor* dst,
19 int radius, int width, int height, int srcStride, int dstStrid e) {
20 const int srcStrideX = direction == MorphDirection::kX ? 1 : srcStride;
21 const int dstStrideX = direction == MorphDirection::kX ? 1 : dstStride;
22 const int srcStrideY = direction == MorphDirection::kX ? srcStride : 1;
23 const int dstStrideY = direction == MorphDirection::kX ? dstStride : 1;
24 radius = SkMin32(radius, width - 1);
25 const SkPMColor* upperSrc = src + radius * srcStrideX;
26 for (int x = 0; x < width; ++x) {
27 const SkPMColor* lp = src;
28 const SkPMColor* up = upperSrc;
29 SkPMColor* dptr = dst;
30 for (int y = 0; y < height; ++y) {
31 __m128i extreme = (type == kDilate) ? _mm_setzero_si128()
32 : _mm_set1_epi32(0xFFFFFFFF);
33 for (const SkPMColor* p = lp; p <= up; p += srcStrideX) {
34 __m128i src_pixel = _mm_cvtsi32_si128(*p);
35 extreme = (type == kDilate) ? _mm_max_epu8(src_pixel, extreme)
36 : _mm_min_epu8(src_pixel, extreme);
37 }
38 *dptr = _mm_cvtsi128_si32(extreme);
39 dptr += dstStrideY;
40 lp += srcStrideY;
41 up += srcStrideY;
42 }
43 if (x >= radius) { src += srcStrideX; }
44 if (x + radius < width - 1) { upperSrc += srcStrideX; }
45 dst += dstStrideX;
46 }
47 }
48
49 #elif defined(SK_ARM_HAS_NEON)
50 template<MorphType type, MorphDirection direction>
51 static void morph(const SkPMColor* src, SkPMColor* dst,
52 int radius, int width, int height, int srcStride, int dstStrid e) {
53 const int srcStrideX = direction == MorphDirection::kX ? 1 : srcStride;
54 const int dstStrideX = direction == MorphDirection::kX ? 1 : dstStride;
55 const int srcStrideY = direction == MorphDirection::kX ? srcStride : 1;
56 const int dstStrideY = direction == MorphDirection::kX ? dstStride : 1;
57 radius = SkMin32(radius, width - 1);
58 const SkPMColor* upperSrc = src + radius * srcStrideX;
59 for (int x = 0; x < width; ++x) {
60 const SkPMColor* lp = src;
61 const SkPMColor* up = upperSrc;
62 SkPMColor* dptr = dst;
63 for (int y = 0; y < height; ++y) {
64 uint8x8_t extreme = vdup_n_u8(type == kDilate ? 0 : 255);
65 for (const SkPMColor* p = lp; p <= up; p += srcStrideX) {
66 uint8x8_t src_pixel = vreinterpret_u8_u32(vdup_n_u32(*p));
67 extreme = (type == kDilate) ? vmax_u8(src_pixel, extreme)
68 : vmin_u8(src_pixel, extreme);
69 }
70 *dptr = vget_lane_u32(vreinterpret_u32_u8(extreme), 0);
71 dptr += dstStrideY;
72 lp += srcStrideY;
73 up += srcStrideY;
74 }
75 if (x >= radius) src += srcStrideX;
76 if (x + radius < width - 1) upperSrc += srcStrideX;
77 dst += dstStrideX;
78 }
79 }
80
81 #else
82 template<MorphType type, MorphDirection direction>
83 static void morph(const SkPMColor* src, SkPMColor* dst,
84 int radius, int width, int height, int srcStride, int dstStrid e) {
85 const int srcStrideX = direction == MorphDirection::kX ? 1 : srcStride;
86 const int dstStrideX = direction == MorphDirection::kX ? 1 : dstStride;
87 const int srcStrideY = direction == MorphDirection::kX ? srcStride : 1;
88 const int dstStrideY = direction == MorphDirection::kX ? dstStride : 1;
89 radius = SkMin32(radius, width - 1);
90 const SkPMColor* upperSrc = src + radius * srcStrideX;
91 for (int x = 0; x < width; ++x) {
92 const SkPMColor* lp = src;
93 const SkPMColor* up = upperSrc;
94 SkPMColor* dptr = dst;
95 for (int y = 0; y < height; ++y) {
96 // If we're maxing (dilate), start from 0; if minning (erode), start from 255.
97 const int start = (type == kDilate) ? 0 : 255;
98 int B = start, G = start, R = start, A = start;
99 for (const SkPMColor* p = lp; p <= up; p += srcStrideX) {
100 int b = SkGetPackedB32(*p),
101 g = SkGetPackedG32(*p),
102 r = SkGetPackedR32(*p),
103 a = SkGetPackedA32(*p);
104 if (type == kDilate) {
105 B = SkTMax(b, B);
106 G = SkTMax(g, G);
107 R = SkTMax(r, R);
108 A = SkTMax(a, A);
109 } else {
110 B = SkTMin(b, B);
111 G = SkTMin(g, G);
112 R = SkTMin(r, R);
113 A = SkTMin(a, A);
114 }
115 }
116 *dptr = SkPackARGB32(A, R, G, B);
117 dptr += dstStrideY;
118 lp += srcStrideY;
119 up += srcStrideY;
120 }
121 if (x >= radius) { src += srcStrideX; }
122 if (x + radius < width - 1) { upperSrc += srcStrideX; }
123 dst += dstStrideX;
124 }
125 }
126
127 #endif
128
129 static auto dilate_x = &morph<kDilate, MorphDirection::kX>,
130 dilate_y = &morph<kDilate, MorphDirection::kY>,
131 erode_x = &morph<kErode, MorphDirection::kX>,
132 erode_y = &morph<kErode, MorphDirection::kY>;
133
134 } // namespace SK_OPTS_NS
135
136 #endif//SkMorphologyImageFilter_opts_DEFINED
137
OLDNEW
« no previous file with comments | « src/opts/SkBlurImageFilter_opts.h ('k') | src/opts/SkMorphology_opts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698