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 |