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.
|
} |
} |