Chromium Code Reviews| Index: src/core/SkLinearBitmapPipeline.cpp |
| diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp |
| index e836746a891ff740d74d7422f08336cff16c214a..103c7ba89c1643d038eeed32bba52781ddc4786c 100644 |
| --- a/src/core/SkLinearBitmapPipeline.cpp |
| +++ b/src/core/SkLinearBitmapPipeline.cpp |
| @@ -132,6 +132,28 @@ private: |
| SkScalar fLength; |
| int fCount; |
| }; |
| + |
|
mtklein_C
2016/03/01 16:34:09
Let'd document what a BilerpSpan represents, espec
herb_g
2016/03/01 22:13:58
Done.
|
| +class BilerpSpan { |
| +public: |
| + BilerpSpan(SkScalar x, SkScalar y0, SkScalar y1, SkScalar length, int count) |
| + : fX{x}, fY0{y0}, fY1{y1}, fLength{length}, fCount{count} { |
| + SkASSERT(count >= 0); |
| + SkASSERT(std::isfinite(length)); |
| + } |
| + |
| + operator std::tuple<SkScalar&, SkScalar&, SkScalar&, SkScalar&, int&>() { |
| + return std::tie(fX, fY0, fY1, fLength, fCount); |
| + } |
| + |
| + bool isEmpty() const { return 0 == fCount; } |
| + |
| +private: |
| + SkScalar fX; |
| + SkScalar fY0; |
| + SkScalar fY1; |
| + SkScalar fLength; |
| + int fCount; |
| +}; |
| } // namespace |
| class SkLinearBitmapPipeline::PointProcessorInterface { |
| @@ -158,6 +180,7 @@ public: |
| // These pixels coordinates are arranged in the following order in xs and ys: |
| // px00 px10 px01 px11 |
| virtual void VECTORCALL bilerpList(Sk4s xs, Sk4s ys) = 0; |
| + virtual void bilerpSpan(BilerpSpan span) = 0; |
| }; |
| class SkLinearBitmapPipeline::PixelPlacerInterface { |
| @@ -197,6 +220,24 @@ void span_fallback(Span span, Stage* stage) { |
| } |
| } |
| +template <typename Next> |
| +void bilerp_span_fallback(BilerpSpan span, Next* next) { |
| + |
|
mtklein_C
2016/03/01 16:34:09
Stray newline.
herb_g
2016/03/01 22:13:58
Done.
|
| + SkASSERT(!span.isEmpty()); |
| + SkScalar x, y0, y1; SkScalar length; int count; |
| + std::tie(x, y0, y1, length, count) = span; |
| + float dx = length / (count - 1); |
|
mtklein_C
2016/03/01 16:34:09
Do we not need the usual inf/NaN worries here, or
herb_g
2016/03/01 22:13:58
Done.
|
| + |
| + Sk4f xs = Sk4f{x} + Sk4f{0.0f, 1.0f, 0.0f, 1.0f}; |
| + Sk4f ys = Sk4f{y0, y0, y1, y1}; |
| + |
| + while (count > 0) { |
| + next->bilerpList(xs, ys); |
| + xs = xs + dx; |
| + count -= 1; |
| + } |
| +} |
| + |
| // PointProcessor uses a strategy to help complete the work of the different stages. The strategy |
| // must implement the following methods: |
| // * processPoints(xs, ys) - must mutate the xs and ys for the stage. |
| @@ -268,6 +309,13 @@ public: |
| } |
| } |
| + void bilerpSpan(BilerpSpan bSpan) override { |
| + SkASSERT(!bSpan.isEmpty()); |
| + if (!fStrategy.maybeProcessBilerpSpan(bSpan, fNext)) { |
| + bilerp_span_fallback(bSpan, this); |
| + } |
| + } |
| + |
| private: |
| Next* const fNext; |
| Strategy fStrategy; |
| @@ -409,17 +457,9 @@ public: |
| SkASSERT(!span.isEmpty()); |
| SkPoint start; SkScalar length; int count; |
| std::tie(start, length, count) = span; |
| - float dx = length / (count - 1); |
| - |
| - Sk4f Xs = Sk4f{X(start)} + Sk4f{-0.5f, 0.5f, -0.5f, 0.5f}; |
| - Sk4f Ys = Sk4f{Y(start)} + Sk4f{-0.5f, -0.5f, 0.5f, 0.5f}; |
| - |
| - Sk4f dXs{dx}; |
| - while (count > 0) { |
| - fNext->bilerpList(Xs, Ys); |
| - Xs = Xs + dXs; |
| - count -= 1; |
| - } |
| + // Adjust the span so that it is in the correct phase with the pixel. |
| + BilerpSpan bSpan{X(start) - 0.5f, Y(start) - 0.5f, Y(start) + 0.5f, length, count}; |
| + fNext->bilerpSpan(bSpan); |
| } |
| private: |
| @@ -540,6 +580,11 @@ public: |
| return true; |
| } |
| + template <typename Next> |
| + bool maybeProcessBilerpSpan(BilerpSpan bSpan, Next* next) { |
| + return false; |
| + } |
| + |
| private: |
| const Sk4s fXMin{SK_FloatNegativeInfinity}; |
| const Sk4s fYMin{SK_FloatNegativeInfinity}; |
| @@ -643,6 +688,11 @@ public: |
| return true; |
| } |
| + template <typename Next> |
| + bool maybeProcessBilerpSpan(BilerpSpan bSpan, Next* next) { |
| + return false; |
| + } |
| + |
| private: |
| const Sk4s fXMax{0.0f}; |
| const Sk4s fXInvMax{0.0f}; |
| @@ -832,6 +882,10 @@ public: |
| span_fallback(span, this); |
| } |
| + void bilerpSpan(BilerpSpan span) override { |
| + bilerp_span_fallback(span, this); |
| + } |
| + |
| private: |
| SkLinearBitmapPipeline::PixelPlacerInterface* const fNext; |
| SourceStrategy fStrategy; |