| 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 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 const void* row(int y) const { return fSrc + y * fWidth[0]; } | 261 const void* row(int y) const { return fSrc + y * fWidth[0]; } |
| 262 | 262 |
| 263 private: | 263 private: |
| 264 const Element* const fSrc; | 264 const Element* const fSrc; |
| 265 const Sk4i fWidth; | 265 const Sk4i fWidth; |
| 266 PixelGetter<colorType, colorProfile> fGetter; | 266 PixelGetter<colorType, colorProfile> fGetter; |
| 267 }; | 267 }; |
| 268 | 268 |
| 269 ////////////////////////////////////////////////////////////////////////////////
//////////////////// | 269 ////////////////////////////////////////////////////////////////////////////////
//////////////////// |
| 270 // GeneralSampler handles all the different sampling scenarios. It makes runtime
decisions to | 270 // GeneralSampler handles all the different sampling scenarios. It makes runtime
decisions to |
| 271 // choose the fastest stratagy given a particular job. It ultimately uses PixelG
etters to access | 271 // choose the fastest strategy given a particular job. It ultimately uses PixelG
etters to access |
| 272 // the pixels. | 272 // the pixels. |
| 273 template<SkColorType colorType, SkColorProfileType colorProfile, typename Next> | 273 template<SkColorType colorType, SkColorProfileType colorProfile, typename Next> |
| 274 class GeneralSampler { | 274 class GeneralSampler { |
| 275 public: | 275 public: |
| 276 template<typename... Args> | 276 template<typename... Args> |
| 277 GeneralSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, Args&&
... args) | 277 GeneralSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, Args&&
... args) |
| 278 : fNext{next}, fStrategy{std::forward<Args>(args)...} { } | 278 : fNext{next}, fStrategy{std::forward<Args>(args)...} { } |
| 279 | 279 |
| 280 GeneralSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, | 280 GeneralSampler(SkLinearBitmapPipeline::BlendProcessorInterface* next, |
| 281 const GeneralSampler& sampler) | 281 const GeneralSampler& sampler) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 305 SkScalar absLength = SkScalarAbs(length); | 305 SkScalar absLength = SkScalarAbs(length); |
| 306 if (absLength < (count - 1)) { | 306 if (absLength < (count - 1)) { |
| 307 this->nearestSpanSlowRate(span); | 307 this->nearestSpanSlowRate(span); |
| 308 } else if (absLength == (count - 1)) { | 308 } else if (absLength == (count - 1)) { |
| 309 this->nearestSpanUnitRate(span); | 309 this->nearestSpanUnitRate(span); |
| 310 } else { | 310 } else { |
| 311 this->nearestSpanFastRate(span); | 311 this->nearestSpanFastRate(span); |
| 312 } | 312 } |
| 313 } | 313 } |
| 314 | 314 |
| 315 Sk4f bilerNonEdgePixel(SkScalar x, SkScalar y) { | 315 Sk4f bilerpNonEdgePixel(SkScalar x, SkScalar y) { |
| 316 Sk4f px00, px10, px01, px11; | 316 Sk4f px00, px10, px01, px11; |
| 317 Sk4f xs = Sk4f{x}; | 317 // bilerp4() expects xs, ys are the top-lefts of the 2x2 kernel. |
| 318 Sk4f ys = Sk4f{y}; | 318 Sk4f xs = Sk4f{x} - 0.5f; |
| 319 Sk4f sampleXs = xs + Sk4f{-0.5f, 0.5f, -0.5f, 0.5f}; | 319 Sk4f ys = Sk4f{y} - 0.5f; |
| 320 Sk4f sampleYs = ys + Sk4f{-0.5f, -0.5f, 0.5f, 0.5f}; | 320 Sk4f sampleXs = xs + Sk4f{0.0f, 1.0f, 0.0f, 1.0f}; |
| 321 Sk4f sampleYs = ys + Sk4f{0.0f, 0.0f, 1.0f, 1.0f}; |
| 321 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); | 322 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); |
| 322 return bilerp4(xs, ys, px00, px10, px01, px11); | 323 return bilerp4(xs, ys, px00, px10, px01, px11); |
| 323 } | 324 } |
| 324 | 325 |
| 325 void VECTORCALL bilerpListFew(int n, Sk4s xs, Sk4s ys) { | 326 void VECTORCALL bilerpListFew(int n, Sk4s xs, Sk4s ys) { |
| 326 SkASSERT(0 < n && n < 4); | 327 SkASSERT(0 < n && n < 4); |
| 327 auto bilerpPixel = [&](int index) { | 328 auto bilerpPixel = [&](int index) { |
| 328 return this->bilerNonEdgePixel(xs[index], ys[index]); | 329 return this->bilerpNonEdgePixel(xs[index], ys[index]); |
| 329 }; | 330 }; |
| 330 | 331 |
| 331 if (n >= 1) fNext->blendPixel(bilerpPixel(0)); | 332 if (n >= 1) fNext->blendPixel(bilerpPixel(0)); |
| 332 if (n >= 2) fNext->blendPixel(bilerpPixel(1)); | 333 if (n >= 2) fNext->blendPixel(bilerpPixel(1)); |
| 333 if (n >= 3) fNext->blendPixel(bilerpPixel(2)); | 334 if (n >= 3) fNext->blendPixel(bilerpPixel(2)); |
| 334 } | 335 } |
| 335 | 336 |
| 336 void VECTORCALL bilerpList4(Sk4s xs, Sk4s ys) { | 337 void VECTORCALL bilerpList4(Sk4s xs, Sk4s ys) { |
| 337 auto bilerpPixel = [&](int index) { | 338 auto bilerpPixel = [&](int index) { |
| 338 return this->bilerNonEdgePixel(xs[index], ys[index]); | 339 return this->bilerpNonEdgePixel(xs[index], ys[index]); |
| 339 }; | 340 }; |
| 340 fNext->blend4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bile
rpPixel(3)); | 341 fNext->blend4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bile
rpPixel(3)); |
| 341 } | 342 } |
| 342 | 343 |
| 343 void VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) { | 344 void VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) { |
| 344 Sk4f px00, px10, px01, px11; | 345 Sk4f px00, px10, px01, px11; |
| 345 Sk4f xs = Sk4f{sampleXs[0]}; | 346 Sk4f xs = Sk4f{sampleXs[0]}; |
| 346 Sk4f ys = Sk4f{sampleYs[0]}; | 347 Sk4f ys = Sk4f{sampleYs[0]}; |
| 347 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); | 348 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); |
| 348 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); | 349 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 } | 508 } |
| 508 } | 509 } |
| 509 | 510 |
| 510 // When moving through source space more slowly than dst space (zoomed in), | 511 // When moving through source space more slowly than dst space (zoomed in), |
| 511 // we'll be sampling from the same source pixel more than once. | 512 // we'll be sampling from the same source pixel more than once. |
| 512 void bilerpSpanSlowRate(Span span, SkScalar ry1) { | 513 void bilerpSpanSlowRate(Span span, SkScalar ry1) { |
| 513 SkPoint start; | 514 SkPoint start; |
| 514 SkScalar length; | 515 SkScalar length; |
| 515 int count; | 516 int count; |
| 516 std::tie(start, length, count) = span; | 517 std::tie(start, length, count) = span; |
| 517 SkFixed fx = SkScalarToFixed(X(start) | 518 SkFixed fx = SkScalarToFixed(X(start)-0.5f); |
| 518 -0.5f); | |
| 519 | 519 |
| 520 SkFixed fdx = SkScalarToFixed(length / (count - 1)); | 520 SkFixed fdx = SkScalarToFixed(length / (count - 1)); |
| 521 //start = start + SkPoint{-0.5f, -0.5f}; | |
| 522 | 521 |
| 523 Sk4f xAdjust; | 522 Sk4f xAdjust; |
| 524 if (fdx >= 0) { | 523 if (fdx >= 0) { |
| 525 xAdjust = Sk4f{-1.0f}; | 524 xAdjust = Sk4f{-1.0f}; |
| 526 } else { | 525 } else { |
| 527 xAdjust = Sk4f{1.0f}; | 526 xAdjust = Sk4f{1.0f}; |
| 528 } | 527 } |
| 529 int ix = SkFixedFloorToInt(fx); | 528 int ix = SkFixedFloorToInt(fx); |
| 530 int ioldx = ix; | 529 int ioldx = ix; |
| 531 Sk4f x{SkFixedToScalar(fx) - ix}; | 530 Sk4f x{SkFixedToScalar(fx) - ix}; |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 | 743 |
| 745 // We're moving through source space faster than dst (zoomed out), | 744 // We're moving through source space faster than dst (zoomed out), |
| 746 // so we'll never reuse a source pixel or be able to do contiguous loads. | 745 // so we'll never reuse a source pixel or be able to do contiguous loads. |
| 747 void bilerpSpanFastRate(Span span, SkScalar y1) { | 746 void bilerpSpanFastRate(Span span, SkScalar y1) { |
| 748 SkPoint start; | 747 SkPoint start; |
| 749 SkScalar length; | 748 SkScalar length; |
| 750 int count; | 749 int count; |
| 751 std::tie(start, length, count) = span; | 750 std::tie(start, length, count) = span; |
| 752 SkScalar x = X(start); | 751 SkScalar x = X(start); |
| 753 SkScalar y = Y(start); | 752 SkScalar y = Y(start); |
| 754 if (false && y == y1) { | 753 // In this sampler, it is assumed that if span.StartY() and y1 are the s
ame then both |
| 754 // y-lines are on the same tile. |
| 755 if (y == y1) { |
| 756 // Both y-lines are on the same tile. |
| 755 struct BilerpWrapper { | 757 struct BilerpWrapper { |
| 756 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) { | 758 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) { |
| 757 fSampler.bilerpListFew(n, xs, ys); | 759 fSampler.bilerpListFew(n, xs, ys); |
| 758 } | 760 } |
| 759 | 761 |
| 760 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) { | 762 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) { |
| 761 fSampler.bilerpList4(xs, ys); | 763 fSampler.bilerpList4(xs, ys); |
| 762 } | 764 } |
| 763 | 765 |
| 764 GeneralSampler& fSampler; | 766 GeneralSampler& fSampler; |
| 765 }; | 767 }; |
| 766 BilerpWrapper wrapper{*this}; | 768 BilerpWrapper wrapper{*this}; |
| 767 span_fallback(span, &wrapper); | 769 span_fallback(span, &wrapper); |
| 768 } else { | 770 } else { |
| 771 // The y-lines are on different tiles. |
| 769 SkScalar dx = length / (count - 1); | 772 SkScalar dx = length / (count - 1); |
| 770 Sk4f ys = {y - 0.5f, y - 0.5f, y1 + 0.5f, y1 + 0.5f}; | 773 Sk4f ys = {y - 0.5f, y - 0.5f, y1 + 0.5f, y1 + 0.5f}; |
| 771 while (count > 0) { | 774 while (count > 0) { |
| 772 Sk4f xs = Sk4f{-0.5f, 0.5f, -0.5f, 0.5f} + Sk4f{x}; | 775 Sk4f xs = Sk4f{-0.5f, 0.5f, -0.5f, 0.5f} + Sk4f{x}; |
| 773 this->bilerpEdge(xs, ys); | 776 this->bilerpEdge(xs, ys); |
| 774 x += dx; | 777 x += dx; |
| 775 count -= 1; | 778 count -= 1; |
| 776 } | 779 } |
| 777 } | 780 } |
| 778 } | 781 } |
| 779 | 782 |
| 780 Next* const fNext; | 783 Next* const fNext; |
| 781 PixelAccessor<colorType, colorProfile> fStrategy; | 784 PixelAccessor<colorType, colorProfile> fStrategy; |
| 782 }; | 785 }; |
| 783 | 786 |
| 784 } // namespace | 787 } // namespace |
| 785 | 788 |
| 786 #endif // SkLinearBitmapPipeline_sampler_DEFINED | 789 #endif // SkLinearBitmapPipeline_sampler_DEFINED |
| OLD | NEW |