aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkLinearBitmapPipeline_tile.h
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2016-12-19 15:40:28 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-12-19 21:22:37 +0000
commitace343286d900446737a027739dafb05c646c417 (patch)
tree0294d9b87dcac98205ef4e7acb2497283daa32dd /src/core/SkLinearBitmapPipeline_tile.h
parent9c16d1e766b60b2d87e2050298a3aa321f394648 (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.h75
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) {