| 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 |