Chromium Code Reviews| Index: src/core/SkLinearBitmapPipeline.cpp |
| diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp |
| index 1565b7e32bce8ac0d8cf1b8e8af3faf79e620b31..0f7299a67111e632e8c23c9ee57d8a80481b7b61 100644 |
| --- a/src/core/SkLinearBitmapPipeline.cpp |
| +++ b/src/core/SkLinearBitmapPipeline.cpp |
| @@ -16,9 +16,9 @@ |
| struct X { |
| explicit X(SkScalar val) : fVal{val} { } |
| - explicit X(SkPoint pt) : fVal{pt.fX} { } |
| - explicit X(SkSize s) : fVal{s.fWidth} { } |
| - explicit X(SkISize s) : fVal(s.fWidth) { } |
| + explicit X(SkPoint pt) : fVal{pt.fX} { } |
| + explicit X(SkSize s) : fVal{s.fWidth} { } |
| + explicit X(SkISize s) : fVal(s.fWidth) { } |
| operator float () const {return fVal;} |
| private: |
| float fVal; |
| @@ -26,14 +26,33 @@ private: |
| struct Y { |
| explicit Y(SkScalar val) : fVal{val} { } |
| - explicit Y(SkPoint pt) : fVal{pt.fY} { } |
| - explicit Y(SkSize s) : fVal{s.fHeight} { } |
| - explicit Y(SkISize s) : fVal(s.fHeight) { } |
| + explicit Y(SkPoint pt) : fVal{pt.fY} { } |
| + explicit Y(SkSize s) : fVal{s.fHeight} { } |
| + explicit Y(SkISize s) : fVal(s.fHeight) { } |
| operator float () const {return fVal;} |
| private: |
| float fVal; |
| }; |
| +template <typename Stage> |
| +void span_fallback(SkPoint start, SkScalar length, int count, Stage* stage) { |
| + SkASSERT(count > 1); |
|
mtklein
2016/02/19 20:54:19
// No point to count == 1... should just use point
herb_g
2016/02/19 22:07:44
Done.
|
| + |
| + float dx = length / (count - 1); |
| + Sk4f Xs = Sk4f(X(start)) + Sk4f{0.0f, 1.0f, 2.0f, 3.0f} * Sk4f{dx}; |
| + Sk4f Ys{Y(start)}; |
| + Sk4f fours = {4.0f * dx}; |
|
mtklein
2016/02/19 20:54:19
fourDX?
herb_g
2016/02/19 22:07:44
Done.
|
| + |
| + while (count >= 4) { |
| + stage->pointList4(Xs, Ys); |
| + Xs = Xs + fours; |
| + count -= 4; |
| + } |
| + if (count > 0) { |
| + stage->pointListFew(count, Xs, Ys); |
| + } |
| +} |
| + |
| template<typename Strategy, typename Next> |
| class PointProcessor final : public PointProcessorInterface { |
| public: |
| @@ -56,6 +75,10 @@ public: |
| fNext->pointList4(newXs, newYs); |
| } |
| + void pointSpan(SkPoint start, SkScalar length, int count) override { |
| + span_fallback(start, length, count, this); |
| + } |
| + |
| private: |
| Next* const fNext; |
| Strategy fStrategy; |
| @@ -90,6 +113,10 @@ public: |
| fNext->bilerpList(newXs, newYs); |
| } |
| + void pointSpan(SkPoint start, SkScalar length, int count) override { |
| + span_fallback(start, length, count, this); |
| + } |
| + |
| private: |
| Next* const fNext; |
| Strategy fStrategy; |
| @@ -102,7 +129,10 @@ class SkippedStage final : public BilerpProcessorInterface { |
| void pointList4(Sk4fArg Xs, Sk4fArg Ys) override { |
| SkFAIL("Skipped stage."); |
| } |
| - virtual void bilerpList(Sk4fArg xs, Sk4fArg ys) override { |
| + void bilerpList(Sk4fArg xs, Sk4fArg ys) override { |
| + SkFAIL("Skipped stage."); |
| + } |
| + void pointSpan(SkPoint start, SkScalar length, int count) override { |
| SkFAIL("Skipped stage."); |
| } |
| }; |
| @@ -215,6 +245,10 @@ public: |
| fNext->bilerpList(Sk4f{xs[3]} + kXOffsets, Sk4f{ys[3]} + kYOffsets); |
| } |
| + void pointSpan(SkPoint start, SkScalar length, int count) override { |
| + span_fallback(start, length, count, this); |
| + } |
| + |
| private: |
| Next* const fNext; |
| }; |
| @@ -455,6 +489,10 @@ public: |
| fNext->placePixel(pixel); |
| } |
| + void pointSpan(SkPoint start, SkScalar length, int count) override { |
| + span_fallback(start, length, count, this); |
| + } |
| + |
| private: |
| PixelPlacerInterface* const fNext; |
| SourceStrategy fStrategy; |
| @@ -557,18 +595,12 @@ SkLinearBitmapPipeline::SkLinearBitmapPipeline( |
| } |
| void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { |
| + SkASSERT(count > 0); |
| fPixelStage->setDestination(dst); |
| - |
| - Sk4f Xs = Sk4f(x) + Sk4f{0.5f, 1.5f, 2.5f, 3.5f}; |
| - Sk4f Ys(y); |
| - Sk4f fours{4.0f}; |
| - |
| - while (count >= 4) { |
| - fFirstStage->pointList4(Xs, Ys); |
| - Xs = Xs + fours; |
| - count -= 4; |
| - } |
| - if (count > 0) { |
| - fFirstStage->pointListFew(count, Xs, Ys); |
| + // Adjust points by 0.5, 0.5 to sample from the center of the pixels. |
| + if (count == 1) { |
| + fFirstStage->pointListFew(1, Sk4f{x + 0.5f}, Sk4f{y + 0.5f}); |
| + } else { |
| + fFirstStage->pointSpan(SkPoint{x + 0.5f, y + 0.5f}, count - 1, count); |
|
mtklein
2016/02/19 20:54:19
// Good place for diagrams and an explanation of r
herb_g
2016/02/19 22:07:44
Done.
|
| } |
| } |