diff options
author | herb <herb@google.com> | 2016-02-19 14:39:47 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-19 14:39:47 -0800 |
commit | 3eb4895ea1205a5a2dd1457bf67a1497a29ebc81 (patch) | |
tree | f8ad6d9bcd4845a87270a70c0d05e2db0b55b2a5 | |
parent | cbf897802b41d61dc35d6db0552d8d9604945fdc (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.cpp | 75 | ||||
-rw-r--r-- | src/core/SkLinearBitmapPipeline.h | 13 | ||||
-rw-r--r-- | tests/SkLinearBitmapPipelineTest.cpp | 2 |
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; }; |