diff options
author | 2016-12-19 15:40:28 -0500 | |
---|---|---|
committer | 2016-12-19 21:22:37 +0000 | |
commit | ace343286d900446737a027739dafb05c646c417 (patch) | |
tree | 0294d9b87dcac98205ef4e7acb2497283daa32dd /src/core/SkLinearBitmapPipeline_tile.h | |
parent | 9c16d1e766b60b2d87e2050298a3aa321f394648 (diff) |
Fix, cleanup and document the clamp tiler better.
* Fix by making the bounds where the bounds of the edge effect starts to be .5 pixels all around the border.
* Sample from the center of the pixel. This was wrong on the left edge.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5127
Change-Id: I39af942644fa58f0ee8dc7027481fef85b9488fe
Reviewed-on: https://skia-review.googlesource.com/5127
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'src/core/SkLinearBitmapPipeline_tile.h')
-rw-r--r-- | src/core/SkLinearBitmapPipeline_tile.h | 75 |
1 files changed, 35 insertions, 40 deletions
diff --git a/src/core/SkLinearBitmapPipeline_tile.h b/src/core/SkLinearBitmapPipeline_tile.h index df47ba0734..716b9bd14c 100644 --- a/src/core/SkLinearBitmapPipeline_tile.h +++ b/src/core/SkLinearBitmapPipeline_tile.h @@ -15,18 +15,29 @@ #include <limits> namespace { + +void assertTiled(const Sk4s& vs, SkScalar vMax) { + SkASSERT(0 <= vs[0] && vs[0] < vMax); + SkASSERT(0 <= vs[1] && vs[1] < vMax); + SkASSERT(0 <= vs[2] && vs[2] < vMax); + SkASSERT(0 <= vs[3] && vs[3] < vMax); +} + +/* + * Clamp in the X direction. + * Observations: + * * sample pointer border - if the sample point is <= 0.5 or >= Max - 0.5 then the pixel + * value should be a border color. For this case, create the span using clampToSinglePixel. + */ class XClampStrategy { public: XClampStrategy(int32_t max) - : fXMaxPixel{SkScalar(max - 0.5f)} + : fXMaxPixel{SkScalar(max - SK_ScalarHalf)} , fXMax{SkScalar(max)} { } void tileXPoints(Sk4s* xs) { - *xs = Sk4s::Min(Sk4s::Max(*xs, 0.0f), fXMaxPixel); - SkASSERT(0 <= (*xs)[0] && (*xs)[0] < fXMax); - SkASSERT(0 <= (*xs)[1] && (*xs)[1] < fXMax); - SkASSERT(0 <= (*xs)[2] && (*xs)[2] < fXMax); - SkASSERT(0 <= (*xs)[3] && (*xs)[3] < fXMax); + *xs = Sk4s::Min(Sk4s::Max(*xs, SK_ScalarHalf), fXMaxPixel); + assertTiled(*xs, fXMax); } template<typename Next> @@ -76,9 +87,9 @@ public: // * Over - for the portion of the span > xMax, take the color at pixel {xMax-1, y} and // use it to fill in the rest of the destination pixels. if (dx >= 0) { - Span leftClamped = span.breakAt(0.0f, dx); + Span leftClamped = span.breakAt(SK_ScalarHalf, dx); if (!leftClamped.isEmpty()) { - leftClamped.clampToSinglePixel({0.0f, y}); + leftClamped.clampToSinglePixel({SK_ScalarHalf, y}); next->pointSpan(leftClamped); } Span center = span.breakAt(fXMax, dx); @@ -86,21 +97,21 @@ public: next->pointSpan(center); } if (!span.isEmpty()) { - span.clampToSinglePixel({fXMax - 1, y}); + span.clampToSinglePixel({fXMaxPixel, y}); next->pointSpan(span); } } else { Span rightClamped = span.breakAt(fXMax, dx); if (!rightClamped.isEmpty()) { - rightClamped.clampToSinglePixel({fXMax - 1, y}); + rightClamped.clampToSinglePixel({fXMaxPixel, y}); next->pointSpan(rightClamped); } - Span center = span.breakAt(0.0f, dx); + Span center = span.breakAt(SK_ScalarHalf, dx); if (!center.isEmpty()) { next->pointSpan(center); } if (!span.isEmpty()) { - span.clampToSinglePixel({0.0f, y}); + span.clampToSinglePixel({SK_ScalarHalf, y}); next->pointSpan(span); } } @@ -115,22 +126,21 @@ private: class YClampStrategy { public: YClampStrategy(int32_t max) - : fYMax{SkScalar(max) - 0.5f} { } + : fYMaxPixel{SkScalar(max) - SK_ScalarHalf} { } void tileYPoints(Sk4s* ys) { - *ys = Sk4s::Min(Sk4s::Max(*ys, 0.0f), fYMax); - SkASSERT(0 <= (*ys)[0] && (*ys)[0] <= fYMax); - SkASSERT(0 <= (*ys)[1] && (*ys)[1] <= fYMax); - SkASSERT(0 <= (*ys)[2] && (*ys)[2] <= fYMax); - SkASSERT(0 <= (*ys)[3] && (*ys)[3] <= fYMax); + *ys = Sk4s::Min(Sk4s::Max(*ys, SK_ScalarHalf), fYMaxPixel); + assertTiled(*ys, fYMaxPixel + SK_ScalarHalf); } SkScalar tileY(SkScalar y) { - return std::min(std::max<SkScalar>(0.0f, y), fYMax); + Sk4f ys{y}; + tileYPoints(&ys); + return ys[0]; } private: - const SkScalar fYMax; + const SkScalar fYMaxPixel; }; SkScalar tile_mod(SkScalar x, SkScalar base) { @@ -148,10 +158,7 @@ public: Sk4s divX = *xs * fXInvMax; Sk4s modX = *xs - divX.floor() * fXMax; *xs = Sk4s::Min(fXCap, modX); - SkASSERT(0 <= (*xs)[0] && (*xs)[0] < fXMax); - SkASSERT(0 <= (*xs)[1] && (*xs)[1] < fXMax); - SkASSERT(0 <= (*xs)[2] && (*xs)[2] < fXMax); - SkASSERT(0 <= (*xs)[3] && (*xs)[3] < fXMax); + assertTiled(*xs, fXMax); } template<typename Next> @@ -245,10 +252,7 @@ public: Sk4s divX = *xs * fXInvMax; Sk4s modX = *xs - divX.floor() * fXMax; *xs = Sk4s::Min(fXCap, modX); - SkASSERT(0 <= (*xs)[0] && (*xs)[0] < fXMax); - SkASSERT(0 <= (*xs)[1] && (*xs)[1] < fXMax); - SkASSERT(0 <= (*xs)[2] && (*xs)[2] < fXMax); - SkASSERT(0 <= (*xs)[3] && (*xs)[3] < fXMax); + assertTiled(*xs, fXMax); } template<typename Next> @@ -328,10 +332,7 @@ public: Sk4s divY = *ys * fYsInvMax; Sk4s modY = *ys - divY.floor() * fYMax; *ys = modY; - SkASSERT(0 <= (*ys)[0] && (*ys)[0] < fYMax); - SkASSERT(0 <= (*ys)[1] && (*ys)[1] < fYMax); - SkASSERT(0 <= (*ys)[2] && (*ys)[2] < fYMax); - SkASSERT(0 <= (*ys)[3] && (*ys)[3] < fYMax); + assertTiled(*ys, fYMax); } SkScalar tileY(SkScalar y) { @@ -359,10 +360,7 @@ public: Sk4f mod = bias - div.floor() * 2.0f * fXMax; Sk4f unbias = mod - fXMax; *xs = Sk4f::Min(unbias.abs(), fXCap); - SkASSERT(0 <= (*xs)[0] && (*xs)[0] < fXMax); - SkASSERT(0 <= (*xs)[1] && (*xs)[1] < fXMax); - SkASSERT(0 <= (*xs)[2] && (*xs)[2] < fXMax); - SkASSERT(0 <= (*xs)[3] && (*xs)[3] < fXMax); + assertTiled(*xs, fXMax); } template <typename Next> @@ -387,10 +385,7 @@ public: Sk4f mod = bias - div.floor() * 2.0f * fYMax; Sk4f unbias = mod - fYMax; *ys = Sk4f::Min(unbias.abs(), fYCap); - SkASSERT(0 <= (*ys)[0] && (*ys)[0] < fYMax); - SkASSERT(0 <= (*ys)[1] && (*ys)[1] < fYMax); - SkASSERT(0 <= (*ys)[2] && (*ys)[2] < fYMax); - SkASSERT(0 <= (*ys)[3] && (*ys)[3] < fYMax); + assertTiled(*ys, fYMax); } SkScalar tileY(SkScalar y) { |