OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef SKIA_EXT_CONVOLVER_H_ | 5 #ifndef SKIA_EXT_CONVOLVER_H_ |
6 #define SKIA_EXT_CONVOLVER_H_ | 6 #define SKIA_EXT_CONVOLVER_H_ |
7 | 7 |
8 #include <cmath> | 8 #include <cmath> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/cpu.h" | 12 #include "base/cpu.h" |
| 13 #include "third_party/skia/include/core/SkSize.h" |
13 #include "third_party/skia/include/core/SkTypes.h" | 14 #include "third_party/skia/include/core/SkTypes.h" |
14 | 15 |
15 // We can build SSE2 optimized versions for all x86 CPUs | 16 // We can build SSE2 optimized versions for all x86 CPUs |
16 // except when building for the IOS emulator. | 17 // except when building for the IOS emulator. |
17 #if defined(ARCH_CPU_X86_FAMILY) && !defined(OS_IOS) | 18 #if defined(ARCH_CPU_X86_FAMILY) && !defined(OS_IOS) |
18 #define SIMD_SSE2 1 | 19 #define SIMD_SSE2 1 |
19 #define SIMD_PADDING 8 // 8 * int16 | 20 #define SIMD_PADDING 8 // 8 * int16 |
20 #endif | 21 #endif |
21 | 22 |
22 // avoid confusion with Mac OS X's math library (Carbon) | 23 // avoid confusion with Mac OS X's math library (Carbon) |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 // Retrieves a filter for the given |value_offset|, a position in the output | 93 // Retrieves a filter for the given |value_offset|, a position in the output |
93 // image in the direction we're convolving. The offset and length of the | 94 // image in the direction we're convolving. The offset and length of the |
94 // filter values are put into the corresponding out arguments (see AddFilter | 95 // filter values are put into the corresponding out arguments (see AddFilter |
95 // above for what these mean), and a pointer to the first scaling factor is | 96 // above for what these mean), and a pointer to the first scaling factor is |
96 // returned. There will be |filter_length| values in this array. | 97 // returned. There will be |filter_length| values in this array. |
97 inline const Fixed* FilterForValue(int value_offset, | 98 inline const Fixed* FilterForValue(int value_offset, |
98 int* filter_offset, | 99 int* filter_offset, |
99 int* filter_length) const { | 100 int* filter_length) const { |
100 const FilterInstance& filter = filters_[value_offset]; | 101 const FilterInstance& filter = filters_[value_offset]; |
101 *filter_offset = filter.offset; | 102 *filter_offset = filter.offset; |
102 *filter_length = filter.length; | 103 *filter_length = filter.trimmed_length; |
103 if (filter.length == 0) { | 104 if (filter.trimmed_length == 0) { |
104 return NULL; | 105 return NULL; |
105 } | 106 } |
106 return &filter_values_[filter.data_location]; | 107 return &filter_values_[filter.data_location]; |
107 } | 108 } |
108 | 109 |
| 110 // Retrieves the filter for the offset 0, presumed to be the one and only. |
| 111 // The offset and length of the filter values are put into the corresponding |
| 112 // out arguments (see AddFilter). Note that |filter_legth| and |
| 113 // |specified_filter_length| may be different if leading/trailing zeros of the |
| 114 // original floating point form were clipped. |
| 115 // There will be |filter_length| values in the return array. |
| 116 // Returns NULL if the filter is 0-length (for instance when all floating |
| 117 // point values passed to AddFilter were clipped to 0). |
| 118 const Fixed* GetSingleFilter(int* specified_filter_length, |
| 119 int* filter_offset, |
| 120 int* filter_length) const; |
109 | 121 |
110 inline void PaddingForSIMD() { | 122 inline void PaddingForSIMD() { |
111 // Padding |padding_count| of more dummy coefficients after the coefficients | 123 // Padding |padding_count| of more dummy coefficients after the coefficients |
112 // of last filter to prevent SIMD instructions which load 8 or 16 bytes | 124 // of last filter to prevent SIMD instructions which load 8 or 16 bytes |
113 // together to access invalid memory areas. We are not trying to align the | 125 // together to access invalid memory areas. We are not trying to align the |
114 // coefficients right now due to the opaqueness of <vector> implementation. | 126 // coefficients right now due to the opaqueness of <vector> implementation. |
115 // This has to be done after all |AddFilter| calls. | 127 // This has to be done after all |AddFilter| calls. |
116 #ifdef SIMD_PADDING | 128 #ifdef SIMD_PADDING |
117 for (int i = 0; i < SIMD_PADDING; ++i) | 129 for (int i = 0; i < SIMD_PADDING; ++i) |
118 filter_values_.push_back(static_cast<Fixed>(0)); | 130 filter_values_.push_back(static_cast<Fixed>(0)); |
119 #endif | 131 #endif |
120 } | 132 } |
121 | 133 |
122 private: | 134 private: |
123 struct FilterInstance { | 135 struct FilterInstance { |
124 // Offset within filter_values for this instance of the filter. | 136 // Offset within filter_values for this instance of the filter. |
125 int data_location; | 137 int data_location; |
126 | 138 |
127 // Distance from the left of the filter to the center. IN PIXELS | 139 // Distance from the left of the filter to the center. IN PIXELS |
128 int offset; | 140 int offset; |
129 | 141 |
130 // Number of values in this filter instance. | 142 // Number of values in this filter instance. |
| 143 int trimmed_length; |
| 144 |
| 145 // Filter length as specified. Note that this may be different from |
| 146 // 'trimmed_length' if leading/trailing zeros of the original floating |
| 147 // point form were clipped differently on each tail. |
131 int length; | 148 int length; |
132 }; | 149 }; |
133 | 150 |
134 // Stores the information for each filter added to this class. | 151 // Stores the information for each filter added to this class. |
135 std::vector<FilterInstance> filters_; | 152 std::vector<FilterInstance> filters_; |
136 | 153 |
137 // We store all the filter values in this flat list, indexed by | 154 // We store all the filter values in this flat list, indexed by |
138 // |FilterInstance.data_location| to avoid the mallocs required for storing | 155 // |FilterInstance.data_location| to avoid the mallocs required for storing |
139 // each one separately. | 156 // each one separately. |
140 std::vector<Fixed> filter_values_; | 157 std::vector<Fixed> filter_values_; |
(...skipping 21 matching lines...) Expand all Loading... |
162 // The layout in memory is assumed to be 4-bytes per pixel in B-G-R-A order | 179 // The layout in memory is assumed to be 4-bytes per pixel in B-G-R-A order |
163 // (this is ARGB when loaded into 32-bit words on a little-endian machine). | 180 // (this is ARGB when loaded into 32-bit words on a little-endian machine). |
164 SK_API void BGRAConvolve2D(const unsigned char* source_data, | 181 SK_API void BGRAConvolve2D(const unsigned char* source_data, |
165 int source_byte_row_stride, | 182 int source_byte_row_stride, |
166 bool source_has_alpha, | 183 bool source_has_alpha, |
167 const ConvolutionFilter1D& xfilter, | 184 const ConvolutionFilter1D& xfilter, |
168 const ConvolutionFilter1D& yfilter, | 185 const ConvolutionFilter1D& yfilter, |
169 int output_byte_row_stride, | 186 int output_byte_row_stride, |
170 unsigned char* output, | 187 unsigned char* output, |
171 bool use_simd_if_possible); | 188 bool use_simd_if_possible); |
| 189 |
| 190 // Does a 1D convolution of the given source image along the X dimension on |
| 191 // a single channel of the bitmap. |
| 192 // |
| 193 // The function uses the same convolution kernel for each pixel. That kernel |
| 194 // must be added to |filter| at offset 0. This is a most straightforward |
| 195 // implementation of convolution, intended chiefly for development purposes. |
| 196 SK_API void SingleChannelConvolveX1D(const unsigned char* source_data, |
| 197 int source_byte_row_stride, |
| 198 int input_channel_index, |
| 199 int input_channel_count, |
| 200 const ConvolutionFilter1D& filter, |
| 201 const SkISize& image_size, |
| 202 unsigned char* output, |
| 203 int output_byte_row_stride, |
| 204 int output_channel_index, |
| 205 int output_channel_count, |
| 206 bool absolute_values); |
| 207 |
| 208 // Does a 1D convolution of the given source image along the Y dimension on |
| 209 // a single channel of the bitmap. |
| 210 SK_API void SingleChannelConvolveY1D(const unsigned char* source_data, |
| 211 int source_byte_row_stride, |
| 212 int input_channel_index, |
| 213 int input_channel_count, |
| 214 const ConvolutionFilter1D& filter, |
| 215 const SkISize& image_size, |
| 216 unsigned char* output, |
| 217 int output_byte_row_stride, |
| 218 int output_channel_index, |
| 219 int output_channel_count, |
| 220 bool absolute_values); |
| 221 |
172 } // namespace skia | 222 } // namespace skia |
173 | 223 |
174 #endif // SKIA_EXT_CONVOLVER_H_ | 224 #endif // SKIA_EXT_CONVOLVER_H_ |
OLD | NEW |