aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar herb <herb@google.com>2016-02-19 14:39:47 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-02-19 14:39:47 -0800
commit3eb4895ea1205a5a2dd1457bf67a1497a29ebc81 (patch)
treef8ad6d9bcd4845a87270a70c0d05e2db0b55b2a5
parentcbf897802b41d61dc35d6db0552d8d9604945fdc (diff)
Add point spans, but fall back for all cases.
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1711963003 curr/maxrss loops min median mean max stddev samples config bench 10/10 MB 1 481µs 504µs 512µs 580µs 6% ▁▁▄▆▂▃▁▁▁▁▁▁▃▇█▅▃█▃▅ nonrendering SkBitmapFPAffineXClampYClampFilterOrig 10/10 MB 1 2.21ms 2.31ms 2.31ms 2.53ms 4% ▁▁▆▃▃▃▄▅▂▁▄▁█▅▁▁▄▂▆▁ nonrendering SkBitmapFPAffineXClampYClampFilterLinr 10/10 MB 1 2.49ms 2.63ms 2.61ms 2.78ms 4% ▄▃▇▄▅▇▆▁▆▁▁▁▅▂▁▄▃█▆▃ nonrendering SkBitmapFPAffineXClampYClampFiltersRGB 10/10 MB 2 150µs 151µs 153µs 162µs 2% ▅▇▂▂▁▁▂▂▁▁▂▂▁▁▁▁▇█▂▁ nonrendering SkBitmapFPAffineXClampYClampNearestOrig 10/10 MB 1 552µs 553µs 562µs 658µs 4% ▁▁▁▁▁▁▁▁▁▄▃▁▁▁▁▁▁▁▁█ nonrendering SkBitmapFPAffineXClampYClampNearestLinr 10/10 MB 1 718µs 742µs 748µs 808µs 4% ▃▃▁▁▅▁▁▁▁▃▃▃▃▇▇▇▁▁▇█ nonrendering SkBitmapFPAffineXClampYClampNearestsRGB 10/10 MB 1 277µs 286µs 292µs 341µs 7% █▁▁▁▁▁▁▁▁▁▃▂▃▃▆█▄▂▂▂ nonrendering SkBitmapFPScaleXClampYClampFilterOrig 10/10 MB 1 2.21ms 2.41ms 2.39ms 2.55ms 4% ▄▆▃▅▇▂▁▁▇▅▆▅▅▆▄▅█▅▆▅ nonrendering SkBitmapFPScaleXClampYClampFilterLinr 10/10 MB 1 2.55ms 2.68ms 2.69ms 2.94ms 4% ▂▃▁▁▄▄▅▅▄▃█▄▃▇▂▁▃▃▂▂ nonrendering SkBitmapFPScaleXClampYClampFiltersRGB 10/10 MB 4 59.9µs 60.6µs 61.6µs 71.1µs 5% ▂▃▄▁▁▁▁█▇▁▂▁▁▁▁▁▁▁▁▁ nonrendering SkBitmapFPScaleXClampYClampNearestOrig 10/10 MB 1 534µs 560µs 559µs 613µs 5% ▇▂▁▅▅▅█▅▅▃▁▁▁▁▂▄▅▁▁▁ nonrendering SkBitmapFPScaleXClampYClampNearestLinr 10/10 MB 1 639µs 658µs 666µs 731µs 5% ▅█▃▂▃▇▆▁▁▁▁▁▂▁▁▁▁▄█▄ nonrendering SkBitmapFPScaleXClampYClampNearestsRGB 10/10 MB 4 61.6µs 65.7µs 65.5µs 70.4µs 5% ▃▃▃█▆▆▂▂▂▅▄▄▇▄▁▂▁▄██ nonrendering SkBitmapFPIdentityXClampYClampFilterOrig 10/10 MB 1 2.22ms 2.34ms 2.35ms 2.57ms 3% ▂█▅▄▃▃▃▄▂▄▄▄▂▄▁▆▃▁▄▃ nonrendering SkBitmapFPIdentityXClampYClampFilterLinr 10/10 MB 1 2.42ms 2.52ms 2.52ms 2.76ms 4% ▁▁▄▂▄▄▃▅█▄▅▁▃▁▁▃▁▄▃▃ nonrendering SkBitmapFPIdentityXClampYClampFiltersRGB 10/10 MB 4 59.7µs 64.7µs 64.8µs 73.3µs 7% ▂▂▄▁▂▁▁▂▁▁▆▄▆▆▇▄▆▇▂█ nonrendering SkBitmapFPIdentityXClampYClampNearestOrig 10/10 MB 1 376µs 388µs 387µs 429µs 4% ▃▃▆▁▄▄▁▃█▁▁▁▁▁▃▃▄▁▁▁ nonrendering SkBitmapFPIdentityXClampYClampNearestLinr 10/10 MB 1 496µs 511µs 518µs 568µs 5% ▂▆▆█▆▃▂▂█▇▃▁▁▁▁▁▁▁▁▁ nonrendering SkBitmapFPIdentityXClampYClampNearestsRGB Review URL: https://codereview.chromium.org/1711963003
-rw-r--r--src/core/SkLinearBitmapPipeline.cpp75
-rw-r--r--src/core/SkLinearBitmapPipeline.h13
-rw-r--r--tests/SkLinearBitmapPipelineTest.cpp2
3 files changed, 70 insertions, 20 deletions
diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp
index 1565b7e32b..958a945aef 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,34 @@ 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) {
+ // If count == 1 use PointListFew instead.
+ SkASSERT(count > 1);
+
+ 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 fourDx = {4.0f * dx};
+
+ while (count >= 4) {
+ stage->pointList4(Xs, Ys);
+ Xs = Xs + fourDx;
+ count -= 4;
+ }
+ if (count > 0) {
+ stage->pointListFew(count, Xs, Ys);
+ }
+}
+
template<typename Strategy, typename Next>
class PointProcessor final : public PointProcessorInterface {
public:
@@ -56,6 +76,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 +114,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 +130,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 +246,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 +490,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 +596,16 @@ 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 {
+ // The count and length arguments start out in a precise relation in order to keep the
+ // math correct through the different stages. Count is the number of pixel to produce.
+ // Since the code samples at pixel centers, length is the distance from the center of the
+ // first pixel to the center of the last pixel. This implies that length is count-1.
+ fFirstStage->pointSpan(SkPoint{x + 0.5f, y + 0.5f}, count - 1, count);
}
}
diff --git a/src/core/SkLinearBitmapPipeline.h b/src/core/SkLinearBitmapPipeline.h
index 5f9da1ea4c..d9748df750 100644
--- a/src/core/SkLinearBitmapPipeline.h
+++ b/src/core/SkLinearBitmapPipeline.h
@@ -22,6 +22,19 @@ public:
virtual ~PointProcessorInterface() { }
virtual void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) = 0;
virtual void pointList4(Sk4fArg xs, Sk4fArg ys) = 0;
+
+ // The pointSpan method efficiently process horizontal spans of pixels.
+ // * start - the point where to start the span.
+ // * length - the number of pixels to traverse in source space.
+ // * count - the number of pixels to produce in destination space.
+ // Both start and length are mapped through the inversion matrix to produce values in source
+ // space. After the matrix operation, the tilers may break the spans up into smaller spans.
+ // The tilers can produce spans that seem nonsensical.
+ // * The clamp tiler can create spans with length of 0. This indicates to copy an edge pixel out
+ // to the edge of the destination scan.
+ // * The mirror tiler can produce spans with negative length. This indicates that the source
+ // should be traversed in the opposite direction to the destination pixels.
+ virtual void pointSpan(SkPoint start, SkScalar length, int count) = 0;
};
class BilerpProcessorInterface : public PointProcessorInterface {
diff --git a/tests/SkLinearBitmapPipelineTest.cpp b/tests/SkLinearBitmapPipelineTest.cpp
index 8a6ed087c3..9d12f1b465 100644
--- a/tests/SkLinearBitmapPipelineTest.cpp
+++ b/tests/SkLinearBitmapPipelineTest.cpp
@@ -13,7 +13,7 @@
struct SinkBilerpProcessor final : public PointProcessorInterface {
void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { fXs = xs; fYs = ys; }
void pointList4(Sk4fArg Xs, Sk4fArg Ys) override { fXs = Xs; fYs = Ys; }
-
+ void pointSpan(SkPoint start, SkScalar length, int count) override { }
Sk4f fXs;
Sk4f fYs;
};