| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #ifndef SkLinearBitmapPipeline_sampler_DEFINED | 8 #ifndef SkLinearBitmapPipeline_sampler_DEFINED |
| 9 #define SkLinearBitmapPipeline_sampler_DEFINED | 9 #define SkLinearBitmapPipeline_sampler_DEFINED |
| 10 | 10 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 // +--------+--------+ | 32 // +--------+--------+ |
| 33 // | 33 // |
| 34 // | 34 // |
| 35 // Given a pixelxy each is multiplied by a different factor derived from the fra
ctional part of x | 35 // Given a pixelxy each is multiplied by a different factor derived from the fra
ctional part of x |
| 36 // and y: | 36 // and y: |
| 37 // * px00 -> (1 - x)(1 - y) = 1 - x - y + xy | 37 // * px00 -> (1 - x)(1 - y) = 1 - x - y + xy |
| 38 // * px10 -> x(1 - y) = x - xy | 38 // * px10 -> x(1 - y) = x - xy |
| 39 // * px01 -> (1 - x)y = y - xy | 39 // * px01 -> (1 - x)y = y - xy |
| 40 // * px11 -> xy | 40 // * px11 -> xy |
| 41 // So x * y is calculated first and then used to calculate all the other factors
. | 41 // So x * y is calculated first and then used to calculate all the other factors
. |
| 42 static Sk4s VECTORCALL bilerp4(Sk4s xs, Sk4s ys, Sk4f px00, Sk4f px10, | 42 static Sk4s SK_VECTORCALL bilerp4(Sk4s xs, Sk4s ys, Sk4f px00, Sk4f px10, |
| 43 Sk4f px01, Sk4f px11) { | 43 Sk4f px01, Sk4f px11) { |
| 44 // Calculate fractional xs and ys. | 44 // Calculate fractional xs and ys. |
| 45 Sk4s fxs = xs - xs.floor(); | 45 Sk4s fxs = xs - xs.floor(); |
| 46 Sk4s fys = ys - ys.floor(); | 46 Sk4s fys = ys - ys.floor(); |
| 47 Sk4s fxys{fxs * fys}; | 47 Sk4s fxys{fxs * fys}; |
| 48 Sk4f sum = px11 * fxys; | 48 Sk4f sum = px11 * fxys; |
| 49 sum = sum + px01 * (fys - fxys); | 49 sum = sum + px01 * (fys - fxys); |
| 50 sum = sum + px10 * (fxs - fxys); | 50 sum = sum + px10 * (fxs - fxys); |
| 51 sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys); | 51 sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys); |
| 52 return sum; | 52 return sum; |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 template <SkColorType colorType, SkGammaType gammaType> | 209 template <SkColorType colorType, SkGammaType gammaType> |
| 210 class PixelAccessor { | 210 class PixelAccessor { |
| 211 using Element = typename PixelGetter<colorType, gammaType>::Element; | 211 using Element = typename PixelGetter<colorType, gammaType>::Element; |
| 212 public: | 212 public: |
| 213 template <typename... Args> | 213 template <typename... Args> |
| 214 PixelAccessor(const SkPixmap& srcPixmap, Args&&... args) | 214 PixelAccessor(const SkPixmap& srcPixmap, Args&&... args) |
| 215 : fSrc{static_cast<const Element*>(srcPixmap.addr())} | 215 : fSrc{static_cast<const Element*>(srcPixmap.addr())} |
| 216 , fWidth{srcPixmap.rowBytesAsPixels()} | 216 , fWidth{srcPixmap.rowBytesAsPixels()} |
| 217 , fGetter{srcPixmap, std::move<Args>(args)...} { } | 217 , fGetter{srcPixmap, std::move<Args>(args)...} { } |
| 218 | 218 |
| 219 void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1,
Sk4f* px2) { | 219 void SK_VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px
1, Sk4f* px2) { |
| 220 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); | 220 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); |
| 221 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); | 221 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); |
| 222 Sk4i bufferLoc = YIs * fWidth + XIs; | 222 Sk4i bufferLoc = YIs * fWidth + XIs; |
| 223 switch (n) { | 223 switch (n) { |
| 224 case 3: | 224 case 3: |
| 225 *px2 = this->getPixelAt(bufferLoc[2]); | 225 *px2 = this->getPixelAt(bufferLoc[2]); |
| 226 case 2: | 226 case 2: |
| 227 *px1 = this->getPixelAt(bufferLoc[1]); | 227 *px1 = this->getPixelAt(bufferLoc[1]); |
| 228 case 1: | 228 case 1: |
| 229 *px0 = this->getPixelAt(bufferLoc[0]); | 229 *px0 = this->getPixelAt(bufferLoc[0]); |
| 230 default: | 230 default: |
| 231 break; | 231 break; |
| 232 } | 232 } |
| 233 } | 233 } |
| 234 | 234 |
| 235 void VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2
, Sk4f* px3) { | 235 void SK_VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f*
px2, Sk4f* px3) { |
| 236 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); | 236 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); |
| 237 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); | 237 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); |
| 238 Sk4i bufferLoc = YIs * fWidth + XIs; | 238 Sk4i bufferLoc = YIs * fWidth + XIs; |
| 239 *px0 = this->getPixelAt(bufferLoc[0]); | 239 *px0 = this->getPixelAt(bufferLoc[0]); |
| 240 *px1 = this->getPixelAt(bufferLoc[1]); | 240 *px1 = this->getPixelAt(bufferLoc[1]); |
| 241 *px2 = this->getPixelAt(bufferLoc[2]); | 241 *px2 = this->getPixelAt(bufferLoc[2]); |
| 242 *px3 = this->getPixelAt(bufferLoc[3]); | 242 *px3 = this->getPixelAt(bufferLoc[3]); |
| 243 } | 243 } |
| 244 | 244 |
| 245 void get4Pixels(const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2,
Sk4f* px3) { | 245 void get4Pixels(const void* src, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2,
Sk4f* px3) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 class NearestNeighborSampler : public SkLinearBitmapPipeline::SampleProcessorInt
erface { | 312 class NearestNeighborSampler : public SkLinearBitmapPipeline::SampleProcessorInt
erface { |
| 313 public: | 313 public: |
| 314 template<typename... Args> | 314 template<typename... Args> |
| 315 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next
, Args&& ... args) | 315 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next
, Args&& ... args) |
| 316 : fNext{next}, fStrategy{std::forward<Args>(args)...} { } | 316 : fNext{next}, fStrategy{std::forward<Args>(args)...} { } |
| 317 | 317 |
| 318 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next
, | 318 NearestNeighborSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next
, |
| 319 const NearestNeighborSampler& sampler) | 319 const NearestNeighborSampler& sampler) |
| 320 : fNext{next}, fStrategy{sampler.fStrategy} { } | 320 : fNext{next}, fStrategy{sampler.fStrategy} { } |
| 321 | 321 |
| 322 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { | 322 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { |
| 323 SkASSERT(0 < n && n < 4); | 323 SkASSERT(0 < n && n < 4); |
| 324 Sk4f px0, px1, px2; | 324 Sk4f px0, px1, px2; |
| 325 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); | 325 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); |
| 326 if (n >= 1) fNext->blendPixel(px0); | 326 if (n >= 1) fNext->blendPixel(px0); |
| 327 if (n >= 2) fNext->blendPixel(px1); | 327 if (n >= 2) fNext->blendPixel(px1); |
| 328 if (n >= 3) fNext->blendPixel(px2); | 328 if (n >= 3) fNext->blendPixel(px2); |
| 329 } | 329 } |
| 330 | 330 |
| 331 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { | 331 void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { |
| 332 Sk4f px0, px1, px2, px3; | 332 Sk4f px0, px1, px2, px3; |
| 333 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); | 333 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); |
| 334 fNext->blend4Pixels(px0, px1, px2, px3); | 334 fNext->blend4Pixels(px0, px1, px2, px3); |
| 335 } | 335 } |
| 336 | 336 |
| 337 void pointSpan(Span span) override { | 337 void pointSpan(Span span) override { |
| 338 SkASSERT(!span.isEmpty()); | 338 SkASSERT(!span.isEmpty()); |
| 339 SkPoint start; | 339 SkPoint start; |
| 340 SkScalar length; | 340 SkScalar length; |
| 341 int count; | 341 int count; |
| 342 std::tie(start, length, count) = span; | 342 std::tie(start, length, count) = span; |
| 343 SkScalar absLength = SkScalarAbs(length); | 343 SkScalar absLength = SkScalarAbs(length); |
| 344 if (absLength < (count - 1)) { | 344 if (absLength < (count - 1)) { |
| 345 this->spanSlowRate(span); | 345 this->spanSlowRate(span); |
| 346 } else if (absLength == (count - 1)) { | 346 } else if (absLength == (count - 1)) { |
| 347 src_strategy_blend(span, fNext, &fStrategy); | 347 src_strategy_blend(span, fNext, &fStrategy); |
| 348 } else { | 348 } else { |
| 349 this->spanFastRate(span); | 349 this->spanFastRate(span); |
| 350 } | 350 } |
| 351 } | 351 } |
| 352 | 352 |
| 353 void repeatSpan(Span span, int32_t repeatCount) override { | 353 void repeatSpan(Span span, int32_t repeatCount) override { |
| 354 while (repeatCount > 0) { | 354 while (repeatCount > 0) { |
| 355 this->pointSpan(span); | 355 this->pointSpan(span); |
| 356 repeatCount--; | 356 repeatCount--; |
| 357 } | 357 } |
| 358 } | 358 } |
| 359 | 359 |
| 360 void VECTORCALL bilerpEdge(Sk4s xs, Sk4s ys) override { | 360 void SK_VECTORCALL bilerpEdge(Sk4s xs, Sk4s ys) override { |
| 361 SkFAIL("Using nearest neighbor sampler, but calling a bilerpEdge."); | 361 SkFAIL("Using nearest neighbor sampler, but calling a bilerpEdge."); |
| 362 } | 362 } |
| 363 | 363 |
| 364 void bilerpSpan(Span span, SkScalar y) override { | 364 void bilerpSpan(Span span, SkScalar y) override { |
| 365 SkFAIL("Using nearest neighbor sampler, but calling a bilerpSpan."); | 365 SkFAIL("Using nearest neighbor sampler, but calling a bilerpSpan."); |
| 366 } | 366 } |
| 367 | 367 |
| 368 private: | 368 private: |
| 369 // When moving through source space more slowly than dst space (zoomed in), | 369 // When moving through source space more slowly than dst space (zoomed in), |
| 370 // we'll be sampling from the same source pixel more than once. | 370 // we'll be sampling from the same source pixel more than once. |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 | 446 |
| 447 // bilerp4() expects xs, ys are the top-lefts of the 2x2 kernel. | 447 // bilerp4() expects xs, ys are the top-lefts of the 2x2 kernel. |
| 448 Sk4f xs = Sk4f{x} - 0.5f; | 448 Sk4f xs = Sk4f{x} - 0.5f; |
| 449 Sk4f ys = Sk4f{y} - 0.5f; | 449 Sk4f ys = Sk4f{y} - 0.5f; |
| 450 Sk4f sampleXs = xs + Sk4f{0.0f, 1.0f, 0.0f, 1.0f}; | 450 Sk4f sampleXs = xs + Sk4f{0.0f, 1.0f, 0.0f, 1.0f}; |
| 451 Sk4f sampleYs = ys + Sk4f{0.0f, 0.0f, 1.0f, 1.0f}; | 451 Sk4f sampleYs = ys + Sk4f{0.0f, 0.0f, 1.0f, 1.0f}; |
| 452 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); | 452 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); |
| 453 return bilerp4(xs, ys, px00, px10, px01, px11); | 453 return bilerp4(xs, ys, px00, px10, px01, px11); |
| 454 } | 454 } |
| 455 | 455 |
| 456 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { | 456 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { |
| 457 SkASSERT(0 < n && n < 4); | 457 SkASSERT(0 < n && n < 4); |
| 458 auto bilerpPixel = [&](int index) { | 458 auto bilerpPixel = [&](int index) { |
| 459 return this->bilerpNonEdgePixel(xs[index], ys[index]); | 459 return this->bilerpNonEdgePixel(xs[index], ys[index]); |
| 460 }; | 460 }; |
| 461 | 461 |
| 462 if (n >= 1) fNext->blendPixel(bilerpPixel(0)); | 462 if (n >= 1) fNext->blendPixel(bilerpPixel(0)); |
| 463 if (n >= 2) fNext->blendPixel(bilerpPixel(1)); | 463 if (n >= 2) fNext->blendPixel(bilerpPixel(1)); |
| 464 if (n >= 3) fNext->blendPixel(bilerpPixel(2)); | 464 if (n >= 3) fNext->blendPixel(bilerpPixel(2)); |
| 465 } | 465 } |
| 466 | 466 |
| 467 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { | 467 void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { |
| 468 auto bilerpPixel = [&](int index) { | 468 auto bilerpPixel = [&](int index) { |
| 469 return this->bilerpNonEdgePixel(xs[index], ys[index]); | 469 return this->bilerpNonEdgePixel(xs[index], ys[index]); |
| 470 }; | 470 }; |
| 471 fNext->blend4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bile
rpPixel(3)); | 471 fNext->blend4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bile
rpPixel(3)); |
| 472 } | 472 } |
| 473 | 473 |
| 474 void pointSpan(Span span) override { | 474 void pointSpan(Span span) override { |
| 475 this->bilerpSpan(span, span.startY()); | 475 this->bilerpSpan(span, span.startY()); |
| 476 } | 476 } |
| 477 | 477 |
| 478 void repeatSpan(Span span, int32_t repeatCount) override { | 478 void repeatSpan(Span span, int32_t repeatCount) override { |
| 479 while (repeatCount > 0) { | 479 while (repeatCount > 0) { |
| 480 this->pointSpan(span); | 480 this->pointSpan(span); |
| 481 repeatCount--; | 481 repeatCount--; |
| 482 } | 482 } |
| 483 } | 483 } |
| 484 | 484 |
| 485 void VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) override { | 485 void SK_VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) override { |
| 486 Sk4f px00, px10, px01, px11; | 486 Sk4f px00, px10, px01, px11; |
| 487 Sk4f xs = Sk4f{sampleXs[0]}; | 487 Sk4f xs = Sk4f{sampleXs[0]}; |
| 488 Sk4f ys = Sk4f{sampleYs[0]}; | 488 Sk4f ys = Sk4f{sampleYs[0]}; |
| 489 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); | 489 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); |
| 490 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); | 490 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); |
| 491 fNext->blendPixel(pixel); | 491 fNext->blendPixel(pixel); |
| 492 } | 492 } |
| 493 | 493 |
| 494 void bilerpSpan(Span span, SkScalar y) override { | 494 void bilerpSpan(Span span, SkScalar y) override { |
| 495 SkASSERT(!span.isEmpty()); | 495 SkASSERT(!span.isEmpty()); |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 } | 801 } |
| 802 } | 802 } |
| 803 | 803 |
| 804 Next* const fNext; | 804 Next* const fNext; |
| 805 PixelAccessor<colorType, gammaType> fStrategy; | 805 PixelAccessor<colorType, gammaType> fStrategy; |
| 806 }; | 806 }; |
| 807 | 807 |
| 808 } // namespace | 808 } // namespace |
| 809 | 809 |
| 810 #endif // SkLinearBitmapPipeline_sampler_DEFINED | 810 #endif // SkLinearBitmapPipeline_sampler_DEFINED |
| OLD | NEW |