OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "SkConvolver.h" | 5 #include "SkConvolver.h" |
6 #include "SkSize.h" | 6 #include "SkSize.h" |
7 #include "SkTypes.h" | 7 #include "SkTypes.h" |
8 | 8 |
9 namespace { | 9 namespace { |
10 | 10 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 // Store the new pixel. | 151 // Store the new pixel. |
152 outRow[outX * 4 + 0] = ClampTo8(accum[0]); | 152 outRow[outX * 4 + 0] = ClampTo8(accum[0]); |
153 outRow[outX * 4 + 1] = ClampTo8(accum[1]); | 153 outRow[outX * 4 + 1] = ClampTo8(accum[1]); |
154 outRow[outX * 4 + 2] = ClampTo8(accum[2]); | 154 outRow[outX * 4 + 2] = ClampTo8(accum[2]); |
155 if (hasAlpha) { | 155 if (hasAlpha) { |
156 outRow[outX * 4 + 3] = ClampTo8(accum[3]); | 156 outRow[outX * 4 + 3] = ClampTo8(accum[3]); |
157 } | 157 } |
158 } | 158 } |
159 } | 159 } |
160 | 160 |
| 161 // There's a bug somewhere here with GCC autovectorization (-ftree-vectorize
) on 32 bit builds. |
| 162 // Dropping to -O2 disables -ftree-vectorize. http://skbug.com/2575 |
| 163 #if defined(__i386) && SK_HAS_ATTRIBUTE(optimize) && defined(SK_RELEASE) |
| 164 #define SK_MAYBE_DISABLE_VECTORIZATION __attribute__((optimize("O2"))) |
| 165 #else |
| 166 #define SK_MAYBE_DISABLE_VECTORIZATION |
| 167 #endif |
| 168 |
| 169 SK_MAYBE_DISABLE_VECTORIZATION |
| 170 static void ConvolveHorizontallyAlpha(const unsigned char* srcData, |
| 171 const SkConvolutionFilter1D& filter, |
| 172 unsigned char* outRow) { |
| 173 return ConvolveHorizontally<true>(srcData, filter, outRow); |
| 174 } |
| 175 |
| 176 SK_MAYBE_DISABLE_VECTORIZATION |
| 177 static void ConvolveHorizontallyNoAlpha(const unsigned char* srcData, |
| 178 const SkConvolutionFilter1D& filter, |
| 179 unsigned char* outRow) { |
| 180 return ConvolveHorizontally<false>(srcData, filter, outRow); |
| 181 } |
| 182 |
| 183 #undef SK_MAYBE_DISABLE_VECTORIZATION |
| 184 |
| 185 |
161 // Does vertical convolution to produce one output row. The filter values and | 186 // Does vertical convolution to produce one output row. The filter values and |
162 // length are given in the first two parameters. These are applied to each | 187 // length are given in the first two parameters. These are applied to each |
163 // of the rows pointed to in the |sourceDataRows| array, with each row | 188 // of the rows pointed to in the |sourceDataRows| array, with each row |
164 // being |pixelWidth| wide. | 189 // being |pixelWidth| wide. |
165 // | 190 // |
166 // The output must have room for |pixelWidth * 4| bytes. | 191 // The output must have room for |pixelWidth * 4| bytes. |
167 template<bool hasAlpha> | 192 template<bool hasAlpha> |
168 void ConvolveVertically(const SkConvolutionFilter1D::ConvolutionFixed* filte
rValues, | 193 void ConvolveVertically(const SkConvolutionFilter1D::ConvolutionFixed* filte
rValues, |
169 int filterLength, | 194 int filterLength, |
170 unsigned char* const* sourceDataRows, | 195 unsigned char* const* sourceDataRows, |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 *filterOffset = filter.fOffset; | 348 *filterOffset = filter.fOffset; |
324 *filterLength = filter.fTrimmedLength; | 349 *filterLength = filter.fTrimmedLength; |
325 *specifiedFilterlength = filter.fLength; | 350 *specifiedFilterlength = filter.fLength; |
326 if (filter.fTrimmedLength == 0) { | 351 if (filter.fTrimmedLength == 0) { |
327 return NULL; | 352 return NULL; |
328 } | 353 } |
329 | 354 |
330 return &fFilterValues[filter.fDataLocation]; | 355 return &fFilterValues[filter.fDataLocation]; |
331 } | 356 } |
332 | 357 |
333 // There's a bug somewhere in here with GCC autovectorization (-ftree-vectorize)
on 32 bit builds. | |
334 // Dropping to -O2 disables -ftree-vectorize. http://skbug.com/2575 | |
335 #if defined(__i386) && SK_HAS_ATTRIBUTE(optimize) && defined(SK_RELEASE) | |
336 __attribute__((optimize("O2"))) | |
337 #endif | |
338 void BGRAConvolve2D(const unsigned char* sourceData, | 358 void BGRAConvolve2D(const unsigned char* sourceData, |
339 int sourceByteRowStride, | 359 int sourceByteRowStride, |
340 bool sourceHasAlpha, | 360 bool sourceHasAlpha, |
341 const SkConvolutionFilter1D& filterX, | 361 const SkConvolutionFilter1D& filterX, |
342 const SkConvolutionFilter1D& filterY, | 362 const SkConvolutionFilter1D& filterY, |
343 int outputByteRowStride, | 363 int outputByteRowStride, |
344 unsigned char* output, | 364 unsigned char* output, |
345 const SkConvolutionProcs& convolveProcs, | 365 const SkConvolutionProcs& convolveProcs, |
346 bool useSimdIfPossible) { | 366 bool useSimdIfPossible) { |
347 | 367 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 } else { | 438 } else { |
419 // Check if we need to avoid SSE2 for this row. | 439 // Check if we need to avoid SSE2 for this row. |
420 if (convolveProcs.fConvolveHorizontally && | 440 if (convolveProcs.fConvolveHorizontally && |
421 nextXRow < lastFilterOffset + lastFilterLength - | 441 nextXRow < lastFilterOffset + lastFilterLength - |
422 avoidSimdRows) { | 442 avoidSimdRows) { |
423 convolveProcs.fConvolveHorizontally( | 443 convolveProcs.fConvolveHorizontally( |
424 &sourceData[(uint64_t)nextXRow * sourceByteRowStride], | 444 &sourceData[(uint64_t)nextXRow * sourceByteRowStride], |
425 filterX, rowBuffer.advanceRow(), sourceHasAlpha); | 445 filterX, rowBuffer.advanceRow(), sourceHasAlpha); |
426 } else { | 446 } else { |
427 if (sourceHasAlpha) { | 447 if (sourceHasAlpha) { |
428 ConvolveHorizontally<true>( | 448 ConvolveHorizontallyAlpha( |
429 &sourceData[(uint64_t)nextXRow * sourceByteRowStride
], | 449 &sourceData[(uint64_t)nextXRow * sourceByteRowStride
], |
430 filterX, rowBuffer.advanceRow()); | 450 filterX, rowBuffer.advanceRow()); |
431 } else { | 451 } else { |
432 ConvolveHorizontally<false>( | 452 ConvolveHorizontallyNoAlpha( |
433 &sourceData[(uint64_t)nextXRow * sourceByteRowStride
], | 453 &sourceData[(uint64_t)nextXRow * sourceByteRowStride
], |
434 filterX, rowBuffer.advanceRow()); | 454 filterX, rowBuffer.advanceRow()); |
435 } | 455 } |
436 } | 456 } |
437 nextXRow++; | 457 nextXRow++; |
438 } | 458 } |
439 } | 459 } |
440 | 460 |
441 // Compute where in the output image this row of final data will go. | 461 // Compute where in the output image this row of final data will go. |
442 unsigned char* curOutputRow = &output[outY * outputByteRowStride]; | 462 unsigned char* curOutputRow = &output[outY * outputByteRowStride]; |
(...skipping 14 matching lines...) Expand all Loading... |
457 filterX.numValues(), curOutputRow
, | 477 filterX.numValues(), curOutputRow
, |
458 sourceHasAlpha); | 478 sourceHasAlpha); |
459 } else { | 479 } else { |
460 ConvolveVertically(filterValues, filterLength, | 480 ConvolveVertically(filterValues, filterLength, |
461 firstRowForFilter, | 481 firstRowForFilter, |
462 filterX.numValues(), curOutputRow, | 482 filterX.numValues(), curOutputRow, |
463 sourceHasAlpha); | 483 sourceHasAlpha); |
464 } | 484 } |
465 } | 485 } |
466 } | 486 } |
OLD | NEW |